Example #1
0
        public static string ExtractGenhFile(string pSourcePath, bool extractHeaderToFile, bool outputExtractionLog, bool outputExtractionFile)
        {
            string outputFileName       = null;
            string headerOutputFileName = null;

            if (IsGenhFile(pSourcePath))
            {
                using (FileStream fs = File.Open(pSourcePath, FileMode.Open, FileAccess.Read))
                {
                    Genh genhFile = new Genh();
                    genhFile.Initialize(fs, pSourcePath);
                    Int32  headerLength     = BitConverter.ToInt32(genhFile.HeaderLength, 0);
                    Int32  originalFileSize = BitConverter.ToInt32(genhFile.OriginalFileSize, 0);
                    string originalFileName = System.Text.Encoding.ASCII.GetString(genhFile.OriginalFileName);

                    outputFileName = Path.Combine(Path.GetDirectoryName(pSourcePath), originalFileName).Trim();
                    ParseFile.ExtractChunkToFile(fs, headerLength, originalFileSize, outputFileName, outputExtractionLog, outputExtractionFile);

                    if (extractHeaderToFile)
                    {
                        headerOutputFileName = Path.Combine(Path.GetDirectoryName(pSourcePath), String.Format("{0}{1}", originalFileName.Trim(), Genh.FILE_EXTENSION_HEADER)).Trim();
                        ParseFile.ExtractChunkToFile(fs, 0, headerLength, headerOutputFileName, outputExtractionLog, outputExtractionFile);
                    }

                    FileInfo fi = new FileInfo(outputFileName);
                    if (fi.Length != (long)originalFileSize)
                    {
                        throw new IOException(String.Format("Extracted file <{0}> size did not match size in header of <{1}>: 0x{2}{3}", outputFileName,
                                                            pSourcePath, originalFileSize.ToString("X8"), Environment.NewLine));
                    }
                }
            }

            return(outputFileName);
        }
Example #2
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);
            }
        }
Example #3
0
        public void UpdateTags()
        {
            int    actualFileEnd;
            string retaggingFilePath;

            string[] splitValue;
            string[] splitParam = new string[] { Environment.NewLine };

            try
            {
                actualFileEnd     = (int)(RESERVED_SECTION_OFFSET + this.reservedSectionLength + this.compressedProgramLength);
                retaggingFilePath = Path.Combine(
                    Path.GetDirectoryName(this.filePath),
                    String.Format(
                        "{0}_RETAG_{1}{2}",
                        Path.GetFileNameWithoutExtension(this.filePath),
                        new Random().Next().ToString(),
                        Path.GetExtension(this.filePath)));

                // extract file without tags
                using (FileStream fs = File.OpenRead(this.filePath))
                {
                    ParseFile.ExtractChunkToFile(fs, 0, actualFileEnd, retaggingFilePath);
                }

                // add new tags
                using (FileStream fs = File.Open(retaggingFilePath, FileMode.Append, FileAccess.Write))
                {
                    byte[] dataToWrite;

                    // write [TAG]
                    dataToWrite = System.Text.Encoding.ASCII.GetBytes(ASCII_TAG);
                    fs.Write(dataToWrite, 0, dataToWrite.Length);

                    // add or update utf8=1 tag
                    this.TagHash["utf8"] = "1";

                    foreach (string key in this.TagHash.Keys)
                    {
                        splitValue = this.TagHash[key].Split(splitParam, StringSplitOptions.None);

                        foreach (string valueItem in splitValue)
                        {
                            dataToWrite = System.Text.Encoding.UTF8.GetBytes(String.Format("{0}={1}", key, valueItem));
                            fs.Write(dataToWrite, 0, dataToWrite.Length);
                            fs.WriteByte(0x0A);
                        }
                    } // foreach (string key in tagHash.Keys)
                }     // using (FileStream fs = File.Open(this.filePath, FileMode.Append, FileAccess.Write))

                File.Delete(this.filePath);
                File.Move(retaggingFilePath, this.filePath);
            }
            catch (Exception _ex)
            {
                throw new Exception(String.Format("Error updating tags for <{0}>", this.filePath), _ex);
            }
        }
Example #4
0
        public void Extract(ref Dictionary <string, FileStream> streamCache, string destinationFolder, bool extractAsRaw)
        {
            string destinationFile = Path.Combine(Path.Combine(destinationFolder, this.ParentDirectoryName), this.FileName);

            if (!streamCache.ContainsKey(this.SourceFilePath))
            {
                streamCache[this.SourceFilePath] = File.OpenRead(this.SourceFilePath);
            }

            ParseFile.ExtractChunkToFile(streamCache[this.SourceFilePath], this.Offset, this.Size, destinationFile);
        }
