Ejemplo n.º 1
0
        public static double MIN_SAMPLE_MATCH_PERCENTAGE = 0.05f; // 5%

        public static ArrayList GetSeqFileList(Stream fs, bool UseSeqMinimumSize, int MinimumSeqSize)
        {
            ArrayList ret = new ArrayList();

            ProbableItemStruct seqEntry = new ProbableItemStruct();
            long offset = 0;
            long seqEof = 0;
            uint seqLength;


            // build file list
            while ((offset = ParseFile.GetNextOffset(fs, offset, PsxSequence.ASCII_SIGNATURE_SEQ)) > -1)
            {
                seqEof = ParseFile.GetNextOffset(fs, offset, PsxSequence.END_SEQUENCE);

                if (seqEof > 0)
                {
                    seqLength = (uint)(seqEof - offset + PsxSequence.END_SEQUENCE.Length);

                    if ((!UseSeqMinimumSize) ||
                        ((UseSeqMinimumSize) && (seqLength >= MinimumSeqSize)))
                    {
                        seqEntry.offset = offset;
                        seqEntry.length = (uint)(seqEof - offset + PsxSequence.END_SEQUENCE.Length);
                        ret.Add(seqEntry);
                    }
                }
                offset += 1;
            }

            return(ret);
        }
Ejemplo n.º 2
0
        public static int GetMpegStreamType(string path)
        {
            int mpegType = -1;

            using (FileStream fs = File.OpenRead(path))
            {
                // look for first packet
                long currentOffset = ParseFile.GetNextOffset(fs, 0, MpegStream.PacketStartBytes);

                if (currentOffset != -1)
                {
                    currentOffset += 4;
                    fs.Position    = currentOffset;
                    byte idByte = (byte)fs.ReadByte();

                    if ((int)ByteConversion.GetHighNibble(idByte) == 2)
                    {
                        mpegType = 1;
                    }
                    else if ((int)ByteConversion.GetHighNibble(idByte) == 4)
                    {
                        mpegType = 2;
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Cannot find Pack Header for file: {0}{1}", Path.GetFileName(path), Environment.NewLine));
                }
            }

            return(mpegType);
        }
Ejemplo n.º 3
0
        public static string[] ExtractSdatsFromFile(string pPath, string pDirectorySuffix)
        {
            ArrayList extractedSdatPaths = new ArrayList();

            string fullPath = Path.GetFullPath(pPath);
            string outputPath;
            string filePrefix = Path.GetFileNameWithoutExtension(fullPath);

            if (!String.IsNullOrEmpty(pDirectorySuffix))
            {
                filePrefix += pDirectorySuffix;
            }

            int  sdatIndex = 0;
            long sdatOffset;
            long previousOffset;

            byte[] sdatSizeBytes;
            int    sdatSize;

            if (!File.Exists(fullPath))
            {
                throw new FileNotFoundException(String.Format("Cannot find file <{0}>", fullPath));
            }
            else
            {
                using (FileStream fs = File.Open(fullPath, FileMode.Open, FileAccess.Read))
                {
                    previousOffset = 0;

                    while ((sdatOffset = ParseFile.GetNextOffset(fs, previousOffset, Sdat.ASCII_SIGNATURE)) != -1)
                    {
                        sdatSizeBytes = ParseFile.ParseSimpleOffset(fs, sdatOffset + 8, 4);
                        sdatSize      = BitConverter.ToInt32(sdatSizeBytes, 0);

                        outputPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(pPath), Path.Combine(filePrefix,
                                                                                                              String.Format("sound_data_{0}.sdat", sdatIndex++.ToString("X2")))));

                        ParseFile.ExtractChunkToFile(fs, sdatOffset, sdatSize, outputPath);

                        extractedSdatPaths.Add(outputPath);

                        // only increment by one since there can be fake or bad SDATs which will move us past proper ones.
                        previousOffset = sdatOffset + 1;
                    }
                }
            }

            // return paths of extracted SDATs
            if (extractedSdatPaths.Count > 0)
            {
                return((string[])extractedSdatPaths.ToArray(typeof(string)));
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 4
0
        public static ArrayList GetSepFileList(Stream fs)
        {
            ArrayList          ret      = new ArrayList();
            ProbableItemStruct sepEntry = new ProbableItemStruct();

            long offset            = 0;
            long sepStartingOffset = 0;
            int  sepSeqCount;
            long seqEof = 0;

            // build file list
            while ((offset = ParseFile.GetNextOffset(fs, offset, PsxSequence.ASCII_SIGNATURE_SEP)) > -1)
            {
                sepStartingOffset = offset;
                sepSeqCount       = 1;
                byte[] nextSepCheckBytes;
                seqEof = offset;

                while ((seqEof = ParseFile.GetNextOffset(fs, seqEof, PsxSequence.END_SEQUENCE)) > -1)
                {
                    nextSepCheckBytes = ParseFile.ParseSimpleOffset(fs, (long)(seqEof + PsxSequence.END_SEQUENCE.Length), 2);
                    Array.Reverse(nextSepCheckBytes);

                    if (nextSepCheckBytes.Length > 0)
                    {
                        if (BitConverter.ToUInt16(nextSepCheckBytes, 0) == (UInt16)sepSeqCount)
                        {
                            sepSeqCount++;
                        }
                        else
                        {
                            sepEntry.offset = sepStartingOffset;
                            sepEntry.length = (uint)(seqEof - sepStartingOffset + PsxSequence.END_SEQUENCE.Length);
                            ret.Add(sepEntry);
                            break;
                        }
                    }
                    else
                    {
                        sepEntry.offset = sepStartingOffset;
                        sepEntry.length = (uint)(seqEof - sepStartingOffset + PsxSequence.END_SEQUENCE.Length);
                        ret.Add(sepEntry);
                        break;
                    }

                    seqEof += 1;
                }

                offset += 1;
            }

            return(ret);
        }
Ejemplo n.º 5
0
        protected void ConvertSubtitles(uint streamId, FileStream subtitleStream)
        {
            long subsLength    = subtitleStream.Length;
            long currentOffset = 0;

            byte[] encodedPresentationTimeStamp;
            ulong  decodedTimeStamp;
            ushort subtitlePacketSize;

            byte[] PNG_HEADER = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
            byte[] PNG_END    = new byte[] { 0x49, 0x45, 0x4E, 0x44 };

            long pngStartOffset;
            long pngEndOffset;
            long pngSize;
            uint pngCount = 0;

            string baseDirectory = Path.GetDirectoryName(subtitleStream.Name);

            baseDirectory = Path.Combine(baseDirectory, String.Format("{0}_PNGs", Path.GetFileNameWithoutExtension(subtitleStream.Name)));
            string destinationFile;

            while (currentOffset < subsLength)
            {
                // decode time stamp
                encodedPresentationTimeStamp = ParseFile.ParseSimpleOffset(subtitleStream, currentOffset, 5);
                decodedTimeStamp             = this.DecodePresentationTimeStamp(encodedPresentationTimeStamp);

                // get subtitle packet size
                subtitlePacketSize = ParseFile.ReadUshortBE(subtitleStream, currentOffset + 0xC);

                // extract PNG
                pngStartOffset = ParseFile.GetNextOffset(subtitleStream, currentOffset + 0x1E, PNG_HEADER);
                pngEndOffset   = ParseFile.GetNextOffset(subtitleStream, pngStartOffset, PNG_END) + 4;
                pngSize        = pngEndOffset - pngStartOffset;

                if (pngSize > (subtitlePacketSize - 0x14))
                {
                    throw new Exception("Warning, PNG size exceeds packet size.");
                }

                destinationFile = Path.Combine(baseDirectory, String.Format("{0}.png", pngCount.ToString("D8")));
                ParseFile.ExtractChunkToFile(subtitleStream, pngStartOffset, pngSize, destinationFile);
                pngCount++;

                // write timestamp and PNG to file

                // move to next block
                currentOffset += 0xE + subtitlePacketSize;
            }
        }
Ejemplo n.º 6
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractStruct, DoWorkEventArgs e)
        {
            ExtractCriAcbAwbStruct extractStruct = (ExtractCriAcbAwbStruct)pExtractStruct;

            byte[] magicBytes;
            long   awbOffset = 0;

            using (FileStream fs = File.Open(pPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                magicBytes = ParseFile.ParseSimpleOffset(fs, 0, 4);

                this.progressStruct.Clear();

                // ACB
                if (ParseFile.CompareSegment(magicBytes, 0, CriAcbFile.SIGNATURE_BYTES))
                {
                    this.progressStruct.GenericMessage = String.Format("Processing ACB file: '{0}'.{1}", Path.GetFileName(pPath), Environment.NewLine);
                    ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                    CriAcbFile acb = new CriAcbFile(fs, 0, extractStruct.IncludeCueIdInFileName);
                    acb.ExtractAll();
                }
                else if (ParseFile.CompareSegment(magicBytes, 0, CriAfs2Archive.SIGNATURE))
                {
                    this.progressStruct.GenericMessage = String.Format("Processing AWB file: '{0}'.{1}", Path.GetFileName(pPath), Environment.NewLine);
                    ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                    CriAfs2Archive afs2 = new CriAfs2Archive(fs, 0);
                    afs2.ExtractAll();
                }
                else
                {
                    this.progressStruct.GenericMessage = String.Format("ACB/AWB signature not found at offset 0...scanning for AWB signature: '{0}'.{1}", Path.GetFileName(pPath), Environment.NewLine);
                    ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                    awbOffset = ParseFile.GetNextOffset(fs, 0, CriAfs2Archive.SIGNATURE);

                    if (awbOffset > 0)
                    {
                        CriAfs2Archive afs2 = new CriAfs2Archive(fs, awbOffset);
                        afs2.ExtractAll();
                    }
                    else
                    {
                        this.progressStruct.GenericMessage = String.Format("File is not an ACB or AWB...skipping: '{0}'.{1}", Path.GetFileName(pPath), Environment.NewLine);
                        ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractMidiStruct, DoWorkEventArgs e)
        {
            long headerOffset = 0;

            using (FileStream fs = File.OpenRead(pPath))
            {
                while ((headerOffset = ParseFile.GetNextOffset(fs, headerOffset, Midi.ASCII_SIGNATURE_MTHD)) > -1)
                {
                    Midi midiFile = new Midi();
                    midiFile.Initialize(fs, pPath, headerOffset);
                    midiFile.ExtractToFile(fs, Path.Combine(Path.GetDirectoryName(pPath), Path.GetFileNameWithoutExtension(pPath)));
                    headerOffset += 1;
                }
            }
        }
Ejemplo n.º 8
0
        public UInt32 getEndOfTrackForSequenceNumber(Stream pStream, int pSequenceNumber)
        {
            UInt32 ret = 0;

            if (pSequenceNumber <= this.midiChunk.maxSeqCount &&
                this.midiChunk.subSeqOffsetAddr[pSequenceNumber] != EMPTY_MIDI_OFFSET)
            {
                Int32 midiBlockOffset = MIDI_CHUNK_OFFSET + this.midiChunk.subSeqOffsetAddr[pSequenceNumber];

                long endOfTrackOffset = ParseFile.GetNextOffset(pStream, (long)midiBlockOffset, END_OF_TRACK_BYTES);

                ret = (UInt32)endOfTrackOffset;
            }

            return(ret);
        }
Ejemplo n.º 9
0
        public static IVolume[] GetVolumes(string isoPath, bool isRawDump)
        {
            ArrayList    volumeList = new ArrayList();
            XDvdFsVolume volume;
            long         volumeOffset;

            using (FileStream fs = File.OpenRead(isoPath))
            {
                volumeOffset = ParseFile.GetNextOffset(fs, 0, XDvdFs.STANDARD_IDENTIFIER, true, 0x800, 0);
                volume       = new XDvdFsVolume();
                volume.Initialize(fs, volumeOffset, isRawDump);
                volumeList.Add(volume);
            }

            return((IVolume[])volumeList.ToArray(typeof(XDvdFsVolume)));
        }
Ejemplo n.º 10
0
        public UInt32 getTempoForSequenceNumber(Stream pStream, int pSequenceNumber)
        {
            UInt32 ret = 0;

            if (pSequenceNumber <= this.midiChunk.maxSeqCount &&
                this.midiChunk.subSeqOffsetAddr[pSequenceNumber] != EMPTY_MIDI_OFFSET)
            {
                Int32 midiBlockOffset = MIDI_CHUNK_OFFSET + this.midiChunk.subSeqOffsetAddr[pSequenceNumber];

                long setTempoOffset = ParseFile.GetNextOffset(pStream, (long)midiBlockOffset, SET_TEMPO_BYTES);

                byte[] tempoValBytes = new byte[4];
                Array.Copy(ParseFile.ParseSimpleOffset(pStream, setTempoOffset + 3, 3), 0, tempoValBytes, 1, 3);

                Array.Reverse(tempoValBytes); // flip order to LE for use with BitConverter
                ret = BitConverter.ToUInt32(tempoValBytes, 0);
            }

            return(ret);
        }
Ejemplo n.º 11
0
        private static bool IsSilentBlock(byte[] pCdxaBlock, ExtractXaStruct pExtractXaStruct)
        {
            bool ret = false;
            int  silentFrameCount = 0;
            long bufferOffset     = 0;

            while ((bufferOffset = ParseFile.GetNextOffset(pCdxaBlock, bufferOffset, Cdxa.XA_SILENT_FRAME)) > -1)
            {
                silentFrameCount++;
                bufferOffset += 1;
            }

            // did we find enough silent frames?
            if (silentFrameCount >= pExtractXaStruct.SilentFramesCount)
            {
                ret = true;
            }

            return(ret);
        }
Ejemplo n.º 12
0
        public static uint GetRiffHeaderSize(string riffHeaderedFile)
        {
            uint headerSize = 0;

            using (FileStream fs = File.OpenRead(riffHeaderedFile))
            {
                long riffHeaderLocation = ParseFile.GetNextOffset(fs, 0, Constants.RiffHeaderBytes);

                if (riffHeaderLocation > -1)
                {
                    long waveChunkLocation = ParseFile.GetNextOffset(fs,
                                                                     riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                    if (waveChunkLocation > -1)
                    {
                        long dataChunkLocation = ParseFile.GetNextOffset(fs,
                                                                         waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffDataBytes);

                        if (dataChunkLocation > -1)
                        {
                            headerSize = (uint)(dataChunkLocation + Constants.RiffDataBytes.Length + 4);
                        }
                        else
                        {
                            throw new FormatException("RIFF header data chunk not found.");
                        }
                    }
                    else
                    {
                        throw new FormatException("RIFF header WAVE chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header not found.");
                }
            }

            return(headerSize);
        }
Ejemplo n.º 13
0
        public static uint GetDataSizeFromRiffHeader(string riffHeaderedFile)
        {
            uint dataSize = 0;

            using (FileStream fs = File.OpenRead(riffHeaderedFile))
            {
                long riffHeaderLocation = ParseFile.GetNextOffset(fs, 0, Constants.RiffHeaderBytes);

                if (riffHeaderLocation > -1)
                {
                    long waveChunkLocation = ParseFile.GetNextOffset(fs,
                                                                     riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                    if (waveChunkLocation > -1)
                    {
                        long dataChunkLocation = ParseFile.GetNextOffset(fs,
                                                                         waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffDataBytes);

                        if (dataChunkLocation > -1)
                        {
                            dataSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, dataChunkLocation + 4, 4), 0);
                        }
                        else
                        {
                            throw new FormatException("RIFF header data chunk not found.");
                        }
                    }
                    else
                    {
                        throw new FormatException("RIFF header WAVE chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header not found.");
                }
            }

            return(dataSize);
        }
Ejemplo n.º 14
0
        public static ushort GetChannelsFromRiffHeader(string riffHeaderedFile)
        {
            ushort channels = 0;

            using (FileStream fs = File.OpenRead(riffHeaderedFile))
            {
                long riffHeaderLocation = ParseFile.GetNextOffset(fs, 0, Constants.RiffHeaderBytes);

                if (riffHeaderLocation > -1)
                {
                    long waveChunkLocation = ParseFile.GetNextOffset(fs,
                                                                     riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                    if (waveChunkLocation > -1)
                    {
                        long fmtChunkLocation = ParseFile.GetNextOffset(fs,
                                                                        waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffFmtBytes);

                        if (fmtChunkLocation > -1)
                        {
                            channels = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, fmtChunkLocation + 0xA, 2), 0);
                        }
                        else
                        {
                            throw new FormatException("RIFF header data chunk not found.");
                        }
                    }
                    else
                    {
                        throw new FormatException("RIFF header WAVE chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header not found.");
                }
            }

            return(channels);
        }
Ejemplo n.º 15
0
        public static IVolume[] GetVolumes(string isoPath, bool isRawDump)
        {
            ArrayList     volumeList = new ArrayList();
            Iso9660Volume volume;
            long          volumeOffset;

            using (FileStream fs = File.OpenRead(isoPath))
            {
                volumeOffset = ParseFile.GetNextOffset(fs, 0, Iso9660.VOLUME_DESCRIPTOR_IDENTIFIER);

                while (volumeOffset > -1)
                {
                    volume = new Iso9660Volume();
                    volume.Initialize(fs, volumeOffset, isRawDump);
                    volumeList.Add(volume);

                    volumeOffset = ParseFile.GetNextOffset(fs, volume.VolumeBaseOffset + ((long)volume.VolumeSpaceSize * (long)volume.LogicalBlockSize), Iso9660.VOLUME_DESCRIPTOR_IDENTIFIER);
                }
            }

            return((IVolume[])volumeList.ToArray(typeof(Iso9660Volume)));
        }
Ejemplo n.º 16
0
        public static uint GetSeqCount(string fileName)
        {
            uint seqCount = 0;
            long offset   = 0;

            if (PsxSequence.IsSepTypeSequence(fileName))
            {
                using (FileStream fs = File.OpenRead(fileName))
                {
                    while ((offset = ParseFile.GetNextOffset(fs, offset, PsxSequence.END_SEQUENCE)) > -1)
                    {
                        seqCount++;
                        offset++;
                    }
                }
            }
            else if (PsxSequence.IsSeqTypeSequence(fileName))
            {
                seqCount = 1;
            }

            return(seqCount);
        }
Ejemplo n.º 17
0
        public static uint GetFrequencyFromRiffHeader(Stream inputStream)
        {
            uint frequency = 0;

            long riffHeaderLocation = ParseFile.GetNextOffset(inputStream, 0, Constants.RiffHeaderBytes);

            if (riffHeaderLocation > -1)
            {
                long waveChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                 riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                if (waveChunkLocation > -1)
                {
                    long fmtChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                    waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffFmtBytes);

                    if (fmtChunkLocation > -1)
                    {
                        frequency = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(inputStream, fmtChunkLocation + 0xC, 4), 0);
                    }
                    else
                    {
                        throw new FormatException("RIFF header data chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header WAVE chunk not found.");
                }
            }
            else
            {
                throw new FormatException("RIFF header not found.");
            }

            return(frequency);
        }
Ejemplo n.º 18
0
        public static uint GetRiffHeaderSize(Stream inputStream)
        {
            uint headerSize = 0;

            long riffHeaderLocation = ParseFile.GetNextOffset(inputStream, 0, Constants.RiffHeaderBytes);

            if (riffHeaderLocation > -1)
            {
                long waveChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                 riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                if (waveChunkLocation > -1)
                {
                    long dataChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                     waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffDataBytes);

                    if (dataChunkLocation > -1)
                    {
                        headerSize = (uint)(dataChunkLocation + Constants.RiffDataBytes.Length + 4);
                    }
                    else
                    {
                        throw new FormatException("RIFF header data chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header WAVE chunk not found.");
                }
            }
            else
            {
                throw new FormatException("RIFF header not found.");
            }

            return(headerSize);
        }
Ejemplo n.º 19
0
        public static long GetDataStartOffsetFromRiffHeader(Stream inputStream)
        {
            long dataOffset = 0;

            long riffHeaderLocation = ParseFile.GetNextOffset(inputStream, 0, Constants.RiffHeaderBytes);

            if (riffHeaderLocation > -1)
            {
                long waveChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                 riffHeaderLocation + Constants.RiffHeaderBytes.Length, Constants.RiffWaveBytes);

                if (waveChunkLocation > -1)
                {
                    long dataChunkLocation = ParseFile.GetNextOffset(inputStream,
                                                                     waveChunkLocation + Constants.RiffWaveBytes.Length, Constants.RiffDataBytes);

                    if (dataChunkLocation > -1)
                    {
                        dataOffset = dataChunkLocation + 8;
                    }
                    else
                    {
                        throw new FormatException("RIFF header data chunk not found.");
                    }
                }
                else
                {
                    throw new FormatException("RIFF header WAVE chunk not found.");
                }
            }
            else
            {
                throw new FormatException("RIFF header not found.");
            }

            return(dataOffset);
        }
Ejemplo n.º 20
0
        public virtual void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxOptions)
        {
            long currentOffset = 0;
            long fileSize;

            long blockSize;
            long videoChunkSize;

            Dictionary <uint, FileStream> streamOutputWriters = new Dictionary <uint, FileStream>();

            ChunkStruct currentChunk = new ChunkStruct();

            ChunkStruct[] audioChunks;

            try
            {
                using (FileStream fs = File.OpenRead(this.FilePath))
                {
                    this.ReadHeader(fs, currentOffset);

                    fileSize      = fs.Length;
                    currentOffset = ParseFile.GetNextOffset(fs, currentOffset, DataStartBytes) + 4;

                    while (currentOffset < fileSize)
                    {
                        if (currentOffset == 0x4C7DC)
                        {
                        }

                        blockSize = this.GetBlockSize(fs, currentOffset);

                        if (blockSize > 0)
                        {
                            // write video block to stream
                            currentChunk = this.GetVideoChunk(fs, currentOffset);

                            if (demuxOptions.ExtractVideo && (currentChunk.Chunk != null))
                            {
                                this.writeChunkToStream(currentChunk.Chunk, currentChunk.ChunkId, streamOutputWriters, this.FileExtensionVideo);
                            }
                            // NDS -- currentBlockId = (uint)(BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, currentOffset, 2), 0) & 0x00FF);


                            // write audio block to stream
                            if (demuxOptions.ExtractAudio && (this.AudioStreamCount > 0))
                            {
                                videoChunkSize = currentChunk.Chunk == null ? 0 : currentChunk.Chunk.Length;
                                audioChunks    = this.GetAudioChunk(fs, currentOffset, blockSize, videoChunkSize);

                                for (uint i = 0; i < this.AudioStreamCount; i++)
                                {
                                    if (audioChunks[i].Chunk != null)
                                    {
                                        this.writeChunkToStream(audioChunks[i].Chunk, audioChunks[i].ChunkId, streamOutputWriters, this.FileExtensionAudio);
                                    }
                                }
                            }

                            // move offset
                            currentOffset += blockSize;
                        }
                        else
                        {
                            break;
                        }
                    }
                } // using (FileStream fs = File.OpenRead(this.FilePath))
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("Exception processing block at offset 0x{0}: {1}{2}", currentOffset.ToString("X"), ex.Message, Environment.NewLine));
            }
            finally
            {
                // clean up
                this.DoFinalTasks(streamOutputWriters, demuxOptions);
            }
        }
Ejemplo n.º 21
0
        public virtual void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxOptions)
        {
            long currentOffset = -1;
            long fileSize;

            byte[] chunkId;
            byte[] fullChunk;
            uint   chunkSize = 0;

            long mvhdOffset = -1;
            long schlOffset = -1;
            long shenOffset = -1;

            Dictionary <string, FileStream> streamWriters = new Dictionary <string, FileStream>();

            try
            {
                using (FileStream fs = File.OpenRead(this.FilePath))
                {
                    fileSize = fs.Length;

                    // find header first header (audio or video)
                    mvhdOffset = ParseFile.GetNextOffset(fs, 0, ElectronicArtsVp6Stream.MVHD_BYTES);

                    if (mvhdOffset == 0) // video header comes first
                    {
                        currentOffset = mvhdOffset;
                    }
                    else // audio header comes first
                    {
                        schlOffset = ParseFile.GetNextOffset(fs, 0, ElectronicArtsVp6Stream.SCHl_BYTES);

                        if ((schlOffset > -1) && (schlOffset < mvhdOffset))
                        {
                            currentOffset = schlOffset;
                        }
                        else
                        {
                            shenOffset = ParseFile.GetNextOffset(fs, 0, ElectronicArtsVp6Stream.SHEN_BYTES);

                            if ((shenOffset > -1) && (shenOffset < mvhdOffset))
                            {
                                currentOffset = shenOffset;
                            }
                        }
                    }

                    // verify headers found
                    if (mvhdOffset >= 0)
                    {
                        if (currentOffset >= 0)
                        {
                            // process file
                            while (currentOffset < fileSize)
                            {
                                // get chunk
                                chunkId = ParseFile.ParseSimpleOffset(fs, currentOffset, 4);

                                // get chunk size
                                chunkSize = (uint)BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, currentOffset + 4, 4), 0);

                                // audio chunk
                                if (demuxOptions.ExtractAudio && this.IsThisAnAudioBlock(chunkId))
                                {
                                    fullChunk = ParseFile.ParseSimpleOffset(fs, currentOffset, (int)chunkSize);
                                    this.writeChunkToStream(fullChunk, "audio", streamWriters, this.FileExtensionAudio);
                                }

                                // video chunk
                                if (demuxOptions.ExtractVideo && this.IsThisAVideoBlock(chunkId))
                                {
                                    fullChunk = ParseFile.ParseSimpleOffset(fs, currentOffset, (int)chunkSize);
                                    this.writeChunkToStream(fullChunk, "video", streamWriters, this.FileExtensionVideo);
                                }

                                // unknown chunk
                                if (!this.IsThisAnAudioBlock(chunkId) && !this.IsThisAVideoBlock(chunkId))
                                {
                                    fullChunk = ParseFile.ParseSimpleOffset(fs, currentOffset, (int)chunkSize);
                                    this.writeChunkToStream(fullChunk, "unknown", streamWriters, ".bin");
                                }

                                // move to next chunk
                                currentOffset += (long)chunkSize;
                            }
                        }
                        else
                        {
                            throw new Exception(String.Format("Cannot find MVHD, SCHl, or SHEN headers.{0}", Environment.NewLine));
                        }
                    }
                    else
                    {
                        throw new Exception(String.Format("Cannot find MVHD header.{0}", Environment.NewLine));
                    } // if (mvhdOffset >= 0)
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                this.DoFinalTasks(streamWriters);
            }
        }
