public static Mp3XingBlock.Model Create(byte[] buf, Mp3Header header) { System.Diagnostics.Debug.Assert(header.IsMpegLayer3); int xix = header.XingOffset; string xingString = ConvertTo.FromAsciiToString(buf, xix, 4); if (xingString == "Info" || xingString == "Xing") { string lameString = ConvertTo.FromAsciiToString(buf, xix + 0x78, 9); if (lameString.StartsWith("LAME")) { return(new Mp3LameBlock.Model(buf, xix, header, xingString, lameString)); } else { return(new Mp3XingBlock.Model(buf, xix, header, xingString)); } } return(null); }
private void ParseAif(Stream stream, byte[] hdr) { Data.GroupId = ConvertTo.FromAsciiToString(hdr, 0, 4); Data.FormType = ConvertTo.FromAsciiToString(hdr, 8, 4); UInt32 gSize = ConvertTo.FromBig32ToUInt32(hdr, 4); if (gSize < 12 || gSize > stream.Length - 8) { IssueModel.Add("File truncated or corrupt.", Severity.Fatal); return; } int hPos = 12; string id0 = ConvertTo.FromAsciiToString(hdr, 12, 4); if (Data.IsCompressed) { if (id0 != "FVER") { IssueModel.Add("Missing 'FVER' chunk."); return; } UInt32 vSize = ConvertTo.FromBig32ToUInt32(hdr, 16); if (vSize != 4) { IssueModel.Add("Bad 'FVER' chunk."); return; } hPos = 24; id0 = ConvertTo.FromAsciiToString(hdr, 24, 4); } if (id0 != "COMM") { IssueModel.Add("Missing 'COMM' chunk."); return; } UInt32 cSize = ConvertTo.FromBig32ToUInt32(hdr, hPos + 4); if (cSize < 18 || cSize > stream.Length - 8) { IssueModel.Add("Bad 'COMM' chunk."); return; } Data.ChannelCount = ConvertTo.FromBig16ToInt32(hdr, hPos + 8); Data.SampleSize = ConvertTo.FromBig16ToInt32(hdr, hPos + 14); ++Data.IffChunkCount; Data.IffSize = gSize; Data.mediaPosition = 0; Data.MediaCount = gSize + 8; Data.ValidSize = hPos + cSize + 8; var hasSSND = false; var buf = new byte[8]; while (Data.ValidSize < Data.MediaCount) { stream.Position = Data.ValidSize; int got = stream.Read(buf, 0, 8); if (got != 8) { IssueModel.Add("Read failed."); return; } cSize = ConvertTo.FromBig32ToUInt32(buf, 4); if (cSize < 8 || Data.ValidSize + cSize > Data.MediaCount - 8) { IssueModel.Add("Bad chunk size or truncated file."); return; } string id = ConvertTo.FromAsciiToString(buf, 0, 4); if (id == "SSND") { if (hasSSND) { IssueModel.Add("Many 'SSND' chunks."); return; } hasSSND = true; } else if (id != "(c) " && id != "ANNO" && id != "AUTH" && id != "NAME") { IssueModel.Add($"Unexpected '{id}' chunk.", Severity.Trivia, IssueTags.StrictWarn); return; } Data.ValidSize += cSize + 8; if ((cSize & 1) != 0) { ++Data.ValidSize; } } if (!hasSSND) { IssueModel.Add("Missing 'SSND' chunk.", Severity.Warning); } }