Example #5
0
        static void Main(string[] args)
        {
            string inFilename;
            long   startOffset;
            long   blockSize;

            string fullInputPath;
            string fullOutputPath;
            string outputDirectory;
            string filePrefix;

            long currentOffset;
            long fileSize;
            uint fileCount = 0;

            if (args.Length < 3)
            {
                Console.WriteLine("Usage: snakesplit.exe <infile> <start offset> <blocksize>");
            }
            else
            {
                inFilename  = args[0];
                startOffset = ByteConversion.GetLongValueFromString(args[1]);
                blockSize   = ByteConversion.GetLongValueFromString(args[2]);

                fullInputPath   = Path.GetFullPath(inFilename);
                filePrefix      = Path.GetFileNameWithoutExtension(fullInputPath);
                outputDirectory = Path.Combine(Path.GetDirectoryName(fullInputPath), "snakesplit");

                if (File.Exists(fullInputPath))
                {
                    using (FileStream fs = File.OpenRead(fullInputPath))
                    {
                        fileSize      = fs.Length;
                        currentOffset = startOffset;

                        while (currentOffset < fileSize)
                        {
                            fullOutputPath = Path.Combine(outputDirectory, String.Format("{0}_{1}.bin", filePrefix, fileCount.ToString("X8")));
                            fileCount++;

                            ParseFile.ExtractChunkToFile(fs, currentOffset, blockSize, fullOutputPath);

                            currentOffset += blockSize;
                        }
                    }
                }
                else
                {
                    Console.WriteLine("File Not Found: " + fullInputPath);
                }
            }
        }
Example #6
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pEasyPsfDriverExtractionStruct,
                                              DoWorkEventArgs e)
        {
            byte[] initialProgramCounter;
            uint   initialProgramCounterValue;

            uint pcOffsetSeq;
            uint pcOffsetVb;
            uint pcOffsetVh;
            uint lengthSeq;
            uint lengthVb;
            uint lengthVh;

            byte[] vhNumberOfPrograms;
            UInt16 vhNumberOfProgramsValue;

            Xsf2ExeStruct decompressionOptions = new Xsf2ExeStruct();

            decompressionOptions.IncludeExtension = false;
            decompressionOptions.StripGsfHeader   = false;
            string extractedDataSectionPath = XsfUtil.ExtractCompressedDataSection(pPath, decompressionOptions);

            if (!String.IsNullOrEmpty(extractedDataSectionPath))
            {
                using (FileStream fs = File.OpenRead(extractedDataSectionPath))
                {
                    // get offset of initial program counter
                    initialProgramCounter      = ParseFile.ParseSimpleOffset(fs, 0x10, 4);
                    initialProgramCounterValue = BitConverter.ToUInt32(initialProgramCounter, 0);

                    pcOffsetSeq = initialProgramCounterValue - PC_OFFSET_CORRECTION;
                    pcOffsetVb  = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, (long)(pcOffsetSeq - 4), 4), 0) - PC_OFFSET_CORRECTION;
                    pcOffsetVh  = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, (long)(pcOffsetSeq - 8), 4), 0) - PC_OFFSET_CORRECTION;

                    lengthSeq = pcOffsetVb - pcOffsetSeq;
                    lengthVb  = pcOffsetVh - pcOffsetVb;

                    vhNumberOfPrograms      = ParseFile.ParseSimpleOffset(fs, (long)(pcOffsetVh + 0x12), 2);
                    vhNumberOfProgramsValue = BitConverter.ToUInt16(vhNumberOfPrograms, 0);
                    lengthVh = (UInt16)((512 * vhNumberOfProgramsValue) + 2592);

                    // extract files
                    ParseFile.ExtractChunkToFile(fs, (long)pcOffsetSeq, (int)lengthSeq, Path.ChangeExtension(pPath, ".seq"));
                    ParseFile.ExtractChunkToFile(fs, (long)pcOffsetVh, (int)lengthVh, Path.ChangeExtension(pPath, ".vh"));
                    ParseFile.ExtractChunkToFile(fs, (long)pcOffsetVb, (int)lengthVb, Path.ChangeExtension(pPath, ".vb"));
                } // using (FileStream fs = File.OpenRead(pPath))

                // delete extracted data
                File.Delete(extractedDataSectionPath);
            } // if (!String.IsNullOrEmpty(extractedDataSectionPath))
        }
Example #7
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;
            }
        }