Ejemplo n.º 22
0
        public virtual Dictionary <string, byte[]> DemultiplexStreams(DemuxOptionsStruct demuxOptions)
        {
            using (FileStream fs = File.OpenRead(this.FilePath))
            {
                long fileSize      = fs.Length;
                long currentOffset = 0;

                byte[] currentBlockId;
                uint   currentBlockIdVal;
                byte[] currentBlockIdNaming;

                BlockSizeStruct blockStruct = new BlockSizeStruct();
                byte[]          blockSizeArray;
                uint            blockSize;

                int audioBlockSkipSize;
                int videoBlockSkipSize;

                int audioBlockFooterSize;
                int videoBlockFooterSize;

                int cutSize;

                bool eofFlagFound = false;

                Dictionary <uint, MemoryStream> streamOutputWriters = new Dictionary <uint, MemoryStream>();
                Dictionary <uint, string>       FilenameTable       = new Dictionary <uint, string>();

                string outputFileName;

                byte   streamId = 0;     // for types that have multiple streams in the same block ID
                uint   currentStreamKey; // hash key for each file
                bool   isAudioBlock;
                string audioFileExtension;

                // look for first packet
                currentOffset = this.GetStartOffset(fs, currentOffset);
                currentOffset = ParseFile.GetNextOffset(fs, currentOffset, this.GetPacketStartBytes());

                if (currentOffset != -1)
                {
                    while (currentOffset < fileSize)
                    {
                        try
                        {
                            // get the current block
                            currentBlockId = ParseFile.ParseSimpleOffset(fs, currentOffset, 4);

                            // get value to use as key to hash table
                            currentBlockIdVal = BitConverter.ToUInt32(currentBlockId, 0);

                            if (BlockIdDictionary.ContainsKey(currentBlockIdVal))
                            {
                                // get info about this block type
                                blockStruct = BlockIdDictionary[currentBlockIdVal];

                                switch (blockStruct.SizeType)
                                {
                                /////////////////////
                                // Static Block Size
                                /////////////////////
                                case PacketSizeType.Static:
                                    currentOffset += blockStruct.Size;     // skip this block
                                    break;

                                //////////////////
                                // End of Stream
                                //////////////////
                                case PacketSizeType.Eof:
                                    eofFlagFound = true;     // set EOF block found so we can exit the loop
                                    break;

                                //////////////////////
                                // Varying Block Size
                                //////////////////////
                                case PacketSizeType.SizeBytes:

                                    // Get the block size
                                    blockSizeArray = ParseFile.ParseSimpleOffset(fs, currentOffset + currentBlockId.Length, blockStruct.Size);

                                    if (!this.BlockSizeIsLittleEndian)
                                    {
                                        Array.Reverse(blockSizeArray);
                                    }

                                    switch (blockStruct.Size)
                                    {
                                    case 4:
                                        blockSize = (uint)BitConverter.ToUInt32(blockSizeArray, 0);
                                        break;

                                    case 2:
                                        blockSize = (uint)BitConverter.ToUInt16(blockSizeArray, 0);
                                        break;

                                    case 1:
                                        blockSize = (uint)blockSizeArray[0];
                                        break;

                                    default:
                                        throw new ArgumentOutOfRangeException(String.Format("Unhandled size block size.{0}", Environment.NewLine));
                                    }


                                    // if block type is audio or video, extract it
                                    isAudioBlock = this.IsThisAnAudioBlock(currentBlockId);

                                    if ((demuxOptions.ExtractAudio && isAudioBlock) ||
                                        (demuxOptions.ExtractVideo && this.IsThisAVideoBlock(currentBlockId)))
                                    {
                                        // reset stream id
                                        streamId = 0;

                                        // if audio block, get the stream number from the queue
                                        if (isAudioBlock && this.UsesSameIdForMultipleAudioTracks)
                                        {
                                            streamId         = this.GetStreamId(fs, currentOffset);
                                            currentStreamKey = (streamId | currentBlockIdVal);
                                        }
                                        else
                                        {
                                            currentStreamKey = currentBlockIdVal;
                                        }

                                        // check if we've already started parsing this stream
                                        if (!streamOutputWriters.ContainsKey(currentStreamKey))
                                        {
                                            // convert block id to little endian for naming
                                            currentBlockIdNaming = BitConverter.GetBytes(currentStreamKey);
                                            Array.Reverse(currentBlockIdNaming);

                                            // build output file name
                                            outputFileName = Path.GetFileNameWithoutExtension(this.FilePath);
                                            outputFileName = outputFileName + "_" + BitConverter.ToUInt32(currentBlockIdNaming, 0).ToString("X8");

                                            // add proper extension
                                            if (this.IsThisAnAudioBlock(currentBlockId))
                                            {
                                                audioFileExtension = this.GetAudioFileExtension(fs, currentOffset);
                                                outputFileName    += audioFileExtension;

                                                if (!this.StreamIdFileType.ContainsKey(streamId))
                                                {
                                                    this.StreamIdFileType.Add(streamId, audioFileExtension);
                                                }
                                            }
                                            else
                                            {
                                                this.FileExtensionVideo = this.GetVideoFileExtension(fs, currentOffset);
                                                outputFileName         += this.FileExtensionVideo;
                                            }

                                            // add output directory
                                            FilenameTable[currentStreamKey] = outputFileName;
                                            // add an output stream for writing
                                            streamOutputWriters[currentStreamKey] = new MemoryStream();
                                        }

                                        // write the block
                                        if (this.IsThisAnAudioBlock(currentBlockId))
                                        {
                                            // write audio
                                            audioBlockSkipSize   = this.GetAudioPacketHeaderSize(fs, currentOffset) + GetAudioPacketSubHeaderSize(fs, currentOffset, streamId);
                                            audioBlockFooterSize = this.GetAudioPacketFooterSize(fs, currentOffset);
                                            cutSize = (int)(blockSize - audioBlockSkipSize - audioBlockFooterSize);
                                            if (cutSize > 0)
                                            {
                                                streamOutputWriters[currentStreamKey].Write(ParseFile.ParseSimpleOffset(fs, currentOffset + currentBlockId.Length + blockSizeArray.Length + audioBlockSkipSize, (int)(blockSize - audioBlockSkipSize)), 0, cutSize);
                                            }
                                        }
                                        else
                                        {
                                            // write video
                                            videoBlockSkipSize   = this.GetVideoPacketHeaderSize(fs, currentOffset);
                                            videoBlockFooterSize = this.GetVideoPacketFooterSize(fs, currentOffset);
                                            cutSize = (int)(blockSize - videoBlockSkipSize - videoBlockFooterSize);
                                            if (cutSize > 0)
                                            {
                                                streamOutputWriters[currentStreamKey].Write(ParseFile.ParseSimpleOffset(fs, currentOffset + currentBlockId.Length + blockSizeArray.Length + videoBlockSkipSize, (int)(blockSize - videoBlockSkipSize)), 0, cutSize);
                                            }
                                        }
                                    }

                                    // move to next block
                                    currentOffset += currentBlockId.Length + blockSizeArray.Length + blockSize;
                                    blockSizeArray = new byte[] { };
                                    break;

                                default:
                                    break;
                                }
                            }
                            else // this is an undexpected block type
                            {
                                this.CloseAllWriters(streamOutputWriters);
                                Array.Reverse(currentBlockId);
                                throw new FormatException(String.Format("Block ID at 0x{0} not found in table: 0x{1}", currentOffset.ToString("X8"), BitConverter.ToUInt32(currentBlockId, 0).ToString("X8")));
                            }

                            // exit loop if EOF block found
                            if (eofFlagFound)
                            {
                                break;
                            }
                        }
                        catch (Exception _ex)
                        {
                            this.CloseAllWriters(streamOutputWriters);
                            throw new Exception(String.Format("Error parsing file at offset {0), '{1}'", currentOffset.ToString("X8"), _ex.Message), _ex);
                        }
                    } // while (currentOffset < fileSize)
                }
                else
                {
                    this.CloseAllWriters(streamOutputWriters);
                    throw new FormatException(String.Format("Cannot find Pack Header for file: {0}{1}", Path.GetFileName(this.FilePath), Environment.NewLine));
                }
                return(this.DoFinalTasks(fs, FilenameTable, streamOutputWriters, demuxOptions.AddHeader));
            }
        }
