// Specific implementation for conservation of non-WM/xxx fields public override bool Remove(BinaryWriter w) { if (Settings.ASF_keepNonWMFieldsWhenRemovingTag) { TagData tag = new TagData(); foreach (byte b in frameMapping.Values) { tag.IntegrateValue(b, ""); } foreach (MetaFieldInfo fieldInfo in GetAdditionalFields()) { if (fieldInfo.NativeFieldCode.ToUpper().StartsWith("WM/")) { MetaFieldInfo emptyFieldInfo = new MetaFieldInfo(fieldInfo); emptyFieldInfo.MarkedForDeletion = true; tag.AdditionalFields.Add(emptyFieldInfo); } } BinaryReader r = new BinaryReader(w.BaseStream); return(Write(r, w, tag)); } else { return(base.Remove(w)); } }
public void TagIO_R_ID3v2_WXXX_ManualUpdate() { string testFileLocation = TestUtils.CopyAsTempTestFile("MP3/id3v2.4_UTF8.mp3"); AudioDataManager theFile = new AudioDataManager(ATL.AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); TagData theTag = new TagData(); theTag.AdditionalFields = new List <MetaFieldInfo>(); MetaFieldInfo info = new MetaFieldInfo(MetaDataIOFactory.TAG_ID3V2, "WXXX", "http://justtheurl.com"); theTag.AdditionalFields.Add(info); Assert.IsTrue(theFile.UpdateTagInFile(theTag, tagType)); Assert.IsTrue(theFile.ReadFromFile(false, true)); Assert.IsNotNull(theFile.getMeta(tagType)); IMetaDataIO meta = theFile.getMeta(tagType); Assert.IsTrue(meta.Exists); Assert.IsTrue(meta.AdditionalFields.ContainsKey("WXXX")); Assert.AreEqual("http://justtheurl.com", meta.AdditionalFields["WXXX"].Split(Settings.InternalValueSeparator)[1]); File.Delete(testFileLocation); }
// Specific implementation for conservation of fields that are required for playback public override bool Remove(BinaryWriter w) { // Empty metadata TagData tag = new TagData(); foreach (byte b in extendedFrameMapping.Values) { tag.IntegrateValue(b, ""); } byte fieldCode; foreach (MetaFieldInfo fieldInfo in GetAdditionalFields()) { fieldCode = Byte.Parse(fieldInfo.NativeFieldCode); if (!playbackFrames.Contains(fieldCode)) { MetaFieldInfo emptyFieldInfo = new MetaFieldInfo(fieldInfo); emptyFieldInfo.MarkedForDeletion = true; tag.AdditionalFields.Add(emptyFieldInfo); } } BinaryReader r = new BinaryReader(w.BaseStream); return(Write(r, w, tag)); }
// Specific implementation for conservation of fields that are required for playback public override bool Remove(BinaryWriter w) { TagData tag = new TagData(); foreach (byte b in frameMapping.Values) { tag.IntegrateValue(b, ""); } string fieldCode; foreach (MetaFieldInfo fieldInfo in GetAdditionalFields()) { fieldCode = fieldInfo.NativeFieldCode.ToLower(); if (!fieldCode.StartsWith("_") && !fieldCode.Equals("DSIZ") && !fieldCode.Equals("COMM")) { MetaFieldInfo emptyFieldInfo = new MetaFieldInfo(fieldInfo); emptyFieldInfo.MarkedForDeletion = true; tag.AdditionalFields.Add(emptyFieldInfo); } } BinaryReader r = new BinaryReader(w.BaseStream); return(Write(r, w, tag)); }
// Specific implementation for conservation of fields that are required for playback public override bool Remove(BinaryWriter w) { TagData tag = new TagData(); foreach (byte b in frameMapping.Values) { tag.IntegrateValue(b, ""); } string fieldCode; foreach (MetaFieldInfo fieldInfo in GetAdditionalFields()) { fieldCode = fieldInfo.NativeFieldCode.ToLower(); if (!fieldCode.StartsWith("_") && !playbackFrames.Contains(fieldCode)) { MetaFieldInfo emptyFieldInfo = new MetaFieldInfo(fieldInfo); emptyFieldInfo.MarkedForDeletion = true; tag.AdditionalFields.Add(emptyFieldInfo); } } w.BaseStream.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin); BinaryReader r = new BinaryReader(w.BaseStream); return(Write(r, w, tag)); }
// FLAC-specific override to handle multiple tags being authorized (e.g. representing multiple artists with multiple ARTIST tags) public new void SetMetaField(string ID, string data, bool readAllMetaFrames, string zone = DEFAULT_ZONE_NAME, byte tagVersion = 0, ushort streamNumber = 0, string language = "") { // Finds the ATL field identifier byte supportedMetaID = getFrameMapping(zone, ID, tagVersion); // If ID has been mapped with an 'classic' ATL field, store it in the dedicated place... if (supportedMetaID < 255) { string targetData = data; if (tagData.hasKey(supportedMetaID)) // If the value already exists, concatenate it with the new one { targetData = tagData[supportedMetaID] + Settings.InternalValueSeparator + data; } base.SetMetaField(ID, targetData, readAllMetaFrames, zone, tagVersion, streamNumber, language); } else if (readAllMetaFrames && ID.Length > 0) // ...else store it in the additional fields Dictionary { MetaFieldInfo fieldInfo = new MetaFieldInfo(getImplementedTagType(), ID, data, streamNumber, language, zone); if (tagData.AdditionalFields.Contains(fieldInfo)) // Prevent duplicates { foreach (MetaFieldInfo info in tagData.AdditionalFields) { if (info.Equals(fieldInfo)) // If the value already exists, concatenate it with the new one { fieldInfo.Value = info.Value + Settings.InternalValueSeparator + fieldInfo.Value; } } tagData.AdditionalFields.Remove(fieldInfo); } tagData.AdditionalFields.Add(fieldInfo); } }
public void SetMetaField(string ID, string data, bool readAllMetaFrames, string zone = FileStructureHelper.DEFAULT_ZONE_NAME, byte tagVersion = 0, ushort streamNumber = 0, string language = "") { // Finds the ATL field identifier byte supportedMetaID = getFrameMapping(zone, ID, tagVersion); // If ID has been mapped with an 'classic' ATL field, store it in the dedicated place... if (supportedMetaID < 255) { if (TagData.TAG_FIELD_TRACK_NUMBER == supportedMetaID && data.Length > 1 && data.StartsWith("0")) { tagData.TrackDigitsForLeadingZeroes = data.Length; } else if (TagData.TAG_FIELD_TRACK_NUMBER_TOTAL == supportedMetaID) { if (data.Contains("/")) { string[] parts = data.Split('/'); if (parts[0].Length > 1 && parts[0].StartsWith("0")) { tagData.TrackDigitsForLeadingZeroes = parts[0].Length; } } } else if (TagData.TAG_FIELD_DISC_NUMBER == supportedMetaID && data.Length > 1 && data.StartsWith("0")) { tagData.DiscDigitsForLeadingZeroes = data.Length; } else if (TagData.TAG_FIELD_DISC_NUMBER_TOTAL == supportedMetaID) { if (data.Contains("/")) { string[] parts = data.Split('/'); if (parts[0].Length > 1 && parts[0].StartsWith("0")) { tagData.DiscDigitsForLeadingZeroes = parts[0].Length; } } } setMetaField(supportedMetaID, data); } else if (readAllMetaFrames) // ...else store it in the additional fields Dictionary { if (ID.Length > 0) { MetaFieldInfo fieldInfo = new MetaFieldInfo(getImplementedTagType(), ID, data, streamNumber, language, zone); if (tagData.AdditionalFields.Contains(fieldInfo)) // Prevent duplicates { tagData.AdditionalFields.Remove(fieldInfo); } tagData.AdditionalFields.Add(fieldInfo); } } }
private void writeCommentChunk(BinaryWriter w, MetaFieldInfo info, string comment = "") { byte[] commentData = null; if (null == info) // Plain string { w.Write(StreamUtils.EncodeBEUInt32(encodeTimestamp(DateTime.Now))); w.Write((short)0); commentData = Utils.Latin1Encoding.GetBytes(comment); } else { w.Write(StreamUtils.EncodeBEUInt32(((CommentData)info.SpecificData).Timestamp)); w.Write(StreamUtils.EncodeBEInt16(((CommentData)info.SpecificData).MarkerId)); commentData = Utils.Latin1Encoding.GetBytes(info.Value); } w.Write(StreamUtils.EncodeBEUInt16((ushort)commentData.Length)); w.Write(commentData); }
public TagData GetDeletionTagData() { TagData tag = new TagData(); foreach (byte b in frameMapping.Values) { tag.IntegrateValue(b, ""); } foreach (MetaFieldInfo fieldInfo in GetAdditionalFields()) { if (!fieldInfo.NativeFieldCode.Equals(VENDOR_METADATA_ID)) { MetaFieldInfo emptyFieldInfo = new MetaFieldInfo(fieldInfo); emptyFieldInfo.MarkedForDeletion = true; tag.AdditionalFields.Add(emptyFieldInfo); } } return(tag); }
private void CreateMetaField(MetaFieldInfo fieldInfo) { var metaContext = OrderContext.MetaDataContext; if (MetaField.GetList(metaContext).Any(x => x.Name == fieldInfo.Name)) { return; } MetaField.Create( metaContext, fieldInfo.MetaNamespace, fieldInfo.Name, fieldInfo.FriendlyName, fieldInfo.Description, fieldInfo.MetaFieldType, fieldInfo.Length, fieldInfo.IsNullable, fieldInfo.IsMultiLanguage, fieldInfo.IsSearchable, fieldInfo.IsEncrypted); }
public void SetMetaField(string ID, string data, bool readAllMetaFrames, string zone = FileStructureHelper.DEFAULT_ZONE_NAME, byte tagVersion = 0, ushort streamNumber = 0, string language = "") { // Finds the ATL field identifier byte supportedMetaID = getFrameMapping(zone, ID, tagVersion); // If ID has been mapped with an 'classic' ATL field, store it in the dedicated place... if (supportedMetaID < 255) { setMetaField(supportedMetaID, data); } else if (readAllMetaFrames) // ...else store it in the additional fields Dictionary { if (ID.Length > 0) { MetaFieldInfo fieldInfo = new MetaFieldInfo(getImplementedTagType(), ID, data, streamNumber, language, zone); if (tagData.AdditionalFields.Contains(fieldInfo)) // Prevent duplicates { tagData.AdditionalFields.Remove(fieldInfo); } tagData.AdditionalFields.Add(fieldInfo); } } }
public void test_RW_Unsupported_Empty(string fileName, bool deleteTempFile = true) { ConsoleLogger log = new ConsoleLogger(); // Source : totally metadata-free file string location = TestUtils.GetResourceLocationRoot() + fileName; string testFileLocation = TestUtils.CopyAsTempTestFile(fileName); AudioDataManager theFile = new AudioDataManager(ATL.AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); // Check that it is indeed tag-free Assert.IsTrue(theFile.ReadFromFile()); Assert.IsNotNull(theFile.getMeta(tagType)); IMetaDataIO meta = theFile.getMeta(tagType); if (canMetaNotExist) { Assert.IsFalse(meta.Exists); } bool handleUnsupportedFields = (testData.AdditionalFields != null && testData.AdditionalFields.Count > 0); bool handleUnsupportedPictures = (testData.Pictures != null && testData.Pictures.Count > 0); char internationalChar = supportsInternationalChars ? '父' : '!'; // Add new unsupported fields TagData theTag = new TagData(); if (handleUnsupportedFields) { theTag.AdditionalFields.Add(new MetaFieldInfo(tagType, "TEST", "This is a test " + internationalChar)); theTag.AdditionalFields.Add(new MetaFieldInfo(tagType, "TES2", "This is another test " + internationalChar)); } // Add new unsupported pictures PictureInfo picInfo = null; byte found = 0; object pictureCode1, pictureCode2; if (tagType.Equals(MetaDataIOFactory.TAG_APE)) { pictureCode1 = "pic1"; pictureCode2 = "pic2"; } else { pictureCode1 = 23; pictureCode2 = 24; } if (handleUnsupportedPictures) { byte[] data = File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic1.jpg"); picInfo = PictureInfo.fromBinaryData(data, PIC_TYPE.Unsupported, tagType, pictureCode1); theTag.Pictures.Add(picInfo); data = File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic2.jpg"); picInfo = PictureInfo.fromBinaryData(data, PIC_TYPE.Unsupported, tagType, pictureCode2); theTag.Pictures.Add(picInfo); } theFile.UpdateTagInFile(theTag, tagType); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.getMeta(tagType)); meta = theFile.getMeta(tagType); Assert.IsTrue(meta.Exists); if (handleUnsupportedFields) { Assert.AreEqual(2, meta.AdditionalFields.Count); Assert.IsTrue(meta.AdditionalFields.Keys.Contains("TEST")); Assert.AreEqual("This is a test " + internationalChar, meta.AdditionalFields["TEST"]); Assert.IsTrue(meta.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test " + internationalChar, meta.AdditionalFields["TES2"]); } if (handleUnsupportedPictures) { Assert.AreEqual(2, meta.EmbeddedPictures.Count); found = 0; foreach (PictureInfo pic in meta.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && (pic.NativePicCode.Equals(pictureCode1) || (pic.NativePicCodeStr != null && pic.NativePicCodeStr.Equals(pictureCode1))) ) { using (Image picture = Image.FromStream(new MemoryStream(pic.PictureData))) { Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(600, picture.Height); Assert.AreEqual(900, picture.Width); } found++; } else if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && (pic.NativePicCode.Equals(pictureCode2) || (pic.NativePicCodeStr != null && pic.NativePicCodeStr.Equals(pictureCode2))) ) { using (Image picture = Image.FromStream(new MemoryStream(pic.PictureData))) { Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(290, picture.Height); Assert.AreEqual(900, picture.Width); } found++; } } Assert.AreEqual(2, found); } // Remove the additional unsupported field if (handleUnsupportedFields) { theTag = new TagData(); MetaFieldInfo fieldInfo = new MetaFieldInfo(tagType, "TEST"); fieldInfo.MarkedForDeletion = true; theTag.AdditionalFields.Add(fieldInfo); } // Remove additional picture if (handleUnsupportedPictures) { picInfo = new PictureInfo(tagType, pictureCode1); picInfo.MarkedForDeletion = true; theTag.Pictures.Add(picInfo); } // Add the new tag and check that it has been indeed added with all the correct information Assert.IsTrue(theFile.UpdateTagInFile(theTag, tagType)); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.getMeta(tagType)); meta = theFile.getMeta(tagType); Assert.IsTrue(meta.Exists); if (handleUnsupportedFields) { // Additional removed field Assert.AreEqual(1, meta.AdditionalFields.Count); Assert.IsTrue(meta.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test " + internationalChar, meta.AdditionalFields["TES2"]); } // Pictures if (handleUnsupportedPictures) { Assert.AreEqual(1, meta.EmbeddedPictures.Count); found = 0; foreach (PictureInfo pic in meta.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && (pic.NativePicCode.Equals(pictureCode2) || (pic.NativePicCodeStr != null && pic.NativePicCodeStr.Equals(pictureCode2))) ) { using (Image picture = Image.FromStream(new MemoryStream(pic.PictureData))) { Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(290, picture.Height); Assert.AreEqual(900, picture.Width); } found++; } } Assert.AreEqual(1, found); } // Get rid of the working copy if (deleteTempFile) { File.Delete(testFileLocation); } }
public void TagIO_RW_VorbisFLAC_Unsupported_Empty() { // Source : tag-free file String testFileLocation = TestUtils.GetTempTestFile(emptyFile); AudioDataManager theFile = new AudioDataManager(AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); // Check that it is indeed tag-free Assert.IsTrue(theFile.ReadFromFile()); Assert.IsNotNull(theFile.NativeTag); Assert.IsFalse(theFile.NativeTag.Exists); // Add new unsupported fields TagData theTag = new TagData(); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST", "This is a test 父")); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST2", "This is another test 父")); // Add new unsupported pictures PictureInfo picInfo = new PictureInfo(Commons.ImageFormat.Jpeg, MetaDataIOFactory.TAG_NATIVE, 0x0A); picInfo.PictureData = File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic1.jpg"); theTag.Pictures.Add(picInfo); picInfo = new PictureInfo(Commons.ImageFormat.Jpeg, MetaDataIOFactory.TAG_NATIVE, 0x0B); picInfo.PictureData = File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic2.jpg"); theTag.Pictures.Add(picInfo); theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); Assert.AreEqual(3, theFile.NativeTag.AdditionalFields.Count); // 3 instead of 2 because of the VENDOR field... (specific to VorbisTag) Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST")); Assert.AreEqual("This is a test 父", theFile.NativeTag.AdditionalFields["TEST"]); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST2")); Assert.AreEqual("This is another test 父", theFile.NativeTag.AdditionalFields["TEST2"]); Assert.AreEqual(2, theFile.NativeTag.EmbeddedPictures.Count); byte found = 0; foreach (PictureInfo pic in theFile.NativeTag.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && pic.NativePicCode.Equals(0x0A)) { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 600); Assert.AreEqual(picture.Width, 900); found++; } else if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && pic.NativePicCode.Equals(0x0B)) { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 290); Assert.AreEqual(picture.Width, 900); found++; } } Assert.AreEqual(2, found); // Remove the additional unsupported field theTag = new TagData(); MetaFieldInfo fieldInfo = new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST"); fieldInfo.MarkedForDeletion = true; theTag.AdditionalFields.Add(fieldInfo); // Remove additional picture picInfo = new PictureInfo(Commons.ImageFormat.Jpeg, MetaDataIOFactory.TAG_NATIVE, 0x0A); picInfo.MarkedForDeletion = true; theTag.Pictures.Add(picInfo); // Add the new tag and check that it has been indeed added with all the correct information Assert.IsTrue(theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE)); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); // Additional removed field Assert.AreEqual(2, theFile.NativeTag.AdditionalFields.Count); // 2 instead of 1 because of the VENDOR field... Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST2")); Assert.AreEqual("This is another test 父", theFile.NativeTag.AdditionalFields["TEST2"]); // Pictures Assert.AreEqual(1, theFile.NativeTag.EmbeddedPictures.Count); found = 0; foreach (PictureInfo pic in theFile.NativeTag.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Unsupported) && pic.NativePicCode.Equals(0x0B)) { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 290); Assert.AreEqual(picture.Width, 900); found++; } } Assert.AreEqual(1, found); // Get rid of the working copy File.Delete(testFileLocation); }
public void TagIO_RW_MP4_Unsupported_Empty() { // Source : tag-free M4A String testFileLocation = TestUtils.CopyAsTempTestFile(emptyFile); AudioDataManager theFile = new AudioDataManager(ATL.AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); // Check that it is indeed tag-free Assert.IsTrue(theFile.ReadFromFile()); Assert.IsNotNull(theFile.NativeTag); Assert.IsFalse(theFile.NativeTag.Exists); // Add new unsupported fields TagData theTag = new TagData(); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST", "This is a test 父")); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TES2", "This is another test 父")); // Add new unsupported pictures PictureInfo picInfo = PictureInfo.fromBinaryData( File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic1.jpg"), PIC_TYPE.Unsupported, MetaDataIOFactory.TAG_NATIVE, "1234"); theTag.Pictures.Add(picInfo); picInfo = PictureInfo.fromBinaryData( File.ReadAllBytes(TestUtils.GetResourceLocationRoot() + "_Images/pic2.jpg"), PIC_TYPE.Unsupported, MetaDataIOFactory.TAG_NATIVE, "5678"); theTag.Pictures.Add(picInfo); theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); Assert.AreEqual(2, theFile.NativeTag.AdditionalFields.Count); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST")); Assert.AreEqual("This is a test 父", theFile.NativeTag.AdditionalFields["TEST"]); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test 父", theFile.NativeTag.AdditionalFields["TES2"]); Assert.AreEqual(2, theFile.NativeTag.EmbeddedPictures.Count); byte found = 0; foreach (PictureInfo pic in theFile.NativeTag.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Generic) && (0 == found)) // No custom nor categorized picture type in MP4 { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 600); Assert.AreEqual(picture.Width, 900); found++; } else if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Generic) && (1 == found)) // No custom nor categorized picture type in MP4 { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 290); Assert.AreEqual(picture.Width, 900); found++; } } Assert.AreEqual(2, found); // Remove the additional unsupported field theTag = new TagData(); MetaFieldInfo fieldInfo = new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST"); fieldInfo.MarkedForDeletion = true; theTag.AdditionalFields.Add(fieldInfo); // Remove additional picture picInfo = new PictureInfo(PictureInfo.PIC_TYPE.Generic, 1); picInfo.MarkedForDeletion = true; theTag.Pictures.Add(picInfo); // Add the new tag and check that it has been indeed added with all the correct information Assert.IsTrue(theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE)); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); // Additional removed field Assert.AreEqual(1, theFile.NativeTag.AdditionalFields.Count); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test 父", theFile.NativeTag.AdditionalFields["TES2"]); // Pictures Assert.AreEqual(1, theFile.NativeTag.EmbeddedPictures.Count); found = 0; foreach (PictureInfo pic in theFile.NativeTag.EmbeddedPictures) { if (pic.PicType.Equals(PictureInfo.PIC_TYPE.Generic) && (0 == found)) { Image picture = Image.FromStream(new MemoryStream(pic.PictureData)); Assert.AreEqual(picture.RawFormat, System.Drawing.Imaging.ImageFormat.Jpeg); Assert.AreEqual(picture.Height, 290); Assert.AreEqual(picture.Width, 900); found++; } } Assert.AreEqual(1, found); // Get rid of the working copy File.Delete(testFileLocation); }
public void TagIO_RW_PSF_Unsupported_Empty() { // Source : tag-free file String testFileLocation = TestUtils.CopyAsTempTestFile(emptyFile); AudioDataManager theFile = new AudioDataManager(ATL.AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); // Check that it is indeed tag-free Assert.IsTrue(theFile.ReadFromFile()); Assert.IsNotNull(theFile.NativeTag); // Assert.IsFalse(theFile.NativeTag.Exists); Tag data contains information required for playback => can never be nonexistent // Add new unsupported fields TagData theTag = new TagData(); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST", "This is a test")); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST2", "This is another test")); theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); Assert.AreEqual(5, theFile.NativeTag.AdditionalFields.Count); // 5 and not 2 because of "utf8", "length" and "fade" mandatory fields Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST")); Assert.AreEqual("This is a test", theFile.NativeTag.AdditionalFields["TEST"]); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST2")); Assert.AreEqual("This is another test", theFile.NativeTag.AdditionalFields["TEST2"]); // Remove the additional unsupported field theTag = new TagData(); MetaFieldInfo fieldInfo = new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST"); fieldInfo.MarkedForDeletion = true; theTag.AdditionalFields.Add(fieldInfo); // Add the new tag and check that it has been indeed added with all the correct information Assert.IsTrue(theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE)); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); // Additional removed field Assert.AreEqual(4, theFile.NativeTag.AdditionalFields.Count); // 4 and not 1 because of "utf8", "length" and "fade" mandatory fields Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST2")); Assert.AreEqual("This is another test", theFile.NativeTag.AdditionalFields["TEST2"]); // Get rid of the working copy File.Delete(testFileLocation); }
public void TagIO_RW_VQF_Unsupported_Empty() { // Source : tag-free file String testFileLocation = TestUtils.CopyAsTempTestFile(emptyFile); AudioDataManager theFile = new AudioDataManager(ATL.AudioData.AudioDataIOFactory.GetInstance().GetFromPath(testFileLocation)); // Check that it is indeed tag-free Assert.IsTrue(theFile.ReadFromFile()); Assert.IsNotNull(theFile.NativeTag); Assert.IsFalse(theFile.NativeTag.Exists); // Add new unsupported fields TagData theTag = new TagData(); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST", "This is a test")); theTag.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TES2", "This is another test")); theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); Assert.AreEqual(2, theFile.NativeTag.AdditionalFields.Count); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TEST")); Assert.AreEqual("This is a test", theFile.NativeTag.AdditionalFields["TEST"]); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test", theFile.NativeTag.AdditionalFields["TES2"]); // Remove the additional unsupported field theTag = new TagData(); MetaFieldInfo fieldInfo = new MetaFieldInfo(MetaDataIOFactory.TAG_NATIVE, "TEST"); fieldInfo.MarkedForDeletion = true; theTag.AdditionalFields.Add(fieldInfo); // Add the new tag and check that it has been indeed added with all the correct information Assert.IsTrue(theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_NATIVE)); Assert.IsTrue(theFile.ReadFromFile(true, true)); Assert.IsNotNull(theFile.NativeTag); Assert.IsTrue(theFile.NativeTag.Exists); // Additional removed field Assert.AreEqual(1, theFile.NativeTag.AdditionalFields.Count); Assert.IsTrue(theFile.NativeTag.AdditionalFields.Keys.Contains("TES2")); Assert.AreEqual("This is another test", theFile.NativeTag.AdditionalFields["TES2"]); // Get rid of the working copy if (Settings.DeleteAfterSuccess) { File.Delete(testFileLocation); } }
protected override bool read(BinaryReader source, MetaDataIO.ReadTagParams readTagParams) { bool result = false; long position; resetData(); source.BaseStream.Seek(0, SeekOrigin.Begin); if (AIFF_CONTAINER_ID.Equals(Utils.Latin1Encoding.GetString(source.ReadBytes(4)))) { // Container chunk size long containerChunkPos = source.BaseStream.Position; int containerChunkSize = StreamUtils.DecodeBEInt32(source.ReadBytes(4)); if (containerChunkPos + containerChunkSize + 4 != source.BaseStream.Length) { LogDelegator.GetLogDelegate()(Log.LV_WARNING, "Header size is incoherent with file size"); } // Form type format = Utils.Latin1Encoding.GetString(source.ReadBytes(4)); if (format.Equals(FORMTYPE_AIFF) || format.Equals(FORMTYPE_AIFC)) { isValid = true; StringBuilder commentStr = new StringBuilder(""); long soundChunkPosition = 0; long soundChunkSize = 0; // Header size included bool nameFound = false; bool authorFound = false; bool copyrightFound = false; bool commentsFound = false; long limit = Math.Min(containerChunkPos + containerChunkSize + 4, source.BaseStream.Length); int annotationIndex = 0; int commentIndex = 0; while (source.BaseStream.Position < limit) { ChunkHeader header = seekNextChunkHeader(source, limit); position = source.BaseStream.Position; if (header.ID.Equals(CHUNKTYPE_COMMON)) { short channels = StreamUtils.DecodeBEInt16(source.ReadBytes(2)); switch (channels) { case 1: channelsArrangement = MONO; break; case 2: channelsArrangement = STEREO; break; case 3: channelsArrangement = ISO_3_0_0; break; case 4: channelsArrangement = ISO_2_2_0; break; // Specs actually allow both 2/2.0 and LRCS case 6: channelsArrangement = LRLcRcCS; break; default: channelsArrangement = UNKNOWN; break; } numSampleFrames = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); sampleSize = (uint)StreamUtils.DecodeBEInt16(source.ReadBytes(2)); // This sample size is for uncompressed data only byte[] byteArray = source.ReadBytes(10); Array.Reverse(byteArray); double aSampleRate = StreamUtils.ExtendedToDouble(byteArray); if (format.Equals(FORMTYPE_AIFC)) { compression = Utils.Latin1Encoding.GetString(source.ReadBytes(4)); } else // AIFF <=> no compression { compression = COMPRESSION_NONE; } if (aSampleRate > 0) { sampleRate = (int)Math.Round(aSampleRate); duration = (double)numSampleFrames * 1000.0 / sampleRate; if (!compression.Equals(COMPRESSION_NONE)) // Sample size is specific to selected compression method { if (compression.ToLower().Equals("fl32")) { sampleSize = 32; } else if (compression.ToLower().Equals("fl64")) { sampleSize = 64; } else if (compression.ToLower().Equals("alaw")) { sampleSize = 8; } else if (compression.ToLower().Equals("ulaw")) { sampleSize = 8; } } if (duration > 0) { bitrate = sampleSize * numSampleFrames * channelsArrangement.NbChannels / duration; } } } else if (header.ID.Equals(CHUNKTYPE_SOUND)) { soundChunkPosition = source.BaseStream.Position - 8; soundChunkSize = header.Size + 8; } else if (header.ID.Equals(CHUNKTYPE_NAME) || header.ID.Equals(CHUNKTYPE_AUTHOR) || header.ID.Equals(CHUNKTYPE_COPYRIGHT)) { structureHelper.AddZone(source.BaseStream.Position - 8, header.Size + 8, header.ID); structureHelper.AddSize(containerChunkPos, containerChunkSize, header.ID); tagExists = true; if (header.ID.Equals(CHUNKTYPE_NAME)) { nameFound = true; } if (header.ID.Equals(CHUNKTYPE_AUTHOR)) { authorFound = true; } if (header.ID.Equals(CHUNKTYPE_COPYRIGHT)) { copyrightFound = true; } SetMetaField(header.ID, Utils.Latin1Encoding.GetString(source.ReadBytes(header.Size)), readTagParams.ReadAllMetaFrames); } else if (header.ID.Equals(CHUNKTYPE_ANNOTATION)) { annotationIndex++; structureHelper.AddZone(source.BaseStream.Position - 8, header.Size + 8, header.ID + annotationIndex); structureHelper.AddSize(containerChunkPos, containerChunkSize, header.ID + annotationIndex); if (commentStr.Length > 0) { commentStr.Append(Settings.InternalValueSeparator); } commentStr.Append(Utils.Latin1Encoding.GetString(source.ReadBytes(header.Size))); tagExists = true; } else if (header.ID.Equals(CHUNKTYPE_COMMENTS)) { commentIndex++; structureHelper.AddZone(source.BaseStream.Position - 8, header.Size + 8, header.ID + commentIndex); structureHelper.AddSize(containerChunkPos, containerChunkSize, header.ID + commentIndex); tagExists = true; commentsFound = true; ushort numComs = StreamUtils.DecodeBEUInt16(source.ReadBytes(2)); for (int i = 0; i < numComs; i++) { CommentData cmtData = new CommentData(); cmtData.Timestamp = StreamUtils.DecodeBEUInt32(source.ReadBytes(4)); cmtData.MarkerId = StreamUtils.DecodeBEInt16(source.ReadBytes(2)); // Comments length ushort comLength = StreamUtils.DecodeBEUInt16(source.ReadBytes(2)); MetaFieldInfo comment = new MetaFieldInfo(getImplementedTagType(), header.ID + commentIndex); comment.Value = Utils.Latin1Encoding.GetString(source.ReadBytes(comLength)); comment.SpecificData = cmtData; tagData.AdditionalFields.Add(comment); // Only read general purpose comments, not those linked to a marker if (0 == cmtData.MarkerId) { if (commentStr.Length > 0) { commentStr.Append(Settings.InternalValueSeparator); } commentStr.Append(comment.Value); } } } else if (header.ID.Equals(CHUNKTYPE_ID3TAG)) { id3v2Offset = source.BaseStream.Position; // Zone is already added by Id3v2.Read id3v2StructureHelper.AddZone(id3v2Offset - 8, header.Size + 8, CHUNKTYPE_ID3TAG); id3v2StructureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_ID3TAG); } source.BaseStream.Position = position + header.Size; if (header.ID.Equals(CHUNKTYPE_SOUND) && header.Size % 2 > 0) { source.BaseStream.Position += 1; // Sound chunk size must be even } } tagData.IntegrateValue(TagData.TAG_FIELD_COMMENT, commentStr.ToString().Replace("\0", " ").Trim()); if (-1 == id3v2Offset) { id3v2Offset = 0; // Switch status to "tried to read, but nothing found" if (readTagParams.PrepareForWriting) { id3v2StructureHelper.AddZone(soundChunkPosition + soundChunkSize, 0, CHUNKTYPE_ID3TAG); id3v2StructureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_ID3TAG); } } // Add zone placeholders for future tag writing if (readTagParams.PrepareForWriting) { if (!nameFound) { structureHelper.AddZone(soundChunkPosition, 0, CHUNKTYPE_NAME); structureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_NAME); } if (!authorFound) { structureHelper.AddZone(soundChunkPosition, 0, CHUNKTYPE_AUTHOR); structureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_AUTHOR); } if (!copyrightFound) { structureHelper.AddZone(soundChunkPosition, 0, CHUNKTYPE_COPYRIGHT); structureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_COPYRIGHT); } if (!commentsFound) { structureHelper.AddZone(soundChunkPosition, 0, CHUNKTYPE_COMMENTS); structureHelper.AddSize(containerChunkPos, containerChunkSize, CHUNKTYPE_COMMENTS); } } result = true; } } return(result); }