示例#1
0
文件: Vorbis.cs 项目: zxc120/GARbro
        VorbisInfoFloor UnpackFloor0(OggBitStream input)
        {
            var info     = new VorbisInfoFloor();
            int order    = input.ReadBits(8);
            int rate     = input.ReadBits(16);
            int barkmap  = input.ReadBits(16);
            int ampbits  = input.ReadBits(6);
            int ampdB    = input.ReadBits(8);
            int numbooks = input.ReadBits(4) + 1;

            if (order < 1 || rate < 1 || barkmap < 1 || numbooks < 1)
            {
                return(null);
            }

            for (int j = 0; j < numbooks; ++j)
            {
                int books = input.ReadByte();
                if (books < 0 || books >= CodecSetup.Books)
                {
                    return(null);
                }
            }
            return(info);
        }
示例#2
0
文件: Vorbis.cs 项目: zxc120/GARbro
        // https://www.xiph.org/vorbis/doc/libvorbis/vorbis_packet_blocksize.html
        public int PacketBlockSize(OggPacket op)
        {
            using (var input = new OggBitStream(op))
            {
                // Check the packet type
                if (input.ReadBits(1) != 0)
                {
                    throw new InvalidDataException("Not an audio data packet.");
                }

                int modebits = 0;
                for (int v = CodecSetup.Modes; v > 1; v >>= 1)
                {
                    modebits++;
                }

                // read our mode and pre/post windowsize
                int mode = input.ReadBits(modebits);

                if (-1 == mode)
                {
                    throw new InvalidDataException("Invalid Ogg/Vorbis packet.");
                }

                return(CodecSetup.BlockSizes[CodecSetup.ModeParam[mode].BlockFlag]);
            }
        }
示例#3
0
文件: Vorbis.cs 项目: zxc120/GARbro
        // https://xiph.org/vorbis/doc/libvorbis/vorbis_synthesis_headerin.html
        public void SynthesisHeaderin(VorbisComment vc, OggPacket op)
        {
            using (var input = new OggBitStream(op))
            {
                int packtype = input.ReadUInt8();
                var buf      = input.ReadBytes(6);
                if (!buf.AsciiEqual("vorbis"))
                {
                    throw new InvalidDataException("Not an Ogg/Vorbis stream.");
                }
                switch (packtype)
                {
                case 1:
                    if (!op.BoS)
                    {
                        throw InvalidHeader();
                    }
                    if (Rate != 0)
                    {
                        throw InvalidHeader();
                    }
                    UnpackInfo(input);
                    break;

                case 3:
                    if (0 == Rate)
                    {
                        throw InvalidHeader();
                    }
                    vc.UnpackComment(input);
                    break;

                case 5:
                    if (0 == Rate || null == vc.Vendor)
                    {
                        throw InvalidHeader();
                    }
                    UnpackBooks(input);
                    break;

                default:
                    throw InvalidHeader();
                }
            }
        }
示例#4
0
文件: Vorbis.cs 项目: zxc120/GARbro
        void UnpackInfo(OggBitStream input)
        {
            Version = input.ReadInt32();
            if (Version != 0)
            {
                throw new InvalidDataException("Invalid Vorbis encoder version.");
            }
            Channels = input.ReadUInt8();
            Rate     = input.ReadInt32();

            BitrateUpper   = input.ReadInt32();
            BitrateNominal = input.ReadInt32();
            BitrateLower   = input.ReadInt32();

            CodecSetup.BlockSizes[0] = 1 << input.ReadBits(4);
            CodecSetup.BlockSizes[1] = 1 << input.ReadBits(4);

            if (input.ReadBits(1) != 1)
            {
                throw InvalidHeader();
            }
        }
示例#5
0
文件: Vorbis.cs 项目: zxc120/GARbro
        internal void UnpackComment(OggBitStream input)
        {
            int vendor_len = input.ReadInt32();

            if (vendor_len < 0)
            {
                throw VorbisInfo.InvalidHeader();
            }
            var vendor = input.ReadBytes(vendor_len);

            int count = input.ReadInt32();

            if (count < 0)
            {
                throw VorbisInfo.InvalidHeader();
            }

            var comments = new List <byte[]> (count);

            for (int i = 0; i < count; ++i)
            {
                int len = input.ReadInt32();
                if (len < 0)
                {
                    throw VorbisInfo.InvalidHeader();
                }
                var bytes = input.ReadBytes(len);
                comments.Add(bytes);
            }
            if (input.ReadBits(1) != 1)
            {
                throw VorbisInfo.InvalidHeader();
            }

            this.Vendor   = vendor;
            this.Comments = comments;
        }
