/*
 *	app.cpp
 *
 *	SofdecProbe.exe - Sofdec情報表示ツール
 *	Copyright (C) 2016-2017 Naoyuki Sawa
 *
 *	* Sun Apr 03 21:51:26 JST 2016 Naoyuki Sawa
 *	- 1st リリース。
 *	* Mon Apr 04 21:27:10 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	* Wed May 04 21:28:21 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cに、AdxHelper関数群を追加した事に伴い、当ツールもリビルドしました。
 *	  当ツールの動作には変更有りません。
 *	* Thu Jul 28 21:15:13 JST 2016 Naoyuki Sawa
 *	- 2016/06/14に、/clip/clipstd.hに'#pragma comment(lib, "liblua.lib")'を追加した事に伴い、当プロジェクトにもlibluaのライブラリパスの設定を追加しました。
 *	  現在の所、当プロジェクトはlibluaを使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
 *	  尚、libluaのインクルードパスは以前から設定していたので、今回、追加したのはlibluaのライブラリパスのみです。
 *	- 2016/07/01に、/clip/libclip/extclip.hに'#include <sqlite3.h>'と'#pragma comment(lib, "sqlite3.lib")'を追加した事に伴い、当プロジェクトにもsqlite3のインクルードパスとライブラリパスの設定を追加しました。
 *	  現在の所、当プロジェクトはsqlite3を使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
 *	- ライブラリをバージョンアップした事に伴い、/clip/tool/SofdecHelper/ をリビルドした事に伴い、当ツールもリビルドしました。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 *	* Fri Jul 29 22:19:58 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 *	* Sat Jul 30 21:25:46 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	- 出力するムービー情報に、「アルファストリームの数(0,又は,1)」を追加しました。
 *	* Mon Aug 01 21:12:56 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、SofdecHelper_Init()の呼び出し処理を変更しました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	* Sat Aug 06 21:14:59 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 *	* Mon Aug 08 21:53:54 JST 2016 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 *	* Tue Dec 20 21:28:56 JST 2016 Naoyuki Sawa
 *	- ライブラリをバージョンアップした事に伴い、/clip/tool/SofdecHelper/ をリビルドした事に伴い、当ツールもリビルドしました。
 *	  当ツールの動作には変更有りません。
 *	- GC_init(),及び,GC_allow_register_threads()の呼び出しを削除しました。
 *	  詳細は、/clip/libclip/extclip.cの'Mon May 30 21:45:50 JST 2016'のコメントを参照して下さい。
 *	* Thu Dec 22 09:49:41 JST 2016 Naoyuki Sawa
 *	- ライブラリをバージョンアップした事に伴い、/clip/tool/SofdecHelper/ をリビルドした事に伴い、当ツールもリビルドしました。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 *	* Mon Apr 03 23:36:16 JST 2017 Naoyuki Sawa
 *	- 暗号化されたデータの情報取得に対応しました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	* Sun Apr 09 22:05:18 JST 2017 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	* Tue Apr 18 21:46:46 JST 2017 Naoyuki Sawa
 *	- /clip/tool/SofdecHelper/ をリビルドした事に伴い、当ツールもリビルドしました。
 *	  詳細は、/clip/tool/SofdecHelper/SofdecHelper.cの同日のコメントを参照して下さい。
 *	  当ツールのソースコード,及び,当ツールの動作には変更有りません。
 */
#include "app.h"
#define VERSION		"20170418"	//最終更新日
/****************************************************************************
 *	main
 ****************************************************************************/
