Ejemplo n.º 1
0
        private static void ReadMatrix(ref Variable vi, UInt32 length, BinaryReader matrixStream)
        {
            Tag  t;
            long offset = matrixStream.BaseStream.Position;

            //Array flags
            //Will always be too large to be in small data format, so not checking t.data
            t = MatfileHelper.ReadTag(matrixStream);
            UInt32 flagsClass = matrixStream.ReadUInt32();
            byte   flags      = (byte)(flagsClass >> 8);

            if ((flags & 0x80) == 0x80)
            {
                throw new IOException("Complex numbers not supported");
            }
            vi.dataType = MatfileHelper.parseArrayType((byte)flagsClass);
            matrixStream.ReadUInt32();//unused flags

            //Dimensions - There are always 2 dimensions, so this
            //tag will never be of small data format, i.e. not checking for t.data
            t = MatfileHelper.ReadTag(matrixStream);
            int[] arrayDimensions = new int[t.length / MatfileHelper.MatlabBytesPerType(t.dataType)];
            int   elements        = 1;

            for (int i = 0; i < arrayDimensions.Length; i++)
            {
                int dimension = (int)matrixStream.ReadUInt32();
                arrayDimensions[arrayDimensions.Length - i - 1] = dimension;
                elements *= dimension;
            }
            //Don't keep single dimensions
            arrayDimensions = arrayDimensions.Where(x => x > 1).ToArray();
            //If by doing this, we end up without dimensions, it means we had a 1x...x1 array.
            //We need at least 1 dimension to instantiate the final array, so...
            if (arrayDimensions.Length == 0)
            {
                arrayDimensions = new int[1] {
                    1
                }
            }
            ;

            //Array name
            t = MatfileHelper.ReadTag(matrixStream);
            if (t.data != null)
            {
                sbyte[] varname = t.data as sbyte[];
                vi.name = Encoding.UTF8.GetString(Array.ConvertAll(varname, x => (byte)x));
            }
            else
            {
                byte[] varname = matrixStream.ReadBytes((int)t.length);
                vi.name = Encoding.UTF8.GetString(varname);
                MatfileHelper.AdvanceTo8ByteBoundary(matrixStream);
            }


            //Read and reshape data
            t = MatfileHelper.ReadTag(matrixStream);
            //if (t.length / MatfileHelper.MatlabBytesPerType(t.dataType) != elements)
            // throw new IOException("Read dimensions didn't correspond to header dimensions");

            Array readBytes;

            if (t.data == null)
            {
                readBytes = MatfileHelper.CastToMatlabType(vi.dataType, matrixStream.ReadBytes((int)t.length));
            }
            else
            {
                readBytes = (Array)t.data;
            }

            Array reshapedData = Array.CreateInstance(vi.dataType, arrayDimensions);

            if (t.dataType != vi.dataType) //This happens when matlab choses to store the data in a smaller datatype when the values permit it
            {
                Array linearData = Array.CreateInstance(vi.dataType, readBytes.Length);
                Array.Copy(readBytes, linearData, readBytes.Length);
                Buffer.BlockCopy(linearData, 0, reshapedData, 0, linearData.Length * MatfileHelper.MatlabBytesPerType(vi.dataType));
                vi.dataType = t.dataType;
            }
            else //Readbytes is already in the correct type
            {
                Buffer.BlockCopy(readBytes, 0, reshapedData, 0, readBytes.Length * MatfileHelper.MatlabBytesPerType(vi.dataType));
            }

            if (reshapedData.Length == 1)
            {
                vi.data = reshapedData.GetValue(0);
            }
            else
            {
                vi.data = reshapedData;
            }

            //Move on in case the data didn't end on a 64 byte boundary
            matrixStream.BaseStream.Seek(offset + length, SeekOrigin.Begin);
        }
Ejemplo n.º 2
0
        private static void ReadMatrix(ref Variable vi, UInt32 length, BinaryReader matrixStream)
        {
            Tag  t;
            long offset = matrixStream.BaseStream.Position;

            //Array flags
            //Will always be too large to be in small data format, so not checking t.data
            //t = MatfileHelper.ReadTag(matrixStream);
            //UInt32 flagsClass = matrixStream.ReadUInt32();
            //byte flags = (byte)(flagsClass >> 8) ;
            //if ((flags & 0x80) == 0x08)
            //    throw new IOException("Complex numbers not supported");
            //vi.dataType = MatfileHelper.parseArrayType((byte)flagsClass);
            //matrixStream.ReadUInt32();//unused flags
            Flag Flag = matrixStream.ReadFlag();

            vi.dataType = Flag.dataClass;

            //Dimensions - There are always 2 dimensions, so this
            //tag will never be of small data format, i.e. not checking for t.data
            t = MatfileHelper.ReadTag(matrixStream);
            int[] arrayDimensions = new int[t.length / MatfileHelper.MatlabBytesPerType(t.dataType)];
            int   elements        = 1;

            for (int i = 0; i < arrayDimensions.Length; i++)
            {
                int dimension = (int)matrixStream.ReadUInt32();// depends on sizeof(t.dataType) => MatfileHelper.MatlabBytesPerType(t.dataType)
                arrayDimensions[arrayDimensions.Length - i - 1] = dimension;
                elements *= dimension;
            }
            //Don't keep single dimensions
            arrayDimensions = arrayDimensions.Where(x => x > 1).ToArray();
            //If by doing this, we end up without dimensions, it means we had a 1x...x1 array.
            //We need at least 1 dimension to instantiate the final array, so...
            if (arrayDimensions.Length == 0)
            {
                arrayDimensions = new int[1] {
                    1
                }
            }
            ;

            //Array name
            t = MatfileHelper.ReadTag(matrixStream);
            if (t.data != null)
            {
                sbyte[] varname = t.data as sbyte[];
                vi.name = Encoding.UTF8.GetString(Array.ConvertAll(varname, x => (byte)x));
            }
            else
            {
                byte[] varname = matrixStream.ReadBytes((int)t.length);
                vi.name = Encoding.UTF8.GetString(varname);
                MatfileHelper.AdvanceTo8ByteBoundary(matrixStream);
            }


            //Read and reshape data
            t = MatfileHelper.ReadTag(matrixStream);
            reshape(ref vi.data, ref vi.dataType, matrixStream, t, arrayDimensions, elements);

            // Read Imaginary data
            if (Flag.Complex)
            {
                t = matrixStream.ReadTag();
                reshape(ref vi.Image, ref vi.dataType, matrixStream, t, arrayDimensions, elements);
            }
            //Move on in case the data didn't end on a 64 byte boundary
            matrixStream.BaseStream.Seek(offset + length, SeekOrigin.Begin);
        }