// PNG処理 public int png_cutter( bool Exe, bool IndexFileCreate, int buffer_Level, int RenbanKeta, string filename, string kakutyoushi, string CreateFileBaseName, string BaseDirectory, TextBox DebugTB ) { byte[] DeletedByte = { 0x89, 0x50, 0x4e, 0x47, 0x0d }; // 意図的に削除されたPNGヘッダ [5バイト] byte[] StartByte = { 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49 }; //とりあえず8バイトもっと細かくはできる byte[] EndByte = { 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, //IEND 0xae, 0x42, 0x60, 0x82 }; ////IEND-CRC //ディレクトリが存在するかしなかのチェックは外部でする if (BaseDirectory != null) { // CreateFileBaseName=BaseDirectory+"\\"+CreateFileBaseName; CreateFileBaseName = BaseDirectory + CreateFileBaseName;//GUI側で+\\しとく } //連番ファイルstring構築 string stRebnan = Convert.ToString(RenbanKeta); stRebnan = "d" + stRebnan; StreamWriter SWidx = null; string stidxs; if (IndexFileCreate == true) { //インデックスファイル名はfilename+"拡張子"+".idx" FileStream FSidx = new FileStream(filename + "_" + kakutyoushi + ".idx", FileMode.Create, FileAccess.Write); SWidx = new StreamWriter(FSidx); SWidx.WriteLine("FileNo,BlockNo,KITEN,Filesize"); } int SBIdx = 0; int ReturnInt = 0; int COUNT = buffer_Level;//4096=デフォルト FileStream sr = new FileStream(filename, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(sr); byte[] buffer = new byte[COUNT]; bool flag, WriteOK = true; int ix, BlockNO = 1, KITEN, beforeKITEN = 0, cFiles, FileNO = 0, ESBIdx = 0; string CuttingFileName = null; FileStream CFN = null; BinaryWriter CFNBR = null; //生成ファイル名は filename+"cut"+FileNO+".拡張子" if (Exe == true) { CuttingFileName = String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, FileNO, kakutyoushi); CFN = new FileStream(CuttingFileName, FileMode.Create, FileAccess.Write); CFNBR = new BinaryWriter(CFN); } /*文字列照合アルゴリズムかkuth/Boyer使ったほうが速い*/ for (int idx = 0; idx < sr.Length; idx += COUNT) { br.Read(buffer, 0, COUNT); //---------- バッファBlockサーチ処理ルーチン //ブロックの末尾にサーチ対象がある場合もルーチンが必要 BlockNO++; ix = 0; while (ix < COUNT) { flag = false; //trueになるまで書き込み+調査 while (flag == false) { //writeバッファはためこんで8096単位で書き込み //このままだと完成ファイルの末尾にゴミヘッダがつく if (Exe == true && WriteOK == true) { CFNBR.Write(buffer[ix]); } if (buffer[ix] == StartByte[SBIdx]) { SBIdx++; if (SBIdx == StartByte.Length) { flag = true; SBIdx = 0; } } else { SBIdx = 0; } if (EndByte != null && buffer[ix] == EndByte[ESBIdx]) { ESBIdx++; if (ESBIdx == EndByte.Length) { WriteOK = false; ESBIdx = 0; } } else { ESBIdx = 0; } ix++; if (ix >= COUNT) { break; } } if (flag == true) { ReturnInt++; KITEN = idx + ix - StartByte.Length + 1; //+1は配列[0]のため cFiles = KITEN - beforeKITEN; //EndHederの時は別処理 beforeKITEN = KITEN; if (IndexFileCreate == true) { stidxs = String.Format("{0},{1},{2},{3}\n", ReturnInt, BlockNO, KITEN, cFiles); SWidx.Write(stidxs); } if (DebugTB != null) { //stidxs=String.Format("{0} {1} {2}\r\n",ReturnInt,BlockNO,KITEN); //なんかtextboxエラーでるので stidxs = String.Format("{0}\r\n", ReturnInt); DebugTB.AppendText(stidxs); } if (Exe == true) { // CFNBR.Write(buffer); CFNBR.Flush(); CFNBR.Close(); CFN.Close(); FileNO++; //1ブロックに複数ファイルがあるときのルーチンが必要[clear!] CuttingFileName = String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, FileNO, kakutyoushi); CFN = new FileStream(CuttingFileName, FileMode.Create, FileAccess.Write); CFNBR = new BinaryWriter(CFN); //★★-プラグインの修正点[ここ以外は基本Datecutterと同じ] CFNBR.Write(DeletedByte); // 削除されたバイト列の書き込み //★★ CFNBR.Write(StartByte); // ヘッダの書き込み WriteOK = true; // CFNBR.Write(buffer,ix-SearchBytes.Length,buffer.Length-(ix-SearchBytes.Length)); } } // SBIdx=0;//削除すれば下段ブロック処理になる[clear!] } // if(Exe == true && FirstWrited == false){CFNBR.Write(buffer);} } if (Exe == true) { CFNBR.Flush(); CFNBR.Close(); //00fileを削除(暫定) File.Delete(String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, 0, kakutyoushi)); } br.Close(); sr.Close(); if (IndexFileCreate == true) { SWidx.Flush(); SWidx.Close(); } return(ReturnInt); }
//bool Exe=trueで実行、falseでシミュレートのみ // buffer_Level はwmvのときは4096でOk /*各拡張子に対応できるよう汎用性をもたせる * ユーザーがサーチバイトを指定できるようにする * ArraySerchとして別に汎用関数を書いてライブラリDLL化しとく * CFN生成の ディレクトリ指定できるように、ディレクトリがない場合作成 * 何枚ファイルを生成するかも引数にする * 返り値=cutできた/cutできるファイル数 */ public int _cutter( string filename, FileAttributeSet FAS, int buffer_Level, bool Exe, bool IndexFileCreate, string CreateFileBaseName, string BaseDirectory, int RenbanKeta, TextBox DebugTB) { if (CreateFileBaseName == null) { CreateFileBaseName = filename + "cut"; } //ディレクトリが存在するかしなかのチェックは外部でする if (BaseDirectory != null) { // CreateFileBaseName=BaseDirectory+"\\"+CreateFileBaseName; CreateFileBaseName = BaseDirectory + CreateFileBaseName; //GUI側で+\\しとく } //連番ファイルstring構築 string stRebnan = Convert.ToString(RenbanKeta); stRebnan = "d" + stRebnan; StreamWriter SWidx = null; string stidxs; if (IndexFileCreate == true) { //インデックスファイル名はfilename+"拡張子"+".idx" FileStream FSidx = new FileStream(filename + "_" + FAS.kakutyoushi + ".idx", FileMode.Create, FileAccess.Write); SWidx = new StreamWriter(FSidx); SWidx.WriteLine("FileNo,BlockNo,KITEN,Filesize"); } int SBIdx = 0; int ReturnInt = 0; int COUNT = buffer_Level; //4096=デフォルト FileStream sr = new FileStream(filename, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(sr); byte [] buffer = new byte[COUNT]; bool flag, WriteOK = true; int ix, BlockNO = 1, KITEN, beforeKITEN = 0, cFiles, FileNO = 0, ESBIdx = 0; string CuttingFileName = null; FileStream CFN = null; BinaryWriter CFNBR = null; int [] KITENS; //生成ファイル名は filename+"cut"+FileNO+".拡張子" if (Exe == true) { CuttingFileName = String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, FileNO, FAS.kakutyoushi); CFN = new FileStream(CuttingFileName, FileMode.Create, FileAccess.Write); CFNBR = new BinaryWriter(CFN); } if (FAS.AnalysisFormatTYPE == 0) { /*文字列照合アルゴリズムかkuth/Boyer使ったほうが速い*/ for (int idx = 0; idx < sr.Length; idx += COUNT) { br.Read(buffer, 0, COUNT); //---------- バッファBlockサーチ処理ルーチン //ブロックの末尾にサーチ対象がある場合もルーチンが必要 BlockNO++; ix = 0; while (ix < COUNT) { flag = false; //trueになるまで書き込み+調査 while (flag == false) { //writeバッファはためこんで8096単位で書き込み //このままだと完成ファイルの末尾にゴミヘッダがつく if (Exe == true && WriteOK == true) { CFNBR.Write(buffer[ix]); } if (buffer[ix] == FAS.AttHeader[SBIdx]) { SBIdx++; if (SBIdx == FAS.AttHeader.Length) { flag = true; SBIdx = 0; } } else { SBIdx = 0; } if (FAS.EndHeader != null && buffer[ix] == FAS.EndHeader[ESBIdx]) { ESBIdx++; if (ESBIdx == FAS.EndHeader.Length) { WriteOK = false; ESBIdx = 0; } } else { ESBIdx = 0; } ix++; if (ix >= COUNT) { break; } } if (flag == true) { ReturnInt++; KITEN = idx + ix - FAS.AttHeader.Length + 1; //+1は配列[0]のため cFiles = KITEN - beforeKITEN; //EndHederの時は別処理 beforeKITEN = KITEN; if (IndexFileCreate == true) { stidxs = String.Format("{0},{1},{2},{3}\n", ReturnInt, BlockNO, KITEN, cFiles); SWidx.Write(stidxs); } if (DebugTB != null) { //stidxs=String.Format("{0} {1} {2}\r\n",ReturnInt,BlockNO,KITEN); //なんかtextboxエラーでるので stidxs = String.Format("{0}\r\n", ReturnInt); DebugTB.AppendText(stidxs); } if (Exe == true) { // CFNBR.Write(buffer); CFNBR.Flush(); CFNBR.Close(); CFN.Close(); FileNO++; Console.WriteLine(FileNO); //1ブロックに複数ファイルがあるときのルーチンが必要[clear!] CuttingFileName = String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, FileNO, FAS.kakutyoushi); CFN = new FileStream(CuttingFileName, FileMode.Create, FileAccess.Write); CFNBR = new BinaryWriter(CFN); CFNBR.Write(FAS.AttHeader); //ヘッダの書き込み WriteOK = true; // CFNBR.Write(buffer,ix-SearchBytes.Length,buffer.Length-(ix-SearchBytes.Length)); } } // SBIdx=0;//削除すれば下段ブロック処理になる[clear!] } // if(Exe == true && FirstWrited == false){CFNBR.Write(buffer);} } } //if(FAS.AnalysisFormatTYPE == 0) //WAV&RIFF/AVI用 else if (FAS.AnalysisFormatTYPE == 1) { BlockNO = 0; //1になってるので0に初期化 int KadanPosition = 0, FindCount = 0, sw, oneWrite, sSize = 0; uint Size = 0; WriteOK = false; byte [] Size4byte = new byte[4]; for (int idx = 0; idx < sr.Length; idx += COUNT) { br.Read(buffer, 0, COUNT); KITENS = SimpleArraySearchS(buffer, FAS.AttHeader, 0, ref KadanPosition , ref FindCount); if (KITENS[0] != -1) { for (int ic = 0; ic < FindCount; ic++) { ReturnInt++; Console.WriteLine("block {0} ,\t bk{1},KITEN{2}", BlockNO, KITENS[ic], (BlockNO * COUNT) + KITENS[ic]); sw = KITENS[ic]; Size = 8 + ReverceEdian(buffer[sw + 4], buffer[sw + 5], buffer[sw + 6], buffer[sw + 7]); Console.WriteLine("@ {0:x2}{1:x2}{2:x2}{3:x2} SIZE={4}+8", buffer[sw + 4], buffer[sw + 5], buffer[sw + 6], buffer[sw + 7], Size); if (Exe == true) { if (WriteOK == true) { CFNBR.Write(buffer, 0, KITENS[ic]); } CFNBR.Flush(); CFNBR.Close(); CFN.Close(); FileNO++; Console.WriteLine("FileCreate{0}", FileNO); CuttingFileName = String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, FileNO, FAS.kakutyoushi); CFN = new FileStream(CuttingFileName, FileMode.Create, FileAccess.Write); CFNBR = new BinaryWriter(CFN); CFNBR.Write(buffer, KITENS[ic], buffer.Length - KITENS[ic]); sSize = (int)Size; sSize -= buffer.Length - KITENS[ic]; WriteOK = true; } } } else { if (Exe == true && WriteOK == true) { if (sSize < buffer.Length) { //oneWrite=sSize; CFNBR.Write(buffer, 0, sSize); //CFNBR.Write(buffer,0,sSize+8);//?暫定 WriteOK = false; } else { sSize -= buffer.Length; CFNBR.Write(buffer); } } } BlockNO++; } // if(Exe == true){CFN.Close();} } if (Exe == true) { CFNBR.Flush(); CFNBR.Close(); //00fileを削除(暫定) File.Delete(String.Format("{0}{1:" + stRebnan + "}{2}", CreateFileBaseName, 0, FAS.kakutyoushi)); } br.Close(); sr.Close(); if (IndexFileCreate == true) { SWidx.Flush(); SWidx.Close(); } return(ReturnInt); } //_cut