Exemple #1
0
        private string ReadAsciiField(BinaryReader2 reader, int numValues)
        {
            var    array = reader.ReadBytes(numValues - 1);
            string text  = Encoding.ASCII.GetString(array);

            return(text.Replace("\0", Environment.NewLine));
        }
Exemple #2
0
 public TiffReader(Stream stream)
 {
     _stream = stream;
     _reader = new BinaryReader2(_stream, true);
     ReadImageFileHeader();
     ImageFileDirectories = ReadImageFileDirectories();
 }
Exemple #3
0
 private long ReadFieldOffset(BinaryReader2 reader)
 {
     if (_bigTiff)
     {
         return(reader.ReadInt64());
     }
     else
     {
         return(reader.ReadUInt32());
     }
 }
Exemple #4
0
        private T ReadFieldValue <T>(BinaryReader2 reader, FieldType fieldType)
        {
            object value = ReadFieldValueAsObject(reader, fieldType);

            var typeT = typeof(T);

            if (typeT.IsEnum)
            {
                return((T)Enum.ToObject(typeT, value));
            }

            // if(typeT == typeof(Rational) || typeT == typeof(SRational))
            //     return (T)value;

            return((T)Convert.ChangeType(value, typeT));
        }
Exemple #5
0
        private T[] ReadFieldValues <T>(BinaryReader2 reader, FieldType fieldType, int numValues)
        {
            var array = ReadFieldValuesAsObjects(reader, fieldType, numValues);

            var typeofT = typeof(T);

            return(array.Select(value =>
            {
                if (typeofT.IsEnum)
                {
                    return (T)Enum.ToObject(typeofT, value);
                }

                // if(typeofT == typeof(Rational) || typeofT == typeof(SRational))
                //     return (T)value;

                return (T)Convert.ChangeType(value, typeofT);
            }).ToArray());
        }
Exemple #6
0
        private object ReadFieldValueAsObject(BinaryReader2 reader, FieldType fieldType)
        {
            switch (fieldType)
            {
            case FieldType.Int64:
                return(reader.ReadInt64());

            case FieldType.UInt64:
                return(reader.ReadInt64());

            case FieldType.Int32:
                return(reader.ReadInt32());

            case FieldType.UInt32:
                return(reader.ReadUInt32());

            case FieldType.Int16:
                return(reader.ReadInt16());

            case FieldType.UInt16:
                return(reader.ReadUInt16());

            case FieldType.Byte:
                return(reader.ReadByte());

            case FieldType.SByte:
                return(reader.ReadSByte());

            case FieldType.Float:
                return(reader.ReadSingle());

            case FieldType.Double:
                return(reader.ReadDouble());

            case FieldType.Rational:
                return(new Rational(reader.ReadUInt32(), reader.ReadUInt32()));

            case FieldType.SRational:
                return(new SRational(reader.ReadInt32(), reader.ReadInt32()));
            }
            Console.WriteLine($"Unknown field type {fieldType}");
            return(0);
        }
