Esempio n. 1
0
 public void ParseFrameHeader(Stream inStream, long currentOffset, ref FrameHeader fHeader)
 {
     fHeader.Clear();
     fHeader.FrameId1  = ParseFile.ReadUshortBE(inStream, currentOffset);
     fHeader.FrameId2  = ParseFile.ReadUshortBE(inStream, currentOffset + 2);
     fHeader.FrameSize = ParseFile.ReadUintBE(inStream, currentOffset + 4);
 }
Esempio n. 2
0
        protected override void ReadHeader(FileStream inStream, long offset)
        {
            long currentOffset = offset;

            ushort chunkTypeId;
            ushort subChunkCount;

            // read header size
            this.HeaderSize = ParseFile.ReadUintLE(inStream, currentOffset + 4) + 8;
            currentOffset  += 8;

            while (currentOffset < this.HeaderSize)
            {
                // read chunk type id
                chunkTypeId = ParseFile.ReadUshortBE(inStream, currentOffset);

                // read subchunk count
                subChunkCount = ParseFile.ReadUshortLE(inStream, currentOffset + 2);

                switch (chunkTypeId)
                {
                // get audio details
                case MobiclipWiiStream.AudioChunkSignature:
                    this.AudioStreamCount    = ParseFile.ReadUintLE(inStream, currentOffset + 4);
                    this.AudioStreamFeatures = new MobiclipAudioStreamFeatures[this.AudioStreamCount];

                    for (uint i = 0; i < this.AudioStreamCount; i++)
                    {
                        this.AudioStreamFeatures[i]            = new MobiclipAudioStreamFeatures();
                        this.AudioStreamFeatures[i].StreamType = ParseFile.ReadUshortBE(inStream, currentOffset + 8 + (i * 0xA));
                        this.AudioStreamFeatures[i].Frequency  = ParseFile.ReadUintLE(inStream, currentOffset + 8 + (i * 0xA) + 2);
                        this.AudioStreamFeatures[i].Channels   = ParseFile.ReadUintLE(inStream, currentOffset + 8 + (i * 0xA) + 6);
                    }

                    break;

                case MobiclipWiiStream.AudioChunkSignaturePcm:
                case MobiclipWiiStream.AudioChunkSignatureA3:
                    this.AudioStreamCount                  = 1;
                    this.AudioStreamFeatures               = new MobiclipAudioStreamFeatures[this.AudioStreamCount];
                    this.AudioStreamFeatures[0]            = new MobiclipAudioStreamFeatures();
                    this.AudioStreamFeatures[0].StreamType = ParseFile.ReadUshortBE(inStream, currentOffset);
                    this.AudioStreamFeatures[0].Frequency  = ParseFile.ReadUintLE(inStream, currentOffset + 4);
                    this.AudioStreamFeatures[0].Channels   = ParseFile.ReadUintLE(inStream, currentOffset + 8);
                    break;

                default:
                    break;
                }

                currentOffset += (subChunkCount * 4) + 4;
            }
        }
Esempio n. 3
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;
            }
        }