int main(int argc, char* argv[]) {
	int exitCode = EXIT_SUCCESS;
#ifdef  _DEBUG
	remove("syslog.out");	//毎回ログを削除する事にした。
	openlog(NULL, LOG_PERROR, LOG_USER);
#endif//_DEBUG
#if     (defined(GC_H) && !defined(USE_BISON_FLEX))
//	putenv("GC_LOG_FILE=CON");//ログ出力先を指定する。
//	GC_set_find_leak(1);//メモリリーク検出を開始する。
#endif//(defined(GC_H) && !defined(USE_BISON_FLEX))
//{{2016/12/20削除:GC_init(),及び,GC_allow_register_threads()の呼び出しを削除しました。
//#if     (defined(GC_H) && defined(PTHREAD_H))
//	GC_init();//この中でGCスレッドが起動する。メインスレッドをpthread_exit()等で終了するとGCスレッドが残ってプロセスが終了しないので注意せよ。
//	GC_allow_register_threads();
//#endif//(defined(GC_H) && defined(PTHREAD_H))
//}}2016/12/20削除:GC_init(),及び,GC_allow_register_threads()の呼び出しを削除しました。
#ifdef  __CLIP_SEH_H__
	SEH_init();
#endif//__CLIP_SEH_H__
#ifdef  USE_GDIPLUS
	Gdiplus_Init();
#endif//USE_GDIPLUS
	app_init(argc, argv);
	exitCode = app_main(argc, argv);
	app_exit();
#ifdef  USE_GDIPLUS
	Gdiplus_Exit();
#endif//USE_GDIPLUS
#if     (defined(GC_H) && !defined(USE_BISON_FLEX))
//	CHECK_LEAKS();//メモリリークを検出する。
#endif//(defined(GC_H) && !defined(USE_BISON_FLEX))
	return exitCode;
}
/****************************************************************************
 *	usage
 ****************************************************************************/
