예제 #1
0
        public override IEnumerable <Track> GetTracks() //bool enabled tracks only?
        {
            if (m_Tracks != null)
            {
                foreach (Track track in m_Tracks)
                {
                    yield return(track);
                }
                yield break;
            }

            var tracks = new List <Track>();

            long position = Position;

            //Get Duration from mdhd, some files have more then one mdhd.
            if (false == m_Duration.HasValue)
            {
                ParseMovieHeader();
            }

            //traf should also be supported.
            foreach (var trakBox in ReadBoxes(Root.Offset, "trak").ToArray())
            {
                //Define variables which need to be reset for every track.

                int trackId = 0;

                ulong created = 0, modified = 0, duration = 0;

                int width = 0, height = 0;

                bool enabled = false, inMovie, inPreview;

                byte[] codecIndication = Media.Common.MemorySegment.EmptyBytes;

                float volume = m_Volume.Value;

                int offset = 0, version = 0, flags = 0;

                byte[] rawData;

                ulong trackTimeScale = m_TimeScale.Value, trackDuration = duration;

                DateTime trackCreated = m_Created.Value, trackModified = m_Modified.Value;

                Sdp.MediaType mediaType = Sdp.MediaType.unknown;

                string name = string.Empty;

                byte channels = 0, bitDepth = 0;

                double rate = 0;

                List <Tuple <long, long> > entries = new List <Tuple <long, long> >();

                List <long> offsets = new List <long>();

                List <int> sampleSizes = new List <int>();

                TimeSpan startTime = TimeSpan.Zero;

                //MAKE ONLY A SINGLE PASS HERE TO REDUCE IO
                using (var stream = trakBox.DataStream)
                {
                    int bytesRead = 0;

                    long length = 0, streamPosition = stream.Position, streamLength = stream.Length;

                    byte[] identifier;

                    //Note could use RawData from trakBox
                    //Would just need a way to ReadLength and Identifier from byte[] rather than Stream.

                    //This would also work but it would cause a seek
                    //foreach(var node in ReadBoxes(trakBox.DataOffset, trakBox.DataSize, null))

                    //While there is data in the stream
                    while (streamPosition < streamLength)
                    {
                        //Read the length
                        length = ReadLength(stream, out bytesRead);

                        streamPosition += bytesRead;

                        //Read the identifier
                        identifier = ReadIdentifier(stream);

                        bytesRead += IdentifierSize;

                        streamPosition += IdentifierSize;

                        length -= MinimumSize;

                        offset = 0;

                        string boxName = ToUTF8FourCharacterCode(identifier);

                        //Determine what to do
                        switch (boxName)
                        {
                        // Next Node has data
                        case "trak": continue;

                        case "elst":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            List <Tuple <int, int, float> > edits = new List <Tuple <int, int, float> >();

                            //Skip Flags and Version
                            offset = LengthSize;

                            int entryCount = Common.Binary.Read32(rawData, offset, Common.Binary.IsLittleEndian);

                            offset += 4;

                            for (int i = 0; i < entryCount && offset < length; ++i)
                            {
                                //Edit Duration, MediaTime, Rate
                                edits.Add(new Tuple <int, int, float>(Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian),
                                                                      Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian),
                                                                      Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian) / ushort.MaxValue));
                            }

                            if (edits.Count > 0 && edits[0].Item2 > 0)
                            {
                                startTime = TimeSpan.FromMilliseconds(edits[0].Item2);
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "tkhd":    //tfhd
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            version = rawData[offset++];

                            flags = Common.Binary.Read24(rawData, offset, Common.Binary.IsLittleEndian);

                            offset += 3;

                            enabled = ((flags & 1) == flags);

                            inMovie = ((flags & 2) == flags);

                            inPreview = ((flags & 3) == flags);

                            if (version == 0)
                            {
                                created = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);

                                modified = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }
                            else
                            {
                                created = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);

                                modified = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }

                            trackId = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            //Skip if not the first active track in the moov header..
                            //if (trackId < NextTrackId) continue;

                            //Skip
                            offset += 4;

                            //Get Duration
                            if (version == 0)
                            {
                                duration = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }
                            else
                            {
                                duration = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }

                            if (duration == 4294967295L)
                            {
                                duration = ulong.MaxValue;
                            }

                            //Reserved
                            offset += 8;

                            //int layer = Common.Binary.ReadU16(rawData, ref offset, Common.Binary.IsLittleEndian);

                            //int altGroup = Common.Binary.ReadU16(rawData, ref offset, Common.Binary.IsLittleEndian);

                            offset += 4;

                            volume = Common.Binary.ReadU16(rawData, ref offset, Common.Binary.IsLittleEndian) / 256;

                            //Skip int and Matrix
                            offset += 38;

                            //Width
                            width = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian) / ushort.MaxValue;

                            //Height
                            height = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian) / ushort.MaxValue;

                            offset = (int)length;

                            goto default;
                        }

                        case "mdhd":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            version = rawData[offset++];

                            flags = Common.Binary.Read24(rawData, ref offset, Common.Binary.IsLittleEndian);

                            ulong mediaCreated, mediaModified, timescale, mediaduration;

                            if (version == 0)
                            {
                                mediaCreated = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);

                                mediaModified = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);

                                timescale = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);

                                mediaduration = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }
                            else
                            {
                                mediaCreated = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);

                                mediaModified = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);

                                timescale = Common.Binary.ReadU32(rawData, ref offset, Common.Binary.IsLittleEndian);

                                mediaduration = Common.Binary.ReadU64(rawData, ref offset, Common.Binary.IsLittleEndian);
                            }

                            trackTimeScale = timescale;

                            trackDuration = mediaduration;

                            trackCreated = IsoBaseDateUtc.AddMilliseconds(mediaCreated * Media.Common.Extensions.TimeSpan.TimeSpanExtensions.MicrosecondsPerMillisecond);

                            trackModified = IsoBaseDateUtc.AddMilliseconds(mediaModified * Media.Common.Extensions.TimeSpan.TimeSpanExtensions.MicrosecondsPerMillisecond);

                            offset = (int)length;

                            goto default;
                        }

                        case "stsd":
                        {
                            //H264
                            // stsd/avc1/avcC contains a field 'lengthSizeMinusOne' specifying the length. But the default is 4.

                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            int sampleDescriptionCount = length > 0 ? Common.Binary.Read32(rawData, LengthSize, Common.Binary.IsLittleEndian) : 0;

                            offset = MinimumSize;

                            if (sampleDescriptionCount > 0)
                            {
                                for (int i = 0; i < sampleDescriptionCount; ++i)
                                {
                                    int len = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian) - 4;

                                    var sampleEntry = rawData.Skip(offset).Take(len);
                                    offset += len;

                                    switch (mediaType)
                                    {
                                    case Sdp.MediaType.audio:
                                    {
                                        //Maybe == mp4a
                                        codecIndication = sampleEntry.Take(4).ToArray();

                                        //32, 16, 16 (dref index)
                                        version = Common.Binary.Read16(sampleEntry, 8, Common.Binary.IsLittleEndian);

                                        //Revision 16, Vendor 32

                                        //ChannelCount 16
                                        channels = (byte)Common.Binary.ReadU16(sampleEntry, 20, Common.Binary.IsLittleEndian);

                                        //SampleSize 16 (A 16-bit integer that specifies the number of bits in each uncompressed sound sample. Allowable values are 8 or 16. Formats using more than 16 bits per sample set this field to 16 and use sound description version 1.)
                                        bitDepth = (byte)Common.Binary.ReadU16(sampleEntry, 22, Common.Binary.IsLittleEndian);

                                        //CompressionId 16
                                        var compressionId = sampleEntry.Skip(24).Take(2);

                                        //Decode to a WaveFormatID (16 bit)
                                        int waveFormatId = Common.Binary.Read16(compressionId, 0, Common.Binary.IsLittleEndian);

                                        //The compression ID is set to -2 and redefined sample tables are used (see “Redefined Sample Tables”).
                                        if (-2 == waveFormatId)
                                        {
                                            //var waveAtom = ReadBox("wave", sampleDescriptionBox.Offset);
                                            //if (waveAtom != null)
                                            //{
                                            //    flags = Common.Binary.Read24(waveAtom.Raw, 9, Common.Binary.IsLittleEndian);
                                            //    //Extrack from flags?
                                            //}
                                        }                //If the formatId is known then use it
                                        else if (waveFormatId > 0)
                                        {
                                            codecIndication = compressionId.ToArray();
                                        }

                                        //@ 26

                                        //PktSize 16

                                        //sr 32

                                        rate = (double)Common.Binary.ReadU32(sampleEntry, 28, Common.Binary.IsLittleEndian) / 65536F;

                                        //@ 32

                                        if (version > 1)
                                        {
                                            //36 total

                                            rate     = BitConverter.Int64BitsToDouble(Common.Binary.Read64(sampleEntry, 32, Common.Binary.IsLittleEndian));
                                            channels = (byte)Common.Binary.ReadU32(sampleEntry, 40, Common.Binary.IsLittleEndian);

                                            //24 More Bytes
                                        }

                                        //else 16 more if version == 1
                                        //else 2 more if version == 0

                                        //@ esds for mp4a

                                        //http://www.mp4ra.org/object.html
                                        // @ +4 +4 +11 == ObjectTypeIndication

                                        break;
                                    }

                                    case Sdp.MediaType.video:
                                    {
                                        codecIndication = sampleEntry.Take(4).ToArray();

                                        //SampleEntry overhead = 8
                                        //Version, Revision, Vendor, TemporalQUal, SpacialQual, Width, Height, hRes,vRes, reversed, FrameCount, compressorName, depth, clrTbl, (extensions)

                                        //Width @ 28
                                        width = Common.Binary.ReadU16(sampleEntry, 28, Common.Binary.IsLittleEndian);
                                        //Height @ 30
                                        height = Common.Binary.ReadU16(sampleEntry, 30, Common.Binary.IsLittleEndian);

                                        //hres, vres, reserved = 12

                                        //FrameCount @ 44 (A 16-bit integer that indicates how many frames of compressed data are stored in each sample. Usually set to 1.)

                                        //@46

                                        //30 bytes compressor name (1 byte length) + 1

                                        //@78

                                        bitDepth = (byte)Common.Binary.ReadU16(sampleEntry, 78, Common.Binary.IsLittleEndian);

                                        //esds box for codec specific data.

                                        break;
                                    }
                                    }

                                    continue;
                                }
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "stts":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            //Skip Flags and Version
                            offset = LengthSize;

                            int entryCount = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            for (int i = 0; i < entryCount && offset < length; ++i)
                            {
                                //Sample Count Sample Duration
                                entries.Add(new Tuple <long, long>(Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian),
                                                                   Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian)));
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "stsz":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            //Skip Flags and Version
                            offset = MinimumSize;

                            int defaultSize = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            int count = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            if (defaultSize == 0)
                            {
                                for (int i = 0; i < count && offset < length; ++i)
                                {
                                    sampleSizes.Add(Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian));
                                }
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "stco":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            //Skip Flags and Version
                            offset = LengthSize;

                            int chunkCount = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            for (int i = 0; i < chunkCount && offset < length; ++i)
                            {
                                offsets.Add((long)Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian));
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "st64":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            //Skip Flags and Version
                            offset = MinimumSize;

                            int chunkCount = Common.Binary.Read32(rawData, ref offset, Common.Binary.IsLittleEndian);

                            for (int i = 0; i < chunkCount && offset < length; ++i)
                            {
                                offsets.Add(Common.Binary.Read64(rawData, ref offset, Common.Binary.IsLittleEndian));
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "hdlr":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            string comp = ToUTF8FourCharacterCode(rawData, LengthSize), sub = ToUTF8FourCharacterCode(rawData, LengthSize * 2);

                            switch (sub)
                            {
                            case "vide": mediaType = Sdp.MediaType.video; break;

                            case "soun": mediaType = Sdp.MediaType.audio; break;

                            case "text": mediaType = Sdp.MediaType.text; break;

                            case "tmcd": mediaType = Sdp.MediaType.timing; break;

                            default: break;
                            }

                            offset = (int)length;

                            goto default;
                        }

                        case "name":
                        {
                            rawData = new byte[length];

                            stream.Read(rawData, 0, (int)length);

                            name = Encoding.UTF8.GetString(rawData);

                            offset = (int)length;

                            goto default;
                        }

                        default:
                        {
                            //If the box was a parent continue parsing
                            if (BaseMediaReader.ParentBoxes.Contains(boxName))
                            {
                                continue;
                            }

                            //Determine how much to skip
                            long toMove = length - offset;

                            //Skip anything which remains if the offset was moved or the entire node if nothing was read.
                            if (toMove > 0)
                            {
                                streamPosition = stream.Position += toMove;
                            }
                            else
                            {
                                streamPosition += length;
                            }

                            continue;
                        }
                        }
                    }
                }

                TimeSpan calculatedDuration = TimeSpan.FromSeconds(trackDuration / (double)trackTimeScale);

                ulong sampleCount = (ulong)sampleSizes.Count();

                //If there are no samples defined and there are entries in the sample to time atom
                if (sampleCount == 0 && entries.Count > 0)
                {
                    //Use the count of entries from the sample to time atom as the count of samples.
                    sampleCount = (ulong)entries.Count;

                    //If there is only one entry use the value in the entry
                    if (sampleCount == 1)
                    {
                        sampleCount = (ulong)entries[0].Item1;
                    }
                }

                rate = mediaType == Sdp.MediaType.audio ? trackTimeScale : (double)((double)sampleCount / ((double)trackDuration / trackTimeScale));

                Track createdTrack = new Track(trakBox, name, trackId, trackCreated, trackModified, (long)sampleCount, width, height, startTime, calculatedDuration, rate, mediaType, codecIndication, channels, bitDepth, enabled);

                createdTrack.Volume = volume;

                tracks.Add(createdTrack);

                yield return(createdTrack);
            }

            m_Tracks = tracks;

            Position = position;
        }