Esempio n. 4
0
        public NintendoWad(string sourceFile)
        {
            // check magic bytes
            if (NintendoWad.IsWadFile(sourceFile))
            {
                // read header
                using (FileStream fs = File.OpenRead(sourceFile))
                {
                    // set source file
                    this.SourceFileName = sourceFile;

                    // parse header
                    this.HeaderSize           = ParseFile.ReadUintBE(fs, 0);
                    this.WadType              = ParseFile.ReadUintBE(fs, 4);
                    this.CertificateChainSize = ParseFile.ReadUintBE(fs, 8);
                    this.Reserved             = ParseFile.ReadUintBE(fs, 0xC);
                    this.TicketSize           = ParseFile.ReadUintBE(fs, 0x10);
                    this.TitleMetaDataSize    = ParseFile.ReadUintBE(fs, 0x14);
                    this.DataSize             = ParseFile.ReadUintBE(fs, 0x18);
                    this.FooterSize           = ParseFile.ReadUintBE(fs, 0x1C);

                    // offsets
                    this.CertificateChainOffset = (uint)this.PadValue(this.HeaderSize, "Certificate Chain Offset");
                    this.TicketOffset           = (uint)this.PadValue(this.CertificateChainOffset + this.CertificateChainSize, "Ticket Offset");
                    this.TitleMetaDataOffset    = (uint)this.PadValue(this.TicketOffset + this.TicketSize, "Title Meta Data Offset");
                    this.DataOffset             = (uint)this.PadValue(this.TitleMetaDataOffset + this.TitleMetaDataSize, "Data Offset");
                    this.FooterOffset           = (uint)this.PadValue(this.DataOffset + this.DataSize, "Footer Offset");

                    // get important values
                    this.TicketId          = ParseFile.ReadUlongBE(fs, this.TicketOffset + 0x1D0);
                    this.TitleId           = ParseFile.ReadUlongBE(fs, this.TicketOffset + 0x1DC);
                    this.TitleIdBytes      = ParseFile.ParseSimpleOffset(fs, this.TicketOffset + 0x1DC, 8);
                    this.EncryptedTitleKey = ParseFile.ParseSimpleOffset(fs, this.TicketOffset + 0x1BF, 0x10);
                    this.CommonKeyIndex    = ParseFile.ReadByte(fs, this.TicketOffset + 0x1F1);

                    // decrypt title key
                    this.DecryptTitleKey();

                    // get TMD content entries
                    this.NumberOfContents = ParseFile.ReadUshortBE(fs, this.TitleMetaDataOffset + 0x1DE);
                    this.ParseTmdContentEntries(fs);
                } // using (FileStream fs = File.OpenRead(sourceFile))
            }
            else
            {
                throw new FormatException("Nintendo WAD magic bytes not found at offset 0x03.");
            }
        }
Esempio n. 5
0
        private void initializeUtfHeader(FileStream UtfTableFs)
        {
            this.TableSize = ParseFile.ReadUintBE(UtfTableFs, 4);

            this.Unknown1 = ParseFile.ReadUshortBE(UtfTableFs, 8);

            this.RowOffset         = (uint)ParseFile.ReadUshortBE(UtfTableFs, 0xA) + 8;
            this.StringTableOffset = ParseFile.ReadUintBE(UtfTableFs, 0xC) + 8;
            this.DataOffset        = ParseFile.ReadUintBE(UtfTableFs, 0x10) + 8;

            this.TableNameOffset = ParseFile.ReadUintBE(UtfTableFs, 0x14);
            this.TableName       = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + this.TableNameOffset);

            this.NumberOfFields = ParseFile.ReadUshortBE(UtfTableFs, 0x18);

            this.RowSize      = ParseFile.ReadUshortBE(UtfTableFs, 0x1A);
            this.NumberOfRows = ParseFile.ReadUintBE(UtfTableFs, 0x1C);
        }
Esempio n. 6
0
        private ushort getBlockSize(Stream inStream, long hcaOffset)
        {
            ushort blockSize = 0;

            long decChunkOffset;
            long compChunkOffset;

            //----------------
            // 'dec ' offset
            //----------------

            // get 'dec' chunk offset, if exists (v1.3, maybe others?)
            decChunkOffset = ParseFile.GetNextOffsetWithLimitMasked(inStream, hcaOffset,
                                                                    hcaOffset + MAX_HEADER_SIZE, DEC_CHUNK_BYTES, MASK_BYTES, true);

            if (decChunkOffset > -1)
            {
                blockSize = ParseFile.ReadUshortBE(inStream, decChunkOffset + 4);
            }
            else
            {
                //----------------
                // 'comp' offset
                //----------------

                // get 'comp' chunk offset, if exists (v1.3, maybe others?)
                compChunkOffset = ParseFile.GetNextOffsetWithLimitMasked(inStream, hcaOffset,
                                                                         hcaOffset + MAX_HEADER_SIZE, COMP_CHUNK_BYTES, MASK_BYTES, true);

                if (compChunkOffset > -1)
                {
                    blockSize = ParseFile.ReadUshortBE(inStream, compChunkOffset + 4);
                }
                else
                {
                    throw new FormatException(
                              String.Format("Cannot find 'dec' or 'comp' chunk to determine block size for HCA starting at 0x{0}", hcaOffset.ToString("X8")));
                }
            }

            return(blockSize);
        }