__declspec(noreturn) static void usage() {
	fprintf(stderr, "SofdecProbe.exe - Sofdec情報表示ツール (%s)\n", VERSION);
	fprintf(stderr, "Copyright (C) 2016-2017 Naoyuki Sawa\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "USAGE:\n");
	fprintf(stderr, "  SofdecProbe.exe [option ...] filename[.usm] [filename[.usm] ...]\n");
	fprintf(stderr, "  ・filenameは、ワイルドカードによる複数指定も可能です。\n");
	fprintf(stderr, "  ・filenameの拡張子が省略されていたら、'.usm'とします。\n");
	fprintf(stderr, "  ・filenameは相対パスで指定して下さい。絶対パスで指定するとエラーが発生します。\n");		//絶対パスがエラーになる理由は、criFsBinder_BindDirectory()でフォルダにバインドすると、バインダが絶対パスを検索しないようだからです。相対パス形式で親フォルダへ辿って行く事は可能です。
	fprintf(stderr, "\n");
	fprintf(stderr, "OPTIONS:\n");
	fprintf(stderr, "  -c               CSV形式で出力します。\n");
	fprintf(stderr, "                   このオプションを指定しなければ、読み易い形式で出力します。\n");
//{{2017/04/03追加:暗号化されたデータの     情報取得に対応しました。
	fprintf(stderr, "  -k復号キー       暗号化されたムービーデータの復号キー(0以外の値)を指定します。\n");
	fprintf(stderr, "                   このオプションを指定しなければ、暗号化されていないムービーデータと見なします。\n");
//}}2017/04/03追加:暗号化されたデータの情報取得に対応しました。
	fprintf(stderr, "  -h               使い方を表示します。\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "OUTPUT FIELDS:\n");
	fprintf(stderr, "  width            ムービー最大幅(8の倍数)\n");
	fprintf(stderr, "  height           ムービー最大高さ(8の倍数)\n");
	fprintf(stderr, "  disp_width       表示したい映像の横ピクセル数(左端から)\n");
	fprintf(stderr, "  disp_height      表示したい映像の縦ピクセル数(上端から)\n");
	fprintf(stderr, "  framerate        フレームレート[x1000]\n");
	fprintf(stderr, "  framerate_n      有理数形式フレームレート(分子) framerate [x1000] = framerate_n / framerate_d\n");
	fprintf(stderr, "  framerate_d      有理数形式フレームレート(分母) framerate [x1000] = framerate_n / framerate_d\n");
	fprintf(stderr, "  total_frames     総フレーム数\n");
	fprintf(stderr, "  material_width   エンコード前のビデオ素材の横ピクセル数\n");
	fprintf(stderr, "  material_height  エンコード前のビデオ素材の縦ピクセル数\n");
	fprintf(stderr, "  alpha            アルファストリームの数(0,又は,1)\n");
	exit(EXIT_FAILURE);
}
/****************************************************************************
 *	
 ****************************************************************************/
void app_init(int argc, char* argv[]) {
	/** no job **/
}
/*--------------------------------------------------------------------------*/
void app_exit() {
	/** no job **/
}
/*--------------------------------------------------------------------------*/
int app_main(int argc, char* argv[]) {
	int exitCode = EXIT_SUCCESS;
	int opt_c = 0;	//'-c'オプションが指定されたら1にする。
	int opt_k = 0;	//'-k'オプションが指定されたら復号キー(0以外)を格納する。	//{{2017/04/03追加:暗号化されたデータの情報取得に対応しました。}}
	//コマンドラインオプションを処理する。
	{
		int opt;
		opterr = 0; //オプションエラーは当プログラム内で処理するので、getopt()内でのエラー表示は不要。
		while((opt = getopt(argc, argv, "ck:h")) != -1) {	//コマンドラインオプションを処理する。
			switch(opt) {
			case 'c':
				opt_c = 1;
				break;
//{{2017/04/03追加:暗号化されたデータの情報取得に対応しました。
			case 'k':
				opt_k = _atoi64(optarg);	//VC++6.0にはstrtoll()やstrtoull()が無いので、仕方無く_atoi64()で代用しました。別の案としてstrtod()で取得して整数化する方法も考えましたが、_atoi64()の方が(非標準ではありますが)自然だと思うので_atoi64()にしました。
				if(!opt_k) { usage(); }
				break;
//}}2017/04/03追加:暗号化されたデータの情報取得に対応しました。
			case 'h':
			default:
				usage();
			}
		}
	}
	//少なくとも一個以上ムービーファイル名が指定されていなければいけない。
	if(optind >= argc) { usage(); }
	//ライブラリを初期化する。
//{{2016/08/01変更:/clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、SofdecHelper_Init()の呼び出し処理を変更しました。
//	SofdecHelper_Init(4);	//アルファ無しムービーならば1,アルファ付きムービーならば2で足りるはずだが、安全のために4としておく事にした。Sofdec2のデフォルト値も4である。
//↓2016/08/01変更:/clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、SofdecHelper_Init()の呼び出し処理を変更しました。
	{
//{{2017/04/03変更:暗号化されたデータの情報取得に対応しました。
//		static const ST_SofdecHelperInfo stSofdecHelperInfo = { 4 };	//アルファ無しムービーならば1,アルファ付きムービーならば2で足りるはずだが、安全のために4としておく事にした。Sofdec2のデフォルト値も4である。
//↓2017/04/03変更:暗号化されたデータの情報取得に対応しました。
		ST_SofdecHelperInfo stSofdecHelperInfo;
		memset(&stSofdecHelperInfo, 0, sizeof stSofdecHelperInfo);
		stSofdecHelperInfo.NumMovies	= 4;				//アルファ無しムービーならば1,アルファ付きムービーならば2で足りるはずだが、安全のために4としておく事にした。Sofdec2のデフォルト値も4である。
		stSofdecHelperInfo.MovieKey	= opt_k;
//}}2017/04/03変更:暗号化されたデータの情報取得に対応しました。
		SofdecHelper_Init(&stSofdecHelperInfo);
	}
//}}2016/08/01変更:/clip/tool/SofdecHelper/SofdecHelper.cの更新に伴い、SofdecHelper_Init()の呼び出し処理を変更しました。
	//各ムービーファイル名について…
	for(;;) {
		char path[MAX_PATH], drive[MAX_DRIVE], dir[MAX_DIR], fname[MAX_FNAME], ext[MAX_EXT];
		int iManaPlayer;
		//ムービーファイル名の拡張子が省略されていたら、'.usm'を補う。
		splitpath(argv[optind], drive, dir, fname, ext);
		makepath(path, drive, dir, fname, ext[0] ? ext : ".usm");
		//ムービーファイルを開く。
		iManaPlayer = SofdecHelper_Load(path);
		//ムービー情報を表示する。
		if(!opt_c) {
			//読み易い形式
			printf("\"%s\"\n", path);
			printf("  width            %d\n", SofdecHelper_GetWidth(iManaPlayer));		//ムービー最大幅(8の倍数)
			printf("  height           %d\n", SofdecHelper_GetHeight(iManaPlayer));		//ムービー最大高さ(8の倍数)
			printf("  disp_width       %d\n", SofdecHelper_GetDispWidth(iManaPlayer));	//表示したい映像の横ピクセル数(左端から)
			printf("  disp_height      %d\n", SofdecHelper_GetDispHeight(iManaPlayer));	//表示したい映像の縦ピクセル数(上端から)
			printf("  framerate        %d\n", SofdecHelper_GetFramerate(iManaPlayer));	//フレームレート[x1000]
			printf("  framerate_n      %d\n", SofdecHelper_GetFramerateN(iManaPlayer));	//有理数形式フレームレート(分子) framerate [x1000] = framerate_n / framerate_d
			printf("  framerate_d      %d\n", SofdecHelper_GetFramerateD(iManaPlayer));	//有理数形式フレームレート(分母) framerate [x1000] = framerate_n / framerate_d
			printf("  total_frames     %d\n", SofdecHelper_GetTotalFrames(iManaPlayer));	//総フレーム数
			printf("  material_width   %d\n", SofdecHelper_GetMaterialWidth(iManaPlayer));	//エンコード前のビデオ素材の横ピクセル数
			printf("  material_height  %d\n", SofdecHelper_GetMaterialHeight(iManaPlayer));	//エンコード前のビデオ素材の縦ピクセル数
			printf("  alpha            %d\n", SofdecHelper_GetAlpha(iManaPlayer));		//アルファストリームの数(0,又は,1)
		} else {
			//CSV形式
			printf("\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
				path,
				SofdecHelper_GetWidth(iManaPlayer),					//ムービー最大幅(8の倍数)
				SofdecHelper_GetHeight(iManaPlayer),					//ムービー最大高さ(8の倍数)
				SofdecHelper_GetDispWidth(iManaPlayer),					//表示したい映像の横ピクセル数(左端から)
				SofdecHelper_GetDispHeight(iManaPlayer),				//表示したい映像の縦ピクセル数(上端から)
				SofdecHelper_GetFramerate(iManaPlayer),					//フレームレート[x1000]
				SofdecHelper_GetFramerateN(iManaPlayer),				//有理数形式フレームレート(分子) framerate [x1000] = framerate_n / framerate_d
				SofdecHelper_GetFramerateD(iManaPlayer),				//有理数形式フレームレート(分母) framerate [x1000] = framerate_n / framerate_d
				SofdecHelper_GetTotalFrames(iManaPlayer),				//総フレーム数
				SofdecHelper_GetMaterialWidth(iManaPlayer),				//エンコード前のビデオ素材の横ピクセル数
				SofdecHelper_GetMaterialHeight(iManaPlayer),				//エンコード前のビデオ素材の縦ピクセル数
				SofdecHelper_GetAlpha(iManaPlayer));					//アルファストリームの数(0,又は,1)
		}
		//ムービーファイルを閉じる。
		SofdecHelper_Free(iManaPlayer);
		//ムービーファイル名を次へ進める。
		if(++optind >= argc) { break; }
		//読み易い形式ならば、空行を挟む。
		if(!opt_c) { putchar('\n'); }
	}
	//ライブラリをクリーンアップする。
	SofdecHelper_Exit();
	return exitCode;
}