예제 #2
0
 public double ReadDouble()
 {
     return(BitConverter.Int64BitsToDouble(this.ReadLong()));
 }
예제 #3
0
 public double Double()
 {
     return(BitConverter.Int64BitsToDouble(Long()));
 }
예제 #4
0
        public static void ReadPrimitive(Stream stream, out double value)
        {
            ulong v = ReadVarint64(stream);

            value = BitConverter.Int64BitsToDouble((long)v);
        }
예제 #5
0
        /// <summary>
        /// Decodes a IEEE-754 double precision value.
        /// </summary>
        /// <param name="source">The source array for this data</param>
        /// <param name="position">The position in <paramref name="source"/> to decode from.</param>
        /// <returns>The decoded value.</returns>
        public static double decodeDouble(byte[] source, int position)
        {
            long dval = decodeInt64(source, position);

            return(BitConverter.Int64BitsToDouble(dval));
        }
예제 #6
0
        public static double DoubleFromNetBytes(byte[] buffer, int offset)
        {
            long i64 = Int64FromNetBytes(buffer, offset);

            return(BitConverter.Int64BitsToDouble(i64));
        }
예제 #7
0
 public double GetDouble(int index)
 {
     return(BitConverter.Int64BitsToDouble((long)ReadLittleEndian(index, sizeof(double))));
 }