Esempio n. 7
0
        /// <summary>
        /// Parse the Content Entries in the Title Meta Data section.
        /// </summary>
        /// <param name="fs">File Stream of WAD.</param>
        private void ParseTmdContentEntries(FileStream fs)
        {
            ulong            nextOffset = this.DataOffset;
            TmdContentStruct contentEntry;
            ArrayList        contentEntryList = new ArrayList();

            for (ushort i = 0; i < this.NumberOfContents; i++)
            {
                contentEntry               = new TmdContentStruct();
                contentEntry.ContentId     = ParseFile.ReadUintBE(fs, this.TitleMetaDataOffset + 0x1E4 + (i * 0x24) + 0);
                contentEntry.ContentIndex  = ParseFile.ReadUshortBE(fs, this.TitleMetaDataOffset + 0x1E4 + (i * 0x24) + 4);
                contentEntry.ContentType   = ParseFile.ReadUshortBE(fs, this.TitleMetaDataOffset + 0x1E4 + (i * 0x24) + 6);
                contentEntry.ContentSize   = ParseFile.ReadUlongBE(fs, this.TitleMetaDataOffset + 0x1E4 + (i * 0x24) + 8);
                contentEntry.Sha1Hash      = ParseFile.ParseSimpleOffset(fs, (this.TitleMetaDataOffset + 0x1E4 + (i * 0x24) + 0x10), 20);
                contentEntry.ContentOffset = nextOffset;
                contentEntryList.Add(contentEntry);

                nextOffset = this.PadValue((contentEntry.ContentOffset + contentEntry.ContentSize),
                                           String.Format("Next Offset for ContentId: 0x{0}", contentEntry.ContentId.ToString("X8")));
            }

            this.TmdContentEntries = (TmdContentStruct[])contentEntryList.ToArray(typeof(TmdContentStruct));
        }