示例#6
0
文件: Vorbis.cs 项目: zxc120/GARbro
        VorbisInfoMapping UnpackMapping(OggBitStream input)
        {
            var info = new VorbisInfoMapping();

            int b = input.ReadBits(1);

            if (b < 0)
            {
                return(null);
            }
            if (b > 0)
            {
                info.submaps = input.ReadBits(4) + 1;
                if (info.submaps <= 0)
                {
                    return(null);
                }
            }
            else
            {
                info.submaps = 1;
            }

            b = input.ReadBits(1);
            if (b < 0)
            {
                return(null);
            }
            if (b > 0)
            {
                info.coupling_steps = input.ReadBits(8) + 1;
                if (info.coupling_steps <= 0)
                {
                    return(null);
                }
                for (int i = 0; i < info.coupling_steps; ++i)
                {
                    int bits  = CountBits((uint)Channels);
                    int testM = input.ReadBits(bits);
                    int testA = input.ReadBits(bits);
                    if (testM < 0 || testA < 0 || testM == testA ||
                        testM >= Channels || testA >= Channels)
                    {
                        return(null);
                    }
                }
            }

            if (input.ReadBits(2) != 0)
            {
                return(null);
            }

            if (info.submaps > 1)
            {
                for (int i = 0; i < Channels; ++i)
                {
                    int chmuxlist = input.ReadBits(4);
                    if (chmuxlist >= info.submaps || chmuxlist < 0)
                    {
                        return(null);
                    }
                }
            }
            for (int i = 0; i < info.submaps; ++i)
            {
                input.ReadByte(); // time submap unused
                int floorsubmap = input.ReadByte();
                if (floorsubmap >= CodecSetup.Floors || floorsubmap < 0)
                {
                    return(null);
                }
                int residuesubmap = input.ReadByte();
                if (residuesubmap >= CodecSetup.Residues || residuesubmap < 0)
                {
                    return(null);
                }
            }
            return(info);
        }
示例#7
0
文件: Vorbis.cs 项目: zxc120/GARbro
        object UnpackResidue(OggBitStream input)
        {
            var info = new VorbisInfoResidue();

            info.begin      = input.ReadBits(24);
            info.end        = input.ReadBits(24);
            info.grouping   = input.ReadBits(24) + 1;
            info.partitions = input.ReadBits(6) + 1;
            info.groupbook  = input.ReadBits(8);

            // check for premature EOP
            if (info.groupbook < 0)
            {
                return(null);
            }

            int acc = 0;

            for (int j = 0; j < info.partitions; ++j)
            {
                int cascade = input.ReadBits(3);
                int cflag   = input.ReadBits(1);
                if (cflag < 0)
                {
                    return(null);
                }
                if (cflag > 0)
                {
                    int c = input.ReadBits(5);
                    if (c < 0)
                    {
                        return(null);
                    }
                    cascade |= c << 3;
                }
                // info.secondstages[j] = cascade;

                acc += CountSetBits((uint)cascade);
            }
            for (int j = 0; j < acc; ++j)
            {
                int book = input.ReadBits(8);
                if (book < 0)
                {
                    return(null);
                }
                if (book >= CodecSetup.Books)
                {
                    return(null);
                }
//                if (CodecSetup.book_param[book].maptype == 0) return null;
//                info.booklist[j] = book;
            }
            if (info.groupbook >= CodecSetup.Books)
            {
                return(null);
            }

            /*
             * int entries = CodecSetup.book_param[info.groupbook].entries;
             * int dim = CodecSetup.book_param[info.groupbook].dim;
             * int partvals = 1;
             * if (dim < 1)
             *  return null;
             * while (dim > 0)
             * {
             *  partvals *= info.partitions;
             *  if (partvals > entries)
             *      return null;
             *  dim--;
             * }
             * info.partvals = partvals;
             */
            return(info);
        }