예제 #8
0
 /// <summary>
 /// Reads a big endian double.
 /// </summary>
 /// <param name="buffer">The raw data buffer.</param>
 /// <param name="offset">The offset into the buffer where the double resides.</param>
 /// <returns>The double read from the buffer at the offset location.</returns>
 public static double ReadDoubleBE(byte[] buffer, int offset)
 {
     return(BitConverter.Int64BitsToDouble(ReadInt64BE(buffer, offset)));
 }
예제 #9
0
        public virtual double readDouble()
        {
            long i = readLong();

            return(BitConverter.Int64BitsToDouble(i));
        }
예제 #10
0
파일: Encdec.cs 프로젝트: zxz2020/Emby
 public static float Dec_floatbe(byte[] src, int si)
 {
     return((float)BitConverter.Int64BitsToDouble(Dec_uint32be(src, si)));
 }
예제 #11
0
파일: Encdec.cs 프로젝트: zxz2020/Emby
 public static double Dec_doublebe(byte[] src, int si)
 {
     return(BitConverter.Int64BitsToDouble(Dec_uint64be(src, si)));
 }
 public static double BytesToDBL(uint[] inp)
 {
     long tmp0 = inp[0]; long tmp1 = inp[1]; tmp1 = tmp1 << 32; return(BitConverter.Int64BitsToDouble(tmp0 + tmp1));
 }