Ejemplo n.º 23
0
        public virtual void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxOptions)
        {
            long currentOffset = 0;
            long packetOffset  = 0;
            long packetSize;
            long fileSize;

            Dictionary <uint, FileStream> streamOutputWriters = new Dictionary <uint, FileStream>();

            Guid  checkGuid;
            ulong blockSize;

            try
            {
                using (FileStream fs = File.OpenRead(this.FilePath))
                {
                    fileSize      = fs.Length;
                    currentOffset = 0;

                    currentOffset = ParseFile.GetNextOffset(fs, 0, MicrosoftAsfContainer.ASF_HEADER_BYTES);

                    if (currentOffset > -1)
                    {
                        while (currentOffset < fileSize)
                        {
                            // get guid
                            checkGuid = new Guid(ParseFile.ParseSimpleOffset(fs, currentOffset, 0x10));
                            blockSize = BitConverter.ToUInt64(ParseFile.ParseSimpleOffset(fs, (currentOffset + 0x10), 8), 0);

                            // process block
                            if (checkGuid.Equals(MicrosoftAsfContainer.ASF_Header_Object))
                            {
                                // parse header
                                this.parseHeader(fs, currentOffset);
                            }
                            else if (checkGuid.Equals(MicrosoftAsfContainer.ASF_Data_Object))
                            {
                                // parse data object
                                this.DataObject = this.parseDataObject(fs, currentOffset);

                                // process data packets
                                packetOffset = currentOffset + 0x32; // header has been parsed

                                for (ulong i = 0; i < this.DataObject.TotalDataPackets; i++)
                                {
                                    // parse packet
                                    try
                                    {
                                        packetSize = this.parseDataPacket(fs, packetOffset, demuxOptions);

                                        // move to next packet
                                        if (packetSize < 0)
                                        {
                                            throw new Exception(String.Format("Error parsing data packet at offset 0x{0}.", packetOffset.ToString("X8")));
                                        }
                                        else
                                        {
                                            packetOffset += packetSize;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        throw new Exception(String.Format("Error parsing data packet at offset 0x{0}: {1}.{2}", packetOffset.ToString("X8"), ex.Message, Environment.NewLine));
                                    }
                                }
                            }

                            // increment counter
                            currentOffset += (long)blockSize;
                        } // while
                    }
                    else
                    {
                        throw new Exception(String.Format("ASF/WMV Header not found.{0}", Environment.NewLine));
                    }
                } // using (FileStream fs = File.OpenRead(this.FilePath))
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("Exception processing block at offset 0x{0}: {1}{2}", currentOffset.ToString("X"), ex.Message, Environment.NewLine));
            }
            finally
            {
                // clean up
                this.DoFinalTasks(demuxOptions);
            }
        }