Exemple #7
0
        private ImageFileDirectory[] ReadImageFileDirectories()
        {
            var ifdList = new List <ImageFileDirectory>();

            long ifdOffset = _bigTiff ? _reader.ReadInt64() : _reader.ReadUInt32();

            while (ifdOffset > 0)
            {
                _reader.Stream.Position = ifdOffset;

                var ifd = new ImageFileDirectory();

                long numFields = _bigTiff ? _reader.ReadInt64() : _reader.ReadUInt16();

                int sizeInBytes = (int)numFields * (2 + 2 + 2 * (_bigTiff ? 8 : 4)) + (_bigTiff ? 8 : 4);
                using (var ifdReader = new BinaryReader2(new MemoryStream(_reader.ReadBytes(sizeInBytes))))
                {
                    ifdReader.StreamIsLittleEndian = _reader.StreamIsLittleEndian;

                    for (int i = 0; i < numFields; i++)
                    {
                        IfdTag    tag       = (IfdTag)ifdReader.ReadUInt16();
                        FieldType fieldType = (FieldType)ifdReader.ReadUInt16();
                        int       numValues = _bigTiff ? (int)ifdReader.ReadInt64() : (int)ifdReader.ReadUInt32();

                        long pos = ifdReader.Stream.Position;

                        switch (tag)
                        {
                        case IfdTag.ImageWidth:
                        {
                            ifd.ImageWidth = ReadFieldValue <int>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.ImageHeight:
                        {
                            ifd.ImageHeight = ReadFieldValue <int>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.BitsPerSample:
                        {
                            if (numValues == 1)
                            {
                                ifd.BitsPerSample = ReadFieldValue <ushort>(ifdReader, fieldType);
                            }
                            else
                            {
                                _reader.Stream.Position = ReadFieldOffset(ifdReader);
                                var bitsPerSamples = ReadFieldValues <ushort>(_reader, fieldType, numValues);

                                ifd.BitsPerSample = (ushort)bitsPerSamples[0];
                                if (bitsPerSamples.Any(bps => bps != ifd.BitsPerSample))
                                {
                                    throw new NotSupportedException($"BitsPerSample must be the same for all samples: {string.Join(", ", bitsPerSamples)}");
                                }
                            }
                        }
                        break;

                        case IfdTag.PhotometricInterpretation:
                        {
                            ifd.PhotometricInterpretation = ReadFieldValue <PhotometricInterpretation>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.Compression:
                        {
                            ifd.Compression = ReadFieldValue <Compression>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.SamplesPerPixel:
                        {
                            ifd.SamplesPerPixel = ReadFieldValue <ushort>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.RowsPerStrip:
                        {
                            ifd.RowsPerStrip = ReadFieldValue <uint>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.PlanarConfiguration:
                        {
                            ifd.PlanarConfiguration = ReadFieldValue <PlanarConfiguration>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.SampleFormat:
                        {
                            ifd.SampleFormat = ReadFieldValue <SampleFormat>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.StripOffsets:
                        {
                            if (numValues == 1)
                            {
                                ifd.StripOffsets = new[] { ReadFieldValue <long>(ifdReader, fieldType) };
                            }
                            else
                            {
                                _reader.Stream.Position = ReadFieldValue <long>(ifdReader, fieldType);
                                ifd.StripOffsets        = ReadFieldValues <long>(_reader, fieldType, numValues);
                            }
                        }
                        break;

                        case IfdTag.StripByteCounts:
                        {
                            if (numValues == 1)
                            {
                                ifd.StripByteCounts = new[] { ReadFieldValue <long>(ifdReader, fieldType) };
                            }
                            else
                            {
                                _reader.Stream.Position = ReadFieldOffset(ifdReader);
                                ifd.StripByteCounts     = ReadFieldValues <long>(_reader, fieldType, numValues);
                            }
                        }
                        break;

                        case IfdTag.Artist:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.Artist = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.Copyright:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.Copyright           = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.DateTime:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            string text = ReadAsciiField(_reader, numValues);
                            DateTime.TryParseExact(text, "yyyy:MM:dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out ifd.DateTime);
                        }
                        break;

                        case IfdTag.ExtraSamples:
                        {
                            ifd.ExtraSamples = ReadFieldValue <ushort>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.HostComputer:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.HostComputer        = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.ImageDescription:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.ImageDescription    = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.Make:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.Make = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.Model:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.Model = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.Orientation:
                        {
                            ifd.Orientation = ReadFieldValue <ushort>(ifdReader, fieldType);
                        }
                        break;

                        case IfdTag.Software:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.Software            = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.DocumentName:
                        {
                            _reader.Stream.Position = ReadFieldOffset(ifdReader);
                            ifd.DocumentName        = ReadAsciiField(_reader, numValues);
                        }
                        break;

                        case IfdTag.FillOrder:
                        {
                            ifd.FillOrder = ReadFieldValue <ushort>(ifdReader, fieldType);
                        }
                        break;

                        default:
                        {
                            if (numValues == 1)
                            {
                                object value = ReadFieldValueAsObject(ifdReader, fieldType);
                                ifd.Entries[tag] = new IfdEntry {
                                    Tag = tag, FieldType = fieldType, Value = value
                                };
                                Console.WriteLine($"Tag: {tag} Type: {fieldType} NumValues: {numValues} Value: {value}");
                            }
                            else
                            {
                                long offset = ReadFieldOffset(ifdReader);
                                ifd.Entries[tag] = new IfdEntry {
                                    Tag = tag, FieldType = fieldType, Offset = offset
                                };
                                Console.WriteLine($"Tag: {tag} Type: {fieldType} NumValues: {numValues} Offset: {offset}");
                            }
                        }
                        break;
                        }

                        ifdReader.Stream.Position = pos + (_bigTiff ? 8 : 4);
                    }

                    if (_bigTiff)
                    {
                        ifdOffset = ifdReader.ReadInt64();
                    }
                    else
                    {
                        ifdOffset = ifdReader.ReadUInt32();
                    }
                }
                ifdList.Add(ifd);
            }

            return(ifdList.ToArray());
        }
Exemple #8
0
        private object[] ReadFieldValuesAsObjects(BinaryReader2 reader, FieldType fieldType, int numValues)
        {
            var array = new object[numValues];

            switch (fieldType)
            {
            case FieldType.Int64:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadInt64();
                }
            }
            break;

            case FieldType.UInt64:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadInt64();
                }
            }
            break;

            case FieldType.Int32:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadInt32();
                }
            }
            break;

            case FieldType.UInt32:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadUInt32();
                }
            }
            break;

            case FieldType.Int16:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadInt16();
                }
            }
            break;

            case FieldType.UInt16:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadUInt16();
                }
            }
            break;

            case FieldType.SByte:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadSByte();
                }
            }
            break;

            case FieldType.Byte:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadByte();
                }
            }
            break;

            case FieldType.Float:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadSingle();
                }
            }
            break;

            case FieldType.Double:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = reader.ReadDouble();
                }
            }
            break;

            case FieldType.Rational:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = new Rational(reader.ReadUInt32(), reader.ReadUInt32());
                }
            }
            break;

            case FieldType.SRational:
            {
                for (int i = 0; i < numValues; i++)
                {
                    array[i] = new SRational(reader.ReadInt32(), reader.ReadInt32());
                }
            }
            break;

            default:
                throw new Exception($"Unknown field type {fieldType}");
            }

            return(array);
        }