Beispiel #1
0
 private void skipPadding(BinaryReaderMixedEndian reader)
 {
     if (version == 4)
     {
         reader.ReadBytes(4);
     }
 }
Beispiel #2
0
        private double readValue(BinaryReaderMixedEndian reader, int type)
        {
            switch (type)
            {
            case SHORT:
            case USHORT:
                return(reader.ReadInt16());

            case INT:
            case UINT:
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                int i = reader.ReadInt32();
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                return(i);

            case FLOAT:
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                float f = reader.ReadSingle();
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                return(f);

            case DOUBLE:
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                double dbl = reader.ReadDouble();
                if (adjustEndianness)
                {
                    reader.SetEndian(!reader.IsLittleEndian);
                }
                return(dbl);

            case BYTE:
            case UBYTE:
            case CHAR:
                return(reader.ReadByte());

            case UNKNOWN:
            case UNKNOWN2:
                return(reader.ReadInt64());
            }

            return(0);
        }
Beispiel #3
0
        public HeaderDM4(BinaryReader reader)
        {
            Reader = new BinaryReaderMixedEndian(reader);

            pixelOffset = 0;

            //LOGGER.info("Verifying Gatan format");

            littleEndian = false;
            pixelSizes   = new List <Double>();
            units        = new List <String>();

            Reader.SetEndian(littleEndian);

            // only support version 3
            version = Reader.ReadInt32();
            if (version != 3 && version != 4)
            {
                throw new FormatException("invalid header");
            }

            //LOGGER.info("Reading tags");

            Reader.ReadBytes(4);
            skipPadding(Reader);
            littleEndian = Reader.ReadInt32() != 1;
            Reader.SetEndian(littleEndian);

            // TagGroup instance

            Reader.ReadBytes(2);
            skipPadding(Reader);
            int numTags = Reader.ReadInt32();

            if (numTags > Reader.BaseStream.Length)
            {
                littleEndian = !littleEndian;
                Reader.SetEndian(littleEndian);
                adjustEndianness = false;
            }
            //LOGGER.debug("tags ({}) {", numTags);
            try
            {
                parseTags(Reader, numTags, null, "  ");
            }
            catch (Exception e)
            {
                throw new FormatException("Unable to parse metadata tag", e);
            }
            //LOGGER.debug("}");

            //LOGGER.info("Populating metadata");

            littleEndian = true;

            if (Dimensions.X == 0 || Dimensions.Y == 0)
            {
                throw new FormatException("Dimensions information not found");
            }

            if (Dimensions.Z == 0)
            {
                Dimensions.Z = 1;
            }
            //m.sizeC = 1;
            //m.sizeT = 1;
            //m.dimensionOrder = "XYZTC";
            //m.imageCount = getSizeZ() * getSizeC() * getSizeT();

            int bytes = (int)(numPixelBytes / Dimensions.Elements());

            if (bytes != ImageFormatsHelper.SizeOf(ValueType))
            {
                throw new Exception("Bytes per pixel does not match the actual size of image data.");
            }

            reader.BaseStream.Seek(pixelOffset, SeekOrigin.Begin);
        }
Beispiel #4
0
 private string FromByteArray(BinaryReaderMixedEndian reader, int n)
 {
     byte[] Bytes = reader.ReadBytes(n);
     return(System.Text.Encoding.UTF8.GetString(Bytes));
 }