Esempio n. 8
0
        protected void InitializeCueList(FileStream fs)
        {
            this.CueNamesToWaveforms = new Dictionary <string, ushort>();

            ulong referenceItemsOffset = 0;
            ulong referenceItemsSize   = 0;
            ulong referenceCorrection  = 0;

            object dummy;
            byte   isStreaming = 0;

            CriUtfTable cueTableUtf = new CriUtfTable();

            cueTableUtf.Initialize(fs, (long)this.CueTableOffset);

            CriUtfTable waveformTableUtf = new CriUtfTable();

            waveformTableUtf.Initialize(fs, (long)this.WaveformTableOffset);

            CriUtfTable synthTableUtf = new CriUtfTable();

            synthTableUtf.Initialize(fs, (long)this.SynthTableOffset);

            this.CueList = new CriAcbCueRecord[cueTableUtf.NumberOfRows];

            for (int i = 0; i < cueTableUtf.NumberOfRows; i++)
            {
                this.CueList[i] = new CriAcbCueRecord();
                this.CueList[i].IsWaveformIdentified = false;

                this.CueList[i].CueId          = (uint)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "CueId");
                this.CueList[i].ReferenceType  = (byte)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceType");
                this.CueList[i].ReferenceIndex = (ushort)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceIndex");

                switch (this.CueList[i].ReferenceType)
                {
                case 2:
                    referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceCorrection  = referenceItemsSize + 2;
                    break;

                case 3:
                case 8:
                    if (i == 0)
                    {
                        referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceCorrection  = referenceItemsSize - 2;    // samples found have only had a '01 00' record => Always Waveform[0]?.
                    }
                    else
                    {
                        referenceCorrection += 4;     // relative to previous offset, do not lookup
                                                      // @TODO: Should this do a referenceItemsSize - 2 for the ReferenceIndex?  Need to find
                                                      //    one where size > 4.
                        //referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceItemsSize = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceCorrection = referenceItemsSize - 2;
                    }
                    break;

                default:
                    throw new FormatException(String.Format("  Unexpected ReferenceType: '{0}' for CueIndex: '{1}.'  Please report to VGMToolbox thread at hcs64.com forums, see link in 'Other' menu item.", this.CueList[i].ReferenceType.ToString("D"), i.ToString("D")));
                }

                if (referenceItemsSize != 0)
                {
                    // get wave form info
                    this.CueList[i].WaveformIndex = ParseFile.ReadUshortBE(fs, (long)(referenceItemsOffset + referenceCorrection));

                    // get Streaming flag, 0 = in ACB files, 1 = in AWB file
                    dummy = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Streaming");

                    if (dummy != null) // check to see if this Id actually exists in the WaveformIndex
                    {
                        isStreaming = (byte)dummy;
                        this.CueList[i].IsStreaming = isStreaming == 0 ? false : true;

                        // get waveform id and encode type from corresponding waveform
                        var waveformId = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Id");

                        if (waveformId != null)
                        {
                            // early revisions of ACB spec used "Id"
                            this.CueList[i].WaveformId = (ushort)waveformId;
                        }
                        else
                        {
                            // later versions using "MemoryAwbId" and  "StreamingAwbId"
                            if (this.CueList[i].IsStreaming)
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "StreamAwbId");
                            }
                            else
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "MemoryAwbId");
                            }
                        }

                        this.CueList[i].EncodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "EncodeType");


                        // update flag
                        this.CueList[i].IsWaveformIdentified = true;
                    } // if (dummy != null)
                }
            }
        }
Esempio n. 9
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;
                    }
                }
            }
        }