Ejemplo n.º 24
0
        public static void ExtractXaFiles(ExtractXaStruct pExtractXaStruct)
        {
            Dictionary <UInt32, CdxaWriterStruct> bwDictionary = new Dictionary <UInt32, CdxaWriterStruct>();
            List <UInt32> bwKeys;

            long offset;

            byte[] trackId;
            byte[] buffer = new byte[Cdxa.XA_BLOCK_SIZE];
            UInt32 trackKey;

            byte[] tempTrackId;
            UInt32 tempTrackKey;

            long previousOffset;
            long distanceBetweenBlocks;
            long distanceCeiling = EMPTY_BLOCK_OFFSET_FLAG;
            Dictionary <long, int> distanceFrequency = new Dictionary <long, int>();

            CdxaWriterStruct workingStruct = new CdxaWriterStruct();

            string outputFileName;
            string outputDirectory = Path.Combine(Path.GetDirectoryName(pExtractXaStruct.Path),
                                                  Path.GetFileNameWithoutExtension(pExtractXaStruct.Path));

            int  totalPasses = 1;
            bool doFileWrite = false;

            if (pExtractXaStruct.DoTwoPass)
            {
                totalPasses = 2;
            }

            using (FileStream fs = File.OpenRead(pExtractXaStruct.Path))
            {
                for (int currentPass = 1; currentPass <= totalPasses; currentPass++)
                {
                    // turn on write flag
                    if (currentPass == totalPasses)
                    {
                        doFileWrite = true;
                    }

                    // get first offset to start the party
                    offset = ParseFile.GetNextOffset(fs, 0, Cdxa.XA_SIG);

                    if (offset != -1) // we have found an XA sig
                    {
                        if (!Directory.Exists(outputDirectory))
                        {
                            Directory.CreateDirectory(outputDirectory);
                        }

                        while ((offset != -1) && ((offset + Cdxa.XA_BLOCK_SIZE) <= fs.Length))
                        {
                            trackId  = ParseFile.ParseSimpleOffset(fs, offset + Cdxa.XA_TRACK_OFFSET, Cdxa.XA_TRACK_SIZE);
                            trackKey = GetTrackKey(trackId);
                            //trackKey = ParseFile.ReadUintBE(fs, offset + Cdxa.XA_TRACK_OFFSET) & 0xFFFF0000;

                            if (pExtractXaStruct.UseEndOfTrackMarkerForEof &&
                                (
                                    ((trackId[2] & Cdxa.XA_END_OF_TRACK_MARKER) == Cdxa.XA_END_OF_TRACK_MARKER) ||
                                    ((trackId[2] & Cdxa.XA_END_OF_AUDIO_MARKER) == Cdxa.XA_END_OF_AUDIO_MARKER)
                                ))
                            {
                                // close the track
                                tempTrackId    = trackId;
                                tempTrackId[2] = Cdxa.XA_CHUNK_ID_DIGITS;
                                tempTrackKey   = GetTrackKey(tempTrackId);

                                if (bwDictionary.ContainsKey(tempTrackKey))
                                {
                                    // close up this file, we're done.
                                    if (doFileWrite)
                                    {
                                        // write the block
                                        // set offset, doing this way because of boxing issues
                                        workingStruct = bwDictionary[tempTrackKey];
                                        workingStruct.CurrentChunkOffset = offset;
                                        bwDictionary[tempTrackKey]       = workingStruct;

                                        // get the next block
                                        buffer = ParseFile.ParseSimpleOffset(fs, offset, Cdxa.XA_BLOCK_SIZE);

                                        // patch if needed
                                        if (pExtractXaStruct.PatchByte0x11)
                                        {
                                            buffer[0x11] = 0x00;
                                        }

                                        // write the block
                                        bwDictionary[tempTrackKey].FileWriter.Write(buffer, 0, buffer.Length);

                                        // set flag that a non-silent block was found
                                        if (!bwDictionary[tempTrackKey].NonSilentBlockDetected)
                                        {
                                            // doing this way because of boxing issues
                                            workingStruct = bwDictionary[tempTrackKey];
                                            workingStruct.NonSilentBlockDetected = true;
                                            bwDictionary[tempTrackKey]           = workingStruct;
                                        }

                                        FixHeaderAndCloseWriter(bwDictionary[tempTrackKey].FileWriter, pExtractXaStruct,
                                                                bwDictionary[tempTrackKey].NonSilentBlockDetected);
                                    }

                                    bwDictionary.Remove(tempTrackKey);
                                }

                                offset += Cdxa.XA_BLOCK_SIZE;
                            }
                            else if ((pExtractXaStruct.FilterAgainstBlockId) &&
                                     ((trackId[2] & 0x0F) != Cdxa.XA_AUDIO_MASK))
                            {
                                offset = ParseFile.GetNextOffset(fs, offset + 1, Cdxa.XA_SIG);
                            }
                            else
                            {
                                // check distance between blocks for possible split
                                if ((doFileWrite) &&
                                    (bwDictionary.ContainsKey(trackKey)) &&
                                    (distanceCeiling != EMPTY_BLOCK_OFFSET_FLAG) &&
                                    (bwDictionary[trackKey].CurrentChunkOffset != EMPTY_BLOCK_OFFSET_FLAG))
                                {
                                    previousOffset        = bwDictionary[trackKey].CurrentChunkOffset;
                                    distanceBetweenBlocks = offset - previousOffset;

                                    if (distanceBetweenBlocks > distanceCeiling)
                                    {
                                        // close up this file, we're done.
                                        FixHeaderAndCloseWriter(bwDictionary[trackKey].FileWriter, pExtractXaStruct,
                                                                bwDictionary[trackKey].NonSilentBlockDetected);
                                        bwDictionary.Remove(trackKey);
                                    }
                                }

                                // First Block only
                                if (!bwDictionary.ContainsKey(trackKey))
                                {
                                    outputFileName = GetOutputFileName(pExtractXaStruct, trackId);
                                    workingStruct  = new CdxaWriterStruct();
                                    workingStruct.CurrentChunkOffset     = EMPTY_BLOCK_OFFSET_FLAG;
                                    workingStruct.NonSilentBlockDetected = false;

                                    if (doFileWrite)
                                    {
                                        workingStruct.FileWriter = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite);
                                    }

                                    bwDictionary.Add(trackKey, workingStruct);

                                    if (doFileWrite && pExtractXaStruct.AddRiffHeader)
                                    {
                                        bwDictionary[trackKey].FileWriter.Write(Cdxa.XA_RIFF_HEADER, 0, Cdxa.XA_RIFF_HEADER.Length);
                                    }
                                }

                                // calculate distance between blocks for possible split
                                if ((!doFileWrite) &&
                                    (bwDictionary[trackKey].CurrentChunkOffset != EMPTY_BLOCK_OFFSET_FLAG))
                                {
                                    previousOffset        = bwDictionary[trackKey].CurrentChunkOffset;
                                    distanceBetweenBlocks = offset - previousOffset;

                                    if (!distanceFrequency.ContainsKey(distanceBetweenBlocks))
                                    {
                                        distanceFrequency.Add(distanceBetweenBlocks, 1);
                                    }
                                    else
                                    {
                                        distanceFrequency[distanceBetweenBlocks]++;
                                    }
                                }

                                // set offset, doing this way because of boxing issues
                                workingStruct = bwDictionary[trackKey];
                                workingStruct.CurrentChunkOffset = offset;
                                bwDictionary[trackKey]           = workingStruct;

                                // get the next block
                                buffer = ParseFile.ParseSimpleOffset(fs, offset, Cdxa.XA_BLOCK_SIZE);

                                // check if this is a "silent" block
                                if ((pExtractXaStruct.UseSilentBlocksForEof) && IsSilentBlock(buffer, pExtractXaStruct))
                                {
                                    if (doFileWrite)
                                    {
                                        // close up this file, we're done.
                                        FixHeaderAndCloseWriter(bwDictionary[trackKey].FileWriter, pExtractXaStruct,
                                                                bwDictionary[trackKey].NonSilentBlockDetected);
                                    }

                                    bwDictionary.Remove(trackKey);
                                }
                                else if (doFileWrite)
                                {
                                    // patch if needed
                                    if (pExtractXaStruct.PatchByte0x11)
                                    {
                                        buffer[0x11] = 0x00;
                                    }

                                    // write the block
                                    bwDictionary[trackKey].FileWriter.Write(buffer, 0, buffer.Length);

                                    // set flag that a non-silent block was found
                                    if (!bwDictionary[trackKey].NonSilentBlockDetected)
                                    {
                                        // doing this way because of boxing issues
                                        workingStruct = bwDictionary[trackKey];
                                        workingStruct.NonSilentBlockDetected = true;
                                        bwDictionary[trackKey] = workingStruct;
                                    }
                                }

                                offset += Cdxa.XA_BLOCK_SIZE;
                            }
                        }

                        // fix header and close writers
                        bwKeys = new List <UInt32>(bwDictionary.Keys);
                        foreach (UInt32 keyname in bwKeys)
                        {
                            if (doFileWrite)
                            {
                                FixHeaderAndCloseWriter(bwDictionary[keyname].FileWriter, pExtractXaStruct,
                                                        bwDictionary[keyname].NonSilentBlockDetected);
                            }

                            bwDictionary.Remove(keyname);
                        }

                        // get statistical mode of distance between blocks
                        if (!doFileWrite)
                        {
                            distanceCeiling = GetDistanceCeiling(distanceFrequency);
                        }
                    }
                    else
                    {
                        // no CD-XA found
                        break;
                    }
                }
            }
        }