示例#8
0
文件: Vorbis.cs 项目: zxc120/GARbro
        VorbisInfoFloor UnpackFloor1(OggBitStream input)
        {
            int max_class = -1;

            var info = new VorbisInfoFloor();
            // read partitions
            int partitions      = input.ReadBits(5); // only 0 to 31 legal
            var partition_class = new int[partitions];

            for (int j = 0; j < partitions; ++j)
            {
                partition_class[j] = input.ReadBits(4);  // only 0 to 15 legal
                if (partition_class[j] < 0)
                {
                    return(null);
                }
                if (max_class < partition_class[j])
                {
                    max_class = partition_class[j];
                }
            }

            // read partition classes
            var class_dim = new int[max_class + 1];

            for (int j = 0; j < max_class + 1; ++j)
            {
                class_dim[j] = input.ReadBits(3) + 1; // 1 to 8
                int class_subs = input.ReadBits(2);   // 0,1,2,3 bits
                if (class_subs < 0)
                {
                    return(null);
                }
                if (class_subs > 0)
                {
                    input.ReadBits(8);  // class_book
                }
                for (int k = 0; k < (1 << class_subs); ++k)
                {
                    int class_subbook = input.ReadBits(8) - 1;  // info.class_subbook[j][k]
                }
            }

            // read the post list
            int mult      = input.ReadBits(2) + 1; // only 1,2,3,4 legal now
            int rangebits = input.ReadBits(4);

            if (rangebits < 0)
            {
                return(null);
            }

            int count = 0;

//            var postlist = new int[VorbisInfoFloor.Posit + 2];
            for (int j = 0, k = 0; j < partitions; ++j)
            {
                count += class_dim[partition_class[j]];
                if (count > VorbisInfoFloor.Posit)
                {
                    return(null);
                }
                for (; k < count; ++k)
                {
                    int t = input.ReadBits(rangebits);
                    if (t < 0 || t >= (1 << rangebits))
                    {
                        return(null);
                    }
//                    postlist[k+2] = t;
                }
            }
//            postlist[0] = 0;
//            postlist[1] = 1<<rangebits;

            // don't allow repeated values in post list as they'd result in
            // zero-length segments

            /*
             * var indices = Enumerable.Range (0, count+2).OrderBy (i => postlist[i]).ToArray();
             * for (int j = 1; j < count+2; j++)
             *  if(postlist[indices[j-1]] == postlist[indices[j]])
             *      return null;
             */
            return(info);
        }
示例#9
0
文件: Vorbis.cs 项目: zxc120/GARbro
        StaticCodebook StaticBookUnpack(OggBitStream input)
        {
            // make sure alignment is correct
            if (input.ReadBits(24) != 0x564342)
            {
                return(null);
            }

            var s = new StaticCodebook();

            // first the basic parameters
            s.dim     = input.ReadBits(16);
            s.entries = input.ReadBits(24);
            if (-1 == s.entries)
            {
                return(null);
            }

            if (iLog((uint)s.dim) + iLog((uint)s.entries) > 24)
            {
                return(null);
            }

            // codeword ordering.... length ordered or unordered?
            switch (input.ReadBits(1))
            {
            case 0:
                // allocated but unused entries?
                int unused = input.ReadBits(1);
                // unordered
                s.lengthlist = new byte[s.entries];

                // allocated but unused entries?
                if (unused > 0)
                {
                    // yes, unused entries
                    for (int i = 0; i < s.entries; ++i)
                    {
                        if (input.ReadBits(1) > 0)
                        {
                            int num = input.ReadBits(5);
                            if (-1 == num)
                            {
                                return(null);
                            }
                            s.lengthlist[i] = (byte)(num + 1);
                        }
                        else
                        {
                            s.lengthlist[i] = 0;
                        }
                    }
                }
                else
                {
                    // all entries used; no tagging
                    for (int i = 0; i < s.entries; ++i)
                    {
                        int num = input.ReadBits(5);
                        if (-1 == num)
                        {
                            return(null);
                        }
                        s.lengthlist[i] = (byte)(num + 1);
                    }
                }
                break;

            case 1: // ordered
                int length = input.ReadBits(5) + 1;
                if (0 == length)
                {
                    return(null);
                }
                s.lengthlist = new byte[s.entries];

                for (int i = 0; i < s.entries;)
                {
                    int num = input.ReadBits(iLog((uint)(s.entries - i)));
                    if (-1 == num || length > 32 || num > s.entries - i ||
                        (num > 0 && ((num - 1) >> (length - 1)) > 1))
                    {
                        return(null);
                    }
                    for (int j = 0; j < num; ++j, ++i)
                    {
                        s.lengthlist[i] = (byte)length;
                    }
                    length++;
                }
                break;

            default:
                return(null);
            }

            // Do we have a mapping to unpack?
            switch ((s.maptype = input.ReadBits(4)))
            {
            case 0: // no mapping
                break;

            case 1:
            case 2:
                // implicitly populated value mapping
                // explicitly populated value mapping

                s.q_min       = input.ReadInt32();
                s.q_delta     = input.ReadInt32();
                s.q_quant     = input.ReadBits(4) + 1;
                s.q_sequencep = input.ReadBits(1);
                if (-1 == s.q_sequencep)
                {
                    return(null);
                }
                int quantvals = 0;
                switch (s.maptype)
                {
                case 1:
                    quantvals = s.dim == 0 ? 0 : s.Maptype1Quantvals();
                    break;

                case 2:
                    quantvals = s.entries * s.dim;
                    break;
                }

                // quantized values
                s.quantlist = new int[quantvals];
                for (int i = 0; i < quantvals; ++i)
                {
                    s.quantlist[i] = input.ReadBits(s.q_quant);
                }

                if (quantvals > 0 && s.quantlist[quantvals - 1] == -1)
                {
                    return(null);
                }
                break;

            default: // EOF
                return(null);
            }

            // all set
            return(s);
        }
