Author: abock
Date: 2005-11-23 17:10:46 -0500 (Wed, 23 Nov 2005)
New Revision: 53421

Added:
   trunk/entagged-sharp/src/Asf/
   trunk/entagged-sharp/src/Asf/AsfFileReader.cs
   trunk/entagged-sharp/src/Asf/Util/
   trunk/entagged-sharp/src/Asf/Util/AsfInfoReader.cs
   trunk/entagged-sharp/src/Asf/Util/AsfTagReader.cs
   trunk/entagged-sharp/src/Asf/Util/GUID.cs
   trunk/entagged-sharp/src/Asf/Util/Utils.cs
Modified:
   trunk/entagged-sharp/ChangeLog
   trunk/entagged-sharp/src/Makefile.am
Log:
2005-11-23  Aaron Bockover  <[EMAIL PROTECTED]>

    * src/Asf/*: Added ASF/WMA parser by Christian Laireiter
    * src/Makefile.am: Added build rules for src/Asf/*



Modified: trunk/entagged-sharp/ChangeLog
===================================================================
--- trunk/entagged-sharp/ChangeLog      2005-11-23 21:59:35 UTC (rev 53420)
+++ trunk/entagged-sharp/ChangeLog      2005-11-23 22:10:46 UTC (rev 53421)
@@ -1,3 +1,8 @@
+2005-11-23  Aaron Bockover  <[EMAIL PROTECTED]>
+
+       * src/Asf/*: Added ASF/WMA parser by Christian Laireiter
+       * src/Makefile.am: Added build rules for src/Asf/*
+
 2005-11-20  Raphael Slinckx  <[EMAIL PROTECTED]>
 
        * src/Util/ByteBuffer.cs:

Added: trunk/entagged-sharp/src/Asf/AsfFileReader.cs
===================================================================
--- trunk/entagged-sharp/src/Asf/AsfFileReader.cs       2005-11-23 21:59:35 UTC 
(rev 53420)
+++ trunk/entagged-sharp/src/Asf/AsfFileReader.cs       2005-11-23 22:10:46 UTC 
(rev 53421)
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *  Copyright 2005 Christian Laireiter <[EMAIL PROTECTED]> 
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"), 
 
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.IO;
+
+using Entagged.Audioformats;
+using Entagged.Audioformats.Asf.Util;
+using Entagged.Audioformats.Util;
+
+namespace Entagged.Audioformats.Asf 
+{
+    // The stream must be seekable and only the information 
+    // of the first audio stream is extracted.
+    
+    [SupportedMimeType ("entagged/wma")]
+    public sealed class AsfFileReader : AudioFileReader 
+    {
+        private static readonly AsfInfoReader infoReader = new AsfInfoReader();
+        private static readonly AsfTagReader tagReader = new AsfTagReader();
+
+        protected override EncodingInfo GetEncodingInfo(Stream stream, string 
mime) 
+        {
+            // AsfInfoReader needs the stream to be at position 0
+            stream.Seek(0, SeekOrigin.Begin);
+            return infoReader.read(stream);
+        }
+
+        protected override Tag GetTag(Stream stream, string mime) 
+        {
+            stream.Seek(0, SeekOrigin.Begin);
+            AsfTagResult result = tagReader.read(stream);
+            return result.Tag;
+        }
+    }
+}

Added: trunk/entagged-sharp/src/Asf/Util/AsfInfoReader.cs
===================================================================
--- trunk/entagged-sharp/src/Asf/Util/AsfInfoReader.cs  2005-11-23 21:59:35 UTC 
(rev 53420)
+++ trunk/entagged-sharp/src/Asf/Util/AsfInfoReader.cs  2005-11-23 22:10:46 UTC 
(rev 53421)
@@ -0,0 +1,128 @@
+/***************************************************************************
+ *  Copyright 2005 Christian Laireiter <[EMAIL PROTECTED]> 
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"), 
 
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+
+using Entagged.Audioformats;
+
+namespace Entagged.Audioformats.Asf.Util 
+{
+    public sealed class AsfInfoReader 
+    {
+       /**
+         * Stores the hex values of codec identifiers to their descriptions. 
<br>
+         */
+        public static readonly string [][] CODEC_DESCRIPTIONS = new string 
[][] 
+        {
+            new string [] { "161",  " (Windows Media Audio (ver 7,8,9))" },
+            new string [] { "162",  " (Windows Media Audio 9 series 
(Professional))" },
+            new string [] { "163",  " (Windows Media Audio 9 series 
(Lossless))" },
+            new string [] { "7A21", " (GSM-AMR (CBR))" },
+            new string [] { "7A22", " (GSM-AMR (VBR))" }
+        };
+
+        public string GetFormatDescription(UInt16 format) 
+        {
+            StringBuilder result = new StringBuilder(format.ToString("x"));
+            string further = " (UNKOWN)";
+            
+            for(int i = 0; i < CODEC_DESCRIPTIONS.Length; i++) {
+                
if(CODEC_DESCRIPTIONS[i][0].ToUpper().Equals(result.ToString().ToUpper())) {
+                    further = CODEC_DESCRIPTIONS[i][1];
+                    break;
+                }
+            }
+            
+            if(result.Length % 2 != 0) {
+                result.Insert(0, "0x0");
+            } else {
+                result.Insert(0, "0x");
+            }
+            
+            result.Append(further);
+            return result.ToString();
+        }
+
+        /*
+        * TODO: Better Implementation of bitrate determination.
+        * Somehow first audio stream makes the day. Then Streamnumber must
+        * be stored, to read the right info out of an optional stream bitrate 
properties
+        * chunk. Or if that comes first, store all the data and assign it on 
occurence of the
+        * fist audio stream.
+        * Where is the info about VBR
+        */
+        public EncodingInfo read(Stream stream) 
+        {
+            EncodingInfo result = new EncodingInfo();
+            /* Assuming we are at the start of the asf header guid */
+            GUID headerGuid = Utils.ReadGUID(stream);
+            if(GUID.GUID_HEADER.Equals(headerGuid)) {
+                //Create a Binarystream (helps reading something like UInt64)
+                BinaryReader reader = new BinaryReader(stream);
+                // Skip length of header
+                stream.Seek(8, SeekOrigin.Current);
+
+                // Read the number of chunks.
+                UInt32 chunkCount = reader.ReadUInt32();
+                // Skip unknown bytes
+                stream.Seek (2, SeekOrigin.Current);
+                // Two flags, When both are set, all Information needed has 
ben read
+                bool isFileHeaderParsed = false;
+                bool isStreamChunkParsed = false;
+
+                // Now read the chunks.
+                for(int i = 0; i < chunkCount && !(isFileHeaderParsed && 
isStreamChunkParsed); i++) {
+                    long chunkStart = stream.Position;
+                    GUID currentGuid = Utils.ReadGUID (stream);
+                    UInt64 chunkLen = reader.ReadUInt64();
+                    // If the current chunk represents a file header...
+                    if (GUID.GUID_FILE.Equals (currentGuid)) {
+                        // ... read all necessary encoding information 
(duration)
+                        stream.Seek (48, SeekOrigin.Current);
+                        // convert from 100ns (steps) to seconds
+                        result.Length = (int) (reader.ReadUInt64() / 10000000);
+                        isFileHeaderParsed = true;
+                    } else if (GUID.GUID_STREAM.Equals (currentGuid)) {
+                        GUID streamTypeGUID = Utils.ReadGUID (stream);
+                        if(GUID.GUID_AUDIOSTREAM.Equals (streamTypeGUID)) {
+                            // Jump over ignored values.
+                            stream.Seek (38, SeekOrigin.Current);
+                            result.EncodingType = GetFormatDescription 
(reader.ReadUInt16());
+                            result.ChannelNumber = reader.ReadUInt16();
+                            result.SamplingRate = (int) reader.ReadUInt32();
+                            result.Bitrate = (int) (reader.ReadUInt32() * 8 / 
1000);
+                            isStreamChunkParsed = true;
+                        }
+                    }
+                    stream.Seek ((long)((ulong)chunkStart + chunkLen - 
(ulong)stream.Position), SeekOrigin.Current);
+                }
+            }
+            
+            return result;
+        }
+    }
+} 

