internal TiffImageFileDirectoryEntry(TiffOperationContext context, TiffTag tag, TiffFieldType type, long valueCount, ReadOnlySpan <byte> valueData) { Tag = tag; Type = type; ValueCount = valueCount; if (context.ByteCountOfValueOffsetField == 4) { uint offset32 = MemoryMarshal.Read <uint>(valueData); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { offset32 = BinaryPrimitives.ReverseEndianness(offset32); } ValueOffset = (long)(ulong)offset32; } else if (context.ByteCountOfValueOffsetField == 8) { ulong offset64 = MemoryMarshal.Read <ulong>(valueData); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { offset64 = BinaryPrimitives.ReverseEndianness(offset64); } ValueOffset = (long)offset64; } else { ValueOffset = 0; } }
/// <summary> /// Construct a TiffImageFileDirectoryEntry. /// </summary> /// <param name="tag">The tag of the IFD entry.</param> /// <param name="type">The field type of the values.</param> /// <param name="valueCount">The number of elements.</param> /// <param name="valueOffset">The offset in the TIFF stream.</param> public TiffImageFileDirectoryEntry(TiffTag tag, TiffFieldType type, long valueCount, long valueOffset) { Tag = tag; Type = type; ValueCount = valueCount; ValueOffset = valueOffset; }
internal bool IsKnownSingleByte() { TiffFieldType type = Type; return(type == TiffFieldType.Byte || type == TiffFieldType.ASCII || type == TiffFieldType.SByte || type == TiffFieldType.Undefined); }
//internal void SetPointer(int addr) //{ Array.Copy(Hex.GetBinary((long)addr, this._owner.Owner.LittleEndian), 0, this._raw, 8, 4); } //internal void SetValue(byte[] val) //{ // if (val.Length > 4) // { // this._meta = val; // this.SetPointer(0); // } // else // { // byte[] newVal = new byte[4]; // if (val.Length < 4) // { // for (int i = 0; i < newVal.Length; i++) // newVal[i] = ((Math.Abs(i - 4) > val.Length) ? byte.Parse("00") : val[i]); // } // else // Array.Copy(val, newVal, 4); // Array.Copy(newVal, 0, this._raw, 8, 4); // } //} //*************************************************************************** // Static Methods // internal static bool MustBePointer(TiffFieldType fldType, int fldCount) { return(!((fldType == TiffFieldType.LongType && fldCount < 2) || (fldType == TiffFieldType.ShortType && fldCount < 3) || ((fldType == TiffFieldType.ByteType || fldType == TiffFieldType.AsciiType) && fldCount < 5))); }
public void SetTag(int idfNum, TiffTagType tagType, params object[] value) { if (tagType == TiffTagType.StripOffsets || tagType == TiffTagType.StripByteCounts) { throw new Exception("The 'StripOffsets' and 'StripByteCounts' tags will be constructed automatically and may not be manually configured."); } ByteCollection tagBts = new ByteCollection(); tagBts.AddRange(Hex.GetBinary((short)tagType, this._littleEndian)); TiffFieldType fldType = (TiffFieldType)Enum.Parse(typeof(TiffTagIDFieldType), tagType.ToString()); tagBts.AddRange(Hex.GetBinary((short)fldType, this._littleEndian)); tagBts.AddRange(Hex.GetBinary(value.Length, this._littleEndian)); if (TiffTag.MustBePointer(fldType, value.Length) || fldType == TiffFieldType.AsciiType) { // We'll have to add the data to the _metaData ByteCollection, // since it won't fit into the tag itself. We'll also need // to make a pointer to the data in the tag. int metaPointer = this._metaData.Count; ByteCollection tmpMetaData = new ByteCollection(); // We need to process each passed value. Often there may be only // one, but we still have to be prepared for multiple values. for (int i = 0; i < value.Length; i++) { try { // First, we need to figure out what kind of data we're deeling with, // since it will determine what we do with it. switch (fldType) { case TiffFieldType.AsciiType: // ASCII type is easy... we just convert the text to ASCII // bytes and dump them to the metaData collection. tmpMetaData.AddRange(System.Text.ASCIIEncoding.ASCII.GetBytes(value[i].ToString())); break; case TiffFieldType.ByteType: tmpMetaData.Add((byte)value[i]); break; case TiffFieldType.ShortType: tmpMetaData.AddRange(Hex.GetBinary((short)value[i], this._littleEndian)); break; case TiffFieldType.LongType: tmpMetaData.AddRange(Hex.GetBinary((int)value[i], this._littleEndian)); break; case TiffFieldType.Rational: string[] vals = ((string)value[i]).Split('/', '|'); tmpMetaData.AddRange(Hex.GetBinary(int.Parse(vals[0]))); tmpMetaData.AddRange(Hex.GetBinary(int.Parse(vals[1]))); break; } } catch { // The most likely reson for ending up here is that we got // passed some data that didn't match the field type for // the specified field. Just chunk the error back up the // stack and let the caller deal with it. throw; } // We don't want to add the values to the actuall metaData // collection until we're sure we've got it all processes // and converted. Otherwise, we might end up wtih 'orphaned' // meta data. this._metaData.AddRange(tmpMetaData.ToArray()); tagBts.AddRange(Hex.GetBinary(metaPointer, this._littleEndian)); } } else { // The tag value is small enough to reside inside the tag itself. // This automatically rules out certain data types such as // Rational and ASCII, so we should only be dealing with // Byte, Short, and Long here. for (int i = 0; i < value.Length; i++) { if (value[i].GetType().Name.ToLower() == "int32") { tagBts.AddRange(Hex.GetBinary((short)value[i], this._littleEndian)); } else if (value[i].GetType().Name.ToLower() == "int64") { tagBts.AddRange(Hex.GetBinary((int)value[i], this._littleEndian)); } } } // If we ended up with less than 12 bytes for the tag data, it means // we're storing a short or byte value that doesn't 'fill' the tag's // value space, so we just need to add 'padding'. int btShort = 12 - tagBts.Count; for (int t = 0; t < btShort; t++) { tagBts.Add(byte.Parse("00")); } // Now, we're read to add the tag to the IDF. this._idfs[idfNum].Tags.Add(new TiffTag(this._idfs[idfNum], tagBts.ToArray())); }
private void AddOrUpdateEntry(TiffTag tag, TiffFieldType type, int count, TiffStreamOffset offset) { if (TryFindEntry(tag, out int i, out _)) { _entries[i] = new TiffImageFileDirectoryEntry(tag, type, count, offset); }