Esempio n. 10
0
        private void initializeUtfSchema(FileStream SourceFs, FileStream UtfTableFs, long schemaOffset)
        {
            long nameOffset;

            long constantOffset;

            long dataOffset;
            long dataSize;

            long rowDataOffset;
            long rowDataSize;

            long currentOffset = schemaOffset;
            long currentRowBase;
            long currentRowOffset = 0;

            CriField field;

            for (uint i = 0; i < this.NumberOfRows; i++)
            {
                //if (i == 0x1a2a)
                //{
                //    int yuuuu = 1;
                //}
                //try
                //{
                currentOffset    = schemaOffset;
                currentRowBase   = this.RowOffset + (this.RowSize * i);
                currentRowOffset = 0;
                this.Rows[i]     = new Dictionary <string, CriField>();

                // parse fields
                for (ushort j = 0; j < this.NumberOfFields; j++)
                {
                    field = new CriField();

                    field.Type = ParseFile.ReadByte(UtfTableFs, currentOffset);
                    nameOffset = ParseFile.ReadUintBE(UtfTableFs, currentOffset + 1);
                    field.Name = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + nameOffset);

                    // each row will have a constant
                    if (((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT) ||
                        ((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT2))
                    {
                        // capture offset of constant
                        constantOffset = currentOffset + 5;

                        // read the constant depending on the type
                        switch (field.Type & COLUMN_TYPE_MASK)
                        {
                        case COLUMN_TYPE_STRING:
                            dataOffset     = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
                            field.Value    = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + dataOffset);
                            currentOffset += 4;
                            break;

                        case COLUMN_TYPE_8BYTE:
                            field.Value    = ParseFile.ReadUlongBE(UtfTableFs, constantOffset);
                            currentOffset += 8;
                            break;

                        case COLUMN_TYPE_DATA:
                            dataOffset   = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
                            dataSize     = ParseFile.ReadUintBE(UtfTableFs, constantOffset + 4);
                            field.Offset = (ulong)(this.BaseOffset + this.DataOffset + dataOffset);
                            field.Size   = (ulong)dataSize;

                            // don't think this is encrypted, need to check
                            field.Value    = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)dataSize);
                            currentOffset += 8;
                            break;

                        case COLUMN_TYPE_FLOAT:
                            field.Value    = ParseFile.ReadFloatBE(UtfTableFs, constantOffset);
                            currentOffset += 4;
                            break;

                        case COLUMN_TYPE_4BYTE2:
                            field.Value    = ParseFile.ReadInt32BE(UtfTableFs, constantOffset);
                            currentOffset += 4;
                            break;

                        case COLUMN_TYPE_4BYTE:
                            field.Value    = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
                            currentOffset += 4;
                            break;

                        case COLUMN_TYPE_2BYTE2:
                            field.Value    = ParseFile.ReadInt16BE(UtfTableFs, constantOffset);
                            currentOffset += 2;
                            break;

                        case COLUMN_TYPE_2BYTE:
                            field.Value    = ParseFile.ReadUshortBE(UtfTableFs, constantOffset);
                            currentOffset += 2;
                            break;

                        case COLUMN_TYPE_1BYTE2:
                            field.Value    = ParseFile.ReadSByte(UtfTableFs, constantOffset);
                            currentOffset += 1;
                            break;

                        case COLUMN_TYPE_1BYTE:
                            field.Value    = ParseFile.ReadByte(UtfTableFs, constantOffset);
                            currentOffset += 1;
                            break;

                        default:
                            throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8")));
                        }     // switch (field.Type & COLUMN_TYPE_MASK)
                    }
                    else if ((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_PERROW)
                    {
                        // read the constant depending on the type
                        switch (field.Type & COLUMN_TYPE_MASK)
                        {
                        case COLUMN_TYPE_STRING:
                            rowDataOffset     = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
                            field.Value       = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + rowDataOffset);
                            currentRowOffset += 4;
                            break;

                        case COLUMN_TYPE_8BYTE:
                            field.Value       = ParseFile.ReadUlongBE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 8;
                            break;

                        case COLUMN_TYPE_DATA:
                            rowDataOffset = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
                            rowDataSize   = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset + 4);
                            field.Offset  = (ulong)(this.BaseOffset + this.DataOffset + rowDataOffset);
                            field.Size    = (ulong)rowDataSize;

                            // don't think this is encrypted
                            field.Value       = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)rowDataSize);
                            currentRowOffset += 8;
                            break;

                        case COLUMN_TYPE_FLOAT:
                            field.Value       = ParseFile.ReadFloatBE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 4;
                            break;

                        case COLUMN_TYPE_4BYTE2:
                            field.Value       = ParseFile.ReadInt32BE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 4;
                            break;

                        case COLUMN_TYPE_4BYTE:
                            field.Value       = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 4;
                            break;

                        case COLUMN_TYPE_2BYTE2:
                            field.Value       = ParseFile.ReadInt16BE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 2;
                            break;

                        case COLUMN_TYPE_2BYTE:
                            field.Value       = ParseFile.ReadUshortBE(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 2;
                            break;

                        case COLUMN_TYPE_1BYTE2:
                            field.Value       = ParseFile.ReadSByte(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 1;
                            break;

                        case COLUMN_TYPE_1BYTE:
                            field.Value       = ParseFile.ReadByte(UtfTableFs, currentRowBase + currentRowOffset);
                            currentRowOffset += 1;
                            break;

                        default:
                            throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8")));
                        } // switch (field.Type & COLUMN_TYPE_MASK)
                    }     // if ((fields[i].Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT)

                    // add field to dictionary
                    this.Rows[i].Add(field.Name, field);

                    // move to next field
                    currentOffset += 5; //  sizeof(CriField.Type + CriField.NameOffset)
                }                       // for (ushort j = 0; j < this.NumberOfFields; j++)
                //}
                //catch (Exception ex)
                //{
                //    int xxxx = 1;
                //}
            } // for (uint i = 0; i < this.NumberOfRows; i++)
        }