示例#10
0
文件: Vorbis.cs 项目: zxc120/GARbro
        void UnpackBooks(OggBitStream input)
        {
            // codebooks
            CodecSetup.Books = input.ReadUInt8() + 1;
            if (CodecSetup.Books <= 0)
            {
                throw InvalidHeader();
            }

            for (int i = 0; i < CodecSetup.Books; ++i)
            {
                var param = StaticBookUnpack(input);
                if (null == param)
                {
                    throw InvalidHeader();
                }
                CodecSetup.BookParam[i] = param;
            }

            // time backend settings; hooks are unused
            int times = input.ReadBits(6) + 1;

            if (times <= 0)
            {
                throw InvalidHeader();
            }
            for (int i = 0; i < times; ++i)
            {
                int test = input.ReadBits(16);
                if (test < 0 || test >= TimeB)
                {
                    throw InvalidHeader();
                }
            }

            // floor backend settings
            CodecSetup.Floors = input.ReadBits(6) + 1;
            if (CodecSetup.Floors <= 0)
            {
                throw InvalidHeader();
            }
            for (int i = 0; i < CodecSetup.Floors; i++)
            {
                int floor_type = input.ReadBits(16);
                if (floor_type < 0 || floor_type >= FloorB)
                {
                    throw InvalidHeader();
                }
                CodecSetup.FloorType[i] = floor_type;
                var param = FloorMethods[floor_type] (input);
                if (null == param)
                {
                    throw InvalidHeader();
                }
                CodecSetup.FloorParam[i] = param;
            }

            // residue backend settings
            CodecSetup.Residues = input.ReadBits(6) + 1;
            if (CodecSetup.Residues <= 0)
            {
                throw InvalidHeader();
            }
            for (int i = 0; i < CodecSetup.Residues; ++i)
            {
                int residue_type = input.ReadBits(16);
                if (residue_type < 0 || residue_type >= ResB)
                {
                    throw InvalidHeader();
                }
                CodecSetup.ResidueType[i] = residue_type;
                var param = UnpackResidue(input);
                if (null == param)
                {
                    throw InvalidHeader();
                }
                CodecSetup.ResidueParam[i] = param;
            }

            // map backend settings
            CodecSetup.Maps = input.ReadBits(6) + 1;
            if (CodecSetup.Maps <= 0)
            {
                throw InvalidHeader();
            }
            for (int i = 0; i < CodecSetup.Maps; ++i)
            {
                int map_type = input.ReadBits(16);
                if (map_type < 0 || map_type >= MapB)
                {
                    throw InvalidHeader();
                }
                CodecSetup.MapType[i] = map_type;
                var param = UnpackMapping(input);
                if (null == param)
                {
                    throw InvalidHeader();
                }
                CodecSetup.MapParam[i] = param;
            }

            // mode settings
            CodecSetup.Modes = input.ReadBits(6) + 1;
            if (CodecSetup.Modes <= 0)
            {
                throw InvalidHeader();
            }
            for (int i = 0; i < CodecSetup.Modes; ++i)
            {
                CodecSetup.ModeParam[i].BlockFlag     = input.ReadBits(1);
                CodecSetup.ModeParam[i].WindowType    = input.ReadBits(16);
                CodecSetup.ModeParam[i].TransformType = input.ReadBits(16);
                CodecSetup.ModeParam[i].Mapping       = input.ReadBits(8);

                if (CodecSetup.ModeParam[i].WindowType >= WindowB ||
                    CodecSetup.ModeParam[i].TransformType >= WindowB ||
                    CodecSetup.ModeParam[i].Mapping >= CodecSetup.Maps ||
                    CodecSetup.ModeParam[i].Mapping < 0)
                {
                    throw InvalidHeader();
                }
            }
            if (input.ReadBits(1) != 1)
            {
                throw InvalidHeader();
            }
        }