예제 #13
0
        public static void Execute()
        {
            string result;
            string expectedResult;

            short aShort = 1;

            byte[] shortBytes = BitConverter.GetBytes(aShort);
            result         = BitConverter.ToString(shortBytes);
            expectedResult = "01-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(shortBytes) doesn't work: result " + result + " != " + expectedResult);

            int anInt = 1;

            byte[] intBytes = BitConverter.GetBytes(anInt);

            result         = BitConverter.ToString(intBytes, 0);
            expectedResult = "01-00-00-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(intBytes) doesn't work: result " + result + " != " + expectedResult);

            long aLong = 1;

            byte[] longBytes = BitConverter.GetBytes(aLong);

            result         = BitConverter.ToString(longBytes, 0);
            expectedResult = "01-00-00-00-00-00-00-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(longBytes) doesn't work: result " + result + " != " + expectedResult);

            ushort anUShort = 1;

            byte[] ushortBytes = BitConverter.GetBytes(anUShort);
            result         = BitConverter.ToString(ushortBytes);
            expectedResult = "01-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(ushortBytes) doesn't work: result " + result + " != " + expectedResult);

            uint anUInt = 1;

            byte[] uintBytes = BitConverter.GetBytes(anUInt);

            result         = BitConverter.ToString(uintBytes, 0);
            expectedResult = "01-00-00-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(uintBytes) doesn't work: result " + result + " != " + expectedResult);

            ulong anULong = 1;

            byte[] ulongBytes = BitConverter.GetBytes(anULong);

            result         = BitConverter.ToString(ulongBytes, 0);
            expectedResult = "01-00-00-00-00-00-00-00";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(ulongBytes) doesn't work: result " + result + " != " + expectedResult);

            // This test works, what is the difference with double? That is saved as an Int32 in oly a register?
            float aFloat = 1.0f;

            byte[] floatBytes = BitConverter.GetBytes(aFloat);

            result         = BitConverter.ToString(floatBytes, 0);
            expectedResult = "00-00-80-3F";

            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(floatBytes) doesn't work: result " + result + " != " + expectedResult);

            double aDouble = 1.0;

            result         = BitConverter.ToString(BitConverter.GetBytes(aDouble));
            expectedResult = "00-00-00-00-00-00-F0-3F";
            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(doubleBytes) doesn't work: result " + result + " != " + expectedResult);

            bool aBool = true;

            result         = BitConverter.ToString(BitConverter.GetBytes(aBool));
            expectedResult = "01";
            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(bool) doesn't work: result " + result + " != " + expectedResult);

            char aChar = 'X';

            result         = BitConverter.ToString(BitConverter.GetBytes(aChar));
            expectedResult = "58-00";
            Assert.IsTrue((result == expectedResult), "BitConverter.ToString(char) doesn't work: result " + result + " != " + expectedResult);

            //Tests for GetBytes and ToXXX
            aShort = 240;
            Assert.IsTrue(BitConverter.ToInt16(BitConverter.GetBytes(aShort), 0) == aShort, "BitConverter works with Int16");

            aShort = -240;
            Assert.IsTrue(BitConverter.ToInt16(BitConverter.GetBytes(aShort), 0) == aShort, "BitConverter works with negativ Int16");

            anInt = 1234;
            Assert.IsTrue(BitConverter.ToInt32(BitConverter.GetBytes(anInt), 0) == anInt, "BitConverter works with Int32");

            anInt = -1234;
            Assert.IsTrue(BitConverter.ToInt32(BitConverter.GetBytes(anInt), 0) == anInt, "BitConverter works with negative Int32");

            aLong = 123456789000;
            Assert.IsTrue(BitConverter.ToInt64(BitConverter.GetBytes(aLong), 0) == aLong, "BitConvert works with Int64");

            aLong = -123456789000;
            Assert.IsTrue(BitConverter.ToInt64(BitConverter.GetBytes(aLong), 0) == aLong, "BitConvert works with negative Int64");

            anUShort = 240;
            Assert.IsTrue(BitConverter.ToUInt16(BitConverter.GetBytes(anUShort), 0) == anUShort, "BitConverter works with UInt16");

            anUInt = 1233346;
            Assert.IsTrue(BitConverter.ToUInt32(BitConverter.GetBytes(anUInt), 0) == anUInt, "BitConverter works with UInt32");

            anULong = 123456789000;
            Assert.IsTrue(BitConverter.ToUInt64(BitConverter.GetBytes(anULong), 0) == anULong, "BitConverter works with UInt64");

            aBool = false;
            Assert.IsTrue(BitConverter.ToBoolean(BitConverter.GetBytes(aBool), 0) == aBool, "BitConverter works with Bool");

            aChar = 'C';
            Assert.IsTrue(BitConverter.ToChar(BitConverter.GetBytes(aChar), 0) == aChar, "BitConverter works with Char");

            double Result;

            byte[] doubleBytes = BitConverter.GetBytes(0d);
            Result = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == 0f, "BitConverter.ToDouble works with 0");

            doubleBytes = BitConverter.GetBytes(1d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == 1f, "BitConverter.ToDouble works with 1");

            doubleBytes = BitConverter.GetBytes(2d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == 2f, "BitConverter.ToDouble works with 2");

            doubleBytes = BitConverter.GetBytes(101d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == 101f, "BitConverter.ToDouble works with 101");

            doubleBytes = BitConverter.GetBytes(-101d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == -101f, "BitConverter.ToDouble works with -101");

            doubleBytes = BitConverter.GetBytes(1.2345d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == 1.2345, "BitConverter.ToDouble works with 1.2345");

            doubleBytes = BitConverter.GetBytes(-1.2345d);
            Result      = BitConverter.ToDouble(doubleBytes, 0);
            Assert.IsTrue(Result == -1.2345, "BitConverter.ToDouble works with -1.2345");

            //Conversion between doubles and long
            Assert.IsTrue(BitConverter.Int64BitsToDouble(1) == 4.94065645841247E-324, "BitConverter long bits to double works");
            Assert.IsTrue(BitConverter.DoubleToInt64Bits(4.94065645841247E-324) == 1, "BitConverter double to long bits works");
        }
 public static double BytesToDouble(byte[] buf, int offset)
 {
     return(BitConverter.Int64BitsToDouble(BytesToLong(buf, offset)));
 }
        private Object Read(QpidType t)
        {
            switch (t.Code)
            {
            case Code.BIN8:
            case Code.UINT8:
                return(ReadUint8());

            case Code.INT8:
                return(Get());

            case Code.CHAR:
                return((char)Get());

            case Code.BOOLEAN:
                return(Get() > 0);

            case Code.BIN16:
            case Code.UINT16:
                return(ReadUint16());

            case Code.INT16:
                return((short)ReadUint16());

            case Code.BIN32:
            case Code.UINT32:
                return(ReadUint32());

            case Code.CHAR_UTF32:
            case Code.INT32:
                return((int)ReadUint32());

            case Code.FLOAT:
                return((float)BitConverter.Int64BitsToDouble(ReadUint32() << 32));

            case Code.BIN64:
            case Code.UINT64:
            case Code.INT64:
            case Code.DATETIME:
                return(ReadUint64());

            case Code.DOUBLE:
                return(BitConverter.Int64BitsToDouble(ReadUint64()));

            case Code.UUID:
                return(ReadUuid());

            case Code.STR8:
                return(ReadStr8());

            case Code.STR16:
                return(ReadStr16());

            case Code.STR8_LATIN:
            case Code.STR8_UTF16:
            case Code.STR16_LATIN:
            case Code.STR16_UTF16:
                // XXX: need to do character conversion
                return(Encoding.UTF8.GetString(ReadBytes(t)));

            case Code.MAP:
                return(ReadMap());

            case Code.LIST:
                return(ReadList());

            case Code.ARRAY:
                return(ReadArray());

            case Code.STRUCT32:
                return(ReadStruct32());

            case Code.BIN40:
            case Code.DEC32:
            case Code.BIN72:
            case Code.DEC64:
                // XXX: what types are we supposed to use here?
                return(ReadBytes(t));

            case Code.VOID:
                return(null);

            default:
                return(ReadBytes(t));
            }
        }
