diff --git a/etc/Patches/!_Readme.txt b/etc/Patches/!_Readme.txt new file mode 100644 index 00000000..7b7c3597 --- /dev/null +++ b/etc/Patches/!_Readme.txt @@ -0,0 +1,14 @@ +LameXP third-party patches +-------------------------- + +This directory contains the modifications (as Unified Diff's) that have been applied to third-party audio tools as part of the development of LameXP. + +Most of these modifications were required to fix Unicode support on the Windows platform and/or to properly flush the STDOUT for "real-time" progress updates. + +Other modifications were required to make the third-party audio tools compile+link properly in the build environment used in the development of LameXP. + +All the patches provided here are Copyright (c) LoRd_MuldeR 2004-2012; they are released under the same license as the original audio tools. + +Please note that the patches provided here have NOT been approved by the original developers of the third-party audio tools - use them at your own risk! + +They are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of FITNESS FOR A PARTICULAR PURPOSE. diff --git a/etc/Patches/AC3Filter-valdec-v0.31b-UTF8+STDOUT+Flush.V1.diff b/etc/Patches/AC3Filter-valdec-v0.31b-UTF8+STDOUT+Flush.V1.diff new file mode 100644 index 00000000..800f02f4 --- /dev/null +++ b/etc/Patches/AC3Filter-valdec-v0.31b-UTF8+STDOUT+Flush.V1.diff @@ -0,0 +1,997 @@ + tools/unicode_support.cpp | 86 ++++++++++++++++++ + tools/unicode_support.h | 21 +++++ + tools/valdec.cpp | 180 ++++++++++++++++++++++++-------------- + tools/valdec.sln | 50 +++++++---- + tools/valdec.vcproj | 61 +++++++------ + valib/lib/valib.vcproj | 19 ++++- + valib/valib/auto_file.cpp | 3 +- + valib/valib/sink/sink_dsound.cpp | 4 +- + valib/valib/sink/sink_stdout.h | 93 ++++++++++++++++++++ + 9 files changed, 402 insertions(+), 115 deletions(-) + +diff --git a/tools/unicode_support.cpp b/tools/unicode_support.cpp +new file mode 100644 +index 0000000..13f89ba +--- /dev/null ++++ b/tools/unicode_support.cpp +@@ -0,0 +1,86 @@ ++#include "unicode_support.h" ++ ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = new char[BuffSize]; //(char*) malloc(sizeof(char) * BuffSize); ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = new wchar_t[BuffSize]; //(wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i, nArgs; ++ LPWSTR *szArglist; ++ ++ szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); ++ ++ if(NULL == szArglist) ++ { ++ fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); ++ exit(-1); ++ } ++ ++ *argv = new char*[nArgs]; //malloc(sizeof(char*) * nArgs); ++ *argc = nArgs; ++ ++ for(i = 0; i < nArgs; i++) ++ { ++ (*argv)[i] = utf16_to_utf8(szArglist[i]); ++ } ++ ++ LocalFree(szArglist); ++} ++ ++void free_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ if(*argv != NULL) ++ { ++ for(int i = 0; i < *argc; i++) ++ { ++ if((*argv)[i] != NULL) ++ { ++ delete [] ((*argv)[i]); ++ (*argv)[i] = NULL; ++ } ++ } ++ delete [] (*argv); ++ *argv = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) delete [] filename_utf16; ++ if(mode_utf16) delete [] mode_utf16; ++ ++ return ret; ++} +diff --git a/tools/unicode_support.h b/tools/unicode_support.h +new file mode 100644 +index 0000000..9ad3173 +--- /dev/null ++++ b/tools/unicode_support.h +@@ -0,0 +1,21 @@ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++char *utf16_to_utf8(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int *argc, char ***argv); ++void free_commandline_arguments_utf8(int *argc, char ***argv); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +diff --git a/tools/valdec.cpp b/tools/valdec.cpp +index 6b24ecf..b5fe15d 100644 +--- a/tools/valdec.cpp ++++ b/tools/valdec.cpp +@@ -15,6 +15,7 @@ + #include "sink\sink_raw.h" + #include "sink\sink_wav.h" + #include "sink\sink_dsound.h" ++#include "sink\sink_stdout.h" + + // filters + #include "filters\dvd_graph.h" +@@ -22,6 +23,7 @@ + // other + #include "win32\cpu.h" + #include "vargs.h" ++#include "unicode_support.h" + + + #define bool2str(v) ((v)? "true": "false") +@@ -65,7 +67,7 @@ const sample_t level_tbl[] = + 1.0 + }; + +-int main(int argc, char *argv[]) ++int valdec_main(int argc, char *argv[]) + { + if (argc < 2) + { +@@ -77,6 +79,7 @@ int main(int argc, char *argv[]) + "\n" + "This utility is a part of AC3Filter project (http://ac3filter.net)\n" + "Copyright (c) 2006-2009 by Alexander Vigovsky\n" ++"Support for Unicode file names and STDOUT output added by LoRd_MuldeR\n" + "\n" + "Usage:\n" + " valdec some_file [options]\n" +@@ -91,6 +94,7 @@ int main(int argc, char *argv[]) + " -r[aw] file.raw - decode to RAW file\n" + " -w[av] file.wav - decode to WAV file\n" + " -n[othing] - do nothing (to be used with -i option)\n" ++" -s[td] - decode to RAW and write to STDOUT\n" + " \n" + " output options:\n" + //" -spdif - spdif output (no other options will work in this mode)\n" +@@ -184,12 +188,13 @@ int main(int argc, char *argv[]) + ///////////////////////////////////////////////////////// + // Sinks + +- enum { mode_undefined, mode_nothing, mode_play, mode_raw, mode_wav, mode_decode } mode = mode_undefined; ++ enum { mode_undefined, mode_nothing, mode_play, mode_raw, mode_wav, mode_decode, mode_stdout } mode = mode_undefined; + const char *out_filename = 0; + + RAWSink raw; + WAVSink wav; + DSoundSink dsound; ++ StdOutSink stdsnk; + NullSink null; + + Sink *sink = 0; +@@ -216,7 +221,7 @@ int main(int argc, char *argv[]) + { + if (parser) + { +- printf("-ac3 : ambigous parser\n"); ++ fprintf(stderr, "-ac3 : ambigous parser\n"); + return 1; + } + +@@ -229,7 +234,7 @@ int main(int argc, char *argv[]) + { + if (parser) + { +- printf("-dts : ambigous parser\n"); ++ fprintf(stderr, "-dts : ambigous parser\n"); + return 1; + } + +@@ -242,7 +247,7 @@ int main(int argc, char *argv[]) + { + if (parser) + { +- printf("-mpa : ambigous parser\n"); ++ fprintf(stderr, "-mpa : ambigous parser\n"); + return 1; + } + +@@ -268,7 +273,7 @@ int main(int argc, char *argv[]) + + if (imask < 0 || imask > array_size(mask_tbl)) + { +- printf("-spk : incorrect speaker configuration\n"); ++ fprintf(stderr, "-spk : incorrect speaker configuration\n"); + return 1; + } + continue; +@@ -280,7 +285,7 @@ int main(int argc, char *argv[]) + iformat = int(arg_num(argv[iarg])); + if (iformat < 0 || iformat > array_size(format_tbl)) + { +- printf("-fmt : incorrect sample format"); ++ fprintf(stderr, "-fmt : incorrect sample format"); + return 1; + } + continue; +@@ -296,7 +301,7 @@ int main(int argc, char *argv[]) + { + if (sink) + { +- printf("-decode : ambigous output mode\n"); ++ fprintf(stderr, "-decode : ambigous output mode\n"); + return 1; + } + +@@ -312,7 +317,7 @@ int main(int argc, char *argv[]) + { + if (sink) + { +- printf("-play : ambigous output mode\n"); ++ fprintf(stderr, "-play : ambigous output mode\n"); + return 1; + } + +@@ -328,12 +333,12 @@ int main(int argc, char *argv[]) + { + if (sink) + { +- printf("-raw : ambigous output mode\n"); ++ fprintf(stderr, "-raw : ambigous output mode\n"); + return 1; + } + if (argc - iarg < 1) + { +- printf("-raw : specify a file name\n"); ++ fprintf(stderr, "-raw : specify a file name\n"); + return 1; + } + +@@ -343,19 +348,40 @@ int main(int argc, char *argv[]) + mode = mode_raw; + continue; + } ++ ++ // -s[td] - RAW output to STDOUT ++ if (is_arg(argv[iarg], "s", argt_exist) || ++ is_arg(argv[iarg], "std", argt_exist)) ++ { ++ if (sink) ++ { ++ fprintf(stderr, "-std : ambigous output mode\n"); ++ return 1; ++ } ++ if (argc - iarg < 1) ++ { ++ fprintf(stderr, "-std : specify a file name\n"); ++ return 1; ++ } + ++ //out_filename = argv[++iarg]; ++ sink = &stdsnk; ++ control = 0; ++ mode = mode_stdout; ++ continue; ++ } + // -w[av] - WAV output + if (is_arg(argv[iarg], "w", argt_exist) || + is_arg(argv[iarg], "wav", argt_exist)) + { + if (sink) + { +- printf("-wav : ambigous output mode\n"); ++ fprintf(stderr, "-wav : ambigous output mode\n"); + return 1; + } + if (argc - iarg < 1) + { +- printf("-wav : specify a file name\n"); ++ fprintf(stderr, "-wav : specify a file name\n"); + return 1; + } + +@@ -372,7 +398,7 @@ int main(int argc, char *argv[]) + { + if (sink) + { +- printf("-nothing : ambigous output mode\n"); ++ fprintf(stderr, "-nothing : ambigous output mode\n"); + return 1; + } + +@@ -614,7 +640,7 @@ int main(int argc, char *argv[]) + continue; + } + +- printf("Error: unknown option: %s\n", argv[iarg]); ++ fprintf(stderr, "Error: unknown option: %s\n", argv[iarg]); + return 1; + } + +@@ -627,13 +653,13 @@ int main(int argc, char *argv[]) + + if (!file.open(input_filename, parser, 1000000)) + { +- printf("Error: Cannot open file '%s'\n", input_filename); ++ fprintf(stderr, "Error: Cannot open file '%s'\n", input_filename); + return 1; + } + + if (!file.stats()) + { +- printf("Error: Cannot detect input file format\n", input_filename); ++ fprintf(stderr, "Error: Cannot detect input file format\n", input_filename); + return 1; + } + +@@ -643,7 +669,7 @@ int main(int argc, char *argv[]) + + if (!file.is_frame_loaded()) + { +- printf("Error: Cannot load the first frame\n"); ++ fprintf(stderr, "Error: Cannot load the first frame\n"); + return 1; + } + +@@ -655,9 +681,9 @@ int main(int argc, char *argv[]) + { + char info[1024]; + file.file_info(info, sizeof(info)); +- printf("%s\n", info); ++ fprintf(stderr, "%s\n", info); + file.stream_info(info, sizeof(info)); +- printf("%s", info); ++ fprintf(stderr, "%s", info); + } + + if (mode == mode_nothing) +@@ -678,7 +704,7 @@ int main(int argc, char *argv[]) + Speakers user_spk(format_tbl[iformat], mask_tbl[imask], 0, level_tbl[iformat]); + if (!dvd_graph.set_user(user_spk)) + { +- printf("Error: unsupported user format (%s %s %i)\n", ++ fprintf(stderr, "Error: unsupported user format (%s %s %i)\n", + user_spk.format_text(), user_spk.mode_text(), user_spk.sample_rate); + return 1; + } +@@ -686,7 +712,7 @@ int main(int argc, char *argv[]) + Speakers in_spk = file.get_spk(); + if (!dvd_graph.set_input(in_spk)) + { +- printf("Error: unsupported input format (%s %s %i)\n", ++ fprintf(stderr, "Error: unsupported input format (%s %s %i)\n", + in_spk.format_text(), in_spk.mode_text(), in_spk.sample_rate); + return 1; + } +@@ -718,10 +744,18 @@ int main(int argc, char *argv[]) + + switch (mode) + { ++ case mode_stdout: ++ if (!stdsnk.is_open()) ++ { ++ fprintf(stderr, "Error: failed to open standard output handle.\n"); ++ return 1; ++ } ++ break; ++ + case mode_raw: + if (!out_filename || !raw.open(out_filename)) + { +- printf("Error: failed to open output file '%s'\n", out_filename); ++ fprintf(stderr, "Error: failed to open output file '%s'\n", out_filename); + return 1; + } + break; +@@ -729,7 +763,7 @@ int main(int argc, char *argv[]) + case mode_wav: + if (!out_filename || !wav.open(out_filename)) + { +- printf("Error: failed to open output file '%s'\n", out_filename); ++ fprintf(stderr, "Error: failed to open output file '%s'\n", out_filename); + return 1; + } + break; +@@ -737,7 +771,7 @@ int main(int argc, char *argv[]) + case mode_play: + if (!dsound.open_dsound(0)) + { +- printf("Error: failed to init DirectSound\n"); ++ fprintf(stderr, "Error: failed to init DirectSound\n"); + return 1; + } + break; +@@ -765,27 +799,28 @@ int main(int argc, char *argv[]) + + int streams = 0; + +-// fprintf(stderr, " 0.0%% Frs: 0 Err: 0 Time: 0:00.000i Level: 0dB FPS: 0 CPU: 0%%\r"); ++// ffprintf(stderr, stderr, " 0.0%% Frs: 0 Err: 0 Time: 0:00.000i Level: 0dB FPS: 0 CPU: 0%%\r"); + + file.seek(0); + +- #define PRINT_STAT \ +- { \ +- if (control) \ +- { \ +- dvd_graph.proc.get_output_levels(control->get_playback_time(), levels); \ +- level = levels[0]; \ +- for (i = 1; i < NCHANNELS; i++) \ +- if (levels[i] > level) \ +- level = levels[i]; \ +- } \ +- fprintf(stderr, "%4.1f%% Frs: %-6i Err: %-i Time: %3i:%02i.%03i Level: %-4idB FPS: %-4i CPU: %.1f%% \r", \ +- file.get_pos(file.relative) * 100, \ +- file.get_frames(), dvd_graph.dec.get_errors(), \ +- int(time/60), int(time) % 60, int(time * 1000) % 1000, \ +- int(value2db(level)), \ +- int(file.get_frames() / time), \ +- cpu_current.usage() * 100); \ ++ #define PRINT_STAT \ ++ { \ ++ if (control) \ ++ { \ ++ dvd_graph.proc.get_output_levels(control->get_playback_time(), levels); \ ++ level = levels[0]; \ ++ for (i = 1; i < NCHANNELS; i++) \ ++ if (levels[i] > level) \ ++ level = levels[i]; \ ++ } \ ++ fprintf(stderr, "[%4.1f%%] Frs: %-6i Err: %-i Time: %3i:%02i.%03i Level: %-4idB FPS: %-4i CPU: %.1f%% \r", \ ++ file.get_pos(file.relative) * 100, \ ++ file.get_frames(), dvd_graph.dec.get_errors(), \ ++ int(time/60), int(time) % 60, int(time * 1000) % 1000, \ ++ int(value2db(level)), \ ++ int(file.get_frames() / time), \ ++ cpu_current.usage() * 100); \ ++ fflush(stderr); \ + } + + #define DROP_STAT \ +@@ -811,7 +846,7 @@ int main(int argc, char *argv[]) + { + char info[1024]; + file.stream_info(info, sizeof(info)); +- printf("\n\n%s", info); ++ fprintf(stderr, "\n\n%s", info); + } + + streams++; +@@ -825,7 +860,7 @@ int main(int argc, char *argv[]) + chunk.set_rawdata(file.get_spk(), file.get_frame(), file.get_frame_size()); + if (!dvd_graph.process(&chunk)) + { +- printf("\nError in dvd_graph.process()\n"); ++ fprintf(stderr, "\nError in dvd_graph.process()\n"); + return 1; + } + +@@ -833,7 +868,7 @@ int main(int argc, char *argv[]) + { + if (!dvd_graph.get_chunk(&chunk)) + { +- printf("\nError in dvd_graph.get_chunk()\n"); ++ fprintf(stderr, "\nError in dvd_graph.get_chunk()\n"); + return 1; + } + +@@ -847,12 +882,12 @@ int main(int argc, char *argv[]) + if (sink->query_input(chunk.spk)) + { + DROP_STAT; +- printf("Opening audio output %s %s %i...\n", ++ fprintf(stderr, "Opening audio output %s %s %i...\n", + chunk.spk.format_text(), chunk.spk.mode_text(), chunk.spk.sample_rate); + } + else + { +- printf("\nOutput format %s %s %i is unsupported\n", ++ fprintf(stderr, "\nOutput format %s %s %i is unsupported\n", + chunk.spk.format_text(), chunk.spk.mode_text(), chunk.spk.sample_rate); + return 1; + } +@@ -860,7 +895,7 @@ int main(int argc, char *argv[]) + + if (!sink->process(&chunk)) + { +- printf("\nError in sink->process()\n"); ++ fprintf(stderr, "\nError in sink->process()\n"); + return 1; + } + } +@@ -893,7 +928,7 @@ int main(int argc, char *argv[]) + + if (!dvd_graph.process_to(&chunk, sink)) + { +- printf("\nProcessing error!\n"); ++ fprintf(stderr, "\nProcessing error!\n"); + return 1; + } + +@@ -907,13 +942,13 @@ int main(int argc, char *argv[]) + // Final statistics + + PRINT_STAT; +- printf("\n---------------------------------------\n"); ++ fprintf(stderr, "\n---------------------------------------\n"); + if (streams > 1) +- printf("Streams found: %i\n", streams); +- printf("Frames/errors: %i/%i\n", file.get_frames(), dvd_graph.dec.get_errors()); +- printf("System time: %ims\n", int(cpu_total.get_system_time() * 1000)); +- printf("Process time: %ims\n", int(cpu_total.get_thread_time() * 1000 )); +- printf("Approx. %.2f%% realtime CPU usage\n", double(cpu_total.get_thread_time() * 100) / file.get_size(file.time)); ++ fprintf(stderr, "Streams found: %i\n", streams); ++ fprintf(stderr, "Frames/errors: %i/%i\n", file.get_frames(), dvd_graph.dec.get_errors()); ++ fprintf(stderr, "System time: %ims\n", int(cpu_total.get_system_time() * 1000)); ++ fprintf(stderr, "Process time: %ims\n", int(cpu_total.get_thread_time() * 1000 )); ++ fprintf(stderr, "Approx. %.2f%% realtime CPU usage\n", double(cpu_total.get_thread_time() * 100) / file.get_size(file.time)); + + ///////////////////////////////////////////////////////// + // Print levels histogram +@@ -930,22 +965,35 @@ int main(int argc, char *argv[]) + max_level = dvd_graph.proc.get_max_level(); + dbpb = dvd_graph.proc.get_dbpb(); + +- printf("\nHistogram:\n"); +- printf("------------------------------------------------------------------------------\n"); ++ fprintf(stderr, "\nHistogram:\n"); ++ fprintf(stderr, "------------------------------------------------------------------------------\n"); + for (i = 0; i*dbpb < 100 && i < MAX_HISTOGRAM; i++) + { +- printf("%2idB: %4.1f ", i * dbpb, hist[i] * 100); ++ fprintf(stderr, "%2idB: %4.1f ", i * dbpb, hist[i] * 100); + for (j = 0; j < 67 && j < hist[i] * 67; j++) +- printf("*"); +- printf("\n"); ++ fprintf(stderr, "*"); ++ fprintf(stderr, "\n"); + } +- printf("------------------------------------------------------------------------------\n"); +- printf("max_level;%f\ndbpb;%i\nhistogram;", max_level, dbpb); ++ fprintf(stderr, "------------------------------------------------------------------------------\n"); ++ fprintf(stderr, "max_level;%f\ndbpb;%i\nhistogram;", max_level, dbpb); + for (i = 0; i < MAX_HISTOGRAM; i++) +- printf("%.4f;", hist[i]); +- printf("\n"); +- printf("------------------------------------------------------------------------------\n"); ++ fprintf(stderr, "%.4f;", hist[i]); ++ fprintf(stderr, "\n"); ++ fprintf(stderr, "------------------------------------------------------------------------------\n"); + } + + return 0; + } ++ ++int main(int argc, char *argv[]) ++{ ++ int argc_utf8; ++ char **argv_utf8; ++ int exit_code; ++ ++ init_commandline_arguments_utf8(&argc_utf8, &argv_utf8); ++ exit_code = valdec_main(argc_utf8, argv_utf8); ++ free_commandline_arguments_utf8(&argc_utf8, &argv_utf8); ++ ++ return exit_code; ++} +diff --git a/tools/valdec.sln b/tools/valdec.sln +index 9120b95..8b0cf39 100644 +--- a/tools/valdec.sln ++++ b/tools/valdec.sln +@@ -1,12 +1,12 @@ +  + Microsoft Visual Studio Solution File, Format Version 10.00 + # Visual Studio 2008 +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "valdec", "valdec.vcproj", "{871889DF-6EF7-461F-AC1B-7DA682CB79A0}" ++Project("{EAF909A5-FA59-4C3D-9431-0FCC20D5BCF9}") = "valdec", "valdec.icproj", "{EB870031-881E-455A-A1E2-5FD222F92D61}" + ProjectSection(ProjectDependencies) = postProject +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C} = {30FCD216-1CAD-48FD-BF4B-337572F7EC9C} ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1} = {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1} + EndProjectSection + EndProject +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "valib", "..\valib\lib\valib.vcproj", "{30FCD216-1CAD-48FD-BF4B-337572F7EC9C}" ++Project("{EAF909A5-FA59-4C3D-9431-0FCC20D5BCF9}") = "valib", "..\valib\lib\valib.icproj", "{C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}" + EndProject + Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution +@@ -16,22 +16,38 @@ Global + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|Win32.ActiveCfg = Debug|Win32 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|Win32.Build.0 = Debug|Win32 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|x64.ActiveCfg = Debug|x64 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|x64.Build.0 = Debug|x64 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|Win32.ActiveCfg = Release|Win32 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|Win32.Build.0 = Release|Win32 +- {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|x64.ActiveCfg = Release|x64 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Debug|Win32.Build.0 = Debug|Win32 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Debug|x64.ActiveCfg = Debug|x64 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Debug|x64.Build.0 = Debug|x64 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Release|Win32.ActiveCfg = Release|Win32 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Release|Win32.Build.0 = Release|Win32 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Release|x64.ActiveCfg = Release|x64 ++ {EB870031-881E-455A-A1E2-5FD222F92D61}.Release|x64.Build.0 = Release|x64 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Debug|Win32.Build.0 = Debug|Win32 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Debug|x64.ActiveCfg = Debug|x64 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Debug|x64.Build.0 = Debug|x64 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Release|Win32.ActiveCfg = Release|Win32 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Release|Win32.Build.0 = Release|Win32 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Release|x64.ActiveCfg = Release|x64 ++ {C9AE46F3-AA5D-421B-99DF-3BBA26AEF6B1}.Release|x64.Build.0 = Release|x64 + {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|x64.Build.0 = Release|x64 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|Win32.ActiveCfg = Debug|Win32 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|Win32.Build.0 = Debug|Win32 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|x64.ActiveCfg = Debug|x64 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|x64.Build.0 = Debug|x64 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|Win32.ActiveCfg = Release|Win32 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|Win32.Build.0 = Release|Win32 +- {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|x64.ActiveCfg = Release|x64 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|x64.ActiveCfg = Release|x64 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|Win32.Build.0 = Release|Win32 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Release|Win32.ActiveCfg = Release|Win32 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|x64.Build.0 = Debug|x64 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|x64.ActiveCfg = Debug|x64 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|Win32.Build.0 = Debug|Win32 ++ {871889DF-6EF7-461F-AC1B-7DA682CB79A0}.Debug|Win32.ActiveCfg = Debug|Win32 + {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|x64.Build.0 = Release|x64 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|x64.ActiveCfg = Release|x64 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|Win32.Build.0 = Release|Win32 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Release|Win32.ActiveCfg = Release|Win32 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|x64.Build.0 = Debug|x64 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|x64.ActiveCfg = Debug|x64 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|Win32.Build.0 = Debug|Win32 ++ {30FCD216-1CAD-48FD-BF4B-337572F7EC9C}.Debug|Win32.ActiveCfg = Debug|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE +diff --git a/tools/valdec.vcproj b/tools/valdec.vcproj +index d6a6b98..4d3056b 100644 +--- a/tools/valdec.vcproj ++++ b/tools/valdec.vcproj +@@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + ++ ++ + +diff --git a/valib/lib/valib.vcproj b/valib/lib/valib.vcproj +index a30826e..3b04d9f 100644 +--- a/valib/lib/valib.vcproj ++++ b/valib/lib/valib.vcproj +@@ -1,7 +1,7 @@ + + + ++ ++ ++ + + + + ++ ++ + +diff --git a/valib/valib/auto_file.cpp b/valib/valib/auto_file.cpp +index 235ad1d..8d99c91 100644 +--- a/valib/valib/auto_file.cpp ++++ b/valib/valib/auto_file.cpp +@@ -1,5 +1,6 @@ + #include + #include "auto_file.h" ++#include "..\..\tools\unicode_support.h" + + #if defined(_MSC_VER) && (_MSC_VER >= 1400) + +@@ -40,7 +41,7 @@ AutoFile::open(const char *filename, const char *mode) + { + if (f) close(); + filesize = max_size; +- f = fopen(filename, mode); ++ f = fopen_utf8(filename, mode); + if (f) + { + if (portable_seek(f, 0, SEEK_END) == 0) +diff --git a/valib/valib/sink/sink_dsound.cpp b/valib/valib/sink/sink_dsound.cpp +index 542d31f..c5aa132 100644 +--- a/valib/valib/sink/sink_dsound.cpp ++++ b/valib/valib/sink/sink_dsound.cpp +@@ -47,8 +47,8 @@ DSoundSink::open_dsound(HWND _hwnd, int _buf_size_ms, int _preload_ms, LPCGUID _ + + // Open DirectSound + +- if FAILED(DirectSoundCreate(_device, &ds, 0)) +- return false; ++ //if FAILED(DirectSoundCreate(_device, &ds, 0)) ++ return false; + + if (!_hwnd) _hwnd = GetForegroundWindow(); + if (!_hwnd) _hwnd = GetDesktopWindow(); +diff --git a/valib/valib/sink/sink_stdout.h b/valib/valib/sink/sink_stdout.h +new file mode 100644 +index 0000000..3112531 +--- /dev/null ++++ b/valib/valib/sink/sink_stdout.h +@@ -0,0 +1,93 @@ ++/* ++ RAW file output audio renderer ++*/ ++ ++#ifndef VALIB_SINK_STDOUT_H ++#define VALIB_SINK_STDOUT_H ++ ++#include "filter.h" ++#include "auto_file.h" ++ ++class StdOutSink : public Sink ++{ ++protected: ++ Speakers spk; ++ HANDLE h; ++ //AutoFile f; ++ ++public: ++ StdOutSink(): ++ h(GetStdHandle(STD_OUTPUT_HANDLE)) ++ {} ++ ++ StdOutSink(const char *_filename): ++ h(GetStdHandle(STD_OUTPUT_HANDLE)) ++ {} ++ ++ StdOutSink(FILE *_f): ++ h(GetStdHandle(STD_OUTPUT_HANDLE)) ++ {} ++ ++ ///////////////////////////////////////////////////////// ++ // RAWSink interface ++ ++ bool open(const char *_filename) ++ { ++ return true; //f.open(_filename, "wb"); ++ } ++ ++ bool open(FILE *_f) ++ { ++ return true; //f.open(_f); ++ } ++ ++ void close() ++ { ++ //f.close(); ++ spk = spk_unknown; ++ } ++ ++ bool is_open() const ++ { ++ return ((h != INVALID_HANDLE_VALUE) && (h != 0)); //f.is_open(); ++ } ++ ++ ///////////////////////////////////////////////////////// ++ // Sink interface ++ ++ virtual bool query_input(Speakers _spk) const ++ { ++ // cannot write linear format ++ return /*f.is_open() &&*/ _spk.format != FORMAT_LINEAR; ++ } ++ ++ virtual bool set_input(Speakers _spk) ++ { ++ if (!query_input(_spk)) ++ return false; ++ ++ spk = _spk; ++ return true; ++ } ++ ++ virtual Speakers get_input() const ++ { ++ return spk; ++ } ++ ++ // data write ++ virtual bool process(const Chunk *_chunk) ++ { ++ if (_chunk->is_dummy()) ++ return true; ++ ++ if (spk != _chunk->spk) ++ if (!set_input(_chunk->spk)) ++ return false; ++ ++ DWORD bytesWritten = 0; ++ return WriteFile(h, _chunk->rawdata, _chunk->size, &bytesWritten, NULL); //f.write(_chunk->rawdata, _chunk->size) == _chunk->size; ++ } ++}; ++ ++#endif diff --git a/etc/Patches/DcaEnc-r720af20-MSVC10-UTF8+Progress+VariousImprovements.V1.diff b/etc/Patches/DcaEnc-r720af20-MSVC10-UTF8+Progress+VariousImprovements.V1.diff new file mode 100644 index 00000000..6dc091d2 --- /dev/null +++ b/etc/Patches/DcaEnc-r720af20-MSVC10-UTF8+Progress+VariousImprovements.V1.diff @@ -0,0 +1,3440 @@ + .gitignore | 7 + + Makefile.am | 26 +- + compiler_info.h | 61 ++++ + config_msvc.h | 101 +++++++ + configure.ac | 20 +- + dcaenc.c | 88 ++++-- + dcaenc.h | 24 ++- + delphi/DcaEncAPI.pas | 44 +++ + delphi/DcaEncTest.cfg | 38 +++ + delphi/DcaEncTest.dof | 136 +++++++++ + delphi/DcaEncTest.dpr | 15 + + delphi/DcaEncTest.res | Bin 0 -> 876 bytes + delphi/DcaEncTestForm.dfm | 35 +++ + delphi/DcaEncTestForm.pas | 111 +++++++ + dllmain.cpp | 19 ++ + main.c | 371 +++++++++++++++++++++-- + math_tables.h | 10 +- + unicode_support.c | 225 ++++++++++++++ + unicode_support.h | 51 ++++ + vc_solution/dcadll_vc2010.vcxproj | 126 ++++++++ + vc_solution/dcadll_vc2010.vcxproj.filters | 48 +++ + vc_solution/dcadll_vc2010.vcxproj.user | 3 + + vc_solution/dcaenc_vc2010.sln | 59 ++++ + vc_solution/dcaenc_vc2010.vcxproj | 206 +++++++++++++ + vc_solution/dcaenc_vc2010.vcxproj.filters | 48 +++ + vc_solution/dcaenc_vc2010.vcxproj.user | 3 + + vc_solution/dcalib_vc2010.vcxproj | 114 +++++++ + vc_solution/dcalib_vc2010.vcxproj.filters | 45 +++ + vc_solution/dcalib_vc2010.vcxproj.user | 3 + + vc_solution/gentables.vcxproj | 125 ++++++++ + vc_solution/gentables.vcxproj.filters | 33 ++ + vc_solution/lib/EncodePointer.lib | Bin 0 -> 1058 bytes + vc_solution/lib/msvcrt_vc6.lib | Bin 0 -> 235942 bytes + wavfile.c | 467 +++++++++++++++++++---------- + wavfile.h | 6 +- + xgetopt.c | 206 +++++++++++++ + xgetopt.h | 29 ++ + 37 files changed, 2644 insertions(+), 259 deletions(-) + +diff --git a/.gitignore b/.gitignore +index 2f63d9a..de6fa6a 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -29,3 +29,10 @@ libtool + ltmain.sh + missing + stamp-h1 ++vc_solution/ipch/ ++vc_solution/Win32/ ++vc_solution/x64/ ++vc_solution/*.opensdf ++vc_solution/*.sdf ++vc_solution/*.vcxproj.user ++vc_solution/*.suo +diff --git a/Makefile.am b/Makefile.am +index f89fe04..7e21572 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -14,19 +14,19 @@ nodist_libdcaenc_la_SOURCES = math_tables.c + libdcaenc_la_LDFLAGS = -version-info 0:0:0 \ + -export-symbols $(top_srcdir)/dcaenc.sym + +-if HAVE_ALSA +-plugin_LTLIBRARIES = libasound_module_pcm_dca.la +-plugindir = $(libdir)/alsa-lib +- +-libasound_module_pcm_dca_la_SOURCES = alsaplugin.c dcaenc.h +-libasound_module_pcm_dca_la_LIBADD = libdcaenc.la @ALSA_LIBS@ +-libasound_module_pcm_dca_la_LDFLAGS = -no-undefined -avoid-version +- +-alsaconfdir = $(datadir)/alsa/pcm +-alsaconf_DATA = dca.conf +-endif +- +-dcaenc_SOURCES = main.c wavfile.c dcaenc.h wavfile.h ++#if HAVE_ALSA ++#plugin_LTLIBRARIES = libasound_module_pcm_dca.la ++#plugindir = $(libdir)/alsa-lib ++# ++#libasound_module_pcm_dca_la_SOURCES = alsaplugin.c dcaenc.h ++#libasound_module_pcm_dca_la_LIBADD = libdcaenc.la @ALSA_LIBS@ ++#libasound_module_pcm_dca_la_LDFLAGS = -no-undefined -avoid-version ++# ++#alsaconfdir = $(datadir)/alsa/pcm ++#alsaconf_DATA = dca.conf ++#endif ++ ++dcaenc_SOURCES = main.c wavfile.c unicode_support.c xgetopt.c dcaenc.h wavfile.h unicode_support.h xgetopt.h + dcaenc_LDADD = libdcaenc.la + + gentables_SOURCES = gentables.c \ +diff --git a/compiler_info.h b/compiler_info.h +new file mode 100644 +index 0000000..01b1cc9 +--- /dev/null ++++ b/compiler_info.h +@@ -0,0 +1,61 @@ ++/* ++ * This file is part of dcaenc. ++ * ++ * Copyright (c) 2008-2011 Alexander E. Patrakov ++ * ++ * dcaenc is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * dcaenc is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with dcaenc; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef COMPILER_INFO_H ++#define COMPILER_INFO_H ++ ++#ifndef _T ++#define __T(X) #X ++#define _T(X) __T(X) ++#endif ++ ++#if defined(__INTEL_COMPILER) ++ #if (__INTEL_COMPILER >= 1200) ++ #define __COMPILER__ "ICL 12.x" ++ #elif (__INTEL_COMPILER >= 1100) ++ #define __COMPILER__ = "ICL 11.x" ++ #elif (__INTEL_COMPILER >= 1000) ++ #define __COMPILER__ = "ICL 10.x" ++ #else ++ #define __COMPILER__ "ICL Unknown" ++ #endif ++#elif defined(_MSC_VER) ++ #if (_MSC_VER == 1600) ++ #if (_MSC_FULL_VER >= 160040219) ++ #define __COMPILER__ "MSVC 2010-SP1" ++ #else ++ #define __COMPILER__ "MSVC 2010" ++ #endif ++ #elif (_MSC_VER == 1500) ++ #if (_MSC_FULL_VER >= 150030729) ++ #define __COMPILER__ "MSVC 2008-SP1" ++ #else ++ #define __COMPILER__ "MSVC 2008" ++ #endif ++ #else ++ #define __COMPILER__ "MSVC Unknown" ++ #endif ++#elif defined(__GNUC__) ++ #define __COMPILER__ "GNU GCC " _T(__GNUC__) "." _T(__GNUC_MINOR__) ++#else ++ #define __COMPILER__ "Unknown" ++#endif ++ ++#endif +diff --git a/config_msvc.h b/config_msvc.h +new file mode 100644 +index 0000000..d72ce68 +--- /dev/null ++++ b/config_msvc.h +@@ -0,0 +1,101 @@ ++/* config.h. Generated from config.h.in by configure. */ ++/* config.h.in. Generated from configure.ac by autoheader. */ ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_DLFCN_H */ ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_INTTYPES_H */ ++ ++/* Define to 1 if you have the `asound' library (-lasound). */ ++/* #undef HAVE_LIBASOUND */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_MEMORY_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDINT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDLIB_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_STRINGS_H */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRING_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_STAT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_SYS_TYPES_H 1 ++ ++/* Define to 1 if you have the header file. */ ++/* #undef HAVE_UNISTD_H */ ++ ++/* Define to the sub-directory in which libtool stores uninstalled libraries. ++ */ ++#define LT_OBJDIR ".libs/" ++ ++/* Name of package */ ++#define PACKAGE "dcaenc" ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#define PACKAGE_BUGREPORT "patrakov@gmail.com" ++ ++/* Define to the full name of this package. */ ++#define PACKAGE_NAME "dcaenc" ++ ++/* Define to the full name and version of this package. */ ++#define PACKAGE_STRING "dcaenc 1" ++ ++/* Define to the one symbol short name of this package. */ ++#define PACKAGE_TARNAME "dcaenc" ++ ++/* Define to the home page for this package. */ ++#define PACKAGE_URL "http://aepatrakov.narod.ru/dcaenc/" ++ ++/* Define to the version of this package. */ ++#define PACKAGE_VERSION "1" ++ ++/* Define to 1 if you have the ANSI C header files. */ ++#define STDC_HEADERS 1 ++ ++/* Version number of package */ ++#define VERSION "1" ++ ++/* Define for Solaris 2.5.1 so the uint32_t typedef from , ++ , or is not used. If the typedef were allowed, the ++ #define below would cause a syntax error. */ ++/* #undef _UINT32_T */ ++ ++/* Define for Solaris 2.5.1 so the uint8_t typedef from , ++ , or is not used. If the typedef were allowed, the ++ #define below would cause a syntax error. */ ++/* #undef _UINT8_T */ ++ ++/* Define to `__inline__' or `__inline' if that's what the C compiler ++ calls it, or to nothing if 'inline' is not supported under any name. */ ++/* #ifndef __cplusplus */ ++#define inline __inline ++/* #endif */ ++ ++/* Define to the type of a signed integer type of width exactly 32 bits if ++ such a type exists and the standard includes do not define it. */ ++/* #undef int32_t */ ++ ++/* Define to the type of a signed integer type of width exactly 64 bits if ++ such a type exists and the standard includes do not define it. */ ++/* #undef int64_t */ ++ ++/* Define to `unsigned int' if does not define. */ ++/* #undef size_t */ ++ ++/* Define to the type of an unsigned integer type of width exactly 32 bits if ++ such a type exists and the standard includes do not define it. */ ++/* #undef uint32_t */ ++ ++/* Define to the type of an unsigned integer type of width exactly 8 bits if ++ such a type exists and the standard includes do not define it. */ ++/* #undef uint8_t */ +diff --git a/configure.ac b/configure.ac +index db25f0a..78c0c07 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -13,7 +13,7 @@ LT_INIT([disable-static]) + + # Checks for programs. + AC_PROG_CC +-PKG_PROG_PKG_CONFIG ++#PKG_PROG_PKG_CONFIG + + # Checks for libraries. + AC_ARG_ENABLE([alsa], +@@ -21,15 +21,15 @@ AC_ARG_ENABLE([alsa], + + ac_save_LIBS="$LIBS" + +-if test "x$enable_alsa" != "xno"; then +- PKG_CHECK_MODULES([ALSA], [alsa >= 1.0.11], [HAVE_ALSA=yes], [HAVE_ALSA=no]) +- AC_CHECK_LIB(asound, snd_pcm_extplug_create,, +- [HAVE_ALSA=no], -ldl) +- if test "x$enable_alsa" = "xyes" -a "x$HAVE_ALSA" = "xno"; then +- AC_MSG_ERROR([ALSA libraries not found]) +- fi +-fi +-AM_CONDITIONAL(HAVE_ALSA, test "x$enable_alsa" != "xno" -a "x$HAVE_ALSA" = "xyes") ++#if test "x$enable_alsa" != "xno"; then ++# PKG_CHECK_MODULES([ALSA], [alsa >= 1.0.11], [HAVE_ALSA=yes], [HAVE_ALSA=no]) ++# AC_CHECK_LIB(asound, snd_pcm_extplug_create,, ++# [HAVE_ALSA=no], -ldl) ++# if test "x$enable_alsa" = "xyes" -a "x$HAVE_ALSA" = "xno"; then ++# AC_MSG_ERROR([ALSA libraries not found]) ++# fi ++#fi ++#AM_CONDITIONAL(HAVE_ALSA, test "x$enable_alsa" != "xno" -a "x$HAVE_ALSA" = "xyes") + LIBS="$ac_save_LIBS" + + # Checks for header files. +diff --git a/dcaenc.c b/dcaenc.c +index 5e762ce..bf0eacf 100644 +--- a/dcaenc.c ++++ b/dcaenc.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include "config.h" + #include "dcaenc.h" + #include "dcaenc_private.h" + #include "int_data.h" +@@ -30,10 +31,9 @@ + #define div_round_up(a, b) (((a) + (b) - 1) / (b)) + #define round_up(a, b) ((((a) + (b) - 1) / (b)) * (b)) + +-dcaenc_context dcaenc_create(int sample_rate, int channel_config, +- int approx_bitrate, int flags) ++dcaenc_context dcaenc_create(int sample_rate, int channel_config, int approx_bitrate, int flags) + { +- int i, frame_bits, bit_step, fir, useful_bitrate; ++ int i, frame_bits, bit_step, fir, useful_bitrate, min_frame_bits; + dcaenc_context result; + + i = 0; +@@ -60,7 +60,7 @@ dcaenc_context dcaenc_create(int sample_rate, int channel_config, + /* Round frame_bits up to the next permitted value */ + frame_bits = round_up(frame_bits, bit_step); + +- int min_frame_bits = 132 + (493 + 28 * 32) * channels_table[channel_config]; ++ min_frame_bits = 132 + (493 + 28 * 32) * channels_table[channel_config]; + if (flags & DCAENC_FLAG_LFE) + min_frame_bits += 72; + +@@ -108,19 +108,19 @@ int dcaenc_output_size(dcaenc_context c) + return c->frame_bits / ((c->flags & DCAENC_FLAG_28BIT) ? 7 : 8); + } + +-static inline const int32_t *pcm_sample(dcaenc_context c, +- const int32_t *container, +- int sample, int channel) ++inline static const int32_t *pcm_sample(dcaenc_context c, ++ const int32_t *container, ++ int sample, int channel) + { + return &container[sample * c->channels + channel]; + } + +-static inline int32_t half32(int32_t a) ++inline static int32_t half32(int32_t a) + { + return (a + 1) >> 1; + } + +-static inline int32_t mul32(int32_t a, int32_t b) ++inline static int32_t mul32(int32_t a, int32_t b) + { + int64_t r = (int64_t)a * b + 0x80000000ULL; + return r >> 32; +@@ -148,7 +148,7 @@ static void dcaenc_subband_transform(dcaenc_context c, const int32_t *input) + accum[i] = 0; + + for (k = 0, i = hist_start, j = 0; +- i < 512; k = (k + 1) & 63, i++, j++) ++ i < 512; k = (k + 1) & 63, i++, j++) + accum[k] += mul32(hist[i], c->band_interpolation[j]); + for (i = 0; i < hist_start; k = (k + 1) & 63, i++, j++) + accum[k] += mul32(hist[i], c->band_interpolation[j]); +@@ -204,7 +204,7 @@ static void dcaenc_lfe_downsample(dcaenc_context c, const int32_t *input) + /* Copy in 64 new samples from input */ + for (i = 0; i < 64; i++) + hist[i + hist_start] = *pcm_sample(c, input, +- lfes * 64 + i, c->channels - 1); ++ lfes * 64 + i, c->channels - 1); + + hist_start = (hist_start + 64) & 511; + } +@@ -313,7 +313,7 @@ static int32_t add_cb(int32_t a, int32_t b) + + /* accepts anything, out_cb[i] can only grow */ + static void adjust_jnd(int samplerate_index, +- const int32_t in[512], int32_t out_cb[256]) ++ const int32_t in[512], int32_t out_cb[256]) + { + int i, j; + int32_t power[256]; +@@ -336,7 +336,7 @@ static void adjust_jnd(int samplerate_index, + denom = add_cb(denom, power[j] + auf[samplerate_index][i][j]); + for (j = 0; j < 256; j++) + out_cb_unnorm[j] = add_cb(out_cb_unnorm[j], +- -denom + auf[samplerate_index][i][j]); ++ -denom + auf[samplerate_index][i][j]); + } + + for (j = 0; j < 256; j++) +@@ -345,11 +345,11 @@ static void adjust_jnd(int samplerate_index, + + + typedef void (*walk_band_t)(dcaenc_context c, int band1, int band2, int f, +- int32_t spectrum1, int32_t spectrum2, int channel, +- int32_t * arg); ++ int32_t spectrum1, int32_t spectrum2, int channel, ++ int32_t * arg); + + static void walk_band_low(dcaenc_context c, int band, int channel, +- walk_band_t walk, int32_t * arg) ++ walk_band_t walk, int32_t * arg) + { + int f; + if (band == 0) { +@@ -358,12 +358,12 @@ static void walk_band_low(dcaenc_context c, int band, int channel, + } else { + for (f = 0; f < 8; f++) + walk(c, band, band - 1, 8 * band - 4 + f, +- c->band_spectrum[7 - f], c->band_spectrum[f], channel, arg); ++ c->band_spectrum[7 - f], c->band_spectrum[f], channel, arg); + } + } + + static void walk_band_high(dcaenc_context c, int band, int channel, +- walk_band_t walk, int32_t * arg) ++ walk_band_t walk, int32_t * arg) + { + int f; + if (band == 31) { +@@ -372,12 +372,12 @@ static void walk_band_high(dcaenc_context c, int band, int channel, + } else { + for (f = 0; f < 8; f++) + walk(c, band, band + 1, 8 * band + 4 + f, +- c->band_spectrum[f], c->band_spectrum[7 - f], channel, arg); ++ c->band_spectrum[f], c->band_spectrum[7 - f], channel, arg); + } + } + + static void walk_whole_spectrum(dcaenc_context c, int channel, +- walk_band_t walk, int32_t * arg) ++ walk_band_t walk, int32_t * arg) + { + int band; + for (band = 0; band < 32; band++) +@@ -453,10 +453,14 @@ static void dcaenc_find_peaks(dcaenc_context c) + } + + static const int snr_fudge = 128; ++static const int USED_1ABITS = 1; ++static const int USED_NABITS = 2; ++static const int USED_26ABITS = 4; + +-static void init_quantization_noise(dcaenc_context c, int noise) ++static int init_quantization_noise(dcaenc_context c, int noise) + { + int ch, band; ++ int ret = 0; + + c->consumed_bits = 132 + 493 * c->fullband_channels; + if (c->flags & DCAENC_FLAG_LFE) +@@ -472,10 +476,19 @@ static void init_quantization_noise(dcaenc_context c, int noise) + - c->band_masking_cb[band] + - noise; + +- c->abits[band][ch] = (snr_cb >= 1312) ? 26 +- : (snr_cb >= 222) ? (8 + mul32(snr_cb - 222, 69000000)) +- : (snr_cb >= 0) ? (2 + mul32(snr_cb, 106000000)) +- : 1; ++ if (snr_cb >= 1312) { ++ c->abits[band][ch] = 26; ++ ret |= USED_26ABITS; ++ } else if (snr_cb >= 222) { ++ c->abits[band][ch] = 8 + mul32(snr_cb - 222, 69000000); ++ ret |= USED_NABITS; ++ } else if (snr_cb >= 0) { ++ c->abits[band][ch] = 2 + mul32(snr_cb, 106000000); ++ ret |= USED_NABITS; ++ } else { ++ c->abits[band][ch] = 1; ++ ret |= USED_1ABITS; ++ } + } + } + +@@ -484,36 +497,41 @@ static void init_quantization_noise(dcaenc_context c, int noise) + c->consumed_bits += bit_consumption[c->abits[band][ch]]; + } + ++ return ret; + } + + static void dcaenc_assign_bits(dcaenc_context c) + { + /* Find the bounds where the binary search should work */ +- int low, high; ++ int low, high, down, used_abits; + init_quantization_noise(c, c->worst_quantization_noise); + low = high = c->worst_quantization_noise; ++ used_abits = 0; + if (c->consumed_bits > c->frame_bits) { + while (c->consumed_bits > c->frame_bits) { ++ assert(("Too low bitrate should have been rejected in dcaenc_create", used_abits != USED_1ABITS)); + low = high; + high += snr_fudge; +- init_quantization_noise(c, high); ++ used_abits = init_quantization_noise(c, high); + } + } else { + while (c->consumed_bits <= c->frame_bits) { + high = low; ++ if (used_abits == USED_26ABITS) ++ goto out; /* The requested bitrate is too high, pad with zeros */ + low -= snr_fudge; +- init_quantization_noise(c, low); ++ used_abits = init_quantization_noise(c, low); + } + } + + /* Now do a binary search between low and high to see what fits */ +- int down; + for (down = snr_fudge >> 1; down; down >>= 1) { + init_quantization_noise(c, high - down); + if (c->consumed_bits <= c->frame_bits) + high -= down; + } + init_quantization_noise(c, high); ++out: + c->worst_quantization_noise = high; + if (high > c->worst_noise_ever) + c->worst_noise_ever = high; +@@ -538,8 +556,9 @@ static void bitstream_init(dcaenc_context c, uint8_t *output) + + static void bitstream_put(dcaenc_context c, uint32_t bits, int nbits) + { ++ int max_bits; + assert(bits < (1 << nbits)); +- int max_bits = (c->flags & DCAENC_FLAG_28BIT) ? 28 : 32; ++ max_bits = (c->flags & DCAENC_FLAG_28BIT) ? 28 : 32; + c->wrote += nbits; + bits &= ~(0xffffffff << nbits); + if (nbits + c->wbits >= max_bits) { +@@ -599,7 +618,7 @@ static int32_t dcaenc_quantize_value(int32_t value, softfloat quant) + static int32_t dcaenc_quantize(dcaenc_context c, int sample, int band, int ch) + { + int32_t result = dcaenc_quantize_value(c->subband_samples[sample][band][ch], +- c->quant[band][ch]); ++ c->quant[band][ch]); + + assert(result <= (quant_levels[c->abits[band][ch]] - 1) / 2); + assert(result >= -(quant_levels[c->abits[band][ch]] / 2)); +@@ -608,11 +627,12 @@ static int32_t dcaenc_quantize(dcaenc_context c, int sample, int band, int ch) + + static int dcaenc_calc_one_scale(int32_t peak_cb, int abits, softfloat *quant) + { +- assert(peak_cb <= 0); +- assert(peak_cb >= -2047); +- int32_t peak = cb_to_level[-peak_cb]; + int our_nscale, try_remove; ++ int32_t peak; + softfloat our_quant; ++ assert(peak_cb <= 0); ++ assert(peak_cb >= -2047); ++ peak = cb_to_level[-peak_cb]; + our_nscale = 127; + + for (try_remove = 64; try_remove > 0; try_remove >>= 1) { +diff --git a/dcaenc.h b/dcaenc.h +index 17f01f3..f62a58b 100644 +--- a/dcaenc.h ++++ b/dcaenc.h +@@ -48,11 +48,23 @@ typedef struct dcaenc_context_s *dcaenc_context; + #define DCAENC_CHANNELS_4FRONT_4REAR 14 + #define DCAENC_CHANNELS_5FRONT_3REAR 15 + +-dcaenc_context dcaenc_create(int sample_rate, int channel_config, int approx_bitrate, int flags); +-int dcaenc_bitrate(dcaenc_context c); +-int dcaenc_input_size(dcaenc_context c); +-int dcaenc_output_size(dcaenc_context c); +-int dcaenc_convert_s32(dcaenc_context c, const int32_t *input, uint8_t *output); +-int dcaenc_destroy(dcaenc_context c, uint8_t *output); ++#if defined(_MSC_VER) || defined(__INTEL_COMPILER) ++ #if defined(DCADLL_VC2010_EXPORTS) ++ #define MAKE_DLL __declspec(dllexport) ++ #elif defined(DCADLL_VC2010_IMPORTS) ++ #define MAKE_DLL __declspec(dllimport) ++ #else ++ #define MAKE_DLL ++ #endif ++#else ++ #define MAKE_DLL ++#endif ++ ++MAKE_DLL dcaenc_context dcaenc_create(int sample_rate, int channel_config, int approx_bitrate, int flags); ++MAKE_DLL int dcaenc_bitrate(dcaenc_context c); ++MAKE_DLL int dcaenc_input_size(dcaenc_context c); ++MAKE_DLL int dcaenc_output_size(dcaenc_context c); ++MAKE_DLL int dcaenc_convert_s32(dcaenc_context c, const int32_t *input, uint8_t *output); ++MAKE_DLL int dcaenc_destroy(dcaenc_context c, uint8_t *output); + + #endif +diff --git a/delphi/DcaEncAPI.pas b/delphi/DcaEncAPI.pas +new file mode 100644 +index 0000000..7cc0735 +--- /dev/null ++++ b/delphi/DcaEncAPI.pas +@@ -0,0 +1,44 @@ ++unit DcaEncAPI; ++ ++interface ++ ++uses Windows, SysUtils; ++ ++const ++ DCAENC_FLAG_28BIT = 1; ++ DCAENC_FLAG_BIGENDIAN = 2; ++ DCAENC_FLAG_LFE = 4; ++ DCAENC_FLAG_PERFECT_QMF = 8; ++ DCAENC_FLAG_IEC_WRAP = 16; ++ ++ DCAENC_CHANNELS_MONO = 0; ++ DCAENC_CHANNELS_DUAL_MONO = 1; ++ DCAENC_CHANNELS_STEREO = 2; ++ DCAENC_CHANNELS_STEREO_SUMDIFF = 3; ++ DCAENC_CHANNELS_STEREO_TOTAL = 4; ++ DCAENC_CHANNELS_3FRONT = 5; ++ DCAENC_CHANNELS_2FRONT_1REAR = 6; ++ DCAENC_CHANNELS_3FRONT_1REAR = 7; ++ DCAENC_CHANNELS_2FRONT_2REAR = 8; ++ DCAENC_CHANNELS_3FRONT_2REAR = 9; ++ DCAENC_CHANNELS_4FRONT_2REAR = 10; ++ DCAENC_CHANNELS_3FRONT_2REAR_1OV = 11; ++ DCAENC_CHANNELS_3FRONT_3REAR = 12; ++ DCAENC_CHANNELS_5FRONT_2REAR = 13; ++ DCAENC_CHANNELS_4FRONT_4REAR = 14; ++ DCAENC_CHANNELS_5FRONT_3REAR = 15; ++ ++type ++ TDcaEncContext = Pointer; ++ ++function dcaenc_create(sample_rate, channel_config, approx_bitrate, flags: integer): TDcaEncContext; cdecl; external 'dcaenc-0.dll'; ++function dcaenc_bitrate(c : TDcaEncContext): integer; cdecl; external 'dcaenc-0.dll'; ++function dcaenc_input_size(c : TDcaEncContext): integer; cdecl; external 'dcaenc-0.dll'; ++function dcaenc_output_size(c : TDcaEncContext): integer; cdecl; external 'dcaenc-0.dll'; ++function dcaenc_convert_s32(c : TDcaEncContext; input: PLongInt; output: PByte): integer; cdecl; external 'dcaenc-0.dll'; ++function dcaenc_destroy(c : TDcaEncContext; output: PByte): integer; cdecl; external 'dcaenc-0.dll'; ++ ++implementation ++ ++end. ++ +diff --git a/delphi/DcaEncTest.cfg b/delphi/DcaEncTest.cfg +new file mode 100644 +index 0000000..30e6ed7 +--- /dev/null ++++ b/delphi/DcaEncTest.cfg +@@ -0,0 +1,38 @@ ++-$A8 ++-$B- ++-$C+ ++-$D+ ++-$E- ++-$F- ++-$G+ ++-$H+ ++-$I+ ++-$J- ++-$K- ++-$L+ ++-$M- ++-$N+ ++-$O+ ++-$P+ ++-$Q- ++-$R- ++-$S- ++-$T- ++-$U- ++-$V+ ++-$W- ++-$X+ ++-$YD ++-$Z1 ++-cg ++-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; ++-H+ ++-W+ ++-M ++-$M16384,1048576 ++-K$00400000 ++-LE"e:\delphi 7\Projects\Bpl" ++-LN"e:\delphi 7\Projects\Bpl" ++-w-UNSAFE_TYPE ++-w-UNSAFE_CODE ++-w-UNSAFE_CAST +diff --git a/delphi/DcaEncTest.dof b/delphi/DcaEncTest.dof +new file mode 100644 +index 0000000..2b75114 +--- /dev/null ++++ b/delphi/DcaEncTest.dof +@@ -0,0 +1,136 @@ ++[FileVersion] ++Version=7.0 ++[Compiler] ++A=8 ++B=0 ++C=1 ++D=1 ++E=0 ++F=0 ++G=1 ++H=1 ++I=1 ++J=0 ++K=0 ++L=1 ++M=0 ++N=1 ++O=1 ++P=1 ++Q=0 ++R=0 ++S=0 ++T=0 ++U=0 ++V=1 ++W=0 ++X=1 ++Y=1 ++Z=1 ++ShowHints=1 ++ShowWarnings=1 ++UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; ++NamespacePrefix= ++SymbolDeprecated=1 ++SymbolLibrary=1 ++SymbolPlatform=1 ++UnitLibrary=1 ++UnitPlatform=1 ++UnitDeprecated=1 ++HResultCompat=1 ++HidingMember=1 ++HiddenVirtual=1 ++Garbage=1 ++BoundsError=1 ++ZeroNilCompat=1 ++StringConstTruncated=1 ++ForLoopVarVarPar=1 ++TypedConstVarPar=1 ++AsgToTypedConst=1 ++CaseLabelRange=1 ++ForVariable=1 ++ConstructingAbstract=1 ++ComparisonFalse=1 ++ComparisonTrue=1 ++ComparingSignedUnsigned=1 ++CombiningSignedUnsigned=1 ++UnsupportedConstruct=1 ++FileOpen=1 ++FileOpenUnitSrc=1 ++BadGlobalSymbol=1 ++DuplicateConstructorDestructor=1 ++InvalidDirective=1 ++PackageNoLink=1 ++PackageThreadVar=1 ++ImplicitImport=1 ++HPPEMITIgnored=1 ++NoRetVal=1 ++UseBeforeDef=1 ++ForLoopVarUndef=1 ++UnitNameMismatch=1 ++NoCFGFileFound=1 ++MessageDirective=1 ++ImplicitVariants=1 ++UnicodeToLocale=1 ++LocaleToUnicode=1 ++ImagebaseMultiple=1 ++SuspiciousTypecast=1 ++PrivatePropAccessor=1 ++UnsafeType=0 ++UnsafeCode=0 ++UnsafeCast=0 ++[Linker] ++MapFile=0 ++OutputObjs=0 ++ConsoleApp=1 ++DebugInfo=0 ++RemoteSymbols=0 ++MinStackSize=16384 ++MaxStackSize=1048576 ++ImageBase=4194304 ++ExeDescription= ++[Directories] ++OutputDir= ++UnitOutputDir= ++PackageDLLOutputDir= ++PackageDCPOutputDir= ++SearchPath= ++Packages=vcl;rtl;vclx;indy;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;dbrtl;soaprtl;dsnap;VclSmp;dbexpress;vcldb;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOfficeXP;JclDeveloperTools;Jcl;JclVcl;JclContainers;JvCore;JvSystem;JvStdCtrls;JvAppFrm;JvBands;JvDB;JvDlgs;JvBDE;JvControls;JvCmp;JvCrypt;JvCustom;JvDocking;JvDotNetCtrls;JvGlobus;JvHMI;JvJans;JvManagedThreads;JvMM;JvNet;JvPageComps;JvPascalInterpreter;JvPluginSystem;JvPrintPreview;JvRuntimeDesign;JvTimeFramework;JvWizards;JvXPCtrls ++Conditionals= ++DebugSourceDirs= ++UsePackages=0 ++[Parameters] ++RunParams= ++HostApplication= ++Launcher= ++UseLauncher=0 ++DebugCWD= ++[Language] ++ActiveLang= ++ProjectLang= ++RootDir= ++[Version Info] ++IncludeVerInfo=0 ++AutoIncBuild=0 ++MajorVer=1 ++MinorVer=0 ++Release=0 ++Build=0 ++Debug=0 ++PreRelease=0 ++Special=0 ++Private=0 ++DLL=0 ++Locale=1031 ++CodePage=1252 ++[Version Info Keys] ++CompanyName= ++FileDescription= ++FileVersion=1.0.0.0 ++InternalName= ++LegalCopyright= ++LegalTrademarks= ++OriginalFilename= ++ProductName= ++ProductVersion=1.0.0.0 ++Comments= +diff --git a/delphi/DcaEncTest.dpr b/delphi/DcaEncTest.dpr +new file mode 100644 +index 0000000..613e628 +--- /dev/null ++++ b/delphi/DcaEncTest.dpr +@@ -0,0 +1,15 @@ ++program DcaEncTest; ++ ++uses ++ Forms, ++ DcaEncTestForm in 'DcaEncTestForm.pas' {Form1}, ++ DcaEncAPI in 'DcaEncAPI.pas'; ++ ++{$R *.res} ++ ++begin ++ Application.Initialize; ++ Application.Title := 'DCA Enc'; ++ Application.CreateForm(TForm1, Form1); ++ Application.Run; ++end. +diff --git a/delphi/DcaEncTest.res b/delphi/DcaEncTest.res +new file mode 100644 +index 0000000..1e4099b +Binary files /dev/null and b/delphi/DcaEncTest.res differ +diff --git a/delphi/DcaEncTestForm.dfm b/delphi/DcaEncTestForm.dfm +new file mode 100644 +index 0000000..5fb08d1 +--- /dev/null ++++ b/delphi/DcaEncTestForm.dfm +@@ -0,0 +1,35 @@ ++object Form1: TForm1 ++ Left = 307 ++ Top = 231 ++ BorderIcons = [biSystemMenu, biMinimize] ++ BorderStyle = bsDialog ++ Caption = 'DCA Enc Test' ++ ClientHeight = 74 ++ ClientWidth = 729 ++ Color = clBtnFace ++ Font.Charset = DEFAULT_CHARSET ++ Font.Color = clWindowText ++ Font.Height = -11 ++ Font.Name = 'MS Sans Serif' ++ Font.Style = [] ++ OldCreateOrder = False ++ OnCloseQuery = FormCloseQuery ++ PixelsPerInch = 96 ++ TextHeight = 13 ++ object Button1: TButton ++ Left = 8 ++ Top = 8 ++ Width = 169 ++ Height = 25 ++ Caption = 'Begin Test' ++ TabOrder = 0 ++ OnClick = Button1Click ++ end ++ object ProgressBar1: TProgressBar ++ Left = 8 ++ Top = 48 ++ Width = 713 ++ Height = 17 ++ TabOrder = 1 ++ end ++end +diff --git a/delphi/DcaEncTestForm.pas b/delphi/DcaEncTestForm.pas +new file mode 100644 +index 0000000..ae42a14 +--- /dev/null ++++ b/delphi/DcaEncTestForm.pas +@@ -0,0 +1,111 @@ ++unit DcaEncTestForm; ++ ++interface ++ ++uses ++ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ++ Dialogs, StdCtrls, DcaEncAPI, ComCtrls; ++ ++type ++ TForm1 = class(TForm) ++ Button1: TButton; ++ ProgressBar1: TProgressBar; ++ procedure Button1Click(Sender: TObject); ++ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); ++ private ++ { Private-Deklarationen } ++ public ++ { Public-Deklarationen } ++ end; ++ ++var ++ Form1: TForm1; ++ ++implementation ++ ++{$R *.dfm} ++ ++procedure TForm1.Button1Click(Sender: TObject); ++var ++ Context: TDcaEncContext; ++ InputBuffer: array of LongInt; ++ OutputBuffer: array of Byte; ++ SamplesInInput: Integer; ++ MaxBytesInOutput: Integer; ++ BytesReturned: Cardinal; ++ BytesWritten: Cardinal; ++ i: Integer; ++ h: THandle; ++const ++ ChannelsInInput: Integer = 2; ++ EncodeSteps: Integer = 10240; ++begin ++ Button1.Enabled := False; ++ ProgressBar1.Position := 0; ++ Application.ProcessMessages; ++ ++ //Create DCA Enc context ++ Context := dcaenc_create(44100, DCAENC_CHANNELS_STEREO, 768000, DCAENC_FLAG_BIGENDIAN); ++ ++ //Context created successfully? ++ if(Context = nil) then ++ begin ++ ShowMessage('Failed to create context!'); ++ Exit; ++ end; ++ ++ //Detect input/output size ++ SamplesInInput := dcaenc_input_size(Context); ++ MaxBytesInOutput := dcaenc_output_size(Context); ++ ++ //Some feedback ++ ShowMessage('SamplesInInput = ' + IntToStr(SamplesInInput)); ++ ShowMessage('MaxBytesInOutput = ' + IntToStr(MaxBytesInOutput)); ++ ++ //Allocate buffers ++ SetLength(InputBuffer, SamplesInInput * ChannelsInInput); ++ SetLength(OutputBuffer, MaxBytesInOutput); ++ ++ //ZeroBuffers ++ ZeroMemory(@InputBuffer[0], SizeOf(LongInt) * SamplesInInput * ChannelsInInput); ++ ZeroMemory(@OutputBuffer[0], SizeOf(Byte) * MaxBytesInOutput); ++ ++ //Create an output file ++ h := CreateFile('Test.dts', GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, 0, 0); ++ if(h = INVALID_HANDLE_VALUE) then ++ begin ++ ShowMessage('Failed to create output file!'); ++ Exit; ++ end; ++ ++ //Encode loop ++ for i := 0 to EncodeSteps do ++ begin ++ // TODO: Load the next 'SamplesInInput' samples into 'InputBuffer' here! ++ // Be aware that samples have to be 32-Bit Signed for DCAEnc. ++ ++ BytesReturned := dcaenc_convert_s32(Context, @InputBuffer[0], @OutputBuffer[0]); ++ WriteFile(h, OutputBuffer[0], BytesReturned, BytesWritten, nil); ++ ProgressBar1.Position := Round((i / EncodeSteps) * 100.0); ++ Application.ProcessMessages; ++ end; ++ ++ //Finalize Encode ++ BytesReturned := dcaenc_destroy(Context, @OutputBuffer[0]); ++ WriteFile(h, OutputBuffer[0], BytesReturned, BytesWritten, nil); ++ ++ //Close output ++ CloseHandle(h); ++ ++ //We are done! ++ ShowMessage('Encode has completed :-)'); ++ Button1.Enabled := True; ++ Application.ProcessMessages; ++end; ++ ++procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); ++begin ++ CanClose := Button1.Enabled; ++end; ++ ++end. +diff --git a/dllmain.cpp b/dllmain.cpp +new file mode 100644 +index 0000000..cd5e470 +--- /dev/null ++++ b/dllmain.cpp +@@ -0,0 +1,19 @@ ++// dllmain.cpp : Defines the entry point for the DLL application. ++#include ++ ++BOOL APIENTRY DllMain( HMODULE hModule, ++ DWORD ul_reason_for_call, ++ LPVOID lpReserved ++ ) ++{ ++ switch (ul_reason_for_call) ++ { ++ case DLL_PROCESS_ATTACH: ++ case DLL_THREAD_ATTACH: ++ case DLL_THREAD_DETACH: ++ case DLL_PROCESS_DETACH: ++ break; ++ } ++ return TRUE; ++} ++ +diff --git a/main.c b/main.c +index dcc7034..829fd2b 100644 +--- a/main.c ++++ b/main.c +@@ -20,62 +20,373 @@ + + #include + #include ++#include ++ + #include "config.h" ++ + #include "dcaenc.h" + #include "wavfile.h" ++#include "unicode_support.h" ++#include "xgetopt.h" ++#include "compiler_info.h" ++ ++//extern const int32_t prototype_filter[512]; + +-extern const int32_t prototype_filter[512]; ++static char status[4] = {'|','/','-','\\'}; ++static const int AUTO_SELECT = -1; + +-int main(int argc, char *argv[]) ++#define BUFFSIZE_SPL 512 ++#define BUFFSIZE_CHN 6 ++#define BUFFSIZE_OUT 16384 ++ ++static int dcaenc_main(int argc, char *argv[]) + { + dcaenc_context c; +- int32_t data[512 * 6]; +- uint8_t output[16384]; ++ int32_t data[BUFFSIZE_SPL * BUFFSIZE_CHN]; ++ uint8_t output[BUFFSIZE_OUT]; + wavfile * f; + FILE * outfile; ++ const char *error_msg; ++ unsigned int samples_total; ++ unsigned int samples_read; ++ unsigned int samples_read_total; ++ unsigned int current_pos; ++ double percent_done; + int bitrate; + int wrote; +- int samples_total; ++ int counter; ++ int status_idx; ++ int show_ver; ++ int show_help; ++ int ignore_len; ++ int enc_flags; ++ int channel_config; ++ int has_lfe; ++ xgetopt_t opt; ++ char t; ++ char *file_input; ++ char *file_output; ++ ++ static const int channel_map[6] = {DCAENC_CHANNELS_MONO, DCAENC_CHANNELS_STEREO, DCAENC_CHANNELS_3FRONT, ++ DCAENC_CHANNELS_2FRONT_2REAR, DCAENC_CHANNELS_3FRONT_2REAR, DCAENC_CHANNELS_3FRONT_2REAR}; ++ ++ fprintf(stderr, "%s-%s [%s]\n", PACKAGE_NAME, PACKAGE_VERSION, __DATE__); ++ fprintf(stderr, "Copyright (c) 2008-2011 Alexander E. Patrakov \n\n"); ++ fprintf(stderr, "This program is free software: you can redistribute it and/or modify\n"); ++ fprintf(stderr, "it under the terms of the GNU General Public License .\n"); ++ fprintf(stderr, "Note that this program is distributed with ABSOLUTELY NO WARRANTY.\n\n"); ++ ++ // ---------------------------- ++ ++ file_input = NULL; ++ file_output = NULL; ++ bitrate = 0; ++ enc_flags = DCAENC_FLAG_BIGENDIAN; ++ channel_config = AUTO_SELECT; ++ has_lfe = 0; ++ show_ver = 0; ++ ignore_len = 0; ++ show_help = 0; ++ ++ memset(&opt, 0, sizeof(xgetopt_t)); ++ while((t = xgetopt(argc, argv, "i:o:b:c:fhlev", &opt)) != EOF) ++ { ++ switch(t) ++ { ++ case 'i': ++ file_input = opt.optarg; ++ break; ++ case 'o': ++ file_output = opt.optarg; ++ break; ++ case 'b': ++ bitrate = (int)(atof(opt.optarg) * 1000.0f); ++ if(bitrate > 6144000 || bitrate < 32000) ++ { ++ fprintf(stderr, "Bitrate must be between 32 and 6144 kbps!\n"); ++ return 1; ++ } ++ break; ++ case 'c': ++ channel_config = atoi(opt.optarg) - 1; ++ if((channel_config < 0) || (channel_config > 15)) ++ { ++ fprintf(stderr, "Bad channel configuration. Must be between 1 and 16!\n"); ++ return 1; ++ } ++ break; ++ case 'f': ++ has_lfe = 1; ++ break; ++ case 'h': ++ show_help = 1; ++ break; ++ case 'l': ++ ignore_len = 1; ++ break; ++ case 'e': ++ enc_flags = enc_flags & (~DCAENC_FLAG_BIGENDIAN); ++ break; ++ case 'v': ++ show_ver = 1; ++ break; ++ case '?': ++ fprintf(stderr, "Unknown commandline option or missing argument: %s\n", argv[opt.optind-1]); ++ return 1; ++ } ++ } + +- static const int channel_map[6] = {DCAENC_CHANNELS_MONO, DCAENC_CHANNELS_STEREO, 0, +- DCAENC_CHANNELS_2FRONT_2REAR, DCAENC_CHANNELS_3FRONT_2REAR, DCAENC_CHANNELS_3FRONT_2REAR }; +- +- if (argc != 4) { +- if (argc == 2 && !strcmp(argv[1], "--version")) { +- printf(PACKAGE_NAME "-" PACKAGE_VERSION "\n"); +- printf(PACKAGE_URL "\n"); +- return 0; +- } else { +- printf("Usage: dcaenc input.wav output.dts bits_per_second\n"); +- return 1; +- } ++ // ---------------------------- ++ ++ if(!file_input || !file_output || bitrate < 1 || show_ver || show_help) ++ { ++ if(show_ver) ++ { ++ fprintf(stderr, PACKAGE_NAME "-" PACKAGE_VERSION "\n"); ++ fprintf(stderr, "Compiled on " __DATE__ " at " __TIME__ " using " __COMPILER__ ".\n"); ++ fprintf(stderr, PACKAGE_URL "\n"); ++ return 0; ++ } ++ else if(show_help) ++ { ++ fprintf(stderr, "Usage:\n dcaenc -i -o -b \n\n"); ++ fprintf(stderr, "Optional:\n"); ++ fprintf(stderr, " -l Ignore input length, can be useful when reading from stdin\n"); ++ fprintf(stderr, " -e Switch output endianess to Little Endian (default is: Big Endian)\n"); ++ fprintf(stderr, " -h Print the help screen that your are looking at right now\n"); ++ fprintf(stderr, " -c Overwrite the channel configuration (default is: Auto Selection)\n"); ++ fprintf(stderr, " -f Add an additional LFE channel (default: used for 6ch input)\n"); ++ fprintf(stderr, " -v Show version info\n\n"); ++ fprintf(stderr, "Remarks:\n"); ++ fprintf(stderr, " * Input or output file name can be \"-\" for stdin/stdout.\n"); ++ fprintf(stderr, " * The bitrate is specified in kilobits per second and may be rounded up.\n"); ++ fprintf(stderr, " - Use Float value for bitrates that are not a multiple of 1 kbps.\n"); ++ fprintf(stderr, " * Supported input sample rates:\n"); ++ fprintf(stderr, " - 32000\n"); ++ fprintf(stderr, " - 44100\n"); ++ fprintf(stderr, " - 48000\n"); ++ fprintf(stderr, " - or those divided by 2 or 4\n"); ++ fprintf(stderr, " * Supported channel modes:\n"); ++ fprintf(stderr, " - 1: MONO\n"); ++ fprintf(stderr, " - 2: DUAL_MONO\n"); ++ fprintf(stderr, " - 3: STEREO\n"); ++ fprintf(stderr, " - 4: STEREO_SUMDIFF\n"); ++ fprintf(stderr, " - 5: STEREO_TOTAL\n"); ++ fprintf(stderr, " - 6: 3FRONT\n"); ++ fprintf(stderr, " - 7: 2FRONT_1REAR\n"); ++ fprintf(stderr, " - 8: 3FRONT_1REAR\n"); ++ fprintf(stderr, " - 9: 2FRONT_2REAR\n"); ++ fprintf(stderr, " - 10: 3FRONT_2REAR\n"); ++ fprintf(stderr, " - 11: 4FRONT_2REAR\n"); ++ fprintf(stderr, " - 12: 3FRONT_2REAR_1OV\n"); ++ fprintf(stderr, " - 13: 3FRONT_3REAR\n"); ++ fprintf(stderr, " - 14: 5FRONT_2REAR\n"); ++ fprintf(stderr, " - 15: 4FRONT_4REAR\n"); ++ fprintf(stderr, " - 16: 5FRONT_3REAR\n"); ++ fprintf(stderr, " * Supported bitrates:\n"); ++ fprintf(stderr, " - mono @ 8 kHz: 32-2048 kbps\n"); ++ fprintf(stderr, " - mono @ 12 kHz: 48-3072 kbps\n"); ++ fprintf(stderr, " - mono @ 16 kHz: 48-3842 kbps\n"); ++ fprintf(stderr, " - mono @ 22.05 kHz: 65-3842 kbps\n"); ++ fprintf(stderr, " - mono @ 24 kHz: 71-3842 kbps\n"); ++ fprintf(stderr, " - mono @ 32 kHz: 95-3842 kbps\n"); ++ fprintf(stderr, " - mono @ 44.1 kHz: 130-3842 kbps\n"); ++ fprintf(stderr, " - mono @ 48 kHz: 142-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 8 kHz: 96-2048 kbps\n"); ++ fprintf(stderr, " - stereo @ 12 kHz: 96-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 16 kHz: 96-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 22.05 kHz: 128-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 24 kHz: 192-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 32 kHz: 192-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 44.1 kHz: 256-3842 kbps\n"); ++ fprintf(stderr, " - stereo @ 48 kHz: 271-3842 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 8 kHz: 112-2048 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 12 kHz: 168-3072 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 16 kHz: 224-3842 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 22.05 kHz: 308-3842 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 32 kHz: 447-3842 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 44.1 kHz: 615-3842 kbps\n"); ++ fprintf(stderr, " - 5.1 @ 48 kHz: 670-3842 kbps\n"); ++ ++ return 0; ++ } ++ else ++ { ++ fprintf(stderr, "Required arguments are missing. Use '-h' option for help!\n"); ++ return 1; ++ } + } +- f = wavfile_open(argv[1]); ++ ++ fprintf(stderr, "Source: %s\n", file_input); ++ fprintf(stderr, "Output: %s\n", file_output); ++ fprintf(stderr, "KBit/s: %d.%03d\n\n", bitrate / 1000, bitrate % 1000); ++ ++ // ---------------------------- ++ ++ f = wavfile_open(file_input, &error_msg, ignore_len); + if (!f) { +- printf("Could not open or parse %s\n", argv[1]); +- return 1; ++ fprintf(stderr, "Could not open or parse \"%s\".\n", file_input); ++ fprintf(stderr, "Error: %s!\n", error_msg); ++ return 1; + } +- bitrate = atoi(argv[3]); + + samples_total = f->samples_left; +- c = dcaenc_create(f->sample_rate, channel_map[f->channels - 1], bitrate, f->channels == 6 ? DCAENC_FLAG_LFE : 0); ++ ++ if(channel_config == AUTO_SELECT) ++ { ++ channel_config = channel_map[f->channels - 1]; ++ if(f->channels == 6) has_lfe = 1; ++ } ++ ++ if(has_lfe) ++ { ++ enc_flags = enc_flags | DCAENC_FLAG_LFE; ++ } ++ ++ switch(f->channels - (has_lfe ? 1 : 0)) ++ { ++ case 1: ++ if(!(channel_config == DCAENC_CHANNELS_MONO)) ++ { ++ fprintf(stderr, "Invalid channel configuration for input audio!\n"); ++ return 1; ++ } ++ break; ++ case 2: ++ if(!(channel_config == DCAENC_CHANNELS_DUAL_MONO || channel_config == DCAENC_CHANNELS_STEREO || ++ channel_config == DCAENC_CHANNELS_STEREO_SUMDIFF || channel_config == DCAENC_CHANNELS_STEREO_TOTAL)) ++ { ++ fprintf(stderr, "Invalid channel configuration for input audio!\n"); ++ return 1; ++ } ++ break; ++ case 4: ++ if(!(channel_config == DCAENC_CHANNELS_3FRONT_1REAR || channel_config == DCAENC_CHANNELS_2FRONT_2REAR)) ++ { ++ fprintf(stderr, "Invalid channel configuration for input audio!\n"); ++ return 1; ++ } ++ break; ++ case 5: ++ if(!(channel_config == DCAENC_CHANNELS_3FRONT_2REAR)) ++ { ++ fprintf(stderr, "Invalid channel configuration for input audio!\n"); ++ return 1; ++ } ++ break; ++ case 6: ++ if(!(channel_config == DCAENC_CHANNELS_3FRONT_3REAR || channel_config == DCAENC_CHANNELS_4FRONT_2REAR || ++ channel_config == DCAENC_CHANNELS_3FRONT_2REAR_1OV)) ++ { ++ fprintf(stderr, "Invalid channel configuration for input audio!\n"); ++ return 1; ++ } ++ break; ++ } ++ ++ // ---------------------------- ++ ++ c = dcaenc_create(f->sample_rate, channel_config, bitrate, enc_flags); + + if (!c) { +- printf("Wrong bitrate or sample rate\n"); +- return 1; ++ fprintf(stderr, "Insufficient bitrate or unsupported sample rate!\n"); ++ return 1; ++ } ++ ++ if((((size_t)(dcaenc_output_size(c))) > BUFFSIZE_OUT) || (((size_t)(dcaenc_input_size(c))) > BUFFSIZE_SPL)) ++ { ++ fprintf(stderr, "Internal error, buffers are too small!\n", file_output); ++ return 1; + } +- outfile = fopen(argv[2], "wb"); +- if (!outfile) { +- printf("Could not open %s\n", argv[2]); +- return 1; ++ ++ outfile = strcmp(file_output, "-") ? fopen_utf8(file_output, "wb") : stdout; ++ if(!outfile) { ++ fprintf(stderr, "Could not open \"%s\" for writing!\n", file_output); ++ return 1; + } +- while (wavfile_read_s32(f, data)) { ++ ++ fflush(stdout); ++ fflush(stderr); ++ ++ // ---------------------------- ++ ++ counter = 0; ++ samples_read_total = 0; ++ status_idx = 0; ++ ++ while(samples_read = wavfile_read_s32(f, data, BUFFSIZE_SPL)) ++ { ++ samples_read_total += samples_read; + wrote = dcaenc_convert_s32(c, data, output); + fwrite(output, 1, wrote, outfile); ++ ++ if(counter == 0) ++ { ++ current_pos = samples_read_total / f->sample_rate; ++ ++ if((samples_total > 0) && (samples_total < UNKNOWN_SIZE)) ++ { ++ percent_done = ((double)(samples_total - f->samples_left)) / ((double)(samples_total)); ++ fprintf(stderr, "Encoding... %d:%02d [%3.1f%%]\r", current_pos / 60, current_pos % 60, percent_done * 100.0); ++ fflush(stderr); ++ } ++ else ++ { ++ fprintf(stderr, "Encoding... %d:%02d [%c]\r", current_pos / 60, current_pos % 60, status[(status_idx = (status_idx+1) % 4)]); ++ fflush(stderr); ++ } ++ } ++ ++ counter = (counter+1) % 125; + } ++ ++ fprintf(stderr, "Encoding... %d:%02d [%3.1f%%]\n", (samples_read_total / f->sample_rate) / 60, (samples_read_total / f->sample_rate) % 60, 100.0); ++ fflush(stderr); ++ + wrote = dcaenc_destroy(c, output); + fwrite(output, 1, wrote, outfile); +- fclose(outfile); ++ if(outfile != stdout) ++ { ++ fclose(outfile); ++ } + wavfile_close(f); ++ ++ fprintf(stderr, "Done.\n"); + return 0; + } ++ ++#ifdef _WIN32 ++ ++#include ++#include ++#include ++ ++int main( int argc, char **argv ) ++{ ++ int dcaenc_argc; ++ char **dcaenc_argv; ++ UINT old_cp; ++ int exit_code; ++ ++ _setmode(_fileno(stdin), _O_BINARY); ++ _setmode(_fileno(stdout), _O_BINARY); ++ ++ old_cp = GetConsoleOutputCP(); ++ SetConsoleOutputCP(CP_UTF8); ++ ++ init_commandline_arguments_utf8(&dcaenc_argc, &dcaenc_argv); ++ exit_code = dcaenc_main(dcaenc_argc, dcaenc_argv); ++ free_commandline_arguments_utf8(&dcaenc_argc, &dcaenc_argv); ++ ++ SetConsoleOutputCP(old_cp); ++ return exit_code; ++} ++ ++#else //_WIN32 ++ ++int main( int argc, char **argv ) ++{ ++ return dcaenc_main(argc, argv); ++} ++ ++#endif //_WIN32 +\ No newline at end of file +diff --git a/math_tables.h b/math_tables.h +index ce2e6c4..2b97618 100644 +--- a/math_tables.h ++++ b/math_tables.h +@@ -17,12 +17,18 @@ extern const int32_t cb_to_add[256]; + + extern const int quant_levels_cb[27]; + +-static inline int32_t cos_t(int x) ++#ifdef _MSC_VER ++#define INLINE __forceinline ++#else ++#define INLINE inline ++#endif ++ ++INLINE static int32_t cos_t(int x) + { + return cos_table[x & 2047]; + } + +-static inline int32_t sin_t(int x) ++INLINE static int32_t sin_t(int x) + { + return cos_t(x - 512); + } +diff --git a/unicode_support.c b/unicode_support.c +new file mode 100644 +index 0000000..283325c +--- /dev/null ++++ b/unicode_support.c +@@ -0,0 +1,225 @@ ++/* ++ * This file is part of dcaenc. ++ * ++ * Copyright (c) 2008-2011 Alexander E. Patrakov ++ * ++ * dcaenc is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * dcaenc is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with dcaenc; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++#include "unicode_support.h" ++ ++#ifdef _WIN32 ++ ++#include ++#include ++#include ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ if(Buffer) ++ { ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++char *utf16_to_ansi(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ if(Buffer) ++ { ++ Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ if(Buffer) ++ { ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i, nArgs; ++ LPWSTR *szArglist; ++ ++ szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); ++ ++ if(NULL == szArglist) ++ { ++ fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); ++ exit(-1); ++ } ++ ++ *argv = (char**) malloc(sizeof(char*) * nArgs); ++ *argc = nArgs; ++ ++ if(NULL == *argv) ++ { ++ fprintf(stderr, "\nFATAL: Malloc failed\n\n"); ++ exit(-1); ++ } ++ ++ for(i = 0; i < nArgs; i++) ++ { ++ (*argv)[i] = utf16_to_utf8(szArglist[i]); ++ if(NULL == (*argv)[i]) ++ { ++ fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n"); ++ exit(-1); ++ } ++ } ++ ++ LocalFree(szArglist); ++} ++ ++void free_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i = 0; ++ ++ if(*argv != NULL) ++ { ++ for(i = 0; i < *argc; i++) ++ { ++ if((*argv)[i] != NULL) ++ { ++ free((*argv)[i]); ++ (*argv)[i] = NULL; ++ } ++ } ++ free(*argv); ++ *argv = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) free(filename_utf16); ++ if(mode_utf16) free(mode_utf16); ++ ++ return ret; ++} ++ ++/* int stat_utf8(const char *path_utf8, struct stat *buf) ++{ ++ int ret = -1; ++ ++ wchar_t *path_utf16 = utf8_to_utf16(path_utf8); ++ if(path_utf16) ++ { ++ ret = wstat(path_utf16, buf); ++ free(path_utf16); ++ } ++ ++ return ret; ++} */ ++ ++int rename_utf8(const char *oldname_utf8, const char *newname_utf8) ++{ ++ int ret = -1; ++ ++ wchar_t *oldname_utf16 = utf8_to_utf16(oldname_utf8); ++ wchar_t *newname_utf16 = utf8_to_utf16(newname_utf8); ++ ++ if(oldname_utf16 && newname_utf16) ++ { ++ _wunlink(newname_utf16); ++ ret = _wrename(oldname_utf16, newname_utf16); ++ } ++ ++ if(newname_utf16) free(newname_utf16); ++ if(oldname_utf16) free(oldname_utf16); ++ ++ return ret; ++} ++ ++char *path_utf8_to_ansi(const char *psz_filename_utf8, int b_create) ++{ ++ char *short_path = NULL; ++ wchar_t *psz_filename_utf16 = NULL; ++ ++ if(!psz_filename_utf8) ++ { ++ return NULL; ++ } ++ ++ psz_filename_utf16 = utf8_to_utf16(psz_filename_utf8); ++ if(psz_filename_utf16) ++ { ++ char *psz_filename_ansi = NULL; ++ if(b_create) ++ { ++ FILE *fh = _wfopen(psz_filename_utf16, L"a+"); ++ if(fh) fclose(fh); ++ } ++ psz_filename_ansi = utf16_to_ansi(psz_filename_utf16); ++ if(psz_filename_ansi) ++ { ++ if(strcmp(psz_filename_ansi, psz_filename_utf8)) ++ { ++ wchar_t short_name_utf16[MAX_PATH]; ++ DWORD result = GetShortPathNameW(psz_filename_utf16, short_name_utf16, MAX_PATH); ++ if((result > 0) && (result < MAX_PATH)) ++ { ++ short_path = utf16_to_ansi(short_name_utf16); ++ free(psz_filename_ansi); ++ } ++ else ++ { ++ short_path = psz_filename_ansi; /*if GetShortPathName() failed, use the ANSI version*/ ++ } ++ } ++ else ++ { ++ short_path = psz_filename_ansi; /*don't convert plain ASCII filenames to "short" path*/ ++ } ++ } ++ free(psz_filename_utf16); ++ } ++ ++ return short_path; ++} ++ ++#endif //_WIN32 +diff --git a/unicode_support.h b/unicode_support.h +new file mode 100644 +index 0000000..96d9ec1 +--- /dev/null ++++ b/unicode_support.h +@@ -0,0 +1,51 @@ ++/* ++ * This file is part of dcaenc. ++ * ++ * Copyright (c) 2008-2011 Alexander E. Patrakov ++ * ++ * dcaenc is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * dcaenc is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with dcaenc; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifdef _WIN32 ++#ifndef _INC_STAT ++struct stat; ++#endif ++char *utf16_to_utf8(const wchar_t *input); ++char *utf16_to_ansi(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int *argc, char ***argv); ++void free_commandline_arguments_utf8(int *argc, char ***argv); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++int rename_utf8(const char *oldname_utf8, const char *newname_utf8); ++char *path_utf8_to_ansi(const char *psz_filename_utf8, int b_create); ++#else ++#define fopen_utf8(NAME, MODE) fopen(NAME, MODE) ++#define rename_utf8(OLD, NEW) rename(OLD, NEW) ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +\ No newline at end of file +diff --git a/vc_solution/dcadll_vc2010.vcxproj b/vc_solution/dcadll_vc2010.vcxproj +new file mode 100644 +index 0000000..807df23 +--- /dev/null ++++ b/vc_solution/dcadll_vc2010.vcxproj +@@ -0,0 +1,126 @@ ++ ++ ++ ++ ++ Debug ++ Win32 ++ ++ ++ Release ++ Win32 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663} ++ Win32Proj ++ dcadll_vc2010 ++ ++ ++ ++ DynamicLibrary ++ true ++ Unicode ++ ++ ++ DynamicLibrary ++ false ++ true ++ Unicode ++ Windows7.1SDK ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ true ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\dll\ ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ dcaenc-0 ++ ++ ++ false ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\dll\ ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ dcaenc-0 ++ ++ ++ ++ NotUsing ++ Level3 ++ Disabled ++ WIN32;_DEBUG;_WINDOWS;_USRDLL;DCADLL_VC2010_EXPORTS;%(PreprocessorDefinitions) ++ ++ ++ Windows ++ true ++ $(TargetDir)$(TargetName)_imp.lib ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ ++ ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ Level3 ++ NotUsing ++ Full ++ true ++ true ++ WIN32;NDEBUG;_WINDOWS;_USRDLL;DCADLL_VC2010_EXPORTS;%(PreprocessorDefinitions) ++ AnySuitable ++ Speed ++ true ++ true ++ NotSet ++ Fast ++ MultiThreadedDLL ++ false ++ false ++ ++ ++ Windows ++ false ++ true ++ true ++ $(TargetDir)$(TargetName).dll.lib ++ UseLinkTimeCodeGeneration ++ $(SolutionDir)lib\EncodePointer.lib;$(SolutionDir)lib\msvcrt_vc6.lib;%(AdditionalDependencies) ++ 5.0 ++ true ++ true ++ ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ ++ ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcadll_vc2010.vcxproj.filters b/vc_solution/dcadll_vc2010.vcxproj.filters +new file mode 100644 +index 0000000..d98bb04 +--- /dev/null ++++ b/vc_solution/dcadll_vc2010.vcxproj.filters +@@ -0,0 +1,48 @@ ++ ++ ++ ++ ++ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} ++ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx ++ ++ ++ {93995380-89BD-4b04-88EB-625FBE52EBFB} ++ h;hpp;hxx;hm;inl;inc;xsd ++ ++ ++ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} ++ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms ++ ++ ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcadll_vc2010.vcxproj.user b/vc_solution/dcadll_vc2010.vcxproj.user +new file mode 100644 +index 0000000..ace9a86 +--- /dev/null ++++ b/vc_solution/dcadll_vc2010.vcxproj.user +@@ -0,0 +1,3 @@ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcaenc_vc2010.sln b/vc_solution/dcaenc_vc2010.sln +new file mode 100644 +index 0000000..2b49e18 +--- /dev/null ++++ b/vc_solution/dcaenc_vc2010.sln +@@ -0,0 +1,59 @@ ++ ++Microsoft Visual Studio Solution File, Format Version 11.00 ++# Visual Studio 2010 ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcaenc_vc2010", "dcaenc_vc2010.vcxproj", "{F90211C8-0718-46F1-AD58-683FA005BFA5}" ++ ProjectSection(ProjectDependencies) = postProject ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866} = {282DDEDF-52A5-442E-90DE-94ABEC4B4866} ++ EndProjectSection ++EndProject ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcalib_vc2010", "dcalib_vc2010.vcxproj", "{B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}" ++ ProjectSection(ProjectDependencies) = postProject ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866} = {282DDEDF-52A5-442E-90DE-94ABEC4B4866} ++ EndProjectSection ++EndProject ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcadll_vc2010", "dcadll_vc2010.vcxproj", "{8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}" ++ ProjectSection(ProjectDependencies) = postProject ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866} = {282DDEDF-52A5-442E-90DE-94ABEC4B4866} ++ EndProjectSection ++EndProject ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gentables", "gentables.vcxproj", "{282DDEDF-52A5-442E-90DE-94ABEC4B4866}" ++EndProject ++Global ++ GlobalSection(SolutionConfigurationPlatforms) = preSolution ++ Debug|Win32 = Debug|Win32 ++ Debug|x64 = Debug|x64 ++ Release|Win32 = Release|Win32 ++ Release|x64 = Release|x64 ++ EndGlobalSection ++ GlobalSection(ProjectConfigurationPlatforms) = postSolution ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Debug|Win32.Build.0 = Debug|Win32 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Debug|x64.ActiveCfg = Debug|x64 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Debug|x64.Build.0 = Debug|x64 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Release|Win32.ActiveCfg = Release|Win32 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Release|Win32.Build.0 = Release|Win32 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Release|x64.ActiveCfg = Release|x64 ++ {F90211C8-0718-46F1-AD58-683FA005BFA5}.Release|x64.Build.0 = Release|x64 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Debug|Win32.Build.0 = Debug|Win32 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Debug|x64.ActiveCfg = Debug|Win32 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Release|Win32.ActiveCfg = Release|Win32 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Release|Win32.Build.0 = Release|Win32 ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F}.Release|x64.ActiveCfg = Release|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Debug|Win32.Build.0 = Debug|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Debug|x64.ActiveCfg = Debug|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Release|Win32.ActiveCfg = Release|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Release|Win32.Build.0 = Release|Win32 ++ {8AFCA1B5-C8F1-4F56-91F7-80415FFEB663}.Release|x64.ActiveCfg = Release|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Debug|Win32.Build.0 = Debug|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Debug|x64.ActiveCfg = Debug|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Release|Win32.ActiveCfg = Release|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Release|Win32.Build.0 = Release|Win32 ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866}.Release|x64.ActiveCfg = Release|Win32 ++ EndGlobalSection ++ GlobalSection(SolutionProperties) = preSolution ++ HideSolutionNode = FALSE ++ EndGlobalSection ++EndGlobal +diff --git a/vc_solution/dcaenc_vc2010.vcxproj b/vc_solution/dcaenc_vc2010.vcxproj +new file mode 100644 +index 0000000..39cb22b +--- /dev/null ++++ b/vc_solution/dcaenc_vc2010.vcxproj +@@ -0,0 +1,206 @@ ++ ++ ++ ++ ++ Debug ++ Win32 ++ ++ ++ Debug ++ x64 ++ ++ ++ Release ++ Win32 ++ ++ ++ Release ++ x64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ true ++ true ++ true ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ {b4ad2963-8469-4dbd-bd26-fad4fe303f8f} ++ ++ ++ ++ {F90211C8-0718-46F1-AD58-683FA005BFA5} ++ Win32Proj ++ dcaenc_vc2010 ++ ++ ++ ++ Application ++ true ++ Unicode ++ ++ ++ Application ++ true ++ Unicode ++ ++ ++ Application ++ false ++ true ++ Unicode ++ Windows7.1SDK ++ ++ ++ Application ++ false ++ true ++ Unicode ++ Windows7.1SDK ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ true ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\ ++ ++ ++ true ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\ ++ ++ ++ false ++ dcaenc ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\ ++ ++ ++ false ++ dcaenc ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\ ++ ++ ++ ++ NotUsing ++ Level3 ++ Disabled ++ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) ++ ++ ++ Console ++ true ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ ++ ++ Level3 ++ Disabled ++ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) ++ ++ ++ Console ++ true ++ ++ ++ ++ ++ Level3 ++ NotUsing ++ Full ++ true ++ true ++ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ++ true ++ AnySuitable ++ Speed ++ true ++ true ++ MultiThreaded ++ false ++ NotSet ++ Fast ++ false ++ ++ ++ Console ++ false ++ true ++ true ++ 5.0 ++ UseLinkTimeCodeGeneration ++ $(SolutionDir)lib\EncodePointer.lib;%(AdditionalDependencies) ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ Level3 ++ NotUsing ++ Full ++ true ++ true ++ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ++ true ++ AnySuitable ++ Speed ++ true ++ true ++ MultiThreaded ++ false ++ StreamingSIMDExtensions2 ++ Fast ++ false ++ ++ ++ Console ++ false ++ true ++ true ++ ++ ++ UseLinkTimeCodeGeneration ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcaenc_vc2010.vcxproj.filters b/vc_solution/dcaenc_vc2010.vcxproj.filters +new file mode 100644 +index 0000000..9af5b8d +--- /dev/null ++++ b/vc_solution/dcaenc_vc2010.vcxproj.filters +@@ -0,0 +1,48 @@ ++ ++ ++ ++ ++ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} ++ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx ++ ++ ++ {93995380-89BD-4b04-88EB-625FBE52EBFB} ++ h;hpp;hxx;hm;inl;inc;xsd ++ ++ ++ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} ++ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms ++ ++ ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcaenc_vc2010.vcxproj.user b/vc_solution/dcaenc_vc2010.vcxproj.user +new file mode 100644 +index 0000000..ace9a86 +--- /dev/null ++++ b/vc_solution/dcaenc_vc2010.vcxproj.user +@@ -0,0 +1,3 @@ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcalib_vc2010.vcxproj b/vc_solution/dcalib_vc2010.vcxproj +new file mode 100644 +index 0000000..5216233 +--- /dev/null ++++ b/vc_solution/dcalib_vc2010.vcxproj +@@ -0,0 +1,114 @@ ++ ++ ++ ++ ++ Debug ++ Win32 ++ ++ ++ Release ++ Win32 ++ ++ ++ ++ {B4AD2963-8469-4DBD-BD26-FAD4FE303F8F} ++ Win32Proj ++ dcalib_vc2010 ++ ++ ++ ++ StaticLibrary ++ true ++ Unicode ++ ++ ++ StaticLibrary ++ false ++ true ++ Unicode ++ Windows7.1SDK ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\lib\ ++ dcaenc-static-0 ++ ++ ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\lib\ ++ dcaenc-static-0 ++ ++ ++ ++ NotUsing ++ Level3 ++ Disabled ++ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) ++ ++ ++ Windows ++ true ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ Level3 ++ NotUsing ++ Full ++ true ++ true ++ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) ++ AnySuitable ++ Speed ++ true ++ true ++ MultiThreaded ++ Fast ++ NotSet ++ false ++ false ++ ++ ++ Windows ++ true ++ true ++ true ++ ++ ++ true ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcalib_vc2010.vcxproj.filters b/vc_solution/dcalib_vc2010.vcxproj.filters +new file mode 100644 +index 0000000..b2d7092 +--- /dev/null ++++ b/vc_solution/dcalib_vc2010.vcxproj.filters +@@ -0,0 +1,45 @@ ++ ++ ++ ++ ++ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} ++ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx ++ ++ ++ {93995380-89BD-4b04-88EB-625FBE52EBFB} ++ h;hpp;hxx;hm;inl;inc;xsd ++ ++ ++ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} ++ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms ++ ++ ++ ++ ++ Source Files ++ ++ ++ Source Files ++ ++ ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/dcalib_vc2010.vcxproj.user b/vc_solution/dcalib_vc2010.vcxproj.user +new file mode 100644 +index 0000000..ace9a86 +--- /dev/null ++++ b/vc_solution/dcalib_vc2010.vcxproj.user +@@ -0,0 +1,3 @@ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/gentables.vcxproj b/vc_solution/gentables.vcxproj +new file mode 100644 +index 0000000..85b4751 +--- /dev/null ++++ b/vc_solution/gentables.vcxproj +@@ -0,0 +1,125 @@ ++ ++ ++ ++ ++ Debug ++ Win32 ++ ++ ++ Release ++ Win32 ++ ++ ++ ++ {282DDEDF-52A5-442E-90DE-94ABEC4B4866} ++ Win32Proj ++ gentables ++ ++ ++ ++ Application ++ true ++ Unicode ++ ++ ++ Application ++ false ++ true ++ Unicode ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ true ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\gen\ ++ ++ ++ false ++ $(SolutionDir)$(Platform)\$(Configuration)\ ++ $(SolutionDir)$(Platform)\$(Configuration)\tmp\gen\ ++ ++ ++ ++ ++ ++ Level3 ++ Disabled ++ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) ++ ++ ++ Console ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ "$(OutDir)\gentables.exe" > "$(SolutionDir)..\math_tables.c" ++ Generating Tables ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ Level3 ++ ++ ++ MaxSpeed ++ true ++ true ++ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) ++ ++ ++ Console ++ true ++ true ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ "$(OutDir)\gentables.exe" > "$(SolutionDir)..\math_tables.c" ++ Generating Tables ++ ++ ++ copy /Y "$(SolutionDir)..\config_msvc.h" "$(SolutionDir)..\config.h" ++ Create: "$(SolutionDir)config.h" ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/gentables.vcxproj.filters b/vc_solution/gentables.vcxproj.filters +new file mode 100644 +index 0000000..754afe3 +--- /dev/null ++++ b/vc_solution/gentables.vcxproj.filters +@@ -0,0 +1,33 @@ ++ ++ ++ ++ ++ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} ++ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx ++ ++ ++ {93995380-89BD-4b04-88EB-625FBE52EBFB} ++ h;hpp;hxx;hm;inl;inc;xsd ++ ++ ++ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} ++ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms ++ ++ ++ ++ ++ ++ ++ ++ Header Files ++ ++ ++ Header Files ++ ++ ++ ++ ++ Source Files ++ ++ ++ +\ No newline at end of file +diff --git a/vc_solution/lib/EncodePointer.lib b/vc_solution/lib/EncodePointer.lib +new file mode 100644 +index 0000000..c035792 +Binary files /dev/null and b/vc_solution/lib/EncodePointer.lib differ +diff --git a/vc_solution/lib/msvcrt_vc6.lib b/vc_solution/lib/msvcrt_vc6.lib +new file mode 100644 +index 0000000..26f03fe +Binary files /dev/null and b/vc_solution/lib/msvcrt_vc6.lib differ +diff --git a/wavfile.c b/wavfile.c +index 950a08d..7f35e2f 100644 +--- a/wavfile.c ++++ b/wavfile.c +@@ -23,189 +23,332 @@ + #include + #include + #include "wavfile.h" ++#include "unicode_support.h" + +-static uint32_t find_chunk(FILE * file, const uint8_t chunk_id[4]) ++#ifdef _M_X64 ++#define SIZE2UINT32(X) (uint32_t)(((X) > UINT32_MAX) ? UINT32_MAX : (X)) ++#define SIZE2INT(X) (uint32_t)(((X) > INT_MAX) ? INT_MAX : (X)) ++#else ++#define SIZE2UINT32(X) (X) ++#define SIZE2INT(X) (X) ++#endif ++ ++#define BUFFSIZE_SAMPLES 512 ++#define BUFFSIZE_BYTES (BUFFSIZE_SAMPLES * 6 * 4) ++ ++static const char *g_error_msg[13] = + { +- uint8_t buffer[8]; +- while (1) { +- size_t chunksize; +- size_t s = fread(buffer, 1, 8, file); +- if (s < 8) +- return 0; +- chunksize = (uint32_t)buffer[4] | ((uint32_t)buffer[5] << 8) | +- ((uint32_t)buffer[6] << 16) | ((uint32_t)buffer[7] << 24); +- if (!memcmp(buffer, chunk_id, 4)) +- return chunksize; +- fseek(file, chunksize, SEEK_CUR); +- } ++ /* 0*/ "Success", ++ /* 1*/ "Failed to open file", ++ /* 2*/ "RIFF header not found", ++ /* 3*/ "WAVE chunk not found", ++ /* 4*/ "Format chunk not found", ++ /* 5*/ "Failed to read Format chunk", ++ /* 6*/ "Invalid or unsupported format tag", ++ /* 7*/ "Unsupported number of channels (only 1, 2, 3, 4, 5 and 6)", ++ /* 8*/ "Unsupported bits per sample (only 16 and 32 for now)", ++ /* 9*/ "Inconsistent block alignment", ++ /*10*/ "Inconsistent average bitrate", ++ /*11*/ "Data chunk not found", ++ /*12*/ "Data chunk size is invalid" ++}; ++ ++static int find_chunk(FILE * file, const uint8_t chunk_id[4], size_t *chunk_size) ++{ ++ uint8_t buffer[8]; ++ *chunk_size = 0; ++ ++ while (1) { ++ size_t chunksize; ++ size_t s = fread(buffer, 1, 8, file); ++ if (s < 8) ++ return 0; ++ chunksize = (uint32_t)buffer[4] | ((uint32_t)buffer[5] << 8) | ++ ((uint32_t)buffer[6] << 16) | ((uint32_t)buffer[7] << 24); ++ ++ if(!memcmp(buffer, chunk_id, 4)) ++ { ++ *chunk_size = chunksize; ++ return 1; ++ } ++ ++ if((chunksize % 2) == 1) chunksize++; //Skip extra "unused" byte at the end of odd-size chunks ++ ++ if(fseek(file, SIZE2UINT32(chunksize), SEEK_CUR)) ++ { ++ while(chunksize > 8) ++ { ++ s = fread(buffer, 1, 8, file); ++ if (s < 8) ++ return 0; ++ chunksize -= 8; ++ } ++ s = fread(buffer, 1, chunksize, file); ++ if (s < chunksize) ++ return 0; ++ } ++ } + } + +-wavfile * wavfile_open(const char * filename) ++wavfile * wavfile_open(const char * filename, const char ** error_msg, const int ignore_len) + { +- wavfile *result; +- size_t s; +- uint8_t buffer[8]; +- uint8_t *fmt; +- uint32_t v; +- uint32_t avg_bps; +- uint32_t block_align; +- static const uint8_t riff[4] = {'R', 'I', 'F', 'F'}; +- static const uint8_t wave[4] = { 'W', 'A', 'V', 'E'}; +- static const uint8_t fmt_[4] = {'f', 'm', 't', ' '}; +- static const uint8_t data[4] = {'d', 'a', 't', 'a'}; +- +- result = (wavfile *)calloc(1, sizeof(wavfile)); +- if (!result) +- goto err0; +- +- result->file = fopen(filename, "rb"); +- if (!result->file) +- goto err1; +- +- s = fread(buffer, 1, 8, result->file); +- if (s < 8) +- goto err2; +- +- if (memcmp(buffer, riff, 4)) +- goto err2; +- +- /* TODO: check size (in buffer[4..8]) */ +- s = fread(buffer, 1, 4, result->file); +- if (s < 4) +- goto err2; +- +- if (memcmp(buffer, wave, 4)) +- goto err2; +- +- s = find_chunk(result->file, fmt_); +- if (s != 16 && s != 40) +- goto err2; +- +- fmt = (uint8_t*)malloc(s); +- if (!fmt) +- goto err2; +- +- if (fread(fmt, 1, s, result->file) != s) +- goto err3; +- +- /* wFormatTag */ +- v = (uint32_t)fmt[0] | ((uint32_t)fmt[1] << 8); +- if (v != 1 && v != 0xfffe) +- goto err3; +- +- /* wChannels */ +- v = (uint32_t)fmt[2] | ((uint32_t)fmt[3] << 8); +- if (v != 1 && v != 2 && v != 4 && v != 5 && v !=6) +- goto err3; +- result->channels = v; +- /* dwSamplesPerSec */ +- result->sample_rate = (uint32_t)fmt[4] | ((uint32_t)fmt[5] << 8) | +- ((uint32_t)fmt[6] << 16) | ((uint32_t)fmt[7] << 24); +- +- /* dwAvgBytesPerSec */ +- avg_bps = (uint32_t)fmt[8] | ((uint32_t)fmt[9] << 8) | +- ((uint32_t)fmt[10] << 16) | ((uint32_t)fmt[11] << 24); +- +- /* wBlockAlign */ +- block_align = (uint32_t)fmt[12] | ((uint32_t)fmt[13] << 8); +- +- /* wBitsPerSample */ +- result->bits_per_sample = (uint32_t)fmt[14] | ((uint32_t)fmt[15] << 8); +- if (result->bits_per_sample != 16 && result->bits_per_sample != 32) +- goto err3; +- +- if (block_align != result->channels * (result->bits_per_sample / 8)) +- goto err3; +- +- if (avg_bps != block_align * result->sample_rate) +- goto err3; +- +- v = find_chunk(result->file, data); +- if (v == 0 || v % block_align != 0) +- goto err3; +- +- result->samples_left = v / block_align; +- free(fmt); +- return result; +- +- err3: ++ wavfile *result; ++ size_t s; ++ uint8_t buffer[8]; ++ uint8_t *fmt; ++ size_t v; ++ uint32_t avg_bps; ++ uint32_t block_align; ++ static const uint8_t riff[4] = {'R', 'I', 'F', 'F'}; ++ static const uint8_t wave[4] = { 'W', 'A', 'V', 'E'}; ++ static const uint8_t fmt_[4] = {'f', 'm', 't', ' '}; ++ static const uint8_t data[4] = {'d', 'a', 't', 'a'}; ++ ++ result = (wavfile *)calloc(1, sizeof(wavfile)); ++ if (!result) ++ goto err0; ++ ++ result->file = strcmp(filename, "-") ? fopen_utf8(filename, "rb") : stdin; ++ if (!result->file) ++ { ++ *error_msg = g_error_msg[1]; ++ goto err1; ++ } ++ ++ s = fread(buffer, 1, 8, result->file); ++ if (s < 8) ++ { ++ *error_msg = g_error_msg[2]; ++ goto err2; ++ } ++ ++ if (memcmp(buffer, riff, 4)) ++ { ++ *error_msg = g_error_msg[2]; ++ goto err2; ++ } ++ ++ /* TODO: check size (in buffer[4..8]) */ ++ s = fread(buffer, 1, 4, result->file); ++ if (s < 4) ++ { ++ *error_msg = g_error_msg[3]; ++ goto err2; ++ } ++ ++ if (memcmp(buffer, wave, 4)) ++ { ++ *error_msg = g_error_msg[3]; ++ goto err2; ++ } ++ ++ if(!find_chunk(result->file, fmt_, &s)) ++ { ++ *error_msg = g_error_msg[4]; ++ goto err2; ++ } ++ if((s < 16) || (s > 40)) ++ { ++ *error_msg = g_error_msg[4]; ++ goto err2; ++ } ++ ++ fmt = (uint8_t*)malloc(s); ++ if(!fmt) ++ { ++ *error_msg = g_error_msg[5]; ++ goto err2; ++ } ++ ++ if(fread(fmt, 1, s, result->file) != s) ++ { ++ *error_msg = g_error_msg[5]; ++ goto err3; ++ } ++ ++ /* skip unused byte (for odd-size chunks) */ ++ if((s % 2) == 1) ++ { ++ char dummy[1]; ++ if(fread(&dummy, 1, 1, result->file) != 1) ++ { ++ *error_msg = g_error_msg[5]; ++ goto err3; ++ } ++ } ++ ++ /* wFormatTag */ ++ v = (uint32_t)fmt[0] | ((uint32_t)fmt[1] << 8); ++ if(v != 1 && v != 0xfffe) ++ { ++ *error_msg = g_error_msg[6]; ++ goto err3; ++ } ++ ++ /* wChannels */ ++ v = (uint32_t)fmt[2] | ((uint32_t)fmt[3] << 8); ++ if((v < 1) || (v > 6)) ++ { ++ *error_msg = g_error_msg[7]; ++ goto err3; ++ } ++ result->channels = SIZE2UINT32(v); ++ ++ /* dwSamplesPerSec */ ++ result->sample_rate = (uint32_t)fmt[4] | ((uint32_t)fmt[5] << 8) | ++ ((uint32_t)fmt[6] << 16) | ((uint32_t)fmt[7] << 24); ++ ++ /* dwAvgBytesPerSec */ ++ avg_bps = (uint32_t)fmt[8] | ((uint32_t)fmt[9] << 8) | ++ ((uint32_t)fmt[10] << 16) | ((uint32_t)fmt[11] << 24); ++ ++ /* wBlockAlign */ ++ block_align = (uint32_t)fmt[12] | ((uint32_t)fmt[13] << 8); ++ ++ /* wBitsPerSample */ ++ result->bits_per_sample = (uint32_t)fmt[14] | ((uint32_t)fmt[15] << 8); ++ if(result->bits_per_sample != 16 && result->bits_per_sample != 32) ++ { ++ *error_msg = g_error_msg[8]; ++ goto err3; ++ } ++ ++ if(block_align != result->channels * (result->bits_per_sample / 8)) ++ { ++ *error_msg = g_error_msg[9]; ++ goto err3; ++ } ++ ++ if(avg_bps != block_align * result->sample_rate) ++ { ++ *error_msg = g_error_msg[10]; ++ goto err3; ++ } ++ ++ if(!find_chunk(result->file, data, &v)) ++ { ++ *error_msg = g_error_msg[11]; ++ goto err3; ++ } ++ if(((v == 0) || (v % block_align != 0)) && (!ignore_len)) ++ { ++ *error_msg = g_error_msg[12]; ++ goto err3; ++ } ++ ++ result->samples_left = SIZE2UINT32(ignore_len ? UNKNOWN_SIZE : (v / block_align)); + free(fmt); +- err2: +- fclose(result->file); +- err1: ++ *error_msg = g_error_msg[0]; ++ return result; ++ ++ err3: ++ free(fmt); ++ err2: ++ if(result->file != stdin) fclose(result->file); ++ err1: + free(result); +- err0: ++ err0: + return NULL; + } + + void wavfile_close(wavfile * f) + { +- fclose(f->file); +- free(f); ++ if(f->file != stdin) ++ { ++ fclose(f->file); ++ } ++ free(f); + } + + static int32_t get_s32_sample(const wavfile * f, const uint8_t *buffer, int sample, int channel) + { +- int offset = (f->bits_per_sample / 8) * (f->channels * sample + channel); +- uint32_t v; +- switch (f->bits_per_sample) { ++ int offset = (f->bits_per_sample / 8) * (f->channels * sample + channel); ++ uint32_t v; ++ switch (f->bits_per_sample) ++ { + case 16: +- v = (uint32_t)buffer[offset + 0] | ((uint32_t)buffer[offset + 1] << 8); +- return v << 16; +- break; ++ v = (uint32_t)buffer[offset + 0] | ((uint32_t)buffer[offset + 1] << 8); ++ return v << 16; ++ break; + case 32: +- v = (uint32_t)buffer[offset + 0] | ((uint32_t)buffer[offset + 1] << 8) | ++ v = (uint32_t)buffer[offset + 0] | ((uint32_t)buffer[offset + 1] << 8) | + ((uint32_t)buffer[offset + 2] << 16) | ((uint32_t)buffer[offset + 3] << 24); +- return v; +- break; ++ return v; ++ break; + default: +- return 0; +- } ++ return 0; ++ } + } + +-int wavfile_read_s32(wavfile * f, int32_t *samples) ++int wavfile_read_s32(wavfile * f, int32_t *samples, size_t sample_count) + { +- uint8_t buffer[512 * 6 * 4]; +- int32_t smpte_sample[6]; +- int samples_to_read; +- int bytes_to_read; +- unsigned int i, ch; +- +- memset(buffer, 0, 512 * 6 * 4); +- samples_to_read = f->samples_left < 512 ? f->samples_left : 512; +- bytes_to_read = samples_to_read * f->channels * (f->bits_per_sample / 8); +- f->samples_left -= samples_to_read; +- if (fread(buffer, 1, bytes_to_read, f->file) != bytes_to_read) { +- f->samples_left = 0; +- } +- +- for (i = 0; i < 512; i++) { +- for (ch = 0; ch < f->channels; ch++) +- smpte_sample[ch] = get_s32_sample(f, buffer, i, ch); +- switch(f->channels) { +- case 1: +- case 2: +- case 4: +- for (ch = 0; ch < f->channels; ch++) +- *(samples++) = smpte_sample[ch]; +- break; +- case 5: +- *(samples++) = smpte_sample[2]; +- *(samples++) = smpte_sample[0]; +- *(samples++) = smpte_sample[1]; +- *(samples++) = smpte_sample[3]; +- *(samples++) = smpte_sample[4]; +- break; +- case 6: +- *(samples++) = smpte_sample[2]; +- *(samples++) = smpte_sample[0]; +- *(samples++) = smpte_sample[1]; +- *(samples++) = smpte_sample[4]; +- *(samples++) = smpte_sample[5]; +- *(samples++) = smpte_sample[3]; +- break; +- } +- } +- +- return f->samples_left; ++ uint8_t buffer[BUFFSIZE_BYTES]; ++ int32_t smpte_sample[6]; ++ int samples_to_read; ++ int bytes_to_read; ++ int bytes_read; ++ unsigned int i, ch; ++ ++ if(sample_count != BUFFSIZE_SAMPLES) ++ { ++ fprintf(stderr, "Only 512 samples currently supported!\n"); ++ return 0; ++ } ++ ++ if(f->samples_left < 1) ++ { ++ return 0; ++ } ++ ++ memset(buffer, 0, BUFFSIZE_BYTES); ++ samples_to_read = (f->samples_left < BUFFSIZE_SAMPLES) ? f->samples_left : BUFFSIZE_SAMPLES; ++ bytes_to_read = samples_to_read * f->channels * (f->bits_per_sample / 8); ++ if(f->samples_left != UNKNOWN_SIZE) { ++ f->samples_left -= samples_to_read; ++ } ++ ++ bytes_read = SIZE2INT(fread(buffer, 1, bytes_to_read, f->file)); ++ if(bytes_read != bytes_to_read) { ++ f->samples_left = 0; ++ } ++ ++ for (i = 0; i < BUFFSIZE_SAMPLES; i++) ++ { ++ for (ch = 0; ch < f->channels; ch++) ++ smpte_sample[ch] = get_s32_sample(f, buffer, i, ch); ++ switch(f->channels) ++ { ++ case 1: ++ case 2: ++ case 4: ++ for (ch = 0; ch < f->channels; ch++) ++ *(samples++) = smpte_sample[ch]; ++ break; ++ case 3: ++ *(samples++) = smpte_sample[2]; ++ *(samples++) = smpte_sample[0]; ++ *(samples++) = smpte_sample[1]; ++ break; ++ case 5: ++ *(samples++) = smpte_sample[2]; ++ *(samples++) = smpte_sample[0]; ++ *(samples++) = smpte_sample[1]; ++ *(samples++) = smpte_sample[3]; ++ *(samples++) = smpte_sample[4]; ++ break; ++ case 6: ++ *(samples++) = smpte_sample[2]; ++ *(samples++) = smpte_sample[0]; ++ *(samples++) = smpte_sample[1]; ++ *(samples++) = smpte_sample[4]; ++ *(samples++) = smpte_sample[5]; ++ *(samples++) = smpte_sample[3]; ++ break; ++ default: ++ fprintf(stderr, "FIXME: Unexpected channel number!\n"); ++ exit(1); ++ } ++ } ++ ++ return bytes_read / (f->channels * (f->bits_per_sample / 8)); + } +diff --git a/wavfile.h b/wavfile.h +index b8945e2..418e55f 100644 +--- a/wavfile.h ++++ b/wavfile.h +@@ -23,6 +23,8 @@ + + #include + ++#define UNKNOWN_SIZE 0xFFFFFFFF ++ + typedef struct { + FILE * file; + unsigned int channels; +@@ -31,8 +33,8 @@ typedef struct { + unsigned int samples_left; + } wavfile; + +-wavfile * wavfile_open(const char * filename); +-int wavfile_read_s32(wavfile * f, int32_t * samples); ++wavfile * wavfile_open(const char * filename, const char ** error_msg, const int ignore_len); ++int wavfile_read_s32(wavfile * f, int32_t *samples, size_t sample_count); + void wavfile_close(wavfile * f); + + #endif +diff --git a/xgetopt.c b/xgetopt.c +new file mode 100644 +index 0000000..507b44d +--- /dev/null ++++ b/xgetopt.c +@@ -0,0 +1,206 @@ ++// XGetopt.cpp Version 1.2 ++// ++// Author: Hans Dietrich ++// hdietrich2@hotmail.com ++// ++// Description: ++// XGetopt.cpp implements getopt(), a function to parse command lines. ++// ++// History ++// Version 1.2 - 2003 May 17 ++// - Added Unicode support ++// ++// Version 1.1 - 2002 March 10 ++// - Added example to XGetopt.cpp module header ++// ++// This software is released into the public domain. ++// You are free to use it in any way you like. ++// ++// This software is provided "as is" with no expressed ++// or implied warranty. I accept no liability for any ++// damage or loss of business that this software may cause. ++// ++/////////////////////////////////////////////////////////////////////////////// ++ ++/////////////////////////////////////////////////////////////////////////////// ++#include ++#include ++/////////////////////////////////////////////////////////////////////////////// ++ ++#include "xgetopt.h" ++ ++/////////////////////////////////////////////////////////////////////////////// ++// ++// X G e t o p t . c p p ++// ++// ++// NAME ++// getopt -- parse command line options ++// ++// SYNOPSIS ++// int getopt(int argc, char *argv[], char *optstring) ++// ++// extern char *optarg; ++// extern int optind; ++// ++// DESCRIPTION ++// The getopt() function parses the command line arguments. Its ++// arguments argc and argv are the argument count and array as ++// passed into the application on program invocation. In the case ++// of Visual C++ programs, argc and argv are available via the ++// variables __argc and __argv (double underscores), respectively. ++// getopt returns the next option letter in argv that matches a ++// letter in optstring. (Note: Unicode programs should use ++// __targv instead of __argv. Also, all character and string ++// literals should be enclosed in _T( ) ). ++// ++// optstring is a string of recognized option letters; if a letter ++// is followed by a colon, the option is expected to have an argument ++// that may or may not be separated from it by white space. optarg ++// is set to point to the start of the option argument on return from ++// getopt. ++// ++// Option letters may be combined, e.g., "-ab" is equivalent to ++// "-a -b". Option letters are case sensitive. ++// ++// getopt places in the external variable optind the argv index ++// of the next argument to be processed. optind is initialized ++// to 0 before the first call to getopt. ++// ++// When all options have been processed (i.e., up to the first ++// non-option argument), getopt returns EOF, optarg will point ++// to the argument, and optind will be set to the argv index of ++// the argument. If there are no non-option arguments, optarg ++// will be set to NULL. ++// ++// The special option "--" may be used to delimit the end of the ++// options; EOF will be returned, and "--" (and everything after it) ++// will be skipped. ++// ++// RETURN VALUE ++// For option letters contained in the string optstring, getopt ++// will return the option letter. getopt returns a question mark (?) ++// when it encounters an option letter not included in optstring. ++// EOF is returned when processing is finished. ++// ++// BUGS ++// 1) Long options are not supported. ++// 2) The GNU double-colon extension is not supported. ++// 3) The environment variable POSIXLY_CORRECT is not supported. ++// 4) The + syntax is not supported. ++// 5) The automatic permutation of arguments is not supported. ++// 6) This implementation of getopt() returns EOF if an error is ++// encountered, instead of -1 as the latest standard requires. ++// ++// EXAMPLE ++// BOOL CMyApp::ProcessCommandLine(int argc, char *argv[]) ++// { ++// int c; ++// ++// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF) ++// { ++// switch (c) ++// { ++// case _T('a'): ++// TRACE(_T("option a\n")); ++// // ++// // set some flag here ++// // ++// break; ++// ++// case _T('B'): ++// TRACE( _T("option B\n")); ++// // ++// // set some other flag here ++// // ++// break; ++// ++// case _T('n'): ++// TRACE(_T("option n: value=%d\n"), atoi(optarg)); ++// // ++// // do something with value here ++// // ++// break; ++// ++// case _T('?'): ++// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]); ++// return FALSE; ++// break; ++// ++// default: ++// TRACE(_T("WARNING: no handler for option %c\n"), c); ++// return FALSE; ++// break; ++// } ++// } ++// // ++// // check for non-option args here ++// // ++// return TRUE; ++// } ++// ++/////////////////////////////////////////////////////////////////////////////// ++ ++int xgetopt(int argc, char *argv[], char *optstring, xgetopt_t *ctx) ++{ ++ char c, *cp; ++ ++ if (ctx->optind == 0) ++ ctx->next = NULL; ++ ++ ctx->optarg = NULL; ++ ++ if (ctx->next == NULL || *ctx->next == '\0') ++ { ++ if (ctx->optind == 0) ++ ctx->optind++; ++ ++ if (ctx->optind >= argc || argv[ctx->optind][0] != '-' || argv[ctx->optind][1] == '\0') ++ { ++ ctx->optarg = NULL; ++ if (ctx->optind < argc) ++ ctx->optarg = argv[ctx->optind]; ++ return EOF; ++ } ++ ++ if (strcmp(argv[ctx->optind], "--") == 0) ++ { ++ ctx->optind++; ++ ctx->optarg = NULL; ++ if (ctx->optind < argc) ++ ctx->optarg = argv[ctx->optind]; ++ return EOF; ++ } ++ ++ ctx->next = argv[ctx->optind]; ++ ctx->next++; // skip past - ++ ctx->optind++; ++ } ++ ++ c = *ctx->next++; ++ cp = strchr(optstring, c); ++ ++ if (cp == NULL || c == ':') ++ return '?'; ++ ++ cp++; ++ if (*cp == ':') ++ { ++ if (*ctx->next != '\0') ++ { ++ ctx->optarg = ctx->next; ++ ctx->next = NULL; ++ } ++ else if (ctx->optind < argc) ++ { ++ ctx->optarg = argv[ctx->optind]; ++ ctx->optind++; ++ } ++ else ++ { ++ return '?'; ++ } ++ } ++ ++ return c; ++} +diff --git a/xgetopt.h b/xgetopt.h +new file mode 100644 +index 0000000..f9371b9 +--- /dev/null ++++ b/xgetopt.h +@@ -0,0 +1,29 @@ ++// XGetopt.h Version 1.2 ++// ++// Author: Hans Dietrich ++// hdietrich2@hotmail.com ++// ++// This software is released into the public domain. ++// You are free to use it in any way you like. ++// ++// This software is provided "as is" with no expressed ++// or implied warranty. I accept no liability for any ++// damage or loss of business that this software may cause. ++// ++/////////////////////////////////////////////////////////////////////////////// ++ ++#ifndef XGETOPT_H ++#define XGETOPT_H ++ ++typedef struct ++{ ++ int optind; ++ int opterr; ++ char *optarg; ++ char *next; ++} ++xgetopt_t; ++ ++int xgetopt(int argc, char *argv[], char *optstring, xgetopt_t *ctx); ++ ++#endif //XGETOPT_H diff --git a/etc/Patches/FAAD-v2.7-UTF8+Flush.V1.diff b/etc/Patches/FAAD-v2.7-UTF8+Flush.V1.diff new file mode 100644 index 00000000..ee5ea71f --- /dev/null +++ b/etc/Patches/FAAD-v2.7-UTF8+Flush.V1.diff @@ -0,0 +1,591 @@ + common/mp4ff/mp4ff.vcproj | 6 ++- + frontend/audio.c | 12 +++++- + frontend/faad.sln | 14 ++---- + frontend/faad.vcproj | 22 ++++++---- + frontend/main.c | 82 +++++++++++++++++++++++++++++------- + frontend/unicode_support.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ + frontend/unicode_support.h | 21 +++++++++ + libfaad/common.h | 1 + + libfaad/libfaad.sln | 6 +- + libfaad/libfaad.vcproj | 11 ++++- + 10 files changed, 230 insertions(+), 43 deletions(-) + +diff --git a/common/mp4ff/mp4ff.vcproj b/common/mp4ff/mp4ff.vcproj +index 70fd4a0..7ed6158 100644 +--- a/common/mp4ff/mp4ff.vcproj ++++ b/common/mp4ff/mp4ff.vcproj +@@ -1,9 +1,10 @@ + + + + + #include + #include ++ + #include "audio.h" ++#include "unicode_support.h" + + + audio_file *open_audio_file(char *infile, int samplerate, int channels, + int outputFormat, int fileType, long channelMask) + { ++ wchar_t *fileNameW; ++ + audio_file *aufile = malloc(sizeof(audio_file)); + + aufile->outputFormat = outputFormat; +@@ -78,7 +82,13 @@ audio_file *open_audio_file(char *infile, int samplerate, int channels, + aufile->toStdio = 1; + } else { + aufile->toStdio = 0; +- aufile->sndfile = fopen(infile, "wb"); ++ aufile->sndfile = NULL; ++ fileNameW = utf8_to_utf16(infile); ++ if(fileNameW) ++ { ++ aufile->sndfile = _wfopen(fileNameW, L"wb"); ++ free(fileNameW); ++ } + } + + if (aufile->sndfile == NULL) +diff --git a/frontend/faad.sln b/frontend/faad.sln +index a47200b..3ccdf0f 100644 +--- a/frontend/faad.sln ++++ b/frontend/faad.sln +@@ -1,15 +1,11 @@ +  +-Microsoft Visual Studio Solution File, Format Version 9.00 +-# Visual Studio 2005 +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "faad", "faad.vcproj", "{2BD8CBB3-DFC9-4A6A-9B7A-07ED749BED58}" +- ProjectSection(ProjectDependencies) = postProject +- {F470BB4A-7675-4D6A-B310-41F33AC6F987} = {F470BB4A-7675-4D6A-B310-41F33AC6F987} +- {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114} = {BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114} +- EndProjectSection ++Microsoft Visual Studio Solution File, Format Version 11.00 ++# Visual Studio 2010 ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "faad", "faad.vcxproj", "{2BD8CBB3-DFC9-4A6A-9B7A-07ED749BED58}" + EndProject +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\libfaad\libfaad.vcproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}" ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "..\libfaad\libfaad.vcxproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}" + EndProject +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4ff", "..\common\mp4ff\mp4ff.vcproj", "{F470BB4A-7675-4D6A-B310-41F33AC6F987}" ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4ff", "..\common\mp4ff\mp4ff.vcxproj", "{F470BB4A-7675-4D6A-B310-41F33AC6F987}" + EndProject + Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution +diff --git a/frontend/faad.vcproj b/frontend/faad.vcproj +index b187293..185f64c 100644 +--- a/frontend/faad.vcproj ++++ b/frontend/faad.vcproj +@@ -1,9 +1,10 @@ + + + + + + +- + +@@ -133,15 +133,16 @@ + + + +- + +@@ -216,6 +216,10 @@ + RelativePath=".\main.c" + > + ++ ++ + + + + #include "audio.h" ++#include "unicode_support.h" + + #ifndef min + #define min(a,b) ( (a) < (b) ? (a) : (b) ) +@@ -69,6 +70,8 @@ static void faad_fprintf(FILE *stream, const char *fmt, ...) + vfprintf(stream, fmt, ap); + + va_end(ap); ++ ++ fflush(stream); + } + } + +@@ -427,11 +430,19 @@ static int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_std + + aac_buffer b; + ++ wchar_t *fileNameW; ++ + memset(&b, 0, sizeof(aac_buffer)); + + if (adts_out) + { +- adtsFile = fopen(adts_fn, "wb"); ++ adtsFile = NULL; ++ fileNameW = utf8_to_utf16(adts_fn); ++ if(fileNameW) ++ { ++ adtsFile = _wfopen(fileNameW, L"wb"); ++ free(fileNameW); ++ } + if (adtsFile == NULL) + { + faad_fprintf(stderr, "Error opening file: %s\n", adts_fn); +@@ -439,7 +450,13 @@ static int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_std + } + } + +- b.infile = fopen(aacfile, "rb"); ++ b.infile = NULL; ++ fileNameW = utf8_to_utf16(aacfile); ++ if(fileNameW) ++ { ++ b.infile = _wfopen(fileNameW, L"rb"); ++ free(fileNameW); ++ } + if (b.infile == NULL) + { + /* unable to open file */ +@@ -634,7 +651,7 @@ static int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_std + if (percent > old_percent) + { + old_percent = percent; +- sprintf(percents, "%d%% decoding %s.", percent, aacfile); ++ sprintf(percents, "[%d%%] decoding %s.", percent, aacfile); + faad_fprintf(stderr, "%s\r", percents); + #ifdef _WIN32 + SetConsoleTitle(percents); +@@ -746,11 +763,19 @@ static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_std + unsigned int framesize; + unsigned long timescale; + ++ wchar_t *fileNameW; + + /* initialise the callback structure */ + mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t)); + +- mp4File = fopen(mp4file, "rb"); ++ mp4File = NULL; ++ fileNameW = utf8_to_utf16(mp4file); ++ if(fileNameW) ++ { ++ mp4File = _wfopen(fileNameW, L"rb"); ++ free(fileNameW); ++ } ++ + mp4cb->read = read_callback; + mp4cb->seek = seek_callback; + mp4cb->user_data = mp4File; +@@ -767,7 +792,13 @@ static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_std + + if (adts_out) + { +- adtsFile = fopen(adts_fn, "wb"); ++ adtsFile = NULL; ++ fileNameW = utf8_to_utf16(adts_fn); ++ if(fileNameW) ++ { ++ adtsFile = _wfopen(fileNameW, L"wb"); ++ free(fileNameW); ++ } + if (adtsFile == NULL) + { + faad_fprintf(stderr, "Error opening file: %s\n", adts_fn); +@@ -973,8 +1004,9 @@ static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_std + if (percent > old_percent) + { + old_percent = percent; +- sprintf(percents, "%d%% decoding %s.", percent, mp4file); ++ sprintf(percents, "[%d%%] decoding %s.", percent, mp4file); + faad_fprintf(stderr, "%s\r", percents); ++ + #ifdef _WIN32 + SetConsoleTitle(percents); + #endif +@@ -1011,7 +1043,7 @@ static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_std + return frameInfo.error; + } + +-int main(int argc, char *argv[]) ++int faad_main(int argc, char *argv[]) + { + int result; + int infoOnly = 0; +@@ -1028,12 +1060,13 @@ int main(int argc, char *argv[]) + int mp4file = 0; + int noGapless = 0; + char *fnp; +- char aacFileName[255]; +- char audioFileName[255]; +- char adtsFileName[255]; ++ char *aacFileName = NULL; //[255]; ++ char *audioFileName = NULL; //[255]; ++ char *adtsFileName = NULL; //[255]; + unsigned char header[8]; + float length = 0; + FILE *hMP4File; ++ wchar_t *fileNameW; + + /* System dependant types */ + #ifdef _WIN32 +@@ -1044,7 +1077,6 @@ int main(int argc, char *argv[]) + + unsigned long cap = NeAACDecGetCapabilities(); + +- + /* begin process command line */ + progName = argv[0]; + while (1) { +@@ -1078,14 +1110,14 @@ int main(int argc, char *argv[]) + if (optarg) + { + outfile_set = 1; +- strcpy(audioFileName, optarg); ++ audioFileName = strdup(optarg); + } + break; + case 'a': + if (optarg) + { + adts_out = 1; +- strcpy(adtsFileName, optarg); ++ adtsFileName = strdup(optarg); + } + break; + case 's': +@@ -1205,7 +1237,7 @@ int main(int argc, char *argv[]) + #endif + + /* point to the specified file name */ +- strcpy(aacFileName, argv[optind]); ++ aacFileName = strdup(argv[optind]); + + #ifdef _WIN32 + begin = GetTickCount(); +@@ -1218,7 +1250,7 @@ int main(int argc, char *argv[]) + */ + if(!writeToStdio && !outfile_set) + { +- strcpy(audioFileName, aacFileName); ++ audioFileName = strdup(aacFileName); + + fnp = (char *)strrchr(audioFileName,'.'); + +@@ -1230,7 +1262,13 @@ int main(int argc, char *argv[]) + + /* check for mp4 file */ + mp4file = 0; +- hMP4File = fopen(aacFileName, "rb"); ++ hMP4File = NULL; ++ fileNameW = utf8_to_utf16(aacFileName); ++ if(fileNameW) ++ { ++ hMP4File = _wfopen(fileNameW, L"rb"); ++ free(fileNameW); ++ } + if (!hMP4File) + { + faad_fprintf(stderr, "Error opening file: %s\n", aacFileName); +@@ -1268,3 +1306,15 @@ int main(int argc, char *argv[]) + + return 0; + } ++ ++int wmain(int argc, wchar_t **argv_utf16) ++{ ++ int result = 0; ++ char **argv_utf8 = NULL; ++ ++ init_commandline_arguments_utf8(argc, &argv_utf8, argv_utf16); ++ result = faad_main(argc, argv_utf8); ++ free_commandline_arguments_utf8(argc, &argv_utf8); ++ ++ return result; ++} +diff --git a/frontend/unicode_support.c b/frontend/unicode_support.c +new file mode 100644 +index 0000000..21ecd5c +--- /dev/null ++++ b/frontend/unicode_support.c +@@ -0,0 +1,98 @@ ++#include "unicode_support.h" ++ ++#include ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ ++ if(!Buffer) ++ { ++ fprintf(stderr, "Error in utf16_to_utf8: Memory allocation failed!\n"); ++ return NULL; ++ } ++ ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ ++ if(!Buffer) ++ { ++ fprintf(stderr, "Error in utf8_to_utf16: Memory allocation failed!\n"); ++ return NULL; ++ } ++ ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int argc, char ***argv_utf8, wchar_t **argv_utf16) ++{ ++ int i = 0; ++ ++ *argv_utf8 = (char**) malloc(argc * sizeof(char*)); ++ if(!(*argv_utf8)) ++ { ++ fprintf(stderr, "Error in init_commandline_arguments_utf8: Memory allocation failed!\n"); ++ exit(-1); ++ } ++ ++ for(i = 0; i < argc; i++) ++ { ++ (*argv_utf8)[i] = utf16_to_utf8(argv_utf16[i]); ++ if(!(*argv_utf8)[i]) ++ { ++ fprintf(stderr, "Error in init_commandline_arguments_utf8: Memory allocation failed!\n"); ++ exit(-1); ++ } ++ } ++} ++ ++void free_commandline_arguments_utf8(int argc, char ***argv_utf8) ++{ ++ int i = 0; ++ ++ if(*argv_utf8 != NULL) ++ { ++ for(i = 0; i < argc; i++) ++ { ++ if((*argv_utf8)[i] != NULL) ++ { ++ free((*argv_utf8)[i]); ++ (*argv_utf8)[i] = NULL; ++ } ++ } ++ free(*argv_utf8); ++ *argv_utf8 = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) free(filename_utf16); ++ if(mode_utf16) free(mode_utf16); ++ ++ return ret; ++} +diff --git a/frontend/unicode_support.h b/frontend/unicode_support.h +new file mode 100644 +index 0000000..cc13fd9 +--- /dev/null ++++ b/frontend/unicode_support.h +@@ -0,0 +1,21 @@ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++char *utf16_to_utf8(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int argc, char ***argv_utf8, wchar_t **argv_utf16); ++void free_commandline_arguments_utf8(int argc, char ***argv_utf8); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +\ No newline at end of file +diff --git a/libfaad/common.h b/libfaad/common.h +index d3b21c3..6796ded 100644 +--- a/libfaad/common.h ++++ b/libfaad/common.h +@@ -346,6 +346,7 @@ char *strchr(), *strrchr(); + + #ifdef __ICL /* only Intel C compiler has fmath ??? */ + ++ #error Deine Mudda! + #include + + #define sin sinf +diff --git a/libfaad/libfaad.sln b/libfaad/libfaad.sln +index 88087f6..a22c0f4 100644 +--- a/libfaad/libfaad.sln ++++ b/libfaad/libfaad.sln +@@ -1,6 +1,6 @@ +-Microsoft Visual Studio Solution File, Format Version 9.00 +-# Visual C++ Express 2005 +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "libfaad.vcproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}" ++Microsoft Visual Studio Solution File, Format Version 11.00 ++# Visual Studio 2010 ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaad", "libfaad.vcxproj", "{BC3EFE27-9015-4C9C-AD3C-72B3B7ED2114}" + EndProject + Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution +diff --git a/libfaad/libfaad.vcproj b/libfaad/libfaad.vcproj +index 6401c9b..2adcf81 100644 +--- a/libfaad/libfaad.vcproj ++++ b/libfaad/libfaad.vcproj +@@ -1,9 +1,11 @@ + + + + + + + + + +- + +@@ -151,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/examples/c/decode/file/main.c b/examples/c/decode/file/main.c +index 20fafa2..6f160a4 100644 +--- a/examples/c/decode/file/main.c ++++ b/examples/c/decode/file/main.c +@@ -76,7 +76,7 @@ int main(int argc, char *argv[]) + return 1; + } + +- if((fout = fopen(argv[2], "wb")) == NULL) { ++ if((fout = fopen_utf8(argv[2], "wb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[2]); + return 1; + } +diff --git a/examples/c/encode/file/example_c_encode_file.vcproj b/examples/c/encode/file/example_c_encode_file.vcproj +index 8a45a4d..319b8bd 100644 +--- a/examples/c/encode/file/example_c_encode_file.vcproj ++++ b/examples/c/encode/file/example_c_encode_file.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -151,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/examples/c/encode/file/main.c b/examples/c/encode/file/main.c +index d1037e3..148e045 100644 +--- a/examples/c/encode/file/main.c ++++ b/examples/c/encode/file/main.c +@@ -59,7 +59,7 @@ int main(int argc, char *argv[]) + return 1; + } + +- if((fin = fopen(argv[1], "rb")) == NULL) { ++ if((fin = fopen_utf8(argv[1], "rb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[1]); + return 1; + } +diff --git a/examples/cpp/decode/file/example_cpp_decode_file.vcproj b/examples/cpp/decode/file/example_cpp_decode_file.vcproj +index cace46f..eda36e1 100644 +--- a/examples/cpp/decode/file/example_cpp_decode_file.vcproj ++++ b/examples/cpp/decode/file/example_cpp_decode_file.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -151,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/examples/cpp/decode/file/main.cpp b/examples/cpp/decode/file/main.cpp +index 5614050..20749c5 100644 +--- a/examples/cpp/decode/file/main.cpp ++++ b/examples/cpp/decode/file/main.cpp +@@ -81,7 +81,7 @@ int main(int argc, char *argv[]) + return 1; + } + +- if((fout = fopen(argv[2], "wb")) == NULL) { ++ if((fout = fopen_utf8(argv[2], "wb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[2]); + return 1; + } +diff --git a/examples/cpp/encode/file/example_cpp_encode_file.vcproj b/examples/cpp/encode/file/example_cpp_encode_file.vcproj +index 7efab70..19d6314 100644 +--- a/examples/cpp/encode/file/example_cpp_encode_file.vcproj ++++ b/examples/cpp/encode/file/example_cpp_encode_file.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -151,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/examples/cpp/encode/file/main.cpp b/examples/cpp/encode/file/main.cpp +index 22448bb..29ce2a0 100644 +--- a/examples/cpp/encode/file/main.cpp ++++ b/examples/cpp/encode/file/main.cpp +@@ -64,7 +64,7 @@ int main(int argc, char *argv[]) + return 1; + } + +- if((fin = fopen(argv[1], "rb")) == NULL) { ++ if((fin = fopen_utf8(argv[1], "rb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[1]); + return 1; + } +diff --git a/include/ogg/ogg.h b/include/ogg/ogg.h +new file mode 100644 +index 0000000..cea5c16 +--- /dev/null ++++ b/include/ogg/ogg.h +@@ -0,0 +1,209 @@ ++/******************************************************************** ++ * * ++ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * ++ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * ++ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * ++ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * ++ * * ++ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * ++ * by the Xiph.Org Foundation http://www.xiph.org/ * ++ * * ++ ******************************************************************** ++ ++ function: toplevel libogg include ++ last mod: $Id: ogg.h 17571 2010-10-27 13:28:20Z xiphmont $ ++ ++ ********************************************************************/ ++#ifndef _OGG_H ++#define _OGG_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include ++#include ++ ++typedef struct { ++ void *iov_base; ++ size_t iov_len; ++} ogg_iovec_t; ++ ++typedef struct { ++ long endbyte; ++ int endbit; ++ ++ unsigned char *buffer; ++ unsigned char *ptr; ++ long storage; ++} oggpack_buffer; ++ ++/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ ++ ++typedef struct { ++ unsigned char *header; ++ long header_len; ++ unsigned char *body; ++ long body_len; ++} ogg_page; ++ ++/* ogg_stream_state contains the current encode/decode state of a logical ++ Ogg bitstream **********************************************************/ ++ ++typedef struct { ++ unsigned char *body_data; /* bytes from packet bodies */ ++ long body_storage; /* storage elements allocated */ ++ long body_fill; /* elements stored; fill mark */ ++ long body_returned; /* elements of fill returned */ ++ ++ ++ int *lacing_vals; /* The values that will go to the segment table */ ++ ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact ++ this way, but it is simple coupled to the ++ lacing fifo */ ++ long lacing_storage; ++ long lacing_fill; ++ long lacing_packet; ++ long lacing_returned; ++ ++ unsigned char header[282]; /* working space for header encode */ ++ int header_fill; ++ ++ int e_o_s; /* set when we have buffered the last packet in the ++ logical bitstream */ ++ int b_o_s; /* set after we've written the initial page ++ of a logical bitstream */ ++ long serialno; ++ long pageno; ++ ogg_int64_t packetno; /* sequence number for decode; the framing ++ knows where there's a hole in the data, ++ but we need coupling so that the codec ++ (which is in a separate abstraction ++ layer) also knows about the gap */ ++ ogg_int64_t granulepos; ++ ++} ogg_stream_state; ++ ++/* ogg_packet is used to encapsulate the data and metadata belonging ++ to a single raw Ogg/Vorbis packet *************************************/ ++ ++typedef struct { ++ unsigned char *packet; ++ long bytes; ++ long b_o_s; ++ long e_o_s; ++ ++ ogg_int64_t granulepos; ++ ++ ogg_int64_t packetno; /* sequence number for decode; the framing ++ knows where there's a hole in the data, ++ but we need coupling so that the codec ++ (which is in a separate abstraction ++ layer) also knows about the gap */ ++} ogg_packet; ++ ++typedef struct { ++ unsigned char *data; ++ int storage; ++ int fill; ++ int returned; ++ ++ int unsynced; ++ int headerbytes; ++ int bodybytes; ++} ogg_sync_state; ++ ++/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ ++ ++extern void oggpack_writeinit(oggpack_buffer *b); ++extern int oggpack_writecheck(oggpack_buffer *b); ++extern void oggpack_writetrunc(oggpack_buffer *b,long bits); ++extern void oggpack_writealign(oggpack_buffer *b); ++extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); ++extern void oggpack_reset(oggpack_buffer *b); ++extern void oggpack_writeclear(oggpack_buffer *b); ++extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); ++extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); ++extern long oggpack_look(oggpack_buffer *b,int bits); ++extern long oggpack_look1(oggpack_buffer *b); ++extern void oggpack_adv(oggpack_buffer *b,int bits); ++extern void oggpack_adv1(oggpack_buffer *b); ++extern long oggpack_read(oggpack_buffer *b,int bits); ++extern long oggpack_read1(oggpack_buffer *b); ++extern long oggpack_bytes(oggpack_buffer *b); ++extern long oggpack_bits(oggpack_buffer *b); ++extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); ++ ++extern void oggpackB_writeinit(oggpack_buffer *b); ++extern int oggpackB_writecheck(oggpack_buffer *b); ++extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); ++extern void oggpackB_writealign(oggpack_buffer *b); ++extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); ++extern void oggpackB_reset(oggpack_buffer *b); ++extern void oggpackB_writeclear(oggpack_buffer *b); ++extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); ++extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); ++extern long oggpackB_look(oggpack_buffer *b,int bits); ++extern long oggpackB_look1(oggpack_buffer *b); ++extern void oggpackB_adv(oggpack_buffer *b,int bits); ++extern void oggpackB_adv1(oggpack_buffer *b); ++extern long oggpackB_read(oggpack_buffer *b,int bits); ++extern long oggpackB_read1(oggpack_buffer *b); ++extern long oggpackB_bytes(oggpack_buffer *b); ++extern long oggpackB_bits(oggpack_buffer *b); ++extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); ++ ++/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ ++ ++extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); ++extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, ++ int count, long e_o_s, ogg_int64_t granulepos); ++extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); ++extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); ++extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); ++ ++/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ ++ ++extern int ogg_sync_init(ogg_sync_state *oy); ++extern int ogg_sync_clear(ogg_sync_state *oy); ++extern int ogg_sync_reset(ogg_sync_state *oy); ++extern int ogg_sync_destroy(ogg_sync_state *oy); ++extern int ogg_sync_check(ogg_sync_state *oy); ++ ++extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); ++extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); ++extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); ++extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); ++extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); ++extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); ++extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); ++ ++/* Ogg BITSTREAM PRIMITIVES: general ***************************/ ++ ++extern int ogg_stream_init(ogg_stream_state *os,int serialno); ++extern int ogg_stream_clear(ogg_stream_state *os); ++extern int ogg_stream_reset(ogg_stream_state *os); ++extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); ++extern int ogg_stream_destroy(ogg_stream_state *os); ++extern int ogg_stream_check(ogg_stream_state *os); ++extern int ogg_stream_eos(ogg_stream_state *os); ++ ++extern void ogg_page_checksum_set(ogg_page *og); ++ ++extern int ogg_page_version(const ogg_page *og); ++extern int ogg_page_continued(const ogg_page *og); ++extern int ogg_page_bos(const ogg_page *og); ++extern int ogg_page_eos(const ogg_page *og); ++extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); ++extern int ogg_page_serialno(const ogg_page *og); ++extern long ogg_page_pageno(const ogg_page *og); ++extern int ogg_page_packets(const ogg_page *og); ++ ++extern void ogg_packet_clear(ogg_packet *op); ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _OGG_H */ +diff --git a/include/ogg/os_types.h b/include/ogg/os_types.h +new file mode 100644 +index 0000000..4438b30 +--- /dev/null ++++ b/include/ogg/os_types.h +@@ -0,0 +1,148 @@ ++/******************************************************************** ++ * * ++ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * ++ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * ++ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * ++ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * ++ * * ++ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * ++ * by the Xiph.Org Foundation http://www.xiph.org/ * ++ * * ++ ******************************************************************** ++ ++ function: #ifdef jail to whip a few platforms into the UNIX ideal. ++ last mod: $Id: os_types.h 17566 2010-10-26 10:56:31Z xiphmont $ ++ ++ ********************************************************************/ ++#ifndef _OS_TYPES_H ++#define _OS_TYPES_H ++ ++/* make it easy on the folks that want to compile the libs with a ++ different malloc than stdlib */ ++#define _ogg_malloc malloc ++#define _ogg_calloc calloc ++#define _ogg_realloc realloc ++#define _ogg_free free ++ ++#if defined(_WIN32) ++ ++# if defined(__CYGWIN__) ++# include ++ typedef int16_t ogg_int16_t; ++ typedef uint16_t ogg_uint16_t; ++ typedef int32_t ogg_int32_t; ++ typedef uint32_t ogg_uint32_t; ++ typedef int64_t ogg_int64_t; ++ typedef uint64_t ogg_uint64_t; ++# elif defined(__MINGW32__) ++# include ++ typedef short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++ typedef int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long ogg_int64_t; ++ typedef unsigned long long ogg_uint64_t; ++# elif defined(__MWERKS__) ++ typedef long long ogg_int64_t; ++ typedef int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++# else ++ /* MSVC/Borland */ ++ typedef unsigned __int64 ogg_uint64_t; ++ typedef __int64 ogg_int64_t; ++ typedef __int32 ogg_int32_t; ++ typedef unsigned __int32 ogg_uint32_t; ++ typedef __int16 ogg_int16_t; ++ typedef unsigned __int16 ogg_uint16_t; ++# endif ++ ++#elif defined(__MACOS__) ++ ++# include ++ typedef SInt16 ogg_int16_t; ++ typedef UInt16 ogg_uint16_t; ++ typedef SInt32 ogg_int32_t; ++ typedef UInt32 ogg_uint32_t; ++ typedef SInt64 ogg_int64_t; ++ ++#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ ++ ++# include ++ typedef int16_t ogg_int16_t; ++ typedef u_int16_t ogg_uint16_t; ++ typedef int32_t ogg_int32_t; ++ typedef u_int32_t ogg_uint32_t; ++ typedef int64_t ogg_int64_t; ++ ++#elif defined(__HAIKU__) ++ ++ /* Haiku */ ++# include ++ typedef short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++ typedef int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long ogg_int64_t; ++ ++#elif defined(__BEOS__) ++ ++ /* Be */ ++# include ++ typedef int16_t ogg_int16_t; ++ typedef u_int16_t ogg_uint16_t; ++ typedef int32_t ogg_int32_t; ++ typedef u_int32_t ogg_uint32_t; ++ typedef int64_t ogg_int64_t; ++ ++#elif defined (__EMX__) ++ ++ /* OS/2 GCC */ ++ typedef short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++ typedef int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long ogg_int64_t; ++ ++#elif defined (DJGPP) ++ ++ /* DJGPP */ ++ typedef short ogg_int16_t; ++ typedef int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long ogg_int64_t; ++ ++#elif defined(R5900) ++ ++ /* PS2 EE */ ++ typedef long ogg_int64_t; ++ typedef int ogg_int32_t; ++ typedef unsigned ogg_uint32_t; ++ typedef short ogg_int16_t; ++ ++#elif defined(__SYMBIAN32__) ++ ++ /* Symbian GCC */ ++ typedef signed short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++ typedef signed int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long int ogg_int64_t; ++ ++#elif defined(__TMS320C6X__) ++ ++ /* TI C64x compiler */ ++ typedef signed short ogg_int16_t; ++ typedef unsigned short ogg_uint16_t; ++ typedef signed int ogg_int32_t; ++ typedef unsigned int ogg_uint32_t; ++ typedef long long int ogg_int64_t; ++ ++#else ++ ++# include ++ ++#endif ++ ++#endif /* _OS_TYPES_H */ +diff --git a/include/share/utf8.h b/include/share/utf8.h +index 7d6650d..ebb3cbe 100644 +--- a/include/share/utf8.h ++++ b/include/share/utf8.h +@@ -18,6 +18,9 @@ + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ ++#include ++#include ++#include + + int utf8_encode(const char *from, char **to); + int utf8_decode(const char *from, char **to); +diff --git a/src/flac/analyze.c b/src/flac/analyze.c +index 47a5e76..85cc9ad 100644 +--- a/src/flac/analyze.c ++++ b/src/flac/analyze.c +@@ -27,6 +27,7 @@ + #include + #include "FLAC/all.h" + #include "analyze.h" ++#include + + typedef struct { + FLAC__int32 residual; +@@ -218,7 +219,7 @@ FLAC__bool dump_stats(const subframe_stats_t *stats, const char *filename) + const double s1 = stats->stddev, s2 = s1*2, s3 = s1*3, s4 = s1*4, s5 = s1*5, s6 = s1*6; + const double p = stats->buckets[stats->peak_index].count; + +- outfile = fopen(filename, "w"); ++ outfile = fopen_utf8(filename, "w"); + + if(0 == outfile) { + fprintf(stderr, "ERROR opening %s: %s\n", filename, strerror(errno)); +diff --git a/src/flac/decode.c b/src/flac/decode.c +index 1e537c0..bb53bcb 100644 +--- a/src/flac/decode.c ++++ b/src/flac/decode.c +@@ -41,6 +41,7 @@ + #include "share/grabbag.h" + #include "share/replaygain_synthesis.h" + #include "decode.h" ++#include + + typedef struct { + #if FLAC__HAS_OGG +@@ -331,7 +332,7 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__ + d->fout = grabbag__file_get_binary_stdout(); + } + else { +- if(0 == (d->fout = fopen(outfilename, "wb"))) { ++ if(0 == (d->fout = fopen_utf8(outfilename, "wb"))) { + flac__utils_printf(stderr, 1, "%s: ERROR: can't open output file %s: %s\n", d->inbasefilename, outfilename, strerror(errno)); + DecoderSession_destroy(d, /*error_occurred=*/true); + return false; +@@ -890,7 +891,7 @@ FLAC__bool write_sane_extended(FILE *f, unsigned val) + FLAC__bool fixup_iff_headers(DecoderSession *d) + { + const char *fmt_desc = (d->is_wave_out? "WAVE" : "AIFF"); +- FILE *f = fopen(d->outfilename, "r+b"); /* stream is positioned at beginning of file */ ++ FILE *f = fopen_utf8(d->outfilename, "r+b"); /* stream is positioned at beginning of file */ + + if(0 == f) { + flac__utils_printf(stderr, 1, "ERROR, couldn't open file %s while fixing up %s chunk size: %s\n", d->outfilename, fmt_desc, strerror(errno)); +@@ -1376,5 +1377,7 @@ void print_stats(const DecoderSession *decoder_session) + (unsigned)decoder_session->samples_processed + ); + } ++ ++ fflush(stderr); + } + } +diff --git a/src/flac/encode.c b/src/flac/encode.c +index 8d24349..c8267c3 100644 +--- a/src/flac/encode.c ++++ b/src/flac/encode.c +@@ -43,6 +43,7 @@ + #include "share/alloc.h" + #include "share/grabbag.h" + #include "encode.h" ++#include + + #ifdef min + #undef min +@@ -2611,7 +2612,7 @@ FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_ + return false; + } + +- if(0 == (f = fopen(cuesheet_filename, "r"))) { ++ if(0 == (f = fopen_utf8(cuesheet_filename, "r"))) { + flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno)); + return false; + } +@@ -2666,6 +2667,8 @@ void print_stats(const EncoderSession *encoder_session) + else { + flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio); + } ++ ++ fflush(stderr); + } + + void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status) +diff --git a/src/flac/flac.vcproj b/src/flac/flac.vcproj +index 0680364..ca82678 100644 +--- a/src/flac/flac.vcproj ++++ b/src/flac/flac.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__HAS_OGG;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +@@ -208,6 +209,10 @@ + > + + ++ ++ + +@@ -246,6 +251,10 @@ + > + + ++ ++ + +diff --git a/src/flac/foreign_metadata.c b/src/flac/foreign_metadata.c +index 3fc5310..88e7c28 100644 +--- a/src/flac/foreign_metadata.c ++++ b/src/flac/foreign_metadata.c +@@ -34,6 +34,7 @@ + #include "FLAC/metadata.h" + #include "share/alloc.h" + #include "foreign_metadata.h" ++#include + + #ifdef min + #undef min +@@ -488,7 +489,7 @@ void flac__foreign_metadata_delete(foreign_metadata_t *fm) + FLAC__bool flac__foreign_metadata_read_from_aiff(foreign_metadata_t *fm, const char *filename, const char **error) + { + FLAC__bool ok; +- FILE *f = fopen(filename, "rb"); ++ FILE *f = fopen_utf8(filename, "rb"); + if(!f) { + if(error) *error = "can't open AIFF file for reading (000)"; + return false; +@@ -501,7 +502,7 @@ FLAC__bool flac__foreign_metadata_read_from_aiff(foreign_metadata_t *fm, const c + FLAC__bool flac__foreign_metadata_read_from_wave(foreign_metadata_t *fm, const char *filename, const char **error) + { + FLAC__bool ok; +- FILE *f = fopen(filename, "rb"); ++ FILE *f = fopen_utf8(filename, "rb"); + if(!f) { + if(error) *error = "can't open WAVE file for reading (000)"; + return false; +@@ -525,12 +526,12 @@ FLAC__bool flac__foreign_metadata_write_to_flac(foreign_metadata_t *fm, const ch + FLAC__metadata_simple_iterator_delete(it); + return false; + } +- if(0 == (fin = fopen(infilename, "rb"))) { ++ if(0 == (fin = fopen_utf8(infilename, "rb"))) { + if(error) *error = "can't open WAVE/AIFF file for reading (002)"; + FLAC__metadata_simple_iterator_delete(it); + return false; + } +- if(0 == (fout = fopen(outfilename, "r+b"))) { ++ if(0 == (fout = fopen_utf8(outfilename, "r+b"))) { + if(error) *error = "can't open FLAC file for updating (003)"; + FLAC__metadata_simple_iterator_delete(it); + fclose(fin); +@@ -557,7 +558,7 @@ FLAC__bool flac__foreign_metadata_read_from_flac(foreign_metadata_t *fm, const c + FLAC__metadata_simple_iterator_delete(it); + return false; + } +- if(0 == (f = fopen(filename, "rb"))) { ++ if(0 == (f = fopen_utf8(filename, "rb"))) { + if(error) *error = "can't open FLAC file for reading (002)"; + FLAC__metadata_simple_iterator_delete(it); + return false; +@@ -572,11 +573,11 @@ FLAC__bool flac__foreign_metadata_write_to_iff(foreign_metadata_t *fm, const cha + { + FLAC__bool ok; + FILE *fin, *fout; +- if(0 == (fin = fopen(infilename, "rb"))) { ++ if(0 == (fin = fopen_utf8(infilename, "rb"))) { + if(error) *error = "can't open FLAC file for reading (000)"; + return false; + } +- if(0 == (fout = fopen(outfilename, "r+b"))) { ++ if(0 == (fout = fopen_utf8(outfilename, "r+b"))) { + if(error) *error = "can't open WAVE/AIFF file for updating (001)"; + fclose(fin); + return false; +diff --git a/src/flac/iffscan.c b/src/flac/iffscan.c +index d03b65b..46d11ef 100644 +--- a/src/flac/iffscan.c ++++ b/src/flac/iffscan.c +@@ -64,7 +64,7 @@ int main(int argc, char *argv[]) + return 1; + } + fn = argv[1]; +- if(0 == (f = fopen(fn, "rb")) || fread(buf, 1, 4, f) != 4) { ++ if(0 == (f = fopen_utf8(fn, "rb")) || fread(buf, 1, 4, f) != 4) { + fprintf(stderr, "ERROR opening %s for reading\n", fn); + return 1; + } +@@ -85,7 +85,7 @@ int main(int argc, char *argv[]) + return 1; + } + } +- if(0 == (f = fopen(fn, "rb"))) { ++ if(0 == (f = fopen_utf8(fn, "rb"))) { + fprintf(stderr, "ERROR opening %s for reading\n", fn); + return 1; + } +diff --git a/src/flac/iffscan.vcproj b/src/flac/iffscan.vcproj +index 0651666..a2c5a58 100644 +--- a/src/flac/iffscan.vcproj ++++ b/src/flac/iffscan.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__HAS_OGG;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/flac/main.c b/src/flac/main.c +index f3716a8..b662978 100644 +--- a/src/flac/main.c ++++ b/src/flac/main.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #if !defined _MSC_VER && !defined __MINGW32__ + /* unlink is in stdio.h in VC++ */ +@@ -294,7 +295,7 @@ static FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 + static unsigned align_reservoir_samples = 0; /* 0 .. 587 */ + + +-int main(int argc, char *argv[]) ++int flac_main(int argc, char *argv[]) + { + int retval = 0; + +@@ -1642,7 +1643,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_ + } + else { + infilesize = grabbag__file_get_filesize(infilename); +- if(0 == (encode_infile = fopen(infilename, "rb"))) { ++ if(0 == (encode_infile = fopen_utf8(infilename, "rb"))) { + flac__utils_printf(stderr, 1, "ERROR: can't open input file %s: %s\n", infilename, strerror(errno)); + return 1; + } +@@ -2179,3 +2180,17 @@ FLAC__int64 local__strtoll(const char *src, char **endptr) + return neg? -ret : ret; + } + #endif ++ ++int main(int __argc, char **__argv) ++{ ++ int argc; ++ char **argv; ++ int exit_code; ++ ++ init_commandline_arguments_utf8(&argc, &argv); ++ exit_code = flac_main(argc, argv); ++ free_commandline_arguments_utf8(&argc, &argv); ++ ++ return exit_code; ++} ++ +diff --git a/src/flac/unicode_support.c b/src/flac/unicode_support.c +new file mode 100644 +index 0000000..d823d9c +--- /dev/null ++++ b/src/flac/unicode_support.c +@@ -0,0 +1,87 @@ ++#include "unicode_support.h" ++ ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i, nArgs; ++ LPWSTR *szArglist; ++ ++ szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); ++ ++ if(NULL == szArglist) ++ { ++ fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); ++ exit(-1); ++ } ++ ++ *argv = malloc(sizeof(char*) * nArgs); ++ *argc = nArgs; ++ ++ for(i = 0; i < nArgs; i++) ++ { ++ (*argv)[i] = utf16_to_utf8(szArglist[i]); ++ } ++ ++ LocalFree(szArglist); ++} ++ ++void free_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i = 0; ++ ++ if(*argv != NULL) ++ { ++ for(i = 0; i < *argc; i++) ++ { ++ if((*argv)[i] != NULL) ++ { ++ free((*argv)[i]); ++ (*argv)[i] = NULL; ++ } ++ } ++ free(*argv); ++ *argv = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) free(filename_utf16); ++ if(mode_utf16) free(mode_utf16); ++ ++ return ret; ++} +diff --git a/src/flac/unicode_support.h b/src/flac/unicode_support.h +new file mode 100644 +index 0000000..97d639e +--- /dev/null ++++ b/src/flac/unicode_support.h +@@ -0,0 +1,21 @@ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++char *utf16_to_utf8(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int *argc, char ***argv); ++void free_commandline_arguments_utf8(int *argc, char ***argv); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +\ No newline at end of file +diff --git a/src/flac/vorbiscomment.c b/src/flac/vorbiscomment.c +index 6b35a1e..83c93eb 100644 +--- a/src/flac/vorbiscomment.c ++++ b/src/flac/vorbiscomment.c +@@ -29,7 +29,8 @@ + #include + #include + #include +- ++#include ++#include + + /* + * This struct and the following 4 static functions are copied from +@@ -125,7 +126,7 @@ static FLAC__bool set_vc_field(FLAC__StreamMetadata *block, const Argument_VcFie + if(0 == (data = malloc(size+1))) + die("out of memory allocating tag value"); + data[size] = '\0'; +- if(0 == (f = fopen(field->field_value, "rb")) || fread(data, 1, size, f) != (size_t)size) { ++ if(0 == (f = fopen_utf8(field->field_value, "rb")) || fread(data, 1, size, f) != (size_t)size) { + free(data); + if(f) + fclose(f); +@@ -169,7 +170,7 @@ static FLAC__bool set_vc_field(FLAC__StreamMetadata *block, const Argument_VcFie + } + else { + FLAC__bool needs_free = false; +- if(raw) { ++ if(true) { + entry.entry = (FLAC__byte *)field->field; + } + else if(utf8_encode(field->field, &converted) >= 0) { +diff --git a/src/libFLAC++/libFLAC++_dynamic.vcproj b/src/libFLAC++/libFLAC++_dynamic.vcproj +index 01aa2ea..6e5f413 100644 +--- a/src/libFLAC++/libFLAC++_dynamic.vcproj ++++ b/src/libFLAC++/libFLAC++_dynamic.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -122,6 +122,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FLACPP_API_EXPORTS" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -145,6 +147,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/libFLAC++/libFLAC++_static.vcproj b/src/libFLAC++/libFLAC++_static.vcproj +index 9d75223..06377a4 100644 +--- a/src/libFLAC++/libFLAC++_static.vcproj ++++ b/src/libFLAC++/libFLAC++_static.vcproj +@@ -1,11 +1,12 @@ + + + + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FLAC_API_EXPORTS;FLAC__HAS_OGG;FLAC__CPU_IA32;FLAC__HAS_NASM;FLAC__USE_3DNOW;VERSION=\"1.2.0\"" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +@@ -436,6 +437,7 @@ + + + + + + + + + + + + file = fopen(iterator->filename, "r+b"))) { ++ if(read_only || 0 == (iterator->file = fopen_utf8(iterator->filename, "r+b"))) { + iterator->is_writable = false; + if(read_only || errno == EACCES) { +- if(0 == (iterator->file = fopen(iterator->filename, "rb"))) { ++ if(0 == (iterator->file = fopen_utf8(iterator->filename, "rb"))) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; + return false; + } +@@ -1380,7 +1380,7 @@ static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain) + + FLAC__ASSERT(0 != chain->filename); + +- if(0 == (file = fopen(chain->filename, "r+b"))) { ++ if(0 == (file = fopen_utf8(chain->filename, "r+b"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } +@@ -1405,7 +1405,7 @@ static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *t + FLAC__ASSERT(0 != chain->head); + + /* copy the file prefix (data up to first metadata block */ +- if(0 == (f = fopen(chain->filename, "rb"))) { ++ if(0 == (f = fopen_utf8(chain->filename, "rb"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } +@@ -1542,7 +1542,7 @@ static FLAC__bool chain_read_(FLAC__Metadata_Chain *chain, const char *filename, + + chain->is_ogg = is_ogg; + +- if(0 == (file = fopen(filename, "rb"))) { ++ if(0 == (file = fopen_utf8(filename, "rb"))) { + chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; + return false; + } +@@ -3240,7 +3240,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix + strcat(*tempfilename, tempfile_suffix); + } + +- if(0 == (*tempfile = fopen(*tempfilename, "w+b"))) { ++ if(0 == (*tempfile = fopen_utf8(*tempfilename, "w+b"))) { + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; + return false; + } +diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c +index 4d86fda..1e02948 100644 +--- a/src/libFLAC/stream_decoder.c ++++ b/src/libFLAC/stream_decoder.c +@@ -628,7 +628,7 @@ static FLAC__StreamDecoderInitStatus init_file_internal_( + if(0 == write_callback || 0 == error_callback) + return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + +- file = filename? fopen(filename, "rb") : stdin; ++ file = filename? fopen_utf8(filename, "rb") : stdin; + + if(0 == file) + return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; +diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c +index 6d9859c..2c1f1ad 100644 +--- a/src/libFLAC/stream_encoder.c ++++ b/src/libFLAC/stream_encoder.c +@@ -1283,7 +1283,7 @@ static FLAC__StreamEncoderInitStatus init_file_internal_( + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; + +- file = filename? fopen(filename, "w+b") : stdout; ++ file = filename? fopen_utf8(filename, "w+b") : stdout; + + if(file == 0) { + encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; +diff --git a/src/metaflac/metaflac.vcproj b/src/metaflac/metaflac.vcproj +index 6da60fe..e2acb7d 100644 +--- a/src/metaflac/metaflac.vcproj ++++ b/src/metaflac/metaflac.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__HAS_OGG;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +@@ -242,6 +243,10 @@ + > + + ++ ++ + +diff --git a/src/monkeys_audio_utilities/flac_mac/flac_mac.vcproj b/src/monkeys_audio_utilities/flac_mac/flac_mac.vcproj +index cc65f83..78fcf25 100644 +--- a/src/monkeys_audio_utilities/flac_mac/flac_mac.vcproj ++++ b/src/monkeys_audio_utilities/flac_mac/flac_mac.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -122,6 +122,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -147,6 +149,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/monkeys_audio_utilities/flac_ren/flac_ren.vcproj b/src/monkeys_audio_utilities/flac_ren/flac_ren.vcproj +index e6f274e..711fb9a 100644 +--- a/src/monkeys_audio_utilities/flac_ren/flac_ren.vcproj ++++ b/src/monkeys_audio_utilities/flac_ren/flac_ren.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -122,6 +122,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -147,6 +149,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/plugin_common/plugin_common_static.vcproj b/src/plugin_common/plugin_common_static.vcproj +index ee64d25..13bf3af 100644 +--- a/src/plugin_common/plugin_common_static.vcproj ++++ b/src/plugin_common/plugin_common_static.vcproj +@@ -1,11 +1,12 @@ + + + + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IN_FLAC_EXPORTS;FLAC__NO_DLL;VERSION=\"1.2.0\";TAGZ_UNICODE" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -152,6 +154,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/share/getopt/getopt_static.vcproj b/src/share/getopt/getopt_static.vcproj +index 028c82d..cd04394 100644 +--- a/src/share/getopt/getopt_static.vcproj ++++ b/src/share/getopt/getopt_static.vcproj +@@ -1,11 +1,12 @@ + + + + + + + + + + + + + for this win32 +diff --git a/src/share/utf8/utf8_static.vcproj b/src/share/utf8/utf8_static.vcproj +index bcc8ca3..ee90ccc 100644 +--- a/src/share/utf8/utf8_static.vcproj ++++ b/src/share/utf8/utf8_static.vcproj +@@ -1,11 +1,12 @@ + + + + + + + + + +- + +@@ -124,6 +124,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -149,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/test_grabbag/picture/test_picture.vcproj b/src/test_grabbag/picture/test_picture.vcproj +index bd300ec..fc2800f 100644 +--- a/src/test_grabbag/picture/test_picture.vcproj ++++ b/src/test_grabbag/picture/test_picture.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -124,6 +124,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -149,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/test_libFLAC++/test_libFLAC++.vcproj b/src/test_libFLAC++/test_libFLAC++.vcproj +index ed392ab..18451ac 100644 +--- a/src/test_libFLAC++/test_libFLAC++.vcproj ++++ b/src/test_libFLAC++/test_libFLAC++.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -124,6 +124,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -149,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/test_libFLAC/test_libFLAC.vcproj b/src/test_libFLAC/test_libFLAC.vcproj +index 47988e7..d62611b 100644 +--- a/src/test_libFLAC/test_libFLAC.vcproj ++++ b/src/test_libFLAC/test_libFLAC.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/test_libs_common/test_libs_common_static.vcproj b/src/test_libs_common/test_libs_common_static.vcproj +index b1c9074..9d960ea 100644 +--- a/src/test_libs_common/test_libs_common_static.vcproj ++++ b/src/test_libs_common/test_libs_common_static.vcproj +@@ -1,11 +1,12 @@ + + + + + + + + + +- + +@@ -125,6 +125,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__HAS_OGG;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -151,6 +153,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + +diff --git a/src/test_streams/test_streams.vcproj b/src/test_streams/test_streams.vcproj +index fec5fac..0988966 100644 +--- a/src/test_streams/test_streams.vcproj ++++ b/src/test_streams/test_streams.vcproj +@@ -1,11 +1,12 @@ + + + + + + +- + +@@ -124,6 +124,8 @@ + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;FLAC__NO_DLL" + RuntimeLibrary="0" + BufferSecurityCheck="false" ++ EnableFunctionLevelLinking="true" ++ EnableEnhancedInstructionSet="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" +@@ -149,6 +151,8 @@ + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" ++ RandomizedBaseAddress="1" ++ DataExecutionPrevention="0" + TargetMachine="1" + /> + + +- + diff --git a/etc/Patches/MAC-v4.11-Flush.V1.diff b/etc/Patches/MAC-v4.11-Flush.V1.diff new file mode 100644 index 00000000..f8fe2059 --- /dev/null +++ b/etc/Patches/MAC-v4.11-Flush.V1.diff @@ -0,0 +1,19 @@ + Source/Console/Console.cpp | 1 + + Source/MACLib/Assembly/Assembly.obj | Bin 836 -> 836 bytes + 2 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/Source/Console/Console.cpp b/Source/Console/Console.cpp +index 7d7c8c4..3a3179b 100644 +--- a/Source/Console/Console.cpp ++++ b/Source/Console/Console.cpp +@@ -63,6 +63,7 @@ void CALLBACK ProgressCallback(int nPercentageDone) + // output the progress + _ftprintf(stderr, _T("Progress: %.1f%% (%.1f seconds remaining, %.1f seconds total) \r"), + dProgress * 100, dRemaining, dElapsed); ++ fflush(stderr); + } + + /*************************************************************************************** +diff --git a/Source/MACLib/Assembly/Assembly.obj b/Source/MACLib/Assembly/Assembly.obj +index b38feba..2289e97 100644 +Binary files a/Source/MACLib/Assembly/Assembly.obj and b/Source/MACLib/Assembly/Assembly.obj differ diff --git a/etc/Patches/Musepack-r475-MSVC10-UTF8+Progress.V1.diff b/etc/Patches/Musepack-r475-MSVC10-UTF8+Progress.V1.diff new file mode 100644 index 00000000..c353c30a --- /dev/null +++ b/etc/Patches/Musepack-r475-MSVC10-UTF8+Progress.V1.diff @@ -0,0 +1,452 @@ + common/unicode_support.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ + common/unicode_support.h | 21 +++++++++++ + libmpcdec/mpc_reader.c | 3 +- + mpcdec/mpcdec.c | 49 ++++++++++++++++++++++++-- + win32/libcommon.vcproj | 11 +++++- + win32/libmpcdec.vcproj | 3 +- + win32/mpcenc.vcproj | 3 +- + win32/musepack.sln | 53 ++++++++------------------- + 8 files changed, 185 insertions(+), 45 deletions(-) + +diff --git a/common/unicode_support.c b/common/unicode_support.c +new file mode 100644 +index 0000000..d823d9c +--- /dev/null ++++ b/common/unicode_support.c +@@ -0,0 +1,87 @@ ++#include "unicode_support.h" ++ ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize, Result; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i, nArgs; ++ LPWSTR *szArglist; ++ ++ szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); ++ ++ if(NULL == szArglist) ++ { ++ fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); ++ exit(-1); ++ } ++ ++ *argv = malloc(sizeof(char*) * nArgs); ++ *argc = nArgs; ++ ++ for(i = 0; i < nArgs; i++) ++ { ++ (*argv)[i] = utf16_to_utf8(szArglist[i]); ++ } ++ ++ LocalFree(szArglist); ++} ++ ++void free_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i = 0; ++ ++ if(*argv != NULL) ++ { ++ for(i = 0; i < *argc; i++) ++ { ++ if((*argv)[i] != NULL) ++ { ++ free((*argv)[i]); ++ (*argv)[i] = NULL; ++ } ++ } ++ free(*argv); ++ *argv = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) free(filename_utf16); ++ if(mode_utf16) free(mode_utf16); ++ ++ return ret; ++} +diff --git a/common/unicode_support.h b/common/unicode_support.h +new file mode 100644 +index 0000000..97d639e +--- /dev/null ++++ b/common/unicode_support.h +@@ -0,0 +1,21 @@ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++char *utf16_to_utf8(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int *argc, char ***argv); ++void free_commandline_arguments_utf8(int *argc, char ***argv); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +\ No newline at end of file +diff --git a/libmpcdec/mpc_reader.c b/libmpcdec/mpc_reader.c +index 06aa49e..f59ffd4 100644 +--- a/libmpcdec/mpc_reader.c ++++ b/libmpcdec/mpc_reader.c +@@ -36,6 +36,7 @@ + #include + #include "internal.h" + #include ++#include "../common/unicode_support.h" + + #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... + typedef struct mpc_reader_stdio_t { +@@ -127,7 +128,7 @@ clean: + mpc_status + mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename) + { +- FILE * stream = fopen(filename, "rb"); ++ FILE * stream = fopen_utf8(filename, "rb"); + if (stream == NULL) return MPC_STATUS_FAIL; + return mpc_reader_init_stdio_stream(p_reader,stream); + } +diff --git a/mpcdec/mpcdec.c b/mpcdec/mpcdec.c +index b60483f..8fdb34b 100644 +--- a/mpcdec/mpcdec.c ++++ b/mpcdec/mpcdec.c +@@ -37,8 +37,10 @@ + #include + #include "../libmpcdec/decoder.h" + #include "../libmpcdec/internal.h" ++#include "../common/unicode_support.h" + #include + #include ++#include + + #ifdef _MSC_VER + #include +@@ -114,7 +116,7 @@ usage(const char *exename) + } + + int +-main(int argc, char **argv) ++mpcdec_main(int argc, char **argv) + { + mpc_reader reader; + mpc_demux* demux; +@@ -122,12 +124,13 @@ main(int argc, char **argv) + mpc_status err; + mpc_bool_t info = MPC_FALSE, is_wav_output = MPC_FALSE, check = MPC_FALSE; + MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; +- clock_t begin, end, sum; int total_samples; t_wav_output_file wav_output; ++ clock_t begin, end, sum; int total_samples, max_samples; t_wav_output_file wav_output; ++ mpc_bool_t verbose_output = MPC_FALSE; + int c; + + fprintf(stderr, About); + +- while ((c = getopt(argc , argv, "ihc")) != -1) { ++ while ((c = getopt(argc , argv, "ihcv")) != -1) { + switch (c) { + case 'i': + info = MPC_TRUE; +@@ -135,6 +138,9 @@ main(int argc, char **argv) + case 'c': + check = MPC_TRUE; + break; ++ case 'v': ++ verbose_output = MPC_TRUE; ++ break; + case 'h': + usage(argv[0]); + return 0; +@@ -177,13 +183,15 @@ main(int argc, char **argv) + SET_BINARY_MODE(stdout); + wavo_fc.m_user_data = stdout; + } else +- wavo_fc.m_user_data = fopen(argv[optind + 1], "wb"); ++ wavo_fc.m_user_data = fopen_utf8(argv[optind + 1], "wb"); + if(!wavo_fc.m_user_data) return !MPC_STATUS_OK; + err = waveformat_output_open(&wav_output, wavo_fc, si.channels, 16, 0, si.sample_freq, (t_wav_uint32) si.samples * si.channels); + if(!err) return !MPC_STATUS_OK; + } + + sum = total_samples = 0; ++ max_samples = (int) mpc_streaminfo_get_length_samples(&si); ++ + while(MPC_TRUE) + { + mpc_frame_info frame; +@@ -199,6 +207,12 @@ main(int argc, char **argv) + total_samples += frame.samples; + sum += end - begin; + ++ if(verbose_output) ++ { ++ fprintf(stderr, "Decoding progress: %3.1f%%\r", (((float)total_samples) / ((float)max_samples)) * 100.0f); ++ fflush(stderr); ++ } ++ + if(is_wav_output) { + #ifdef MPC_FIXED_POINT + mpc_int16_t tmp_buff[MPC_DECODER_BUFFER_LENGTH]; +@@ -217,6 +231,19 @@ main(int argc, char **argv) + } + } + ++ if(verbose_output) ++ { ++ if(err == MPC_STATUS_OK) ++ { ++ fprintf(stderr, "Decoding progress: %3.1f%%\n", 100.0f); ++ } ++ else ++ { ++ fprintf(stderr, "\n"); ++ } ++ fflush(stderr); ++ } ++ + if (err != MPC_STATUS_OK) + fprintf(stderr, "An error occured while decoding\n"); + else if (check) +@@ -247,3 +274,17 @@ main(int argc, char **argv) + #endif + return err; + } ++ ++int ++main(int __argc, char **__argv) ++{ ++ int argc; ++ char **argv; ++ int exit_code; ++ ++ init_commandline_arguments_utf8(&argc, &argv); ++ exit_code = mpcdec_main(argc, argv); ++ free_commandline_arguments_utf8(&argc, &argv); ++ ++ return exit_code; ++} +diff --git a/win32/libcommon.vcproj b/win32/libcommon.vcproj +index 0acf049..567671a 100644 +--- a/win32/libcommon.vcproj ++++ b/win32/libcommon.vcproj +@@ -1,7 +1,7 @@ +  + + ++ ++ + + + ++ ++ + + + +diff --git a/win32/libmpcdec.vcproj b/win32/libmpcdec.vcproj +index 16db2c3..3abf055 100644 +--- a/win32/libmpcdec.vcproj ++++ b/win32/libmpcdec.vcproj +@@ -1,7 +1,7 @@ + + + + #include +@@ -161,7 +162,7 @@ static int startread(sox_format_t * ft) + chan1_pos = lsx_tell(ft); + + for (i = 1; i < channels; i++) { +- if ((p->ch[i] = fopen(ft->filename, "rb")) == NULL) ++ if ((p->ch[i] = fopen_utf8(ft->filename, "rb")) == NULL) + { + lsx_fail_errno(ft,errno,"Can't open channel file '%s'", + ft->filename); +diff --git a/src/adpcm.c b/src/adpcm.c +index 2e13867..15c27c2 100644 +--- a/src/adpcm.c ++++ b/src/adpcm.c +@@ -33,6 +33,7 @@ + + #include "sox_i.h" + #include "adpcm.h" ++#include "unicode_support.h" + + #include + #include +diff --git a/src/effects_i.c b/src/effects_i.c +index 7d72166..65d6a0b 100644 +--- a/src/effects_i.c ++++ b/src/effects_i.c +@@ -20,6 +20,7 @@ + + #define LSX_EFF_ALIAS + #include "sox_i.h" ++#include "unicode_support.h" + #include + #include + +@@ -355,7 +356,7 @@ FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename) + effp->global_info->global_info->stdin_in_use_by = effp->handler.name; + file = stdin; + } +- else if (!(file = fopen(filename, "r"))) { ++ else if (!(file = fopen_utf8(filename, "r"))) { + lsx_fail("couldn't open file %s: %s", filename, strerror(errno)); + return NULL; + } +diff --git a/src/formats.c b/src/formats.c +index cac686c..1baa213 100644 +--- a/src/formats.c ++++ b/src/formats.c +@@ -19,6 +19,7 @@ + */ + + #include "sox_i.h" ++#include "unicode_support.h" + + #include + #include +@@ -396,7 +397,7 @@ static FILE * xfopen(char const * identifier, char const * mode, lsx_io_type * i + #endif + return f; + } +- return fopen(identifier, mode); ++ return fopen_utf8(identifier, mode); + } + + /* Hack to rewind pipes (a small amount). +@@ -847,8 +848,8 @@ static sox_format_t * open_write( + ft->fp = stdout; + } + else { +- struct stat st; +- if (!stat(path, &st) && (st.st_mode & S_IFMT) == S_IFREG && ++ struct _stat st; ++ if (!stat_utf8(path, &st) && (st.st_mode & S_IFMT) == S_IFREG && + (overwrite_permitted && !overwrite_permitted(path))) { + lsx_fail("permission to overwrite `%s' denied", path); + goto error; +@@ -858,7 +859,7 @@ static sox_format_t * open_write( + buffer? fmemopen(buffer, buffer_size, "w+b") : + buffer_ptr? open_memstream(buffer_ptr, buffer_size_ptr) : + #endif +- fopen(path, "w+b"); ++ fopen_utf8(path, "w+b"); + if (ft->fp == NULL) { + lsx_fail("can't open output file `%s': %s", path, strerror(errno)); + goto error; +diff --git a/src/libsox.c b/src/libsox.c +index 75354e4..a766aa9 100644 +--- a/src/libsox.c ++++ b/src/libsox.c +@@ -19,6 +19,8 @@ + */ + + #include "sox_i.h" ++#include "unicode_support.h" ++ + #include + + const char *sox_version(void) +diff --git a/src/libsox_i.c b/src/libsox_i.c +index 8a7074a..b498cc0 100644 +--- a/src/libsox_i.c ++++ b/src/libsox_i.c +@@ -20,6 +20,7 @@ + + + #include "sox_i.h" ++#include "unicode_support.h" + + #ifdef HAVE_IO_H + #include +@@ -48,8 +49,8 @@ + #ifdef WIN32 + static int check_dir(char * buf, size_t buflen, char const * name) + { +- struct stat st; +- if (!name || stat(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR) ++ struct _stat st; ++ if (!name || stat_utf8(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR) + { + return 0; + } +@@ -102,7 +103,7 @@ FILE * lsx_tmpfile(void) + fildes = mkstemp(name); + #ifdef HAVE_UNISTD_H + lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (unlinked)", name); +- unlink(name); ++ unlink_utf8(name); + #else + lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (O_TEMPORARY)", name); + #endif +diff --git a/src/noiseprof.c b/src/noiseprof.c +index 603402f..d46c280 100644 +--- a/src/noiseprof.c ++++ b/src/noiseprof.c +@@ -19,6 +19,7 @@ + */ + + #include "noisered.h" ++#include "unicode_support.h" + + #include + #include +@@ -75,7 +76,7 @@ static int sox_noiseprof_start(sox_effect_t * effp) + effp->global_info->global_info->stdout_in_use_by = effp->handler.name; + data->output_file = stdout; + } +- else if ((data->output_file = fopen(data->output_filename, "w")) == NULL) { ++ else if ((data->output_file = fopen_utf8(data->output_filename, "w")) == NULL) { + lsx_fail("Couldn't open profile file %s: %s", data->output_filename, strerror(errno)); + return SOX_EOF; + } +diff --git a/src/sox.c b/src/sox.c +index 665149b..da43424 100644 +--- a/src/sox.c ++++ b/src/sox.c +@@ -24,6 +24,7 @@ + #include "soxconfig.h" + #include "sox.h" + #include "util.h" ++#include "unicode_support.h" + + #include + #include +@@ -236,12 +237,12 @@ static void cleanup(void) + if (file_count) { + if (ofile->ft) { + if (!success && ofile->ft->fp) { /* If we failed part way through */ +- struct stat st; /* writing a normal file, remove it. */ +- if (!stat(ofile->ft->filename, &st) && ++ struct _stat st; /* writing a normal file, remove it. */ ++ if (!stat_utf8(ofile->ft->filename, &st) && + (st.st_mode & S_IFMT) == S_IFREG) +- unlink(ofile->ft->filename); ++ unlink_utf8(ofile->ft->filename); + } +- sox_close(ofile->ft); /* Assume we can unlink a file before closing it. */ ++ sox_close(ofile->ft); /* Assume we can unlink_utf8 a file before closing it. */ + } + free(ofile->filename); + free(ofile); +@@ -293,8 +294,8 @@ static char const * str_time(double seconds) + + static char const * size_and_bitrate(sox_format_t * ft, char const * * text) + { +- struct stat st; /* ft->fp may validly be NULL, so stat not fstat */ +- if (stat(ft->filename, &st) || (st.st_mode & S_IFMT) != S_IFREG) ++ struct _stat st; /* ft->fp may validly be NULL, so stat not fstat */ ++ if (stat_utf8(ft->filename, &st) || (st.st_mode & S_IFMT) != S_IFREG) + return NULL; + if (ft->signal.length && ft->signal.channels && ft->signal.rate && text) { + double secs = ft->signal.length / ft->signal.channels / ft->signal.rate; +@@ -906,7 +907,7 @@ static char * * strtoargv(char * s, int * argc) + + static void read_user_effects(char const *filename) + { +- FILE *file = fopen(filename, "rt"); ++ FILE *file = fopen_utf8(filename, "rt"); + const size_t buffer_size_step = 1024; + size_t buffer_size = buffer_size_step; + char *s = lsx_malloc(buffer_size); /* buffer for one input line */ +@@ -1269,6 +1270,7 @@ static void display_status(sox_bool all_done) + lsx_sigfigs3((double)output_samples), + vu(0), vu(1), headroom(), lsx_sigfigs3((double)total_clips())); + } ++ fflush(stderr); + if (all_done) + fputc('\n', stderr); + } +@@ -2123,7 +2125,7 @@ static void read_comment_file(sox_comments_t * comments, char const * const file + int c; + size_t text_length = 100; + char * text = lsx_malloc(text_length + 1); +- FILE * file = fopen(filename, "rt"); ++ FILE * file = fopen_utf8(filename, "rt"); + + if (file == NULL) { + lsx_fail("Cannot open comment file `%s'", filename); +@@ -2830,7 +2832,7 @@ static sox_bool cmp_comment_text(char const * c1, char const * c2) + return c1 && c2 && !strcasecmp(c1, c2); + } + +-int main(int argc, char **argv) ++static int sox_main(int argc, char **argv) + { + size_t i; + char mybase[6]; +@@ -3032,3 +3034,16 @@ int main(int argc, char **argv) + + return 0; + } ++ ++int main( int argc, char **argv ) ++{ ++ int sox_argc; ++ char **sox_argv; ++ int exit_code; ++ ++ init_commandline_arguments_utf8(&sox_argc, &sox_argv); ++ exit_code = sox_main(sox_argc, sox_argv); ++ free_commandline_arguments_utf8(&sox_argc, &sox_argv); ++ ++ return exit_code; ++} +diff --git a/src/unicode_support.c b/src/unicode_support.c +new file mode 100644 +index 0000000..e0cbbc9 +--- /dev/null ++++ b/src/unicode_support.c +@@ -0,0 +1,148 @@ ++#include "unicode_support.h" ++ ++#include ++#include ++ ++char *utf16_to_utf8(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ if(Buffer) ++ { ++ Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++char *utf16_to_ansi(const wchar_t *input) ++{ ++ char *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL); ++ Buffer = (char*) malloc(sizeof(char) * BuffSize); ++ if(Buffer) ++ { ++ Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++wchar_t *utf8_to_utf16(const char *input) ++{ ++ wchar_t *Buffer; ++ int BuffSize = 0, Result = 0; ++ ++ BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); ++ Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); ++ if(Buffer) ++ { ++ Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); ++ } ++ ++ return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; ++} ++ ++void init_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i, nArgs; ++ LPWSTR *szArglist; ++ ++ szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); ++ ++ if(NULL == szArglist) ++ { ++ fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n"); ++ exit(-1); ++ } ++ ++ *argv = (char**) malloc(sizeof(char*) * nArgs); ++ *argc = nArgs; ++ ++ if(NULL == *argv) ++ { ++ fprintf(stderr, "\nFATAL: Malloc failed\n\n"); ++ exit(-1); ++ } ++ ++ for(i = 0; i < nArgs; i++) ++ { ++ (*argv)[i] = utf16_to_utf8(szArglist[i]); ++ if(NULL == (*argv)[i]) ++ { ++ fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n"); ++ exit(-1); ++ } ++ } ++ ++ LocalFree(szArglist); ++} ++ ++void free_commandline_arguments_utf8(int *argc, char ***argv) ++{ ++ int i = 0; ++ ++ if(*argv != NULL) ++ { ++ for(i = 0; i < *argc; i++) ++ { ++ if((*argv)[i] != NULL) ++ { ++ free((*argv)[i]); ++ (*argv)[i] = NULL; ++ } ++ } ++ free(*argv); ++ *argv = NULL; ++ } ++} ++ ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) ++{ ++ FILE *ret = NULL; ++ wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); ++ wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); ++ ++ if(filename_utf16 && mode_utf16) ++ { ++ ret = _wfopen(filename_utf16, mode_utf16); ++ } ++ ++ if(filename_utf16) free(filename_utf16); ++ if(mode_utf16) free(mode_utf16); ++ ++ return ret; ++} ++ ++int stat_utf8(const char *path_utf8, struct _stat *buf) ++{ ++ int ret = -1; ++ ++ wchar_t *path_utf16 = utf8_to_utf16(path_utf8); ++ if(path_utf16) ++ { ++ ret = _wstat(path_utf16, buf); ++ free(path_utf16); ++ } ++ ++ return ret; ++} ++ ++int unlink_utf8(const char *path_utf8) ++{ ++ int ret = -1; ++ ++ wchar_t *path_utf16 = utf8_to_utf16(path_utf8); ++ if(path_utf16) ++ { ++ ret = _wunlink(path_utf16); ++ free(path_utf16); ++ } ++ ++ return ret; ++} +diff --git a/src/unicode_support.h b/src/unicode_support.h +new file mode 100644 +index 0000000..6775e00 +--- /dev/null ++++ b/src/unicode_support.h +@@ -0,0 +1,16 @@ ++#ifndef UNICODE_SUPPORT_H_INCLUDED ++#define UNICODE_SUPPORT_H_INCLUDED ++ ++#include ++#include ++ ++char *utf16_to_utf8(const wchar_t *input); ++char *utf16_to_ansi(const wchar_t *input); ++wchar_t *utf8_to_utf16(const char *input); ++void init_commandline_arguments_utf8(int *argc, char ***argv); ++void free_commandline_arguments_utf8(int *argc, char ***argv); ++FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8); ++int stat_utf8(const char *path_utf8, struct _stat *buf); ++int unlink_utf8(const char *path_utf8); ++ ++#endif +\ No newline at end of file +diff --git a/src/util.h b/src/util.h +index f10b676..4a835f0 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -91,6 +91,10 @@ + + #ifdef _MSC_VER + ++#define inline __inline ++#define snprintf _snprintf ++ ++/* + #define __STDC__ 1 + #define O_BINARY _O_BINARY + #define O_CREAT _O_CREAT +@@ -141,6 +145,7 @@ + #define off_t __int64 + #define HAVE_FSEEKO 1 + #endif ++*/ + + #elif defined(__MINGW32__) +