Added: trunk/entagged-sharp/src/Asf/Util/AsfTagReader.cs
===================================================================
--- trunk/entagged-sharp/src/Asf/Util/AsfTagReader.cs   2005-11-23 21:59:35 UTC 
(rev 53420)
+++ trunk/entagged-sharp/src/Asf/Util/AsfTagReader.cs   2005-11-23 22:10:46 UTC 
(rev 53421)
@@ -0,0 +1,184 @@
+/***************************************************************************
+ *  Copyright 2005 Christian Laireiter <[EMAIL PROTECTED]> 
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"), 
 
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+ 
+using Entagged.Audioformats;
+
+namespace Entagged.Audioformats.Asf.Util 
+{
+    public sealed class AsfTagResult 
+    {
+        private Tag tag;
+
+        public Tag Tag {
+            get { 
+                return this.tag; 
+            }
+        }
+
+        internal void SetTag(Tag value) 
+        {
+            this.tag = value;
+        }
+    }
+
+    public sealed class AsfTagReader 
+    {
+        private void FillExtendedContentDescValues (Stream stream, Tag tag) 
+        {
+            BinaryReader reader = new BinaryReader (stream);
+            UInt16 descCount = reader.ReadUInt16();
+            for (int i = 0; i < descCount; i++) {
+                UInt16 strLen = reader.ReadUInt16();
+                string propName = ReadFixedSizeUTF16Str(reader,strLen);
+                int propType = reader.ReadUInt16();
+                string value = null;
+                switch (propType) {
+                    case 0:
+                        strLen = reader.ReadUInt16();
+                        value = ReadFixedSizeUTF16Str(reader,strLen);
+                        break;
+                    case 1:
+                        int size = reader.ReadUInt16();
+                        stream.Seek (size, SeekOrigin.Current);
+                        break;
+                    case 2:
+                        // Boolean value.
+                        reader.ReadUInt16();
+                        value = (reader.ReadUInt32() == 1).ToString();
+                        break;
+                    case 3:
+                        value = reader.ReadUInt32().ToString();
+                        break;
+                    case 4:
+                        value = reader.ReadUInt64().ToString();
+                        break;
+                    case 5:
+                        value = reader.ReadUInt16().ToString();
+                        break;
+                }
+                if (propName.Equals("WM/AlbumTitle")) {
+                    tag.SetAlbum (value);
+                } else
+                if (propName.Equals("WM/AlbumArtist")) {
+                    // Even in Author was set, this will override.
+                    tag.SetArtist(value);
+                } else
+                if (propName.Equals("WM/TrackNumber")) {
+                    tag.SetTrack(value);
+                } else
+                if (propName.Equals("WM/Year")) {
+                    tag.SetYear(value);
+                }else
+                if (propName.Equals("WM/Genre")) {
+                    tag.SetGenre (value);
+                }
+            }
+        }
+
+        private void FillContentDescriptorValues (Stream stream, Tag tag) 
+        {
+            BinaryReader reader = new BinaryReader(stream);
+            UInt16[] sizes = new UInt16[5];
+            for (int i = 0; i < sizes.Length; i++) {
+                sizes[i] = reader.ReadUInt16();
+            }
+            string[] strings = new string[sizes.Length];
+            for (int i = 0; i < strings.Length; i++) {
+                strings[i] = ReadFixedSizeUTF16Str(reader, sizes[i]);
+            }
+            // Now assign values to tag.
+            if (sizes[0] > 0)
+                tag.SetTitle(strings[0]);
+            if (sizes[1] > 0)
+                tag.SetArtist(strings[1]);
+            if (sizes[3] > 0)
+                tag.SetComment(strings[3]);
+        }
+
+        public AsfTagResult read (Stream stream) 
+        {
+            AsfTagResult result = new AsfTagResult();
+            Tag tag = new Tag();
+            /* Assuming we are at the start of the asf header guid */
+            GUID headerGuid = Utils.ReadGUID (stream);
+            if (GUID.GUID_HEADER.Equals(headerGuid)) {
+                //Create a Binarystream (helps reading something like UInt64)
+                BinaryReader reader = new BinaryReader(stream);
+                // Skip length of header
+                stream.Seek (8, SeekOrigin.Current);
+
+                // Read the number of chunks.
+                UInt32 chunkCount = reader.ReadUInt32();
+                // Skip unknown bytes
+                stream.Seek (2, SeekOrigin.Current);
+                // Two flags, When both are set, all Information needed has 
ben read
+                bool isContentDescriptionParsed = false;
+                bool isExtendedDescriptionParsed = false;
+
+                // Now read the chunks.
+                for (int i = 0; i < chunkCount &&
+                     !(isContentDescriptionParsed && 
isExtendedDescriptionParsed);
+                     i++) {
+                    long chunkStart = stream.Position;
+                    GUID currentGuid = Utils.ReadGUID (stream);
+                    UInt64 chunkLen = reader.ReadUInt64();
+                    if (GUID.GUID_CONTENTDESCRIPTION.Equals(currentGuid)) {
+                        FillContentDescriptorValues (stream, tag);
+                        isContentDescriptionParsed = true;
+                    }
+                    if (GUID.GUID_EXTENDED_CONTENT_DESCRIPTION.Equals 
(currentGuid)) {
+                        FillExtendedContentDescValues (stream, tag);
+                        isExtendedDescriptionParsed = true;
+                    }
+                    stream.Seek ((long)((ulong)chunkStart
+                            + chunkLen - (ulong)stream.Position), 
SeekOrigin.Current);
+                }
+                result.SetTag(tag);
+            }
+            return result;
+        }
+
+        private static String ReadFixedSizeUTF16Str(BinaryReader reader, int 
strLen) 
+        {
+            UnicodeEncoding encoding = new UnicodeEncoding();
+            byte[] strBytes = new byte[strLen];
+            reader.Read (strBytes,0,strBytes.Length);
+            if (strBytes[strBytes.Length-1] == 0 && 
strBytes[strBytes.Length-2] == 0) {
+                byte[] copy = new byte[strBytes.Length-2];
+                Array.Copy (strBytes,0,copy,0,copy.Length);
+                strBytes = copy;
+            }
+            char[] chars = new 
char[encoding.GetCharCount(strBytes,0,strBytes.Length)];
+            encoding.GetChars (strBytes,0,strBytes.Length,chars,0);
+            // TODO The optional zero termination must be recognized to 
construct the string.
+            return new string (chars);
+        }
+    }
+
+}
\ No newline at end of file