Ejemplo n.º 25
0
        public void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxOptions)
        {
            long currentOffset = 0;
            uint frameCount    = 1;
            uint nextFrameSize;

            byte[] currentFrame;

            byte[] videoChunkSizeBytes = null;
            uint   videoChunkSize;

            byte[] audioChunkSizeBytes = null;
            uint   audioChunkSize;
            long   dataStart;

            byte[] videoChunk;
            byte[] audioChunk;

            // bool isAudioHeaderWritten = false;
            Dictionary <string, bool> isAudioHeaderWritten = new Dictionary <string, bool>();
            bool isVideoHeaderWritten = false;

            byte[] thpHeader;
            byte[] firstFrameSize;
            long   headerLocation;

            uint previousFrameSizeVideo = 0;
            uint previousFrameSizeAudio = 0;
            uint nextFrameSizeVideo;
            uint nextFrameSizeAudio;

            byte[] previousFrameSizeBytes;
            byte[] nextFrameSizeBytes;

            uint totalDataSize = 0;

            byte[] totalDataSizeBytes;

            byte[] fourEmptyBytes = new byte[] { 0x00, 0x00, 0x00, 0x00 };

            long videoFrameOffset = 0;
            long audioFrameOffset = 0;

            byte[] lastOffsetBytes;

            string audioStreamHashKey;

            byte[] bigEndianOne = new byte[] { 0x00, 0x00, 0x00, 0x01 };

            Dictionary <string, FileStream> streamWriters = new Dictionary <string, FileStream>();

            try
            {
                using (FileStream fs = File.OpenRead(this.FilePath))
                {
                    headerLocation = ParseFile.GetNextOffset(fs, currentOffset, MAGIC_BYTES);
                    currentOffset  = headerLocation;

                    if (currentOffset > -1)
                    {
                        // read header
                        this.ReadHeader(fs, currentOffset);
                        nextFrameSize = this.FirstFrameSize;

                        // get component info
                        this.ParseComponents(fs);

                        // process frames
                        currentOffset = this.FirstFrameOffset;

                        while (currentOffset <= this.LastFrameOffset)
                        {
                            // read frame
                            currentFrame = ParseFile.ParseSimpleOffset(fs, (long)currentOffset, (int)nextFrameSize);

                            // get size of next frame
                            nextFrameSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(currentFrame, 0, 4));

                            // get size of next audio/video frame (for writing output frame headers)
                            if (frameCount < this.NumberOfFrames)
                            {
                                nextFrameSizeVideo = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, currentOffset + currentFrame.Length + 8, 4));
                                nextFrameSizeAudio = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, currentOffset + currentFrame.Length + 0xC, 4));
                            }
                            else
                            {
                                nextFrameSizeVideo = 0;
                                nextFrameSizeAudio = 0;
                            }

                            videoChunkSizeBytes = ParseFile.ParseSimpleOffset(currentFrame, 8, 4);
                            videoChunkSize      = ByteConversion.GetUInt32BigEndian(videoChunkSizeBytes);

                            if (this.ContainsAudio)
                            {
                                audioChunkSizeBytes = ParseFile.ParseSimpleOffset(currentFrame, 0xC, 4);
                                audioChunkSize      = ByteConversion.GetUInt32BigEndian(audioChunkSizeBytes);
                                dataStart           = 0x10;
                            }
                            else
                            {
                                audioChunkSize = 0;
                                dataStart      = 0xC;
                            }

                            #region WRITE VIDEO
                            ///////////////
                            // write video
                            ///////////////
                            if (demuxOptions.ExtractVideo)
                            {
                                if (streamWriters.ContainsKey("video"))
                                {
                                    videoFrameOffset = streamWriters["video"].Length;
                                }

                                // attach THP header
                                if (!isVideoHeaderWritten)
                                {
                                    // get original header
                                    thpHeader = ParseFile.ParseSimpleOffset(fs, headerLocation, (int)(fs.Length - this.DataSize));

                                    // clean out audio info
                                    thpHeader = this.RemoveAudioInfoFromThpHeader(thpHeader);

                                    // update first frame size in header
                                    firstFrameSize = ByteConversion.GetBytesBigEndian((uint)(videoChunkSize + 0xC));
                                    Array.Copy(firstFrameSize, 0, thpHeader, 0x18, 4);

                                    // write updated header
                                    this.writeChunkToStream(thpHeader, "video", streamWriters, this.FileExtensionVideo);
                                    isVideoHeaderWritten = true;
                                }

                                // add frame header

                                // write next frame size
                                nextFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(nextFrameSizeVideo + 0xC));
                                this.writeChunkToStream(nextFrameSizeBytes, "video", streamWriters, this.FileExtensionVideo);

                                // write previous frame size
                                previousFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(previousFrameSizeVideo + 0xC));
                                this.writeChunkToStream(nextFrameSizeBytes, "video", streamWriters, this.FileExtensionVideo);

                                // write video size
                                this.writeChunkToStream(videoChunkSizeBytes, "video", streamWriters, this.FileExtensionVideo);

                                // write data
                                videoChunk = ParseFile.ParseSimpleOffset(currentFrame, (int)dataStart, (int)videoChunkSize);
                                this.writeChunkToStream(videoChunk, "video", streamWriters, this.FileExtensionVideo);

                                // save previous bytes for next frame
                                previousFrameSizeVideo = videoChunkSize;
                            }
                            #endregion

                            #region WRITE AUDIO
                            ///////////////
                            // write audio
                            ///////////////
                            if (demuxOptions.ExtractAudio && this.ContainsAudio)
                            {
                                //if (this.NumberOfAudioBlocksPerFrame > 1)
                                //{
                                //    int x = 1;
                                //}

                                // add blocks
                                for (int i = 0; i < this.NumberOfAudioBlocksPerFrame; i++)
                                {
                                    audioStreamHashKey = String.Format("track_{0}", i.ToString("D2"));

                                    // write file header
                                    if (streamWriters.ContainsKey(audioStreamHashKey))
                                    {
                                        audioFrameOffset = streamWriters[audioStreamHashKey].Position;
                                    }

                                    // attach THP header
                                    if (!isAudioHeaderWritten.ContainsKey(audioStreamHashKey) ||
                                        isAudioHeaderWritten[audioStreamHashKey] == false)
                                    {
                                        // get original header
                                        thpHeader = ParseFile.ParseSimpleOffset(fs, headerLocation, (int)(fs.Length - this.DataSize));

                                        // clean out video info
                                        thpHeader = this.RemoveVideoInfoFromThpHeader(thpHeader);

                                        // update first frame size in header
                                        firstFrameSize = ByteConversion.GetBytesBigEndian((uint)(audioChunkSize + 0x10));
                                        Array.Copy(firstFrameSize, 0, thpHeader, 0x18, 4);

                                        // set NumberOfAudioBlocksPerFrame to 1
                                        Array.Copy(bigEndianOne, 0, thpHeader, 0x50, 4);

                                        // write updated header
                                        this.writeChunkToStream(thpHeader, audioStreamHashKey, streamWriters, this.FileExtensionAudio);
                                        isAudioHeaderWritten.Add(audioStreamHashKey, true);
                                    }

                                    //////////////////////
                                    // write frame header
                                    //////////////////////

                                    // write next frame size
                                    nextFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(nextFrameSizeAudio + 0x10));
                                    this.writeChunkToStream(nextFrameSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio);

                                    // write previous frame size
                                    previousFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(previousFrameSizeAudio + 0x10));
                                    this.writeChunkToStream(nextFrameSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio);

                                    // write video size (zero)
                                    this.writeChunkToStream(fourEmptyBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio);

                                    // write audio size for this frame
                                    this.writeChunkToStream(audioChunkSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio);

                                    // write chunk
                                    audioChunk = ParseFile.ParseSimpleOffset(currentFrame, (int)(dataStart + videoChunkSize + (i * audioChunkSize)), (int)audioChunkSize);
                                    this.writeChunkToStream(audioChunk, audioStreamHashKey, streamWriters, this.FileExtensionAudio);

                                    // set previous frame size for next frame
                                    previousFrameSizeAudio = audioChunkSize;
                                }
                            }
                            #endregion

                            // increment offset and frame counter
                            currentOffset += currentFrame.Length;
                            frameCount++;
                        }

                        // fix headers as needed

                        // data size
                        foreach (string key in streamWriters.Keys)
                        {
                            totalDataSize      = (uint)(streamWriters[key].Length - this.FirstFrameOffset);
                            totalDataSizeBytes = ByteConversion.GetBytesBigEndian(totalDataSize);

                            streamWriters[key].Position = 0x1C;
                            streamWriters[key].Write(totalDataSizeBytes, 0, 4);
                        }

                        // frame offsets
                        for (int i = 0; i < this.NumberOfAudioBlocksPerFrame; i++)
                        {
                            audioStreamHashKey = String.Format("audio_{0}", i.ToString("DD"));

                            if (streamWriters.ContainsKey(audioStreamHashKey))
                            {
                                lastOffsetBytes = ByteConversion.GetBytesBigEndian((uint)audioFrameOffset);

                                streamWriters[audioStreamHashKey].Position = 0x2C;
                                streamWriters[audioStreamHashKey].Write(lastOffsetBytes, 0, 4);
                            }
                        }

                        if (streamWriters.ContainsKey("video"))
                        {
                            lastOffsetBytes = ByteConversion.GetBytesBigEndian((uint)videoFrameOffset);

                            streamWriters["video"].Position = 0x2C;
                            streamWriters["video"].Write(lastOffsetBytes, 0, 4);
                        }
                    }
                    else
                    {
                        throw new FormatException("Cannot find THP header.");
                    }
                } // using (FileStream fs = File.OpenRead(this.FilePath))
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            finally
            {
                foreach (string key in streamWriters.Keys)
                {
                    // close writers
                    if (streamWriters[key] != null &&
                        streamWriters[key].CanWrite)
                    {
                        streamWriters[key].Close();
                        streamWriters[key].Dispose();
                    }
                }
            }
        }