Example #8
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pSimpleCutterSnakebiteStruct, DoWorkEventArgs e)
        {
            SimpleCutterSnakebiteStruct simpleCutterSnakebiteStruct = (SimpleCutterSnakebiteStruct)pSimpleCutterSnakebiteStruct;

            using (FileStream fs = File.OpenRead(pPath))
            {
                long startOffset = VGMToolbox.util.ByteConversion.GetLongValueFromString(simpleCutterSnakebiteStruct.StartOffset);
                long cutLength   = -1;

                if (simpleCutterSnakebiteStruct.UseEndAddress)
                {
                    cutLength = (VGMToolbox.util.ByteConversion.GetLongValueFromString(simpleCutterSnakebiteStruct.EndAddress) - startOffset) + 1;
                }
                else if (simpleCutterSnakebiteStruct.UseLength)
                {
                    cutLength = VGMToolbox.util.ByteConversion.GetLongValueFromString(simpleCutterSnakebiteStruct.Length);
                }
                else if (simpleCutterSnakebiteStruct.UseFileEnd)
                {
                    cutLength = (fs.Length - startOffset) + 1;
                }

                if (!String.IsNullOrEmpty(simpleCutterSnakebiteStruct.NewFileExtension))
                {
                    if (!simpleCutterSnakebiteStruct.NewFileExtension.StartsWith("."))
                    {
                        simpleCutterSnakebiteStruct.NewFileExtension = "." + simpleCutterSnakebiteStruct.NewFileExtension;
                    }
                    simpleCutterSnakebiteStruct.OutputFile = Path.ChangeExtension(pPath, simpleCutterSnakebiteStruct.NewFileExtension);
                }

                if (!Path.IsPathRooted(simpleCutterSnakebiteStruct.OutputFile))
                {
                    simpleCutterSnakebiteStruct.OutputFile = Path.Combine(Path.GetDirectoryName(pPath), simpleCutterSnakebiteStruct.OutputFile);

                    if (simpleCutterSnakebiteStruct.OutputFile.Equals(pPath))
                    {
                        simpleCutterSnakebiteStruct.OutputFile = Path.Combine(Path.GetDirectoryName(simpleCutterSnakebiteStruct.OutputFile),
                                                                              Path.GetFileNameWithoutExtension(simpleCutterSnakebiteStruct.OutputFile) + "_cut" +
                                                                              Path.GetExtension(simpleCutterSnakebiteStruct.OutputFile));
                    }
                }

                ParseFile.ExtractChunkToFile(fs, startOffset, cutLength, simpleCutterSnakebiteStruct.OutputFile, true, true);

                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("File <{0}>, extracted.{1}", simpleCutterSnakebiteStruct.OutputFile, Environment.NewLine);
                ReportProgress(this.progress, this.progressStruct);
            }
        }
Example #9
0
        /// <summary>
        /// Extract the title meta data.
        /// </summary>
        /// <returns>File name of extracted file.</returns>
        public string ExtractTitleMetaData()
        {
            string destinationFile = Path.Combine(
                this.GetUnpackFolder(false),
                (this.TitleId.ToString("X8") + ".tmd"));


            using (FileStream fs = File.OpenRead(this.SourceFileName))
            {
                ParseFile.ExtractChunkToFile(fs, this.TitleMetaDataOffset, this.TitleMetaDataSize, destinationFile);
            }

            return(destinationFile);
        }
Example #10
0
        /// <summary>
        /// Extract the certificate chain.
        /// </summary>
        /// <returns>File name of extracted file.</returns>
        public string ExtractCertificateChain()
        {
            string destinationFile = Path.Combine(
                this.GetUnpackFolder(false),
                (this.TitleId.ToString("X8") + ".cert"));


            using (FileStream fs = File.OpenRead(this.SourceFileName))
            {
                ParseFile.ExtractChunkToFile(fs, this.CertificateChainOffset, this.CertificateChainSize, destinationFile);
            }

            return(destinationFile);
        }
        public static void TrimFileToLength(string path, long totalLength)
        {
            string fullPath = Path.GetFullPath(path);

            if (File.Exists(fullPath))
            {
                string destinationPath = Path.ChangeExtension(fullPath, ".trimmed");

                using (FileStream fs = File.OpenRead(path))
                {
                    ParseFile.ExtractChunkToFile(fs, 0, totalLength, destinationPath);
                }

                File.Copy(destinationPath, path, true);
                File.Delete(destinationPath);
            }
        }
Example #12
0
        /// <summary>
        /// Extract optional footer.
        /// </summary>
        /// <returns>File name of extracted file or String.Empty if footer is not present.</returns>
        public string ExtractFooter()
        {
            string destinationFile = String.Empty;

            if (this.FooterSize > 0)
            {
                destinationFile = Path.Combine(
                    this.GetUnpackFolder(false),
                    (this.TitleId.ToString("X8") + ".trailer"));

                using (FileStream fs = File.OpenRead(this.SourceFileName))
                {
                    ParseFile.ExtractChunkToFile(fs, this.FooterOffset, this.FooterSize, destinationFile);
                }
            }

            return(destinationFile);
        }
Example #13
0
        public void ExtractToFile(Stream pStream, string pOutputDirectory, object Options)
        {
            string outputFileName = Path.GetFileName(this.filePath);
            int    fileCount      = 0;

            if (!Directory.Exists(pOutputDirectory))
            {
                Directory.CreateDirectory(pOutputDirectory);
            }
            else
            {
                fileCount = Directory.GetFiles(pOutputDirectory, String.Format("{0}*", Path.GetFileNameWithoutExtension(outputFileName)), SearchOption.TopDirectoryOnly).Length;
            }

            outputFileName = String.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(outputFileName), fileCount.ToString("X4"), Midi.FILE_EXTENSION);
            outputFileName = Path.Combine(pOutputDirectory, outputFileName);

            ParseFile.ExtractChunkToFile(pStream, this.fileStartOffset, this.totalFileLength, outputFileName, true, true);
        }