Esempio n. 11
0
        public void ParseHeader(Stream inStream, long currentOffset)
        {
            this.HeaderSize      = ParseFile.ReadUintBE(inStream, currentOffset + 0x10);   // 0x10-0x13
            this.BodySize        = ParseFile.ReadUintBE(inStream, currentOffset + 0x14);   // 0x14-0x17
            this.Blocks          = ParseFile.ReadUintBE(inStream, currentOffset + 0x18);   // 0x18-0x1B
            this.AudioFrames     = ParseFile.ReadUintBE(inStream, currentOffset + 0x1C);   // 0x1C-0x1F
            this.VideoFrames     = ParseFile.ReadUintBE(inStream, currentOffset + 0x20);   // 0x20-0x23
            this.Unk24           = ParseFile.ReadUintBE(inStream, currentOffset + 0x24);   // 0x24-0x27 (0x8257,0x8256)
            this.Duration        = ParseFile.ReadUintBE(inStream, currentOffset + 0x28);   // 0x28-0x2B
            this.Unk2C           = ParseFile.ReadUintBE(inStream, currentOffset + 0x2C);   // 0x2C-0x2F (0)
            this.AudioFrameSize  = ParseFile.ReadUintBE(inStream, currentOffset + 0x30);   // 0x30-0x33
            this.Hres            = ParseFile.ReadUshortBE(inStream, currentOffset + 0x34); // 0x34-0x35
            this.Vres            = ParseFile.ReadUshortBE(inStream, currentOffset + 0x36); // 0x36-0x37
            this.Unk38           = ParseFile.ReadUshortBE(inStream, currentOffset + 0x38); // 0x38-0x3B (0x0202)
            this.Unk3A           = ParseFile.ReadByte(inStream, currentOffset + 0x3A);     // 0x3A (0 or 0x12)
            this.Unk3B           = ParseFile.ReadByte(inStream, currentOffset + 0x3B);     // 0x3B (0)
            this.AudioChannels   = ParseFile.ReadByte(inStream, currentOffset + 0x3C);     // 0x3C
            this.AudioBitdepth   = ParseFile.ReadByte(inStream, currentOffset + 0x3D);     // 0x3D
            this.Pad             = ParseFile.ReadUshortBE(inStream, currentOffset + 0x3E); // 0x3E-0x3F (0)
            this.AudioSampleRate = ParseFile.ReadUintBE(inStream, currentOffset + 0x40);   // 0x40-0x43

            // save off original header
            this.FullHeader = ParseFile.ParseSimpleOffset(inStream, currentOffset, (int)this.HeaderSize);

            #region AUDIO/VIDEO features checks
            // set video present flags
            if (this.VideoFrames == 0)
            {
                if (this.Hres == 0)
                {
                    throw new Exception("Video frame count greater than 0, but horizontal resolution equals zero.");
                }
                else if (this.Vres == 0)
                {
                    throw new Exception("Video frame count greater than 0, but vertical resolution equals zero.");
                }
                else
                {
                    this.IsVideoPresent = true;
                }
            }

            // set audio present flags
            if (this.AudioFrames > 0)
            {
                if (this.AudioFrameSize == 0)
                {
                    throw new Exception("Audio frame count greater than 0, but audio frame size equals zero.");
                }
                else if (this.AudioChannels == 0)
                {
                    throw new Exception("Audio frame count greater than 0, but audio channel count equals zero.");
                }
                else if (this.AudioBitdepth == 0)
                {
                    throw new Exception("Audio frame count greater than 0, but audio bit depth equals zero.");
                }
                else if (this.AudioSampleRate == 0)
                {
                    throw new Exception("Audio frame count greater than 0, but audio sample rate equals zero.");
                }
                else
                {
                    this.IsAudioPresent = true;
                }
            }
            #endregion
        }