Exemplo n.º 1
0
        private void readFrames(BinaryReader source, TagInfo Tag, MetaDataIO.ReadTagParams readTagParams)
        {
            string frameName;
            string strValue;
            int    frameDataSize;
            long   valuePosition;
            int    frameFlags;

            source.BaseStream.Seek(Tag.FileSize - Tag.DataShift - Tag.Size, SeekOrigin.Begin);
            // Read all stored fields
            for (int iterator = 0; iterator < Tag.FrameCount; iterator++)
            {
                frameDataSize = source.ReadInt32();
                frameFlags    = source.ReadInt32();
                frameName     = StreamUtils.ReadNullTerminatedString(source, Utils.Latin1Encoding); // Slightly more permissive than what APE specs indicate in terms of allowed characters ("Space(0x20), Slash(0x2F), Digits(0x30...0x39), Letters(0x41...0x5A, 0x61...0x7A)")

                valuePosition = source.BaseStream.Position;

                if ((frameDataSize > 0) && (frameDataSize <= 500))
                {
                    /*
                     * According to spec : "Items are not zero-terminated like in C / C++.
                     * If there's a zero character, multiple items are stored under the key and the items are separated by zero characters."
                     *
                     * => Values have to be splitted
                     */
                    strValue = Utils.StripEndingZeroChars(Encoding.UTF8.GetString(source.ReadBytes(frameDataSize)));
                    strValue = strValue.Replace('\0', Settings.InternalValueSeparator).Trim();
                    SetMetaField(frameName.Trim().ToUpper(), strValue, readTagParams.ReadAllMetaFrames);
                }
                else if (frameDataSize > 0) // Size > 500 => Probably an embedded picture
                {
                    int picturePosition;
                    PictureInfo.PIC_TYPE picType = decodeAPEPictureType(frameName);

                    if (picType.Equals(PictureInfo.PIC_TYPE.Unsupported))
                    {
                        addPictureToken(getImplementedTagType(), frameName);
                        picturePosition = takePicturePosition(getImplementedTagType(), frameName);
                    }
                    else
                    {
                        addPictureToken(picType);
                        picturePosition = takePicturePosition(picType);
                    }

                    if (readTagParams.ReadPictures || readTagParams.PictureStreamHandler != null)
                    {
                        // Description seems to be a null-terminated ANSI string containing
                        //    * The frame name
                        //    * A byte (0x2E)
                        //    * The picture type (3 characters; similar to the 2nd part of the mime-type)
                        String      description = StreamUtils.ReadNullTerminatedString(source, Utils.Latin1Encoding);
                        ImageFormat imgFormat   = ImageUtils.GetImageFormatFromMimeType(description.Substring(description.Length - 3, 3));

                        PictureInfo picInfo = new PictureInfo(imgFormat, picType, getImplementedTagType(), frameName, picturePosition);
                        picInfo.Description = description;
                        picInfo.PictureData = new byte[frameDataSize - description.Length - 1];
                        source.BaseStream.Read(picInfo.PictureData, 0, frameDataSize - description.Length - 1);

                        tagData.Pictures.Add(picInfo);

                        if (readTagParams.PictureStreamHandler != null)
                        {
                            MemoryStream mem = new MemoryStream(picInfo.PictureData);
                            readTagParams.PictureStreamHandler(ref mem, picInfo.PicType, picInfo.NativeFormat, picInfo.TagType, picInfo.NativePicCode, picInfo.Position);
                            mem.Close();
                        }
                    }
                }
                source.BaseStream.Seek(valuePosition + frameDataSize, SeekOrigin.Begin);
            }
        }