예제 #16
0
 public double method_18()
 {
     return(BitConverter.Int64BitsToDouble(Marshal.ReadInt64(this.intptr_0, 8)));
 }
예제 #17
0
        /// <summary>
        /// Determines the range of floating point numbers that will match the specified value with the given tolerance.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="maxNumbersBetween">The <c>ulps</c> difference.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown if <paramref name="maxNumbersBetween"/> is smaller than zero.
        /// </exception>
        /// <returns>Tuple of the bottom and top range ends.</returns>
        public static Tuple <double, double> RangeOfMatchingFloatingPointNumbers(this double value, long maxNumbersBetween)
        {
            // Make sure ulpDifference is non-negative
            if (maxNumbersBetween < 1)
            {
                throw new ArgumentOutOfRangeException("maxNumbersBetween");
            }

            // If the value is infinity (positive or negative) just
            // return the same infinity for the range.
            if (double.IsInfinity(value))
            {
                return(new Tuple <double, double>(value, value));
            }

            // If the value is a NaN then the range is a NaN too.
            if (double.IsNaN(value))
            {
                return(new Tuple <double, double>(double.NaN, double.NaN));
            }

            // Translate the bit pattern of the double to an integer.
            // Note that this leads to:
            // double > 0 --> long > 0, growing as the double value grows
            // double < 0 --> long < 0, increasing in absolute magnitude as the double
            //                          gets closer to zero!
            //                          i.e. 0 - double.epsilon will give the largest long value!
            long intValue = AsInt64(value);

#if PORTABLE
            // We need to protect against over- and under-flow of the intValue when
            // we start to add the ulpsDifference.
            if (intValue < 0)
            {
                // Note that long.MinValue has the same bit pattern as
                // -0.0. Therefore we're working in opposite direction (i.e. add if we want to
                // go more negative and subtract if we want to go less negative)
                var topRangeEnd = Math.Abs(long.MinValue - intValue) < maxNumbersBetween
                                  // Got underflow, which can be fixed by splitting the calculation into two bits
                                  // first get the remainder of the intValue after subtracting it from the long.MinValue
                                  // and add that to the ulpsDifference. That way we'll turn positive without underflow
                    ? Int64BitsToDouble(maxNumbersBetween + (long.MinValue - intValue))
                                  // No problems here, move along.
                    : Int64BitsToDouble(intValue - maxNumbersBetween);

                var bottomRangeEnd = Math.Abs(intValue) < maxNumbersBetween
                                     // Underflow, which means we'd have to go further than a long would allow us.
                                     // Also we couldn't translate it back to a double, so we'll return -Double.MaxValue
                    ? -double.MaxValue
                                     // intValue is negative. Adding the positive ulpsDifference means that it gets less negative.
                                     // However due to the conversion way this means that the actual double value gets more negative :-S
                    : Int64BitsToDouble(intValue + maxNumbersBetween);

                return(new Tuple <double, double>(bottomRangeEnd, topRangeEnd));
            }
            else
            {
                // IntValue is positive
                var topRangeEnd = long.MaxValue - intValue < maxNumbersBetween
                                  // Overflow, which means we'd have to go further than a long would allow us.
                                  // Also we couldn't translate it back to a double, so we'll return Double.MaxValue
                    ? double.MaxValue
                                  // No troubles here
                    : Int64BitsToDouble(intValue + maxNumbersBetween);

                // Check the bottom range end for underflows
                var bottomRangeEnd = intValue > maxNumbersBetween
                                     // No problems here. IntValue is larger than ulpsDifference so we'll end up with a
                                     // positive number.
                    ? Int64BitsToDouble(intValue - maxNumbersBetween)
                                     // Int value is bigger than zero but smaller than the ulpsDifference. So we'll need to deal with
                                     // the reversal at the negative end
                    : Int64BitsToDouble(long.MinValue + (maxNumbersBetween - intValue));

                return(new Tuple <double, double>(bottomRangeEnd, topRangeEnd));
            }
#else
            // We need to protect against over- and under-flow of the intValue when
            // we start to add the ulpsDifference.
            if (intValue < 0)
            {
                // Note that long.MinValue has the same bit pattern as
                // -0.0. Therefore we're working in opposite direction (i.e. add if we want to
                // go more negative and subtract if we want to go less negative)
                var topRangeEnd = Math.Abs(long.MinValue - intValue) < maxNumbersBetween
                                  // Got underflow, which can be fixed by splitting the calculation into two bits
                                  // first get the remainder of the intValue after subtracting it from the long.MinValue
                                  // and add that to the ulpsDifference. That way we'll turn positive without underflow
                    ? BitConverter.Int64BitsToDouble(maxNumbersBetween + (long.MinValue - intValue))
                                  // No problems here, move along.
                    : BitConverter.Int64BitsToDouble(intValue - maxNumbersBetween);

                var bottomRangeEnd = Math.Abs(intValue) < maxNumbersBetween
                                     // Underflow, which means we'd have to go further than a long would allow us.
                                     // Also we couldn't translate it back to a double, so we'll return -Double.MaxValue
                    ? -double.MaxValue
                                     // intValue is negative. Adding the positive ulpsDifference means that it gets less negative.
                                     // However due to the conversion way this means that the actual double value gets more negative :-S
                    : BitConverter.Int64BitsToDouble(intValue + maxNumbersBetween);

                return(new Tuple <double, double>(bottomRangeEnd, topRangeEnd));
            }
            else
            {
                // IntValue is positive
                var topRangeEnd = long.MaxValue - intValue < maxNumbersBetween
                                  // Overflow, which means we'd have to go further than a long would allow us.
                                  // Also we couldn't translate it back to a double, so we'll return Double.MaxValue
                    ? double.MaxValue
                                  // No troubles here
                    : BitConverter.Int64BitsToDouble(intValue + maxNumbersBetween);

                // Check the bottom range end for underflows
                var bottomRangeEnd = intValue > maxNumbersBetween
                                     // No problems here. IntValue is larger than ulpsDifference so we'll end up with a
                                     // positive number.
                    ? BitConverter.Int64BitsToDouble(intValue - maxNumbersBetween)
                                     // Int value is bigger than zero but smaller than the ulpsDifference. So we'll need to deal with
                                     // the reversal at the negative end
                    : BitConverter.Int64BitsToDouble(long.MinValue + (maxNumbersBetween - intValue));

                return(new Tuple <double, double>(bottomRangeEnd, topRangeEnd));
            }
#endif
        }