Ejemplo n.º 26
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pPsfDataFinderStruct, DoWorkEventArgs e)
        {
            PsfDataFinderStruct psfStruct = (PsfDataFinderStruct)pPsfDataFinderStruct;

            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = String.Format("[{0}]{1}", pPath, Environment.NewLine);
            this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

            long offset;

            string    seqName;
            int       seqNumber = 0;
            ArrayList seqFiles  = new ArrayList();
            bool      seqNamingMessageDisplayed = false;

            string    sepName;
            int       sepNumber = 0;
            ArrayList sepFiles  = new ArrayList();
            bool      sepNamingMessageDisplayed = false;

            int vhNumber      = 0;
            int minSampleSize = -1;
            int maxSampleSize = -1;
            int minRowLength;

            VhStruct  vhObject;
            long      sampleOffset;
            ArrayList vhArrayList = new ArrayList();

            ArrayList        emptyRowList = new ArrayList();
            ProbableVbStruct potentialVb;

            ProbableVbStruct[] potentialVbList;
            byte[]             vbRow = new byte[0x10];
            long previousVbOffset    = -1;

            // improve algorithm later
            using (FileStream fs = File.OpenRead(pPath))
            {
                string destinationFolder = Path.Combine(Path.GetDirectoryName(pPath), Path.GetFileNameWithoutExtension(pPath));

                // get VH files
                #region VH EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting VH{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                offset = 0;

                while ((offset = ParseFile.GetNextOffset(fs, offset, XsfUtil.VAB_SIGNATURE)) > -1)
                {
                    vhObject                = new VhStruct();
                    vhObject.FileName       = String.Format("{0}_{1}.VH", Path.GetFileNameWithoutExtension(pPath), vhNumber++.ToString("X4"));
                    vhObject.startingOffset = offset;
                    vhObject.vhProgramCount = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, (offset + 0x12), 2), 0);
                    vhObject.vbSampleCount  = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, (offset + 0x16), 2), 0);
                    vhObject.vbSampleSizes  = new uint[vhObject.vbSampleCount];
                    vhObject.length         = 2592 + (512 * vhObject.vhProgramCount);

                    vhObject.vabSize          = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4), 0);
                    vhObject.expectedVbLength = vhObject.vabSize - vhObject.length;

                    vhObject.offsetTableOffset    = offset + (512 * vhObject.vhProgramCount) + 2080;
                    vhObject.offsetTableOffset   += 2; // not sure but seems to be needed
                    vhObject.IsSmallSamplePresent = false;
                    vhObject.HasHeaderMismatch    = false;

                    for (int i = 0; i < vhObject.vbSampleCount; i++)
                    {
                        sampleOffset = vhObject.offsetTableOffset + (i * 2);
                        vhObject.vbSampleSizes[i]          = (uint)BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(fs, sampleOffset, 2), 0);
                        vhObject.vbSampleSizes[i]        <<= 3;
                        vhObject.expectedVbLengthBySample += vhObject.vbSampleSizes[i];

                        if ((minSampleSize < 0) || (vhObject.vbSampleSizes[i] < minSampleSize))
                        {
                            minSampleSize = (int)vhObject.vbSampleSizes[i];

                            if (minSampleSize < Psf.MIN_ADPCM_ROW_SIZE)
                            {
                                vhObject.IsSmallSamplePresent = true;
                            }
                        }

                        // update max sample size
                        if ((maxSampleSize < 0) || (vhObject.vbSampleSizes[i] > maxSampleSize))
                        {
                            maxSampleSize = (int)vhObject.vbSampleSizes[i];
                        }
                    }

                    if (vhObject.expectedVbLength != vhObject.expectedVbLengthBySample)
                    {
                        vhObject.HasHeaderMismatch = true;

                        //vhObject.expectedVbLength = vhObject.expectedVbLengthBySample;

                        //this.progressStruct.Clear();
                        //this.progressStruct.GenericMessage = String.Format("     Warning, for VH <{0}>, header does not match samples' lengths.  Ignoring header value.{1}", vhObject.FileName, Environment.NewLine);
                        //this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);
                    }

                    vhArrayList.Add(vhObject);

                    // extract file
                    ParseFile.ExtractChunkToFile(fs, vhObject.startingOffset, (int)vhObject.length,
                                                 Path.Combine(destinationFolder, vhObject.FileName), true, true);

                    offset += 1;
                }

                #endregion

                // get SEQ Files
                #region SEQ EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting SEQ{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                // get SEQ file list
                seqFiles = Psf.GetSeqFileList(fs, psfStruct.UseSeqMinimumSize, psfStruct.MinimumSize);

                foreach (Psf.ProbableItemStruct seq in seqFiles)
                {
                    if (seq.length > 0)
                    {
                        if (psfStruct.ReorderSeqFiles)
                        {
                            if ((vhArrayList.Count < seqFiles.Count))
                            {
                                if (!seqNamingMessageDisplayed)
                                {
                                    this.progressStruct.Clear();
                                    this.progressStruct.ErrorMessage = String.Format(
                                        "Warning, cannot reorder SEQ files, there are less VH files than SEQ files.{0}", Environment.NewLine);
                                    this.ReportProgress(this.progress, this.progressStruct);
                                    seqNamingMessageDisplayed = true;
                                }
                                seqName = String.Format("{0}_{1}.SEQ", Path.GetFileNameWithoutExtension(pPath), seqNumber++.ToString("X4"));
                            }
                            else
                            {
                                vhObject = (VhStruct)vhArrayList[vhArrayList.Count - seqFiles.Count + seqNumber++];
                                seqName  = Path.ChangeExtension(vhObject.FileName, ".SEQ");
                            }
                        }
                        else
                        {
                            seqName = String.Format("{0}_{1}.SEQ", Path.GetFileNameWithoutExtension(pPath), seqNumber++.ToString("X4"));
                        }

                        ParseFile.ExtractChunkToFile(fs, seq.offset, (int)seq.length,
                                                     Path.Combine(destinationFolder, seqName), true, true);
                    }
                    else
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format(" Warning SEQ found with length less than 0,  at Offset 0x{1}: {2}{3}", seq.offset.ToString("X8"), seq.length.ToString("X8"), Environment.NewLine);
                        this.ReportProgress(this.progress, this.progressStruct);
                    }
                }
                #endregion

                // get SEP Files
                #region SEP EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting SEP{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                // get SEP file list
                sepFiles = Psf.GetSepFileList(fs);

                foreach (Psf.ProbableItemStruct sep in sepFiles)
                {
                    if (sep.length > 0)
                    {
                        if (psfStruct.ReorderSeqFiles)
                        {
                            if ((vhArrayList.Count < sepFiles.Count))
                            {
                                if (!sepNamingMessageDisplayed)
                                {
                                    this.progressStruct.Clear();
                                    this.progressStruct.ErrorMessage = String.Format(
                                        "Warning, cannot reorder SEP files, there are less VH files than SEP files.{0}", Environment.NewLine);
                                    this.ReportProgress(this.progress, this.progressStruct);
                                    sepNamingMessageDisplayed = true;
                                }
                                sepName = String.Format("{0}_{1}.SEP", Path.GetFileNameWithoutExtension(pPath), sepNumber++.ToString("X4"));
                            }
                            else
                            {
                                vhObject = (VhStruct)vhArrayList[vhArrayList.Count - sepFiles.Count + sepNumber++];
                                sepName  = Path.ChangeExtension(vhObject.FileName, ".SEP");
                            }
                        }
                        else
                        {
                            sepName = String.Format("{0}_{1}.SEP", Path.GetFileNameWithoutExtension(pPath), sepNumber++.ToString("X4"));
                        }

                        ParseFile.ExtractChunkToFile(fs, sep.offset, (int)sep.length,
                                                     Path.Combine(destinationFolder, sepName), true, true);
                    }
                    else
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format(" Warning SEP found with length less than 0,  at Offset 0x{1}: {2}{3}", sep.offset.ToString("X8"), sep.length.ToString("X8"), Environment.NewLine);
                        this.ReportProgress(this.progress, this.progressStruct);
                    }
                }
                #endregion

                // get VB files
                #region VB EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting VB...WARNING, THIS WILL TAKE A LONG TIME...{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                offset = 0;

                // setup arrays for checking skips
                VhStruct[] vhList = (VhStruct[])vhArrayList.ToArray(typeof(VhStruct));
                Psf.ProbableItemStruct[] seqList = (Psf.ProbableItemStruct[])seqFiles.ToArray(typeof(Psf.ProbableItemStruct));
                Psf.ProbableItemStruct[] sepList = (Psf.ProbableItemStruct[])sepFiles.ToArray(typeof(Psf.ProbableItemStruct));

                // build list of potential adpcm start indexes (VB_START_BYTES)
                potentialVb = new ProbableVbStruct();

                // check for the smallest found size or use default
                //minRowLength = (minSampleSize / 0x10) - 1; // divide into rows
                //if ((minRowLength > 0) && (minRowLength > MIN_ADPCM_ROW_COUNT))
                //{
                minRowLength = Psf.MIN_ADPCM_ROW_COUNT;
                //}

                while ((offset = ParseFile.GetNextOffset(fs, offset, Psf.VB_START_BYTES, psfStruct.UseZeroOffsetForVb,
                                                         0x10, 0)) > -1)
                {
                    //if (offset >= 0x42E83)
                    //{
                    //    int r = 1;
                    //}

                    if (!CancellationPending)
                    {
                        try
                        {
                            vbRow = ParseFile.ParseSimpleOffset(fs, offset, vbRow.Length);

                            // check for potential sony adpcm signature, and also make sure this offset is not inside another
                            //   more easily parsed file since those formats are solid
                            //if ((!InsideAnotherFile(offset, vhList, seqList, sepList)) &&
                            //    (IsPotentialAdpcm(fs, offset + 0x10, minRowLength)))
                            if (Psf.IsPotentialAdpcm(fs, offset + 0x10, minRowLength, false))
                            {
                                // check if we have passed a different file type and reset previousVbOffset if we did
                                if (SteppedOverAnotherFile(previousVbOffset, offset, vhList, seqList, sepList))
                                {
                                    // need to add flag here so length calculation doesn't screw up?
                                    previousVbOffset = -1;
                                }

                                // check if we have exceeded the max sample size and reset previous offset
                                //  so the chunk size check doesn't apply
                                if ((offset - previousVbOffset) > maxSampleSize)
                                {
                                    previousVbOffset = -1;
                                }

                                // try to preserve proper VB chunk size
                                if ((previousVbOffset == -1) || ((offset - previousVbOffset) % 0x10 == 0))
                                {
                                    previousVbOffset   = offset;
                                    potentialVb.offset = offset;
                                    emptyRowList.Add(potentialVb);
                                }
                            }
                        }
                        catch (Exception vbEx)
                        {
                            this.progressStruct.Clear();
                            this.progressStruct.ErrorMessage = String.Format(" ERROR finding VB for <{0}> at Offset 0x{1}: {2}{3}", pPath, offset.ToString("X8"), vbEx.Message, Environment.NewLine);
                            this.ReportProgress(this.progress, this.progressStruct);
                        }

                        offset += 1;
                    }
                    else
                    {
                        e.Cancel = true;
                        return;
                    }
                }

                potentialVbList = (ProbableVbStruct[])emptyRowList.ToArray(typeof(ProbableVbStruct));

                // set probable lengths
                for (int i = 0; i < potentialVbList.Length; i++)
                {
                    if (i > 0)
                    {
                        potentialVbList[i - 1].length = (uint)(potentialVbList[i].offset - potentialVbList[i - 1].offset);
                    }
                }

                // compare VH sample sizes to potential adpcm sizes/indexes
                vhObject.startingOffset   = 0;
                vhObject.length           = 0;
                vhObject.vbStartingOffset = 0;
                vhObject.vbLength         = 0;

                string   vbName;
                string   newFileName;
                string[] dupeFileNames;

                for (int i = 0; i < vhArrayList.Count; i++)
                {
                    vhObject = (VhStruct)vhArrayList[i];

                    if (vhObject.vbSampleSizes.Length < 1)
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format(" ERROR building VB for <{0}>: {1} refers to a single VAG, cannot determine proper VB.  Skipping...{2}", pPath, vhObject.FileName, Environment.NewLine);
                        this.ReportProgress(this.progress, this.progressStruct);
                    }
                    else
                    {
                        for (int j = 0; j < potentialVbList.Length; j++)
                        {
                            // we have a potential match or are at the last item.  skip rows that are too small
                            if ((vhObject.vbSampleSizes[0] < Psf.MIN_ADPCM_ROW_SIZE) ||
                                (vhObject.vbSampleSizes[0] <= potentialVbList[j].length) ||
                                (potentialVbList[j].length == 0))
                            {
                                try
                                {
                                    vhObject = PopulateVbOffsetLength(fs, potentialVbList, j, vhObject, psfStruct.RelaxVbEofRestrictions);

                                    if (vhObject.vbLength > 0)
                                    {
                                        // check for other BD files that matched and rename accordingly
                                        dupeFileNames = Directory.GetFiles(destinationFolder, Path.GetFileNameWithoutExtension(vhObject.FileName) + "*.VB");

                                        if (dupeFileNames.Length >= 1)
                                        {
                                            vbName = String.Format("{0}_{1}.VB", Path.GetFileNameWithoutExtension(vhObject.FileName), (dupeFileNames.Length).ToString("X4"));

                                            if (dupeFileNames.Length == 1)
                                            {
                                                // rename existing
                                                newFileName = String.Format("{0}_{1}.VB", Path.GetFileNameWithoutExtension(vhObject.FileName), (dupeFileNames.Length - 1).ToString("X4"));
                                                File.Move(dupeFileNames[0], Path.Combine(Path.GetDirectoryName(dupeFileNames[0]), newFileName));
                                            }
                                        }
                                        else
                                        {
                                            vbName = Path.ChangeExtension(vhObject.FileName, ".VB");
                                        }


                                        ParseFile.ExtractChunkToFile(fs, vhObject.vbStartingOffset, (int)vhObject.vbLength,
                                                                     Path.Combine(destinationFolder, vbName), true, true);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    this.progressStruct.Clear();
                                    this.progressStruct.ErrorMessage = String.Format(" ERROR building VB for <{0}>: {1}{2}", pPath, ex.Message, Environment.NewLine);
                                    this.ReportProgress(this.progress, this.progressStruct);
                                }
                            } // if (vhObject.vbSampleSizes[0] == potentialVbList[j].length)
                        }     // for (int j = 0; j < potentialVbList.Length; j++)
                    }
                }
                #endregion
            }
        }