Example #14
0
        public static string RemoveChunkFromFile(string path, long startingOffset, long length)
        {
            string fullPath = Path.GetFullPath(path);

            int bytesRead;

            byte[] bytes = new byte[1024];

            string ret = String.Empty;

            if (File.Exists(fullPath))
            {
                string destinationPath = Path.ChangeExtension(fullPath, ".cut");

                using (FileStream sourceFs = File.OpenRead(fullPath))
                {
                    // extract initial chunk
                    ParseFile.ExtractChunkToFile(sourceFs, 0, startingOffset, destinationPath);

                    // append remainder
                    using (FileStream outFs = File.Open(destinationPath, FileMode.Append, FileAccess.Write))
                    {
                        sourceFs.Position = startingOffset + length;
                        bytesRead         = sourceFs.Read(bytes, 0, bytes.Length);

                        while (bytesRead > 0)
                        {
                            outFs.Write(bytes, 0, bytesRead);
                            bytesRead = sourceFs.Read(bytes, 0, bytes.Length);
                        }
                    }

                    ret = destinationPath;
                }
            }

            return(ret);
        }
        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
            }
        }
Example #16
0
        static void Main(string[] args)
        {
            const string LBA_SWITCH        = "/LBA";
            const string MULTIPLIER_SWITCH = "/M";

            string inFilename;
            string outFilename;
            string startOffset;
            string cutSize;

            string fullInputPath;
            string fullOutputPath;

            long longStartOffset;
            long longCutSize;

            bool   doLba        = false;
            bool   doMultiplier = false;
            string multiplierChunk;
            long   multiplierValue = 1;

            char[] multiplierSplitParam = new char[1] {
                '='
            };

            if (args.Length < 3)
            {
                Console.WriteLine("Usage: manakut.exe <infile> <outfile> <start offset> <cut size> [/lba|/m=<multiplier>]");
                Console.WriteLine("   or: manakut.exe <infile> <outfile> <start offset> [/lba|/m=<multiplier>]");
                Console.WriteLine();
                Console.WriteLine("The 4 parameter option will read from <start offset> to EOF.");
                Console.WriteLine("Use the /lba switch to multiply start offset by 0x800.");
                Console.WriteLine("Use the /m switch to multiply start offset by the value after the equals sign.");
            }
            else
            {
                inFilename  = args[0];
                outFilename = args[1];
                startOffset = args[2];


                fullInputPath  = Path.GetFullPath(inFilename);
                fullOutputPath = Path.GetFullPath(outFilename);

                if (File.Exists(fullInputPath))
                {
                    using (FileStream fs = File.OpenRead(fullInputPath))
                    {
                        longStartOffset = VGMToolbox.util.ByteConversion.GetLongValueFromString(startOffset);

                        // check for LBA or MULTIPLIER switch
                        if ((args.Length > 4) && (args[4].ToUpper().Equals(LBA_SWITCH)))
                        {
                            doLba = true;
                        }
                        else if ((args.Length > 4) && (args[4].ToUpper().Substring(0, 2).Equals(MULTIPLIER_SWITCH)))
                        {
                            doMultiplier    = true;
                            multiplierChunk = args[4].Split(multiplierSplitParam)[1];
                            multiplierValue = VGMToolbox.util.ByteConversion.GetLongValueFromString(multiplierChunk);
                        }
                        else if ((args.Length > 3) && (args[3].ToUpper().Equals(LBA_SWITCH)))
                        {
                            doLba = true;
                        }
                        else if ((args.Length > 3) &&
                                 (args[3].Length >= MULTIPLIER_SWITCH.Length) &&
                                 (args[3].ToUpper().Substring(0, 2).Equals(MULTIPLIER_SWITCH)))
                        {
                            doMultiplier    = true;
                            multiplierChunk = args[3].Split(multiplierSplitParam)[1];
                            multiplierValue = VGMToolbox.util.ByteConversion.GetLongValueFromString(multiplierChunk);
                        }

                        // GET CUTSIZE
                        if ((args.Length > 3) &&
                            (!args[3].ToUpper().Equals(LBA_SWITCH)) &&
                            ((args[3].Length < MULTIPLIER_SWITCH.Length) || (!args[3].ToUpper().Substring(0, 2).Equals(MULTIPLIER_SWITCH))))
                        {
                            cutSize     = args[3];
                            longCutSize = VGMToolbox.util.ByteConversion.GetLongValueFromString(cutSize);
                        }
                        else
                        {
                            longCutSize = fs.Length - longStartOffset;
                        }

                        // set LBA/MULTIPLIER values
                        if (doLba)
                        {
                            longStartOffset *= 0x800;
                        }
                        else if (doMultiplier)
                        {
                            longStartOffset *= multiplierValue;
                        }

                        ParseFile.ExtractChunkToFile(fs, longStartOffset, longCutSize, fullOutputPath);
                    }
                }
                else
                {
                    Console.WriteLine("File Not Found: " + fullInputPath);
                }
            }
        }