예제 #18
0
 public GrisuDouble(ulong d64)
 {
     d64_   = d64;
     value_ = BitConverter.Int64BitsToDouble((long)d64);
 }
예제 #19
0
 public override double ReadDouble()
 {
     byte[] numArray = new byte[8];
     this.trans.ReadAll(numArray, 0, 8);
     return(BitConverter.Int64BitsToDouble(this.bytesToLong(numArray)));
 }
예제 #20
0
 public GrisuDouble(DiyFp diy_fp)
 {
     d64_   = DiyFpToUInt64(diy_fp);
     value_ = BitConverter.Int64BitsToDouble((long)d64_);
 }
예제 #21
0
 public override double ReadDouble()
 {
     return(BitConverter.Int64BitsToDouble(ReadLong()));
 }
예제 #22
0
 public static Constant DoubleFromBitpattern(long bits)
 {
     return(Constant.Real64(BitConverter.Int64BitsToDouble(bits)));
 }
예제 #23
0
 /// <summary>
 /// Reinterprets the given 64-bit integer's bits as a 64-bit floating-point
 /// number.
 /// </summary>
 /// <param name="value">The value to reinterpret.</param>
 /// <returns>A 64-bit floating-point number.</returns>
 public static double ReinterpretAsFloat64(long value)
 {
     return(BitConverter.Int64BitsToDouble(value));
 }
