//*************************************************************************** // Private Methods // private void GetTags(byte[] data) { // The first thing we need to do is try and validate the binary stream. // It *should* contain N sets of 12-byte lengths, so it the length // of the data is not a multiple of 12, it's no good. if (data.Length % 12 != 0) { throw new ArgumentException("The provided binary data does not appear to be valid. Binary stream must consist of N sets of 12-byte lengths.", "data"); } // If the data is at least the correct length to be valid, determine the // total number of tags in the stream. int tagCnt = data.Length / 12; // And, finally, start dumping the stream into TiffTag objects 12 bytes // at a time. for (int i = 0; i < tagCnt; i++) { byte[] val = new byte[12]; Array.Copy(data, i * 12, val, 0, 12); TiffTag newTag = new TiffTag(this, val); // We'll store the tags in the collection using the readable name of // the tag as the key. This will make accessing individual tags // later much easier. this._tags.Add(newTag, newTag.TagID.ToString()); } }
public object[] GetTagValues(TiffTagType tagType) { if (!this.HasTag(tagType)) { return(null); } // First we have to retrieve the requested tag. TiffTag tag = this.GetTag(tagType); byte[] raw = tag.GetValue(); // Prepare a collection to hold the return values. ObjectCollection retVal = new ObjectCollection(); // Next, we have to determine what kind of data we're dealing with. switch (tag.FieldType) { case TiffFieldType.AsciiType: string val = System.Text.ASCIIEncoding.ASCII.GetString(raw); retVal.Add(val); break; case TiffFieldType.ByteType: retVal.AddRange(raw); break; case TiffFieldType.LongType: for (int i = 0; i < (raw.Length / 4); i++) { retVal.Add(Hex.GetInteger( new byte[] { raw[i * 4], raw[(i * 4) + 1], raw[(i * 4) + 2], raw[(i * 4) + 3] })); } break; case TiffFieldType.ShortType: for (int i = 0; i < (raw.Length / 2); i++) { retVal.Add(Hex.GetInteger( new byte[] { raw[i * 2], raw[(i * 2) + 1] })); } break; case TiffFieldType.Rational: for (int i = 0; i < (raw.Length / 8); i++) { int num = Hex.GetInteger(new byte[] { raw[i * 8], raw[(i * 8) + 1], raw[(i * 8) + 2], raw[(i * 8) + 3] }); int den = Hex.GetInteger(new byte[] { raw[(i * 8) + 4], raw[(i * 8) + 5], raw[(i * 8) + 6], raw[(i * 8) + 7] }); retVal.Add(num / den); } break; } // And, finally, return the value(s). return(retVal.ToArray()); }
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())); }