Example #17
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
            }
        }
Example #18
0
        public void ExtractGdRomData(Stream cdStream,
                                     string destinationPath, long volumeBaseOffset,
                                     long lba, long length, bool isRaw, long nonRawSectorSize,
                                     CdSectorType fileMode, bool extractAsRaw)
        {
            long offset;
            long adjustedLba;
            int  maxWriteSize;
            long bytesWritten = 0;

            CdSectorType mode;
            long         lbaCounter = 0;

            byte[] sectorHeader;
            byte[] sector;

            // create directory
            string destinationFolder = Path.GetDirectoryName(destinationPath);

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

            for (int i = (this.TrackCount - 1); i >= 0; i--)
            {
                if (lba >= this.TrackEntries[i].StartSector)
                {
                    if (isRaw)
                    {
                        mode = fileMode;

                        using (FileStream outStream = File.OpenWrite(destinationPath))
                        {
                            adjustedLba = lba - this.TrackEntries[i].StartSector;

                            while (bytesWritten < length)
                            {
                                offset       = volumeBaseOffset + ((adjustedLba + lbaCounter) * this.TrackEntries[i].SectorSize);
                                sector       = ParseFile.ParseSimpleOffset(cdStream, offset, (int)CdRom.RAW_SECTOR_SIZE);
                                sectorHeader = ParseFile.ParseSimpleOffset(sector, 0, CdRom.MAX_HEADER_SIZE);

                                if (mode == CdSectorType.Unknown)
                                {
                                    mode = CdRom.GetSectorType(sectorHeader);
                                }

                                maxWriteSize = CdRom.ModeDataSize[mode] < (length - bytesWritten) ? CdRom.ModeDataSize[mode] : (int)(length - bytesWritten);

                                if (extractAsRaw)
                                {
                                    outStream.Write(sector, 0, sector.Length);
                                }
                                else
                                {
                                    outStream.Write(sector, CdRom.ModeHeaderSize[mode], maxWriteSize);
                                }

                                bytesWritten += maxWriteSize;
                                lbaCounter++;
                            }
                        }
                    }
                    else
                    {
                        offset = ((lba - this.TrackEntries[i].StartSector) * this.TrackEntries[i].SectorSize) + this.TrackEntries[i].Offset;
                        ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath);
                    }

                    break;
                }
            }
        }
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractSonyAdpcmStruct, DoWorkEventArgs e)
        {
            ExtractSonyAdpcmStruct extractSonyAdpcmStruct = (ExtractSonyAdpcmStruct)pExtractSonyAdpcmStruct;

            long      offset    = extractSonyAdpcmStruct.StartOffset;
            ArrayList adpcmList = new ArrayList();

            Psf.ProbableItemStruct adpcmDataItem = new Psf.ProbableItemStruct();

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

            bool previousRowIsZeroes = false;

            FileInfo fi = new FileInfo(pPath);

            using (FileStream fs = File.Open(pPath, FileMode.Open, FileAccess.Read))
            {
                while (offset < fi.Length)
                {
                    if (!CancellationPending)
                    {
                        if (ExtractSonyAdpcmWorker.IsPotentialAdpcm(fs, offset, Psf.MIN_ADPCM_ROW_SIZE, false, ref previousRowIsZeroes))
                        {
                            // create probable adpcm item
                            adpcmDataItem.Init();

                            // set starting offset
                            adpcmDataItem.offset = offset;

                            // move to next row
                            offset += Psf.SONY_ADPCM_ROW_SIZE;

                            // loop until end
                            while (Psf.IsSonyAdpcmRow(fs, offset))
                            {
                                offset += Psf.SONY_ADPCM_ROW_SIZE;
                            }

                            adpcmDataItem.length = (uint)(offset - adpcmDataItem.offset);
                            adpcmList.Add(adpcmDataItem);
                        }

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


                // extract files
                foreach (Psf.ProbableItemStruct p in adpcmList)
                {
                    outputFileName = String.Format("{0}_{1}.bin", Path.GetFileNameWithoutExtension(pPath), fileCount.ToString("X8"));
                    outputFilePath = Path.Combine(outputPath, outputFileName);

                    ParseFile.ExtractChunkToFile(fs, p.offset, (int)p.length, outputFilePath,
                                                 extractSonyAdpcmStruct.OutputBatchFiles, extractSonyAdpcmStruct.OutputBatchFiles);

                    fileCount++;
                }
            }
        }
Example #20
0
        public static string ExtractAdxStreams(string path, string filePrefix, string outputFolder, out string messages)
        {
            string        extractedToFolder = String.Empty;
            StringBuilder messageBuffer     = new StringBuilder();

            messages = String.Empty;

            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 outputFileName;
            string outputFilePath;

            FileInfo fi = new FileInfo(path);

            using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
            {
                if (!String.IsNullOrEmpty(outputFolder))
                {
                    extractedToFolder = outputFolder;
                }
                else
                {
                    extractedToFolder = Path.Combine(Path.GetDirectoryName(path), String.Format("{0}_ADXs", Path.GetFileNameWithoutExtension(path)));
                }

                while ((offset = ParseFile.GetNextOffset(fs, offset, ADX_SIG_BYTES)) > -1)
                {
                    // 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
                            if (!String.IsNullOrEmpty(filePrefix))
                            {
                                outputFileName = String.Format("{0}_{1}.adx", filePrefix, fileCount.ToString("X8"));
                            }
                            else
                            {
                                outputFileName = String.Format("{0}_{1}.adx", Path.GetFileNameWithoutExtension(path), fileCount.ToString("X8"));
                            }

                            outputFilePath = Path.Combine(extractedToFolder, outputFileName);

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

                            messageBuffer.AppendFormat("{0} - offset: 0x{1} size: 0x{2}{3}", outputFileName, offset.ToString("X8"), fileSize.ToString("X8"), Environment.NewLine);

                            fileCount++;
                        }

                        offset += fileSize;
                    }
                    else
                    {
                        offset += 1;
                    }
                }
            }

            messages = messageBuffer.ToString();

            return(extractedToFolder);
        }
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pPsf2DataFinderStruct, DoWorkEventArgs e)
        {
            Psf2DataFinderStruct psf2Struct = (Psf2DataFinderStruct)pPsf2DataFinderStruct;

            long offset;

            uint   sqLength;
            string sqName;
            int    sqNumber = 0;

            Psf2.ProbableItemStruct sqEntry;
            ArrayList sqFiles = new ArrayList();
            bool      sqNamingMessageDisplayed = false;

            uint   hdLength;
            string hdName;
            int    hdNumber = 0;

            HdStruct  hdObject;
            ArrayList hdArrayList = new ArrayList();

            ArrayList emptyRowList = new ArrayList();

            Psf2.ProbableItemStruct   potentialBd;
            Psf2.ProbableItemStruct[] potentialBdList;
            byte[] bdRow = new byte[0x10];

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

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

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

                offset = 0;

                while ((offset = ParseFile.GetNextOffset(fs, offset, Psf2.HD_SIGNATURE)) > -1)
                {
                    try
                    {
                        hdLength = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4), 0);

                        hdName = String.Format("{0}_{1}.HD", Path.GetFileNameWithoutExtension(pPath), hdNumber++.ToString("X4"));
                        ParseFile.ExtractChunkToFile(fs, offset - 0x10, (int)hdLength,
                                                     Path.Combine(destinationFolder, hdName), true, true);

                        // get info
                        hdObject                  = new HdStruct();
                        hdObject.FileName         = hdName;
                        hdObject.startingOffset   = offset - 0x10;
                        hdObject.length           = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4), 0);
                        hdObject.expectedBdLength = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0x10, 4), 0);
                        hdObject.vagSectionOffset = hdObject.startingOffset + BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0x20, 4), 0);
                        hdObject.maxVagInfoNumber = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, hdObject.vagSectionOffset + 0xC, 4), 0);

                        hdObject.vagInfoOffsetAddr    = new long[hdObject.maxVagInfoNumber + 1];
                        hdObject.vagOffset            = new long[hdObject.maxVagInfoNumber + 1];
                        hdObject.vagLengths           = new long[hdObject.maxVagInfoNumber];
                        hdObject.IsSmallSamplePresent = false;

                        for (int i = 0; i <= hdObject.maxVagInfoNumber; i++)
                        {
                            hdObject.vagInfoOffsetAddr[i] = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, hdObject.vagSectionOffset + 0x10 + (i * 4), 4), 0);
                            hdObject.vagOffset[i]         = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, hdObject.vagSectionOffset + hdObject.vagInfoOffsetAddr[i], 4), 0);

                            if (i > 0)
                            {
                                hdObject.vagLengths[i - 1] = hdObject.vagOffset[i] - hdObject.vagOffset[i - 1];

                                if (hdObject.vagLengths[i - 1] < Psf2.MIN_ADPCM_ROW_SIZE)
                                {
                                    hdObject.IsSmallSamplePresent = true;
                                }
                            }
                        }

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

                    // increment offset
                    offset += 1;
                }
                #endregion

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

                sqEntry = new Psf2.ProbableItemStruct();
                offset  = 0;

                // build file list
                while ((offset = ParseFile.GetNextOffset(fs, offset, Ps2SequenceData.SIGNATURE_BYTES)) > -1)
                {
                    sqLength = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4), 0);

                    if ((!psf2Struct.UseSeqMinimumSize) || ((psf2Struct.UseSeqMinimumSize) &&
                                                            (sqLength >= psf2Struct.MinimumSize)))
                    {
                        sqEntry.offset = offset - 0x10;
                        sqEntry.length = sqLength;
                        sqFiles.Add(sqEntry);
                    }

                    offset += 1;
                }

                foreach (Psf2.ProbableItemStruct sq in sqFiles)
                {
                    if (psf2Struct.ReorderSqFiles)
                    {
                        if (hdArrayList.Count < sqFiles.Count)
                        {
                            if (!sqNamingMessageDisplayed)
                            {
                                this.progressStruct.Clear();
                                this.progressStruct.ErrorMessage = String.Format(
                                    "Warning, cannot reorder SQ files, there are less HD files than SQ files.{0}", Environment.NewLine);
                                this.ReportProgress(this.progress, this.progressStruct);
                                sqNamingMessageDisplayed = true;
                            }

                            sqName = String.Format("{0}_{1}.SQ", Path.GetFileNameWithoutExtension(pPath), sqNumber++.ToString("X4"));
                        }
                        else
                        {
                            hdObject = (HdStruct)hdArrayList[hdArrayList.Count - sqFiles.Count + sqNumber++];
                            sqName   = Path.ChangeExtension(hdObject.FileName, ".SQ");
                        }
                    }
                    else
                    {
                        sqName = String.Format("{0}_{1}.SQ", Path.GetFileNameWithoutExtension(pPath), sqNumber++.ToString("X4"));
                    }

                    ParseFile.ExtractChunkToFile(fs, sq.offset, (int)sq.length,
                                                 Path.Combine(destinationFolder, sqName), true, true);
                }


                #endregion

                // get BD files
                #region BD EXTRACT
                this.progressStruct.Clear();
                this.progressStruct.GenericMessage = String.Format("  Extracting BD...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
                potentialBd = new Psf2.ProbableItemStruct();

                while ((offset = ParseFile.GetNextOffset(fs, offset, Psf2.VB_START_BYTES, false)) > -1)
                {
                    //if (offset == 0x1DD3800)
                    //{
                    //    int fff = 1;
                    //}

                    if ((psf2Struct.UseZeroOffsetForBd) && (offset % 0x10 == 0) ||
                        (!psf2Struct.UseZeroOffsetForBd))
                    {
                        try
                        {
                            bdRow = ParseFile.ParseSimpleOffset(fs, offset, bdRow.Length);

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

                    offset += 1;
                }

                potentialBdList = (Psf2.ProbableItemStruct[])emptyRowList.ToArray(typeof(Psf2.ProbableItemStruct));

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

                // compare HD sample sizes to potential adpcm sizes/indexes
                hdObject.startingOffset   = 0;
                hdObject.length           = 0;
                hdObject.bdStartingOffset = 0;
                hdObject.bdLength         = 0;

                string   bdName;
                string   newFileName;
                string[] dupeFileNames;

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

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

                                        if (dupeFileNames.Length >= 1)
                                        {
                                            bdName = String.Format("{0}_{1}.BD", Path.GetFileNameWithoutExtension(hdObject.FileName), (dupeFileNames.Length).ToString("X4"));

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


                                        ParseFile.ExtractChunkToFile(fs, hdObject.bdStartingOffset, (int)hdObject.bdLength,
                                                                     Path.Combine(destinationFolder, bdName), 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
            }
        }
Example #22
0
        static void Main(string[] args)
        {
            string inFilename;
            string outFilename;
            string startOffset;
            string endOffset;

            string fullInputPath;
            string fullOutputPath;

            long longStartOffset;
            long longEndOffset;

            if (args.Length < 3)
            {
                Console.WriteLine("Usage: snakebite.exe <infile> <outfile> <start offset> <end offset>");
                Console.WriteLine("   or: snakebite.exe <infile> <outfile> <start offset>");
                Console.WriteLine();
                Console.WriteLine("The 3 parameter option will read from <start offset> to EOF.");
            }
            else
            {
                inFilename  = args[0];
                outFilename = args[1];
                startOffset = args[2];


                fullInputPath  = Path.GetFullPath(inFilename);
                fullOutputPath = Path.GetFullPath(outFilename);

                if (File.Exists(fullInputPath))
                {
                    using (FileStream fs = File.OpenRead(fullInputPath))
                    {
                        if (startOffset.StartsWith("0x"))
                        {
                            startOffset     = startOffset.Substring(2);
                            longStartOffset = long.Parse(startOffset, System.Globalization.NumberStyles.HexNumber, null);
                        }
                        else
                        {
                            longStartOffset = long.Parse(startOffset, System.Globalization.NumberStyles.Integer, null);
                        }

                        if (args.Length > 3)
                        {
                            endOffset = args[3];

                            if (endOffset.StartsWith("0x"))
                            {
                                endOffset     = endOffset.Substring(2);
                                longEndOffset = long.Parse(endOffset, System.Globalization.NumberStyles.HexNumber, null);
                            }
                            else
                            {
                                longEndOffset = long.Parse(endOffset, System.Globalization.NumberStyles.Integer, null);
                            }
                        }
                        else
                        {
                            longEndOffset = fs.Length;
                        }

                        long size = ((longEndOffset - longStartOffset) + 1);

                        ParseFile.ExtractChunkToFile(fs, longStartOffset, size, fullOutputPath);
                    }
                }
                else
                {
                    Console.WriteLine("File Not Found: " + fullInputPath);
                }
            }
        }
Example #23
0
        public static void ExtractCdData(Stream cdStream,
                                         string destinationPath, long volumeBaseOffset,
                                         long lba, long length, bool isRaw, long nonRawSectorSize,
                                         CdSectorType fileMode, bool extractAsRaw)
        {
            long offset;
            int  maxWriteSize;
            long bytesWritten = 0;

            CdSectorType mode;
            long         lbaCounter = 0;

            byte[] sectorHeader;
            byte[] sector;

            // create directory
            string destinationFolder = Path.GetDirectoryName(destinationPath);

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

            if (isRaw)
            {
                switch (fileMode)
                {
                case CdSectorType.Audio:
                case CdSectorType.Mode2Form2:
                case CdSectorType.XaInterleaved:
                    offset = volumeBaseOffset + ((lba + lbaCounter) * CdRom.RAW_SECTOR_SIZE);
                    ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath);
                    break;

                default:
                    mode = fileMode;

                    using (FileStream outStream = File.OpenWrite(destinationPath))
                    {
                        while (bytesWritten < length)
                        {
                            offset       = volumeBaseOffset + ((lba + lbaCounter) * CdRom.RAW_SECTOR_SIZE);
                            sector       = ParseFile.ParseSimpleOffset(cdStream, offset, (int)CdRom.RAW_SECTOR_SIZE);
                            sectorHeader = ParseFile.ParseSimpleOffset(sector, 0, MAX_HEADER_SIZE);

                            if (mode == CdSectorType.Unknown)
                            {
                                mode = GetSectorType(sectorHeader);
                            }

                            maxWriteSize = CdRom.ModeDataSize[mode] < (length - bytesWritten) ? CdRom.ModeDataSize[mode] : (int)(length - bytesWritten);

                            if (extractAsRaw)
                            {
                                outStream.Write(sector, 0, sector.Length);
                            }
                            else
                            {
                                outStream.Write(sector, CdRom.ModeHeaderSize[mode], maxWriteSize);
                            }

                            bytesWritten += maxWriteSize;
                            lbaCounter++;
                        }
                    }
                    break;
                }
                ;
            }
            else
            {
                offset = volumeBaseOffset + (lba * nonRawSectorSize);
                ParseFile.ExtractChunkToFile(cdStream, offset, length, destinationPath);
            }
        }
Example #24
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;
                    }
                }
            }
        }