Ejemplo n.º 27
0
        public static bool GetPsAdpcmLoop(string pSourcePath,
                                          GenhCreationStruct pGenhCreationStruct, out string pLoopStart, out string pLoopEnd)
        {
            bool ret = false;

            pLoopStart = Genh.EMPTY_SAMPLE_COUNT;
            pLoopEnd   = Genh.EMPTY_SAMPLE_COUNT;

            long loopStart = -1;
            long loopEnd   = -1;

            long loopCheckBytesOffset;

            byte[] possibleLoopBytes;

            long   headerSkip       = VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.HeaderSkip);
            int    channels         = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Channels);
            int    interleave       = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(pGenhCreationStruct.Interleave);
            string fullIncomingPath = Path.GetFullPath(pSourcePath);

            byte[] checkByte = new byte[1];

            FileInfo fi = new FileInfo(Path.GetFullPath(fullIncomingPath));

            if ((fi.Length - headerSkip) % 0x10 != 0)
            {
                throw new Exception(String.Format("Error processing <{0}> Length of file minus the header skip value is not divisible by 0x10.  This is not a proper PS ADPCM rip.", fullIncomingPath));
            }

            using (BinaryReader br = new BinaryReader(File.OpenRead(fullIncomingPath)))
            {
                // Loop Start
                br.BaseStream.Position = headerSkip + 0x01;

                while (br.BaseStream.Position < fi.Length)
                {
                    br.Read(checkByte, 0, checkByte.Length);

                    if (checkByte[0] == 0x06)
                    {
                        loopStart = br.BaseStream.Position - 2 - headerSkip;

                        break;
                    }
                    else
                    {
                        br.BaseStream.Position += 0x10 - 0x01;
                    }
                }

                // Loop End
                br.BaseStream.Position = fi.Length - 0x0F;

                while (br.BaseStream.Position > headerSkip)
                {
                    br.Read(checkByte, 0, checkByte.Length);

                    if (checkByte[0] == 0x03)
                    {
                        loopEnd = br.BaseStream.Position + 0x0E - headerSkip;

                        //if (channels > 1)
                        //{
                        //    loopEnd -= interleave;
                        //}

                        break;
                    }
                    else if (br.BaseStream.Position >= 0x11)
                    {
                        br.BaseStream.Position -= 0x11;
                    }
                    else
                    {
                        br.BaseStream.Position = headerSkip;
                    }
                }

                // if loop end found but start not found, try alternate method
                if ((loopEnd >= 0) && (loopStart < 0))
                {
                    loopCheckBytesOffset = loopEnd + headerSkip - SONY_ADPCM_LOOP_HACK_BYTE_COUNT;
                    possibleLoopBytes    = ParseFile.ParseSimpleOffset(
                        br.BaseStream,
                        loopCheckBytesOffset,
                        SONY_ADPCM_LOOP_HACK_BYTE_COUNT - 0x10);
                    loopStart = ParseFile.GetNextOffset(br.BaseStream, 0, possibleLoopBytes, true);

                    if ((loopStart > 0) && (loopStart < loopCheckBytesOffset))
                    {
                        loopStart += SONY_ADPCM_LOOP_HACK_BYTE_COUNT - headerSkip;
                    }
                }
            }

            if (loopStart >= 0)
            {
                pLoopStart = (loopStart / 16 / channels * 28).ToString();
                ret        = true;
            }

            if (loopEnd >= 0)
            {
                pLoopEnd = (loopEnd / 16 / channels * 28).ToString();
                ret      = true;
            }

            return(ret);
        }
Ejemplo n.º 28
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractAdxStruct, DoWorkEventArgs e)
        {
            ExtractAdxStruct extractAdxStruct = (ExtractAdxStruct)pExtractAdxStruct;

            long offset = 0;

            uint copyrightOffset;

            byte[] copyrightBytes;
            uint   totalHeaderSize;

            int  encodingType;
            uint blockSize;
            uint bitDepth;
            uint channelCount;
            uint sampleRate;

            uint totalSamples;

            uint fileSize;

            int    fileCount  = 0;
            string outputPath = Path.Combine(Path.GetDirectoryName(pPath), "_cri_adx_ext");
            string outputFileName;
            string outputFilePath;

            FileInfo fi = new FileInfo(pPath);

            using (FileStream fs = File.Open(pPath, FileMode.Open, FileAccess.Read))
            {
                outputPath = Path.Combine(Path.GetDirectoryName(pPath), String.Format("{0}_ADXs", Path.GetFileNameWithoutExtension(pPath)));

                while ((offset = ParseFile.GetNextOffset(fs, offset, ADX_SIG_BYTES)) > -1)
                {
                    if (!this.CancellationPending)
                    {
                        // get offset to copyright string
                        copyrightOffset = (uint)ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 2, 2));
                        copyrightBytes  = ParseFile.ParseSimpleOffset(fs, offset + copyrightOffset - 2, CRI_COPYRIGHT_BYTES.Length);

                        // check that copyright bytes are present
                        if (ParseFile.CompareSegment(copyrightBytes, 0, CRI_COPYRIGHT_BYTES))
                        {
                            // verify this is standard ADX
                            encodingType = ParseFile.ParseSimpleOffset(fs, offset + 4, 1)[0];

                            if (encodingType != 3)
                            {
                                fileSize = 1;
                            }
                            else
                            {
                                // get other info
                                blockSize       = (uint)ParseFile.ParseSimpleOffset(fs, offset + 5, 1)[0];
                                bitDepth        = (uint)ParseFile.ParseSimpleOffset(fs, offset + 6, 1)[0];
                                channelCount    = (uint)ParseFile.ParseSimpleOffset(fs, offset + 7, 1)[0];
                                sampleRate      = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 8, 4));
                                totalSamples    = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4));
                                totalHeaderSize = copyrightOffset + 4;

                                // calculate file size
                                fileSize = (((totalSamples + 0x1F) / (bitDepth * 8)) * channelCount * blockSize) + totalHeaderSize + blockSize;

                                // extract file
                                outputFileName = String.Format("{0}_{1}.adx", Path.GetFileNameWithoutExtension(pPath), fileCount.ToString("X8"));
                                outputFilePath = Path.Combine(outputPath, outputFileName);

                                this.progressStruct.Clear();
                                this.progressStruct.GenericMessage = String.Format("{0} - offset: 0x{1} size: 0x{2}{3}", outputFileName, offset.ToString("X8"), fileSize.ToString("X8"), Environment.NewLine);
                                ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                                ParseFile.ExtractChunkToFile(fs, offset, (int)fileSize, outputFilePath, true, true);

                                fileCount++;
                            }

                            offset += fileSize;
                        }
                        else
                        {
                            offset += 1;
                        }
                    }
                    else
                    {
                        e.Cancel = true;
                        return;
                    }
                }
            }
        }
