Esempio n. 1
0
        /// <summary>
        /// ID3v2タグを読む
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="createImageObject"></param>
        /// <returns></returns>
        public static ID3tag readID3tag(System.IO.Stream strm, bool createImageObject)
        {
            // ヘッダ読み込み
            byte[] id3_header = strm.ReadBytes(HEADER_LEN);
            Header header     = readHeader(id3_header);

            if (header == null)
            {
                return(null);
            }
            if (header.Size >= strm.Length)
            {
                return(null);
            }
            ID3tag tag = new ID3tag();

            tag.head = header;

            // 拡張ヘッダがあるときサイズだけ読んでスキップ
            if (tag.head.Flag.HasFlag(HEADER_FLAG.EXTENSION))
            {
                byte[] ext_header = strm.ReadBytes(EXT_HEADER_LEN);
                var    size       = tag.head.Version == ID3V2_VER.ID3V23
                    ? ReadUInt32(ext_header, 0)
                    : ReadUInt28(ext_header, 0) - EXT_HEADER_LEN; // v3とv4でEXT_HEADER_LENの扱いが違う
                strm.Seek(size, System.IO.SeekOrigin.Current);
            }

            // 全Frameのデータ領域を読み出す
            byte[] frame_buf = strm.ReadBytes(header.Size);

            // .2, .3の場合は非同期化の解除
            if (header.Version != ID3V2_VER.ID3V24 && header.Flag.HasFlag(HEADER_FLAG.UNSYNC))
            {
                decodeUnsync(ref frame_buf);
            }

            // 各Frameのデータ読み出し
            var tagBodyStream = new MemoryStream(frame_buf, 0, frame_buf.Length);

            while (true)
            {
                try
                {
                    Frame fr = readFrame(tagBodyStream, tag, createImageObject);
                    if (fr != null)
                    {
                        tag.frame.Add(fr);
                    }
                }
                catch (EndOfTagException)
                {
                    break;
                }
            }
            return(tag);
        }
Esempio n. 2
0
        /// <summary>
        /// ID3V2タグフレームを読む
        /// </summary>
        /// <param name="strm"></param>
        /// <param name="tag"></param>
        /// <param name="createImageObject"></param>
        /// <returns></returns>
        private static Frame readFrame(Stream strm, ID3tag tag, bool createImageObject)
        {
            int frameHeaderSize = (tag.head.Version == ID3V2_VER.ID3V22) ? FRAME_HEADER_LEN_2 : FRAME_HEADER_LEN_34;

            if (strm.Length - strm.Position < frameHeaderSize)
            {
                throw new EndOfTagException();
            }
            byte[] buf   = strm.ReadBytes(frameHeaderSize);
            var    frame = readFrameHeader(buf, tag.head.Version);

            if (frame.Size <= 0)
            {
                throw new EndOfTagException();
            }
            if (strm.Length - strm.Position < frame.Size)
            {
                throw new EndOfTagException();
            }

            int  offset      = 0;
            bool unsupported = false;

            if (frame.ID == null)
            {
                unsupported = true;
            }

            // 暗号化なんて知りませんよっと
            if (frame.Flag.HasFlag(FRAME_FLAG.CRYPTED))
            {
                unsupported = true;
            }

            // 圧縮は実装してない
            if (frame.Flag.HasFlag(FRAME_FLAG.COMPRESSED))
            {
                unsupported = true;
            }

            // グループ識別子を無視
            if (frame.Flag.HasFlag(FRAME_FLAG.GROUPED))
            {
                // unsupportedにはしない
                offset += 1;
            }

            // DATALENGTHを飛ばす
            if (frame.Flag.HasFlag(FRAME_FLAG.DATALENGTH))
            {
                offset += 4;
            }

            if (unsupported)
            {
                strm.Seek(frame.Size, SeekOrigin.Current);
                return(null);
            }

            strm.Seek(offset, SeekOrigin.Current);
            byte[] buffer = strm.ReadBytes(frame.Size - offset);
            if (frame.Flag.HasFlag(FRAME_FLAG.UNSYNC) && tag.head.Version == ID3V2_VER.ID3V24)
            {
                decodeUnsync(ref buffer);
            }

            MemoryStream frameBodyStream = new MemoryStream(buffer);

            readFrameBody(frameBodyStream, frame, createImageObject);
            return(frame);
        }