Example #25
0
        protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractAdxStruct, DoWorkEventArgs e)
        {
            ExtractHcaStruct extractAdxStruct = (ExtractHcaStruct)pExtractAdxStruct;

            long offset = 0;

            byte   revisionMajor;
            byte   revisionMinor;
            ushort dataOffset;

            long fmtChunkOffset;

            uint   blockCount;
            ushort blockSize;

            long fileSize;

            int    fileCount  = 0;
            string outputPath = Path.Combine(Path.GetDirectoryName(pPath), "_cri_hca_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}_HCAs", Path.GetFileNameWithoutExtension(pPath)));

                while ((offset = ParseFile.GetNextOffsetMasked(fs, offset, HCA_SIG_BYTES, MASK_BYTES)) > -1)
                {
                    if (!this.CancellationPending)
                    {
                        // get version
                        revisionMajor = ParseFile.ReadByte(fs, offset + 4);
                        revisionMinor = ParseFile.ReadByte(fs, offset + 5);

                        // get data offset
                        dataOffset = ParseFile.ReadUshortBE(fs, offset + 6);

                        // get 'fmt' chunk offset
                        fmtChunkOffset = ParseFile.GetNextOffsetMasked(fs, offset, FMT_CHUNK_BYTES, MASK_BYTES);

                        if (fmtChunkOffset > -1)
                        {
                            // get block count
                            blockCount = ParseFile.ReadUintBE(fs, fmtChunkOffset + 8);


                            // get block size
                            blockSize = this.getBlockSize(fs, offset);


                            // calculate file size
                            fileSize = dataOffset + (blockCount * blockSize);

                            // extract file
                            outputFileName = String.Format("{0}_{1}.hca", 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, fileSize, outputFilePath, true, true);

                            // increment counter
                            fileCount++;

                            // move pointer
                            offset += fileSize;
                        }
                        else
                        {
                            throw new FormatException(String.Format("'fmt' chunk not found for HCA starting at 0x{0}", offset.ToString("X8")));
                        }
                    }
                    else
                    {
                        e.Cancel = true;
                        return;
                    }
                }
            }
        }