Added: trunk/entagged-sharp/src/Asf/Util/GUID.cs
===================================================================
--- trunk/entagged-sharp/src/Asf/Util/GUID.cs   2005-11-23 21:59:35 UTC (rev 
53420)
+++ trunk/entagged-sharp/src/Asf/Util/GUID.cs   2005-11-23 22:10:46 UTC (rev 
53421)
@@ -0,0 +1,281 @@
+/***************************************************************************
+ *  Copyright 2005 Christian Laireiter <[EMAIL PROTECTED]> 
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"), 
 
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Entagged.Audioformats.Asf.Util 
+{
+    /**
+     * This class is used for representation of GUIDs and as a reference
+     * listof all Known GUIDs. <br>
+     */
+    public sealed class GUID 
+    {
+        /**
+         * This constant defines the GUID for stream chunks describing audio
+         * streams, indicating the the audio stream has no error concealment. 
<br>
+         */
+        public static readonly GUID GUID_AUDIO_ERROR_CONCEALEMENT_ABSENT = new 
GUID(
+            new int[] { 0x40, 0xA4, 0xF1, 0x49, 0xCE, 0x4E, 0xD0, 0x11, 0xA3,
+                    0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 },
+            "Audio error concealment absent.");
+
+        /**
+         * This constant stores the GUID indicating that stream type is audio.
+         */
+        public static readonly GUID GUID_AUDIOSTREAM = new GUID(new int[] { 
0x40,
+            0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80,
+            0x5F, 0x5C, 0x44, 0x2B }, " Audio stream");
+
+        /**
+         * This constant represents the guid for a chunk which contains Title,
+         * author, copyright, description and rating.
+         */
+        public static readonly GUID GUID_CONTENTDESCRIPTION = new GUID(new 
int[] {
+            0x33, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00,
+            0xAA, 0x00, 0x62, 0xCE, 0x6C }, "Content Description");
+
+        /**
+         * This constant stores the GUID for Encoding-Info chunks.
+         */
+        public static readonly GUID GUID_ENCODING = new GUID(new int[] { 0x40, 
0x52,
+            0xD1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xA3, 0xA4, 0x00, 0xA0, 0xC9,
+            0x03, 0x48, 0xF6 }, "Encoding description");
+
+        /**
+         * This constant defines the GUID for a WMA "Extended Content 
Description"
+         * chunk. <br>
+         */
+        public static readonly GUID GUID_EXTENDED_CONTENT_DESCRIPTION = new 
GUID(
+            new int[] { 0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97,
+                    0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50 },
+            "Extended Content Description");
+
+        /**
+         * GUID of ASF file header.
+         */
+        public static readonly GUID GUID_FILE = new GUID(new int[] { 0xA1, 
0xDC,0xAB,
+            0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20,
+            0x53, 0x65 }, "File header");
+
+        /**
+        * This constant defines the GUID of a asf header chunk.
+        */
+        public static readonly GUID GUID_HEADER = new GUID(new int[] { 0x30, 
0x26,
+            0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00,
+            0x62, 0xce, 0x6c }, "Asf header");
+
+        /**
+        * The length of bytes a "asf" GUID takes.
+        */
+        public const int GUID_LENGTH = 16;
+
+        /**
+        * This constant stores the GUID indicating a stream object.
+        */
+        public static readonly GUID GUID_STREAM = new GUID(new int[] { 0x91, 
0x07,
+            0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C,
+            0x20, 0x53, 0x65 }, "Stream");
+
+        /**
+         * This constant stores a GUID whose functionality is unknown.
+         */
+        public static readonly GUID GUID_HEADER_EXTENSION = new GUID(new int[] 
{ 0xB5, 0x03,
+            0xBF, 0x5F, 0x2E, 0xA9, 0xCF, 0x11, 0x8E, 0xE3, 0x00, 0xC0, 0x0C,
+            0x20, 0x53, 0x65 }, "Header Extension");
+
+        /**
+         * This constant stores a GUID indicating a "stream bitrate properties"
+         * chunk.
+         */
+        public static readonly GUID GUID_STREAM_BITRATE_PROPERTIES = new GUID(
+            new int[] { 0xCE, 0x75, 0xF8, 0x7B, 0x8D, 0x46, 0xD1, 0x11, 0x8D,
+                    0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2 },
+            "Stream bitrate properties");
+
+        /**
+         * This constant stores the GUID indicating that stream type is video.
+         */
+        public static readonly GUID GUID_VIDEOSTREAM = new GUID(new int[] { 
0xC0,
+            0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80,
+            0x5F, 0x5C, 0x44, 0x2B }, "Video stream");
+
+        /**
+         * This field stores all knwon GUIDs.
+         */
+        public static readonly GUID[] KNOWN_GUIDS = new GUID[] {
+            GUID_AUDIO_ERROR_CONCEALEMENT_ABSENT, GUID_CONTENTDESCRIPTION,
+            GUID_AUDIOSTREAM, GUID_ENCODING, GUID_FILE, GUID_HEADER,
+            GUID_STREAM, GUID_EXTENDED_CONTENT_DESCRIPTION, GUID_VIDEOSTREAM,
+            GUID_HEADER_EXTENSION, GUID_STREAM_BITRATE_PROPERTIES };
+
+        public static readonly Hashtable KNOWN_GUID_TABLE;
+
+
+        /**
+        * An optional description of what the GUID represents.
+        */
+        private string description;
+
+        /**
+        * Stores the Bytes of the represented GUID.
+        */
+        private int[] guid = null;
+
+        static GUID () {
+            KNOWN_GUID_TABLE = new Hashtable();
+            for (int i = 0; i < KNOWN_GUIDS.Length; i++) {
+                KNOWN_GUID_TABLE.Add(KNOWN_GUIDS[i],KNOWN_GUIDS[i]);
+            }
+        }
+        
+        /**
+        * Creates an instance with the given GUID data.
+        */    
+        public GUID (int[] guid) {
+            SetGUID(guid);
+        }
+
+        /**
+         * Creates an instance.<br>
+         * guid is the GUID byte array as ints.
+         * desc is the optional description.
+         */
+        public GUID (int[] guid, String desc) {
+            SetGUID(guid);
+            this.description = desc;
+        }
+
+        /**
+         * This method asserts that the given array may be representing
+         * a valid GUID.<br>
+         * For that it must not be null and must be as long as GUID.GUID_LENGTH
+         * specifies.<br>
+         * @return true if all matches.
+         */
+        public static bool AssertGUID (int[] guid) {
+            bool result = false;
+            if (guid != null) {
+                if (guid.Length == GUID.GUID_LENGTH) {
+                    result = true;
+                }
+            }
+            return result;
+        }
+
+        /**
+        * This method searches a GUID in [EMAIL PROTECTED] #KNOWN_GUIDS}which 
is equal to the
+        * given <code>guid</code> and returns its description. <br>
+        * This method is useful if a guid was read out of a file and no
+        * identification has been done yet.
+        *
+        * @param guid
+        *            guid, which description is needed.
+        * @return description of the guid if found. Else <code>null</code>
+        */
+        public static string GetGuidDescription(GUID guid) {
+            string result = null;
+            if (guid == null) {
+                throw new ArgumentException ("Argument must not be null.");
+            }
+            for (int i = 0; i < KNOWN_GUIDS.Length; i++) {
+                if (KNOWN_GUIDS[i].Equals(guid)) {
+                    result = KNOWN_GUIDS[i].GetDescription();
+                }
+            }
+            return result;
+        }
+
+        /**
+         * If the given object is a GUID, the values are compared to each 
other.
+         */
+        public override bool Equals (Object o) {
+            bool result = false;
+            if (o is GUID) {
+                GUID other = (GUID)o;
+                result = true;
+                for (int i = 0; i < GUID.GUID_LENGTH && result; i++) {
+                    result &= other.guid[i] == this.guid[i];
+                }
+            } else {
+                result = false;
+            }
+            return result;
+        }
+
+        public byte[] GetBytes () {
+            byte[] result = new byte[GUID.GUID_LENGTH];
+            for (int i = 0; i < result.Length; i++) {
+                result[i] = (byte) (this.guid[i] & 0xFF);
+            }
+            return result;
+        }
+
+        /**
+         * Returns the optional description of the GUID.
+         */
+        public string GetDescription () {
+            return this.description;
+        }
+
+        public override int GetHashCode() {
+            long sum = 0;
+            for (int i = 0; i < GUID.GUID_LENGTH; i++) {
+                sum += this.guid[i];
+                sum <<=1;
+            }
+            return (int) (sum % UInt32.MaxValue);
+        }
+
+        /**
+         * Sets the optional description of the GUID.
+         */
+        public void SetDescription (string desc) {
+            this.description = desc;
+        }
+
+        /**
+         * Sets this.guid and validating the integer array.
+         */
+        public void SetGUID (int[] guid) {
+            if (!GUID.AssertGUID(guid)) {
+                throw new ArgumentException ("Invalid GUID");
+            }
+            this.guid = new int[guid.Length];
+            guid.CopyTo(this.guid,0);
+        }
+
+        public override string ToString() {
+            StringBuilder result = new StringBuilder ("GUID: ");
+            foreach (int curr in this.guid) {
+                result.Append(curr.ToString("x"));
+                result.Append(",");
+            }
+            return result.ToString();
+        }
+    }
+}