예제 #24
0
 /** 读出一个双浮点数值 */
 public double readDouble()
 {
     return(BitConverter.Int64BitsToDouble(readLong()));
 }
 /// <summary>
 /// Converts the specified 64-bit signed integer to a double-precision
 /// floating point number. Note: the endianness of this converter does not
 /// affect the returned value.
 /// </summary>
 /// <param name="value">The number to convert. </param>
 /// <returns>A double-precision floating point number whose value is equivalent to value.</returns>
 public double Int64BitsToDouble(long value)
 {
     return(BitConverter.Int64BitsToDouble(value));
 }
예제 #26
0
 /// <summary>
 ///     Reads double.
 /// </summary>
 public virtual double ReadDouble()
 {
     return(BitConverter.Int64BitsToDouble(ReadInt64()));
 }
예제 #27
0
        /// <summary>
        /// Returns a double-precision floating point number converted from eight bytes at a specified position in a byte array.
        /// </summary>
        /// <param name="value">An array of bytes.</param>
        /// <param name="startIndex">The starting position within <paramref name="value"/>.</param>
        /// <returns>A double precision floating point number formed by eight bytes beginning at <paramref name="startIndex"/>.</returns>
        /// <remarks>
        /// The ToDouble method converts the bytes from index <paramref name="startIndex"/> to <paramref name="startIndex"/> + 7 to a <see cref="Double"/>
        /// value.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> is less than zero or greater than the length of <paramref name="value"/> minus 8.
        /// </exception>
        public double ToDouble(byte[] value, int startIndex)
        {
            long val = this.ToInt64(value, startIndex);

            return(BitConverter.Int64BitsToDouble(val));
        }
예제 #28
0
 public double GetDouble(int index)
 {
     return(BitConverter.Int64BitsToDouble(this.GetLong(index)));
 }
예제 #29
0
 private static double CheckAndSwap(double v, DataViewEndianness isLittleEndian)
 {
     return(IsByteSwapRequired(isLittleEndian) ? BitConverter.Int64BitsToDouble(SwapBytes(BitConverter.DoubleToInt64Bits(v))) : v);
 }
예제 #30
0
 public static double GetDoubleB(AbstractIoBuffer bb, int bi)
 {
     return(BitConverter.Int64BitsToDouble(GetLongB(bb, bi)));
 }