Exemplo n.º 2
0
        public void readTagField(BinaryReader source, string zoneCode, string fieldName, ushort fieldDataType, int fieldDataSize, ReadTagParams readTagParams, bool isExtendedHeader = false, ushort languageIndex = 0, ushort streamNumber = 0)
        {
            string fieldValue = "";
            bool   setMeta    = true;

            addFrameClass(fieldName, fieldDataType);

            if (0 == fieldDataType) // Unicode string
            {
                fieldValue = Utils.StripEndingZeroChars(Encoding.Unicode.GetString(source.ReadBytes(fieldDataSize)));
            }
            else if (1 == fieldDataType) // Byte array
            {
                if (fieldName.ToUpper().Equals("WM/PICTURE"))
                {
                    byte picCode = source.ReadByte();
                    // TODO factorize : abstract PictureTypeDecoder + unsupported / supported decision in MetaDataIO ?
                    PictureInfo.PIC_TYPE picType = ID3v2.DecodeID3v2PictureType(picCode);

                    int picturePosition;
                    if (picType.Equals(PictureInfo.PIC_TYPE.Unsupported))
                    {
                        addPictureToken(MetaDataIOFactory.TAG_NATIVE, picCode);
                        picturePosition = takePicturePosition(MetaDataIOFactory.TAG_NATIVE, picCode);
                    }
                    else
                    {
                        addPictureToken(picType);
                        picturePosition = takePicturePosition(picType);
                    }

                    if (readTagParams.ReadPictures)
                    {
                        int    picSize     = source.ReadInt32();
                        string mimeType    = StreamUtils.ReadNullTerminatedString(source, Encoding.Unicode);
                        string description = StreamUtils.ReadNullTerminatedString(source, Encoding.Unicode);

                        PictureInfo picInfo = PictureInfo.fromBinaryData(source.BaseStream, picSize, picType, getImplementedTagType(), picCode, picturePosition);
                        picInfo.Description = description;

                        tagData.Pictures.Add(picInfo);
                    }
                    setMeta = false;
                }
                else
                {
                    source.BaseStream.Seek(fieldDataSize, SeekOrigin.Current);
                }
            }
            else if (2 == fieldDataType) // 16-bit Boolean (metadata); 32-bit Boolean (extended header)
            {
                if (isExtendedHeader)
                {
                    fieldValue = source.ReadUInt32().ToString();
                }
                else
                {
                    fieldValue = source.ReadUInt16().ToString();
                }
            }
            else if (3 == fieldDataType) // 32-bit unsigned integer
            {
                uint intValue = source.ReadUInt32();
                if (fieldName.Equals("WM/GENRE", StringComparison.OrdinalIgnoreCase))
                {
                    intValue++;
                }
                fieldValue = intValue.ToString();
            }
            else if (4 == fieldDataType) // 64-bit unsigned integer
            {
                fieldValue = source.ReadUInt64().ToString();
            }
            else if (5 == fieldDataType) // 16-bit unsigned integer
            {
                fieldValue = source.ReadUInt16().ToString();
            }
            else if (6 == fieldDataType) // 128-bit GUID; unused for now
            {
                source.BaseStream.Seek(fieldDataSize, SeekOrigin.Current);
            }

            if (setMeta)
            {
                SetMetaField(fieldName.Trim(), fieldValue, readTagParams.ReadAllMetaFrames, zoneCode, 0, streamNumber, decodeLanguage(source.BaseStream, languageIndex));
            }
        }
Exemplo n.º 3
0
        private bool readFrames(BinaryReader source, TagInfo Tag, MetaDataIO.ReadTagParams readTagParams)
        {
            string frameName;
            string strValue;
            int    frameDataSize;
            long   valuePosition;
            int    frameFlags;

            source.BaseStream.Seek(Tag.FileSize - Tag.DataShift - Tag.Size, SeekOrigin.Begin);
            // Read all stored fields
            for (int iterator = 0; iterator < Tag.FrameCount; iterator++)
            {
                frameDataSize = source.ReadInt32();
                frameFlags    = source.ReadInt32();
                frameName     = StreamUtils.ReadNullTerminatedString(source, Utils.Latin1Encoding); // Slightly more permissive than what APE specs indicate in terms of allowed characters ("Space(0x20), Slash(0x2F), Digits(0x30...0x39), Letters(0x41...0x5A, 0x61...0x7A)")

                valuePosition = source.BaseStream.Position;

                if (frameDataSize < 0 || valuePosition + frameDataSize > Tag.FileSize)
                {
                    LogDelegator.GetLogDelegate()(Log.LV_ERROR, "Invalid value found while reading APEtag frame");
                    return(false);
                }

                if ((frameDataSize > 0) && (frameDataSize <= 1000))
                {
                    /*
                     * According to spec : "Items are not zero-terminated like in C / C++.
                     * If there's a zero character, multiple items are stored under the key and the items are separated by zero characters."
                     *
                     * => Values have to be splitted
                     */
                    strValue = Utils.StripEndingZeroChars(Encoding.UTF8.GetString(source.ReadBytes(frameDataSize)));
                    strValue = strValue.Replace('\0', Settings.InternalValueSeparator).Trim();
                    SetMetaField(frameName.Trim().ToUpper(), strValue, readTagParams.ReadAllMetaFrames);
                }
                else if (frameDataSize > 0 && !frameName.ToLower().Contains("lyrics")) // Size > 1000 => Probably an embedded picture
                {
                    int picturePosition;
                    PictureInfo.PIC_TYPE picType = decodeAPEPictureType(frameName);

                    if (picType.Equals(PictureInfo.PIC_TYPE.Unsupported))
                    {
                        addPictureToken(getImplementedTagType(), frameName);
                        picturePosition = takePicturePosition(getImplementedTagType(), frameName);
                    }
                    else
                    {
                        addPictureToken(picType);
                        picturePosition = takePicturePosition(picType);
                    }

                    if (readTagParams.ReadPictures)
                    {
                        // Description seems to be a null-terminated ANSI string containing
                        //    * The frame name
                        //    * A byte (0x2E)
                        //    * The picture type (3 characters; similar to the 2nd part of the mime-type)
                        string      description = StreamUtils.ReadNullTerminatedString(source, Utils.Latin1Encoding);
                        PictureInfo picInfo     = PictureInfo.fromBinaryData(source.BaseStream, frameDataSize - description.Length - 1, picType, getImplementedTagType(), frameName, picturePosition);
                        picInfo.Description = description;
                        tagData.Pictures.Add(picInfo);
                    }
                }
                source.BaseStream.Seek(valuePosition + frameDataSize, SeekOrigin.Begin);
            }

            return(true);
        }