Added: trunk/entagged-sharp/src/Asf/Util/Utils.cs
===================================================================
--- trunk/entagged-sharp/src/Asf/Util/Utils.cs  2005-11-23 21:59:35 UTC (rev 
53420)
+++ trunk/entagged-sharp/src/Asf/Util/Utils.cs  2005-11-23 22:10:46 UTC (rev 
53421)
@@ -0,0 +1,44 @@
+/***************************************************************************
+ *  Copyright 2005 Christian Laireiter <[EMAIL PROTECTED]> 
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"), 
 
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.IO;
+
+namespace Entagged.Audioformats.Asf.Util 
+{
+    public sealed class Utils 
+    {
+        public static GUID ReadGUID (Stream stream) 
+        {
+            byte[] guid = new byte[GUID.GUID_LENGTH];
+            stream.Read(guid,0,guid.Length);
+            int[] tmp = new int[guid.Length];
+            for (int i = 0; i < guid.Length; i++) {
+                tmp[i] = guid[i];
+            }   
+            return new GUID(tmp);
+        }
+    }
+}

Modified: trunk/entagged-sharp/src/Makefile.am
===================================================================
--- trunk/entagged-sharp/src/Makefile.am        2005-11-23 21:59:35 UTC (rev 
53420)
+++ trunk/entagged-sharp/src/Makefile.am        2005-11-23 22:10:46 UTC (rev 
53421)
@@ -17,6 +17,13 @@
        $(srcdir)/Ape/Util/WavFormatHeader.cs \
        $(srcdir)/Ape/Util/WavRIFFHeader.cs
 
+ASF_CSFILES = \
+       $(srcdir)/Asf/AsfFileReader.cs \
+       $(srcdir)/Asf/Util/AsfTagReader.cs \
+       $(srcdir)/Asf/Util/GUID.cs \
+       $(srcdir)/Asf/Util/AsfInfoReader.cs \
+       $(srcdir)/Asf/Util/Utils.cs
+
 FLAC_CSFILES = \
        $(srcdir)/Flac/FlacFileReader.cs \
        $(srcdir)/Flac/Util/FlacInfoReader.cs \
@@ -89,6 +96,7 @@
        $(srcdir)/Tag.cs \
        $(srcdir)/CreativeCommons.cs \
        $(APE_CSFILES) \
+       $(ASF_CSFILES) \
        $(FLAC_CSFILES) \
        $(OGG_CSFILES) \
        $(MPC_CSFILES) \

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to