Ejemplo n.º 29
0
        private void RenameFilesFromExternalList(ExternalListFileRenamerStruct inputValues)
        {
            string fileMask = null;

            string[] sourceFiles;
            int      sourceFileCount;

            long listFileLength;
            long fileNameOffset;

            StringBuilder renameScript;
            StringBuilder undoScript;

            string sourceFile;

            byte[] destinationFileTerminator = new byte[0];
            long   destinationFileBytesSize  = -1;

            byte[] destinationFileBytes;
            string destinationFile;
            string destinationFolder;

            long currentOffset;

            // verify directory exists and list file exists
            if (Directory.Exists(inputValues.SourceFolder) &&
                File.Exists(inputValues.ListFileLocation))
            {
                // set file mask
                fileMask = inputValues.SourceFileMask.Trim();
                fileMask = String.IsNullOrEmpty(fileMask) ? "*.*" : fileMask;

                // get source file count
                sourceFiles     = Directory.GetFiles(inputValues.SourceFolder, fileMask, SearchOption.TopDirectoryOnly);
                sourceFileCount = sourceFiles.GetLength(0);

                // verify some source files exist
                if (sourceFileCount == 0)
                {
                    throw new Exception(String.Format("Source directory is empty."));
                }
                else
                {
                    // convert file name offset to long
                    fileNameOffset = ByteConversion.GetLongValueFromString(inputValues.OffsetToFileNames);

                    // open List File
                    using (FileStream listFs = File.Open(inputValues.ListFileLocation, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        listFileLength = listFs.Length;

                        // verify offset exists within list file
                        if (listFileLength < fileNameOffset)
                        {
                            throw new IOException(String.Format("File name offset is greater than the size of the list file."));
                        }
                        else
                        {
                            renameScript = new StringBuilder();
                            undoScript   = new StringBuilder();

                            // parse file name terminator, if included
                            if (inputValues.FileNameHasTerminator)
                            {
                                try
                                {
                                    destinationFileTerminator = ByteConversion.GetBytesFromHexString(inputValues.FileNameTerminator);
                                }
                                catch (Exception ex1)
                                {
                                    throw new FormatException(String.Format("Unable to convert File Name Terminator Bytes to hex: '{0}'", ex1.Message), ex1);
                                }
                            }
                            else // convert static filename size
                            {
                                try
                                {
                                    destinationFileBytesSize = ByteConversion.GetLongValueFromString(inputValues.FileNameStaticSize);
                                }
                                catch (Exception ex2)
                                {
                                    throw new FormatException(String.Format("Unable to convert File Name static size fo a number: '{0}'", ex2.Message), ex2);
                                }
                            }


                            try
                            {
                                // rename files
                                currentOffset = fileNameOffset;

                                for (int i = 0; i < sourceFileCount; i++)
                                {
                                    sourceFile = sourceFiles[i];

                                    // get name for files with a terminator
                                    if (inputValues.FileNameHasTerminator)
                                    {
                                        destinationFileBytesSize = ParseFile.GetNextOffset(listFs, currentOffset, destinationFileTerminator) - currentOffset;
                                    }

                                    // read destination file name
                                    if (destinationFileBytesSize > 0)
                                    {
                                        destinationFileBytes = ParseFile.ParseSimpleOffset(listFs, currentOffset, (int)destinationFileBytesSize);
                                        destinationFile      = this.getFileNameFromEncodedBytes(inputValues.FileNameEncoding, inputValues.FileNameCodePage, destinationFileBytes);
                                        currentOffset       += destinationFileBytesSize + destinationFileTerminator.Length;
                                    }
                                    else
                                    {
                                        this.progressStruct.Clear();
                                        this.progressStruct.FileName       = sourceFile;
                                        this.progressStruct.GenericMessage = String.Format("Warning: End of List File reached when renaming <{0}>{1}", sourceFile, Environment.NewLine);
                                        this.ReportProgress(Constants.ProgressMessageOnly, progressStruct);
                                        break;
                                    }

                                    // rename file and build scripts
                                    destinationFile = Path.Combine(inputValues.SourceFolder, destinationFile).Trim();

                                    if (inputValues.KeepOriginalFileExtension)
                                    {
                                        if (String.IsNullOrEmpty(Path.GetExtension(destinationFile)))
                                        {
                                            destinationFile += Path.GetExtension(sourceFile);
                                        }
                                        else
                                        {
                                            Path.ChangeExtension(destinationFile, Path.GetExtension(sourceFile));
                                        }
                                    }

                                    if (sourceFile != destinationFile)
                                    {
                                        renameScript.AppendFormat("rename \"{0}\" \"{1}\" {2}", Path.GetFileName(sourceFile), Path.GetFileName(destinationFile), Environment.NewLine);
                                        undoScript.AppendFormat("rename \"{0}\" \"{1}\" {2}", Path.GetFileName(destinationFile), Path.GetFileName(sourceFile), Environment.NewLine);

                                        destinationFolder = Path.GetDirectoryName(destinationFile);

                                        if (!Directory.Exists(destinationFolder))
                                        {
                                            Directory.CreateDirectory(destinationFolder);
                                        }

                                        File.Move(sourceFile, destinationFile);
                                    }



                                    // report progress
                                    this.progressStruct.Clear();
                                    this.progressStruct.FileName = sourceFile;
                                    this.ReportProgress(((i + 1) * 100) / sourceFileCount, progressStruct);
                                }
                            }
                            finally
                            {
                                if (renameScript.Length > 0)
                                {
                                    // write to file.
                                    FileUtil.CreateFileFromString(Path.Combine(inputValues.SourceFolder, RENAME_SCRIPT_NAME), renameScript.ToString());
                                }

                                if (undoScript.Length > 0)
                                {
                                    // write to file.
                                    FileUtil.CreateFileFromString(Path.Combine(inputValues.SourceFolder, UNDO_RENAME_SCRIPT_NAME), undoScript.ToString());
                                }
                            }
                        } // if (listFileLength < fileNameOffset)
                    }     // using (FileStream listFs = File.Open(inputValues.ListFileLocation, FileMode.Open, FileAccess.Read, FileShare.Read))
                }         // if (sourceFileCount == 0)
            }
            else
            {
                throw new IOException(String.Format("Directory not found: <{0}>", inputValues.SourceFolder));
            } // if (Directory.Exists(inputValues.SourceFolder))
        }
Ejemplo n.º 30
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pPspSeqDataFinderStruct, DoWorkEventArgs e)
        {
            PspSeqDataFinderStruct pspStruct = (PspSeqDataFinderStruct)pPspSeqDataFinderStruct;

            long offset;

            int        phdNumber = 0;
            PphdStruct phdObject;
            ArrayList  phdArrayList = new ArrayList();

            string midName;
            int    midNumber = 0;

            Psf.ProbableItemStruct midEntry;
            ArrayList midFiles = new ArrayList();
            bool      midNamingMessageDisplayed = false;
            Midi      midiFile = new Midi();

            Psf.ProbableItemStruct   potentialPbd;
            Psf.ProbableItemStruct[] potentialPbdList;
            byte[]    pbdRow       = new byte[Psf.SONY_ADPCM_ROW_SIZE];
            ArrayList emptyRowList = new ArrayList();

            // display file name
            this.progressStruct.Clear();
            this.progressStruct.GenericMessage = String.Format("[{0}]{1}", pPath, Environment.NewLine);
            this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

            // open file
            using (FileStream fs = File.OpenRead(pPath))
            {
                string destinationFolder = Path.Combine(Path.GetDirectoryName(pPath), Path.GetFileNameWithoutExtension(pPath));

                // get PHD files
                #region PHD EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting PHD{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                offset = 0;

                while ((offset = ParseFile.GetNextOffset(fs, offset, PPHD_SIGNATURE)) > -1)
                {
                    try
                    {
                        // get PPHD data
                        phdObject          = GetPphdData(fs, offset);
                        phdObject.FileName = String.Format("{0}_{1}.PHD", Path.GetFileNameWithoutExtension(pPath), phdNumber++.ToString("X4"));

                        // extract the file
                        ParseFile.ExtractChunkToFile(fs, offset, (int)phdObject.length,
                                                     Path.Combine(destinationFolder, phdObject.FileName), true, true);

                        // add to array
                        phdArrayList.Add(phdObject);
                    }
                    catch (Exception pphdEx)
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format("      Error extracting PPHD at offset 0x{0}: {1}{2}", offset.ToString("X8"), pphdEx.Message, Environment.NewLine);
                        ReportProgress(progress, this.progressStruct);
                    }

                    // increment offset
                    offset += 1;
                }

                #endregion

                // get MID Files
                #region MID EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting MID{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                midEntry = new Psf.ProbableItemStruct();
                offset   = 0;

                // build file list
                while ((offset = ParseFile.GetNextOffset(fs, offset, Midi.ASCII_SIGNATURE_MTHD)) > -1)
                {
                    midiFile.Initialize(fs, pPath, offset);
                    midEntry.offset = midiFile.FileStartOffset;
                    midEntry.length = (uint)midiFile.TotalFileLength;
                    midFiles.Add(midEntry);

                    offset += 1;
                }

                foreach (Psf.ProbableItemStruct mid in midFiles)
                {
                    if (pspStruct.ReorderMidFiles)
                    {
                        if (phdArrayList.Count < midFiles.Count)
                        {
                            if (!midNamingMessageDisplayed)
                            {
                                this.progressStruct.Clear();
                                this.progressStruct.ErrorMessage = String.Format(
                                    "Warning, cannot reorder MID files, there are less PHD files than MID files.{0}", Environment.NewLine);
                                this.ReportProgress(this.progress, this.progressStruct);
                                midNamingMessageDisplayed = true;
                            }

                            midName = String.Format("{0}_{1}.MID", Path.GetFileNameWithoutExtension(pPath), midNumber++.ToString("X4"));
                        }
                        else
                        {
                            phdObject = (PphdStruct)phdArrayList[phdArrayList.Count - midFiles.Count + midNumber++];
                            midName   = Path.ChangeExtension(phdObject.FileName, ".MID");
                        }
                    }
                    else
                    {
                        midName = String.Format("{0}_{1}.MID", Path.GetFileNameWithoutExtension(pPath), midNumber++.ToString("X4"));
                    }

                    ParseFile.ExtractChunkToFile(fs, mid.offset, (int)mid.length,
                                                 Path.Combine(destinationFolder, midName), true, true);
                }
                #endregion

                // get PBD files
                #region PBD EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting PBD...WARNING, THIS CAN TAKE A LONG TIME...{0}", Environment.NewLine);
                this.ReportProgress(Constants.ProgressMessageOnly, this.progressStruct);

                offset = 0;

                // build list of potential adpcm start indexes
                potentialPbd = new Psf.ProbableItemStruct();

                // build list of potential adpcm start indexes
                while ((offset = ParseFile.GetNextOffset(fs, offset, Psf.VB_START_BYTES, pspStruct.UseZeroOffsetForPbd, 0x10L, 0x00L, true)) > -1)
                {
                    try
                    {
                        pbdRow = ParseFile.ParseSimpleOffset(fs, offset, pbdRow.Length);

                        if (Psf.IsPotentialAdpcm(fs, offset + 0x10, Psf.MIN_ADPCM_ROW_COUNT, false))
                        {
                            potentialPbd.offset = offset;
                            emptyRowList.Add(potentialPbd);
                        }
                    }
                    catch (Exception pbdEx)
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format(" ERROR finding BD for <{0}> at Offset 0x{1}: {2}{3}", pPath, offset.ToString("X8"), pbdEx.Message, Environment.NewLine);
                        this.ReportProgress(this.progress, this.progressStruct);
                    }

                    offset += 1;
                }

                potentialPbdList = (Psf.ProbableItemStruct[])emptyRowList.ToArray(typeof(Psf.ProbableItemStruct));

                // set probable lengths
                for (int i = 0; i < potentialPbdList.Length; i++)
                {
                    if (i > 0)
                    {
                        potentialPbdList[i - 1].length = (uint)(potentialPbdList[i].offset - potentialPbdList[i - 1].offset);
                    }
                }

                // compare PHD sample sizes to potential adpcm sizes/indexes
                phdObject.startingOffset    = 0;
                phdObject.length            = 0;
                phdObject.pbdStartingOffset = 0;
                phdObject.pbdLength         = 0;

                string   pbdName;
                string   newFileName;
                string[] dupeFileNames;

                for (int i = 0; i < phdArrayList.Count; i++)
                {
                    phdObject = (PphdStruct)phdArrayList[i];
                    if (phdObject.vagLengths.Length < 1)
                    {
                        this.progressStruct.Clear();
                        this.progressStruct.ErrorMessage = String.Format(" ERROR building PBD for <{0}>: {1} refers to a single VAG, cannot determine proper PBD.  Skipping...{2}", pPath, phdObject.FileName, Environment.NewLine);
                        this.ReportProgress(this.progress, this.progressStruct);
                    }
                    else
                    {
                        for (int j = 0; j < potentialPbdList.Length; j++)
                        {
                            // we have a potential match or are at the last item.
                            if ((phdObject.vagLengths[0] <= potentialPbdList[j].length) ||
                                (potentialPbdList[j].length == 0))
                            {
                                try
                                {
                                    phdObject = PopulatePbdOffsetLength(fs, potentialPbdList, j, phdObject);

                                    if (phdObject.pbdLength > 0)
                                    {
                                        // check for other BD files that matched and rename accordingly
                                        dupeFileNames = Directory.GetFiles(destinationFolder, Path.GetFileNameWithoutExtension(phdObject.FileName) + "*.PBD");

                                        if (dupeFileNames.Length >= 1)
                                        {
                                            pbdName = String.Format("{0}_{1}.PBD", Path.GetFileNameWithoutExtension(phdObject.FileName), (dupeFileNames.Length).ToString("X4"));

                                            if (dupeFileNames.Length == 1)
                                            {
                                                // rename existing
                                                newFileName = String.Format("{0}_{1}.PBD", Path.GetFileNameWithoutExtension(phdObject.FileName), (dupeFileNames.Length - 1).ToString("X4"));
                                                File.Move(dupeFileNames[0], Path.Combine(Path.GetDirectoryName(dupeFileNames[0]), newFileName));
                                            }
                                        }
                                        else
                                        {
                                            pbdName = Path.ChangeExtension(phdObject.FileName, ".PBD");
                                        }


                                        ParseFile.ExtractChunkToFile(fs, phdObject.pbdStartingOffset, phdObject.pbdLength,
                                                                     Path.Combine(destinationFolder, pbdName), true, true);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    this.progressStruct.Clear();
                                    this.progressStruct.ErrorMessage = String.Format("     ERROR building BD for <{0}>: {1}{2}", pPath, ex.Message, Environment.NewLine);
                                    this.ReportProgress(this.progress, this.progressStruct);
                                }
                            }
                        }
                    }
                }

                #endregion
            }
        }