Beispiel #5
0
        private void parseTags(BinaryReaderMixedEndian reader, int numTags, string parent, string indent)
        {
            for (int i = 0; i < numTags; i++)
            {
                if (reader.BaseStream.Position + 3 >= reader.BaseStream.Length)
                {
                    break;
                }

                byte type   = reader.ReadByte(); // can be 21 (data) or 20 (tag group)
                int  length = reader.ReadInt16();

                // image data is in tag with type 21 and label 'Data'
                // image dimensions are in type 20 tag with 2 type 15 tags
                // bytes per pixel is in type 21 tag with label 'PixelDepth'

                String labelString = null;
                String value       = null;

                if (type == VALUE)
                {
                    labelString = FromByteArray(reader, length);
                    skipPadding(reader);
                    skipPadding(reader);
                    int skip = reader.ReadInt32(); // equal to '%%%%' / 623191333
                    skipPadding(reader);
                    int n = reader.ReadInt32();
                    skipPadding(reader);
                    int    dataType = reader.ReadInt32();
                    string sb       = labelString;
                    if (sb.Length > 32)
                    {
                        sb = sb.Substring(0, 20) + "... (" + sb.Length + ")";
                    }

                    //LOGGER.debug("{}{}: n={}, dataType={}, label={}",
                    //             new Object[]
                    //             {
                    //                 indent,
                    //                 i,
                    //                 n,
                    //                 dataType,
                    //                 sb
                    //             });
                    if (skip != 623191333)
                    {
                        Debug.WriteLine("Skip mismatch: {}", skip);
                    }

                    if (n == 1)
                    {
                        if ("Dimensions".Equals(parent) && labelString.Length == 0)
                        {
                            if (adjustEndianness)
                            {
                                Reader.SetEndian(!Reader.IsLittleEndian);
                            }
                            if (i == 0)
                            {
                                Dimensions.X = reader.ReadInt32();
                            }
                            else if (i == 1)
                            {
                                Dimensions.Y = reader.ReadInt32();
                            }
                            else if (i == 2)
                            {
                                Dimensions.Z = reader.ReadInt32();
                            }

                            if (adjustEndianness)
                            {
                                Reader.SetEndian(!Reader.IsLittleEndian);
                            }
                        }
                        else
                        {
                            value = readValue(reader, dataType).ToString(CultureInfo.InvariantCulture);
                        }
                    }
                    else if (n == 2)
                    {
                        if (dataType == 18)
                        {
                            // this should always be true
                            length = reader.ReadInt32();
                        }
                        else
                        {
                            //LOGGER.warn("dataType mismatch: {}", dataType);
                        }

                        value = FromByteArray(reader, length);
                    }
                    else if (n == 3)
                    {
                        if (dataType == GROUP)
                        {
                            // this should always be true
                            skipPadding(reader);
                            dataType = reader.ReadInt32();
                            long dataLength = 0;
                            if (version == 4)
                            {
                                dataLength = reader.ReadInt64();
                            }
                            else
                            {
                                dataLength = reader.ReadInt32();
                            }

                            length = (int)(dataLength & 0xffffffff);
                            if (labelString.Equals("Data"))
                            {
                                if (dataLength > 0)
                                {
                                    pixelOffset = reader.BaseStream.Position;
                                    reader.BaseStream.Seek(reader.BaseStream.Position + getNumBytes(dataType) * dataLength, SeekOrigin.Begin);
                                    numPixelBytes = reader.BaseStream.Position - pixelOffset;
                                }
                            }
                            else
                            {
                                if (dataType == 10)
                                {
                                    reader.ReadBytes(length);
                                }
                                else
                                {
                                    value = FromByteArray(reader, length * 2);
                                }
                            }
                        }
                        else
                        {
                            //LOGGER.warn("dataType mismatch: {}", dataType);
                        }
                    }
                    else
                    {
                        // this is a normal struct of simple types
                        if (dataType == ARRAY)
                        {
                            reader.ReadBytes(4);
                            skipPadding(reader);
                            skipPadding(reader);
                            int           numFields = reader.ReadInt32();
                            long          startFP   = reader.BaseStream.Position;
                            StringBuilder s         = new StringBuilder();
                            reader.ReadBytes(4);
                            skipPadding(reader);
                            long baseFP = reader.BaseStream.Position;
                            if (version == 4)
                            {
                                baseFP += 4;
                            }

                            int width = version == 4 ? 16 : 8;
                            for (int j = 0; j < numFields; j++)
                            {
                                reader.BaseStream.Seek(baseFP + j * width, SeekOrigin.Begin);
                                dataType = reader.ReadInt32();
                                reader.BaseStream.Seek(startFP + numFields * width + j * getNumBytes(dataType), SeekOrigin.Begin);
                                s.Append(readValue(reader, dataType));
                                if (j < numFields - 1)
                                {
                                    s.Append(", ");
                                }
                            }

                            value = s.ToString();
                        }
                        else if (dataType == GROUP)
                        {
                            // this is an array of structs
                            skipPadding(reader);
                            dataType = reader.ReadInt32();
                            if (dataType == ARRAY)
                            {
                                // should always be true
                                reader.ReadBytes(4);
                                skipPadding(reader);
                                skipPadding(reader);
                                int   numFields = reader.ReadInt32();
                                int[] dataTypes = new int[numFields];
                                long  baseFP    = reader.BaseStream.Position + 12;
                                for (int j = 0; j < numFields; j++)
                                {
                                    reader.ReadBytes(4);
                                    if (version == 4)
                                    {
                                        reader.BaseStream.Seek(baseFP + j * 16, SeekOrigin.Begin);
                                    }

                                    dataTypes[j] = reader.ReadInt32();
                                }

                                skipPadding(reader);
                                int len = reader.ReadInt32();

                                double[][] values = Helper.ArrayOfFunction(a => new double[len], numFields);

                                for (int k = 0; k < len; k++)
                                {
                                    for (int q = 0; q < numFields; q++)
                                    {
                                        values[q][k] = readValue(reader, dataTypes[q]);
                                    }
                                }
                            }
                            else
                            {
                                //LOGGER.warn("dataType mismatch: {}", dataType);
                            }
                        }
                    }
                }
                else if (type == GROUP)
                {
                    labelString = FromByteArray(reader, length);
                    reader.ReadBytes(2);
                    skipPadding(reader);
                    skipPadding(reader);
                    skipPadding(reader);
                    int num = reader.ReadInt32();
                    //LOGGER.debug("{}{}: group({}) {} {", new Object[] { indent, i, num, labelString });
                    parseTags(reader, num, string.IsNullOrEmpty(labelString) ? parent : labelString, indent + "  ");
                    //LOGGER.debug("{}}", indent);
                }
                else
                {
                    //LOGGER.debug("{}{}: unknown type: {}", new Object[] { indent, i, type });
                }

                if (value != null)
                {
                    bool validPhysicalSize = parent != null && (parent.Equals("Dimension") ||
                                                                ((pixelSizes.Count() == 4 || units.Count() == 4) && parent.Equals("2")));
                    if (labelString.Equals("Scale") && validPhysicalSize)
                    {
                        if (value.IndexOf(',') == -1)
                        {
                            pixelSizes.Add(double.Parse(value, CultureInfo.InvariantCulture));
                        }
                    }
                    else if (labelString.Equals("Units") && validPhysicalSize)
                    {
                        // make sure that we don't add more units than sizes
                        if (pixelSizes.Count() == units.Count() + 1)
                        {
                            units.Add(value);
                        }
                    }
                    else if (labelString.Equals("LowLimit"))
                    {
                        signed = double.Parse(value, CultureInfo.InvariantCulture) < 0;
                    }
                    else if (labelString.Equals("Acquisition Start Time (epoch)"))
                    {
                        timestamp = long.Parse(value, CultureInfo.InvariantCulture);
                    }
                    else if (labelString.Equals("Voltage"))
                    {
                        voltage = double.Parse(value, CultureInfo.InvariantCulture);
                    }
                    else if (labelString.Equals("Microscope Info"))
                    {
                        info = value;
                    }
                    else if (labelString.Equals("Indicated Magnification"))
                    {
                        mag = double.Parse(value, CultureInfo.InvariantCulture);
                    }
                    else if (labelString.Equals("Gamma"))
                    {
                        gamma = double.Parse(value, CultureInfo.InvariantCulture);
                    }
                    else if (labelString.StartsWith("xPos"))
                    {
                        double number = double.Parse(value, CultureInfo.InvariantCulture);
                        posX = number;
                    }
                    else if (labelString.StartsWith("yPos"))
                    {
                        double number = double.Parse(value, CultureInfo.InvariantCulture);
                        posY = number;
                    }
                    else if (labelString.StartsWith("Specimen position"))
                    {
                        double number = double.Parse(value, CultureInfo.InvariantCulture);
                        posZ = number;
                    }
                    else if (labelString == "Sample Time")
                    {
                        sampleTime = double.Parse(value, CultureInfo.InvariantCulture);
                    }
                    else if (labelString == "DataType")
                    {
                        int pixelType = int.Parse(value);
                        switch (pixelType)
                        {
                        case 1:
                            ValueType = typeof(short);
                            break;

                        case 10:
                            ValueType = typeof(ushort);
                            break;

                        case 2:
                            ValueType = typeof(float);
                            break;

                        case 12:
                            ValueType = typeof(double);
                            break;

                        case 9:
                            ValueType = typeof(byte);
                            break;

                        case 6:
                            ValueType = typeof(byte);
                            break;

                        case 7:
                            ValueType = typeof(int);
                            break;

                        case 11:
                            ValueType = typeof(uint);
                            break;
                        }
                    }

                    value = null;
                }
            }
        }