PPMを解析するクラス
先日作ったC#用のうごメモPPMファイルを解析するクラスです。
アニメーションデータサイズなどの触れる必要のないものは隠蔽してしまいます。
また、新しく作る必要がないので、コンストラクタはprotected、書き換える必要もないのでプロパティはすべてgetアクセサのみ実装です。
最初がPARAになっていないファイルはNotUgoMemoFile例外を出します。
チェックは適当。
class NotUgoMemoFile : Exception { public NotUgoMemoFile() : base("このファイルはうごメモPPMファイルではありません。") { } } class UgoMemo { protected UgoMemo() { } //コンストラクタは公開されない //private uint magicNumber; //ファイルタイプ。常に「PARA」が指定されていなければならない uint animationSize; //アニメーションデータサイズ uint soundSize; //音声データのサイズ ushort frameLength; //フレーム数(ページ-1) ushort unKnow; //不明なデータ(0x2400で固定) ushort locked; //ロック(0でなし。1でロック) ushort savedFrame; //サムネイル表示されているページ番号 char[] originalAuthorName; //原作者名 char[] parentAuthorName; //親作者名 char[] userName; //作者名 ulong parentAuthorID; //親作者ID ulong userAuthorID; //作者ID byte[] parentMemoID; //親作ID byte[] memoID; //このメモのID ulong originalAuthorID; //原作者ID byte[] partialFileName; //?不明 uint timeStamp; //最終変更日(2000年からの経過秒) ushort filter; //フィルタ。0x0000 //static static int PARA = 0x41524150; //うごメモPPMファイル識別子 //public property (GetOnly) /// <summary> /// フレーム数。ページ数-1 /// </summary> public int FrameLength { get { return frameLength; } } /// <summary> /// ロック状態(ロックでtrue) /// </summary> public bool Locked { get { return locked == 1; } } /// <summary> /// 最後に保存されたフレーム。サムネイルのページ /// </summary> public int SavedFrame { get { return savedFrame; } } /// <summary> /// 原作者名 /// </summary> public string OriginalAuthorName { get { return new string(originalAuthorName).Trim(); } } /// <summary> /// 親作者名 /// </summary> public string ParetAuthorName { get { return new string(parentAuthorName).Trim(); } } /// <summary> /// 作者名 /// </summary> public string UserName { get { return new string(userName).Trim(); } } /// <summary> /// 更新日 /// </summary> public DateTime TimeStamp { get { var dt = new DateTime(2000, 1, 1); return dt.AddSeconds(timeStamp);} } /// <summary> /// 作者ID /// </summary> public string UserAuthorID { get { return this.userAuthorID.ToString("X16"); } } /// <summary> /// 親作者ID /// </summary> public string ParentAuthorID { get { return this.parentAuthorID.ToString("X16"); } } /// <summary> /// 原作者ID /// </summary> public string OriginalAuthorID { get { return this.originalAuthorID.ToString("X16"); } } /// <summary> /// このメモのファイル名 /// </summary> public string MemoFileName { get { return memoID[0x0].ToString("X2") + memoID[0x1].ToString("X2") + memoID[0x2].ToString("X2") + "_" + Encoding.ASCII.GetString(memoID, 3, 13) + "_" + (memoID[0x10] + (memoID[0x11] * 10)).ToString("000") + ".ppm"; } } /// <summary> /// 親作品のファイル名 /// </summary> public string ParentFileName { get { return parentMemoID[0x0].ToString("X2") + parentMemoID[0x1].ToString("X2") + parentMemoID[0x2].ToString("X2") + "_" + Encoding.ASCII.GetString(parentMemoID, 3, 13) + "_" + (parentMemoID[0x10] + (parentMemoID[0x11] * 10)).ToString("000") + ".ppm"; } } //public method public static UgoMemo LoadFile(string FileName) { using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read)) { return LoadFile(fs); } } /// <summary> /// PPMファイルを読み込む /// </summary> /// <param name="s">PPMファイルのストリーム</param> /// <returns>読み込まれたUgoMemoクラスのインスタンス</returns> public static UgoMemo LoadFile(Stream s) { using (BinaryReader br = new BinaryReader(s, Encoding.Unicode)) { UgoMemo u = new UgoMemo(); u.magicNumber = br.ReadUInt32(); u.soundSize = br.ReadUInt32(); if (u.magicNumber != PARA) throw new NotUgoMemoFile(); //マジックナンバーチェックで例外 u.animationSize = br.ReadUInt32(); u.frameLength = br.ReadUInt16(); u.unKnow = br.ReadUInt16(); u.locked = br.ReadUInt16(); u.savedFrame = br.ReadUInt16(); u.originalAuthorName = br.ReadChars(11); u.parentAuthorName = br.ReadChars(11); u.userName = br.ReadChars(11); u.parentAuthorID = br.ReadUInt64(); u.userAuthorID = br.ReadUInt64(); u.parentMemoID = br.ReadBytes(18); u.memoID = br.ReadBytes(18); u.originalAuthorID = br.ReadUInt64(); u.partialFileName = br.ReadBytes(8); u.timeStamp = br.ReadUInt32(); u.filter = br.ReadUInt16(); return u; } } }
ところで、PPMファイルには、「ページ透過」というなぞの指定が。いったいなんだ?これ。このころはバージョン1で、上紙を消すということもないはずだし。
・・・というか、上紙、下紙の表示情報はどこだ?もしや0x9Eのあたりか!?
確認せねば。
2011/4/30 : ID関係の間違いを修正