/// <summary> /// Will stock the thumbnail into exif directory if available. /// </summary> /// <param name="exifDirectory">where to stock the thumbnail</param> /// <param name="tiffHeaderOffset">the tiff lcHeader lcOffset value</param> private void StoreThumbnailBytes(AbstractDirectory exifDirectory, int tiffHeaderOffset) { if (!exifDirectory.ContainsTag(ExifDirectory.TAG_COMPRESSION)) { return; } if (!exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH) || !exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET)) { return; } try { int offset = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_OFFSET); int length = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_LENGTH); byte[] result = new byte[length]; for (int i = 0; i < result.Length; i++) { result[i] = base.data[tiffHeaderOffset + offset + i]; } exifDirectory.SetObject(ExifDirectory.TAG_THUMBNAIL_DATA, result); } catch (Exception e) { exifDirectory.HasError = true; Trace.TraceError("Unable to extract thumbnail: " + e.Message); } }
/// <summary> /// This method serves as marsheller of objects for dataset. /// It converts from IPTC octets to relevant java object. /// </summary> /// <param name="aDirectory">the directory</param> /// <param name="aDirectoryType">the directory type</param> /// <param name="aTagType">the tag type</param> /// <param name="anOffset">the lcOffset</param> /// <param name="aTagByteCount">the tag byte count</param> private void ProcessTag( AbstractDirectory aDirectory, int aDirectoryType, int aTagType, int anOffset, int aTagByteCount) { int tagIdentifier = aTagType | (aDirectoryType << 8); switch (tagIdentifier) { case IptcDirectory.TAG_RECORD_VERSION: // short short shortValue = (short)((base.data[anOffset] << 8) | base.data[anOffset + 1]); aDirectory.SetObject(tagIdentifier, shortValue); return; case IptcDirectory.TAG_URGENCY: // byte aDirectory.SetObject(tagIdentifier, base.data[anOffset]); return; case IptcDirectory.TAG_RELEASE_DATE: case IptcDirectory.TAG_DATE_CREATED: // Date object if (aTagByteCount >= 8) { string dateStr = Utils.Decode(base.data, anOffset, aTagByteCount, false); try { int year = Convert.ToInt32(dateStr.Substring(0, 4)); int month = Convert.ToInt32(dateStr.Substring(4, 2)); //No -1 here; int day = Convert.ToInt32(dateStr.Substring(6, 2)); DateTime date = new DateTime(year, month, day); aDirectory.SetObject(tagIdentifier, date); return; } catch (Exception) { // fall through and we'll store whatever was there as a String } } break; // Added for .Net compiler //case IptcDirectory.TAG_RELEASE_TIME: //case IptcDirectory.TAG_TIME_CREATED: } // If no special handling by now, treat it as a string string str = null; if (aTagByteCount < 1) { str = ""; } else { str = Utils.Decode(base.data, anOffset, aTagByteCount, false); } if (aDirectory.ContainsTag(tagIdentifier)) { string[] oldStrings; string[] newStrings; try { oldStrings = aDirectory.GetStringArray(tagIdentifier); } catch (MetadataException) { oldStrings = null; } if (oldStrings == null) { newStrings = new String[1]; } else { newStrings = new string[oldStrings.Length + 1]; for (int i = 0; i < oldStrings.Length; i++) { newStrings[i] = oldStrings[i]; } } newStrings[newStrings.Length - 1] = str; aDirectory.SetObject(tagIdentifier, newStrings); } else { aDirectory.SetObject(tagIdentifier, str); } }
/// <summary> /// Processes tag /// </summary> /// <param name="directory">the directory</param> /// <param name="aTagType">the tag type</param> /// <param name="tagValueOffset">the lcOffset value</param> /// <param name="componentCount">the component count</param> /// <param name="formatCode">the format code</param> private void ProcessTag( AbstractDirectory directory, int tagType, int tagValueOffset, int componentCount, int formatCode) { // Directory simply stores raw values // The display side uses a Descriptor class per directory to turn the raw values into 'pretty' descriptions switch (formatCode) { case FMT_UNDEFINED: Debug.Write("Found a tag made of bytes"); // this includes exif user comments byte[] tagBytes = new byte[componentCount]; int byteCount = componentCount * BYTES_PER_FORMAT[formatCode]; for (int i = 0; i < byteCount; i++) { tagBytes[i] = base.data[tagValueOffset + i]; } directory.SetObject(tagType, tagBytes); break; case FMT_STRING: Debug.Write("Found a tag made of string"); string lcStr = null; if (tagType == ExifDirectory.TAG_USER_COMMENT) { lcStr = ReadCommentString( tagValueOffset, componentCount, formatCode); } else { lcStr = ReadString(tagValueOffset, componentCount); } directory.SetObject(tagType, lcStr); break; case FMT_SRATIONAL: //goto case FMT_URATIONAL; case FMT_URATIONAL: if (componentCount == 1) { Debug.Write("Found a tag made of rational"); Rational rational = new Rational(Get32Bits(tagValueOffset), Get32Bits(tagValueOffset + 4)); directory.SetObject(tagType, rational); } else { Debug.Write("Found a tag made of rationals"); Rational[] rationals = new Rational[componentCount]; for (int i = 0; i < componentCount; i++) { rationals[i] = new Rational(Get32Bits(tagValueOffset + (8 * i)), Get32Bits(tagValueOffset + 4 + (8 * i))); } directory.SetObject(tagType, rationals); } break; case FMT_SBYTE: //goto case FMT_BYTE; case FMT_BYTE: if (componentCount == 1) { Debug.Write("Found a tag made of byte"); // this may need to be a byte, but I think casting to int is fine int b = base.data[tagValueOffset]; directory.SetObject(tagType, b); } else { Debug.Write("Found a tag made of bytes but will use ints"); int[] bytes = new int[componentCount]; for (int i = 0; i < componentCount; i++) { bytes[i] = base.data[tagValueOffset + i]; } directory.SetIntArray(tagType, bytes); } break; case FMT_SINGLE: //goto case FMT_DOUBLE; case FMT_DOUBLE: if (componentCount == 1) { Debug.Write("Found a tag made of double but will use int"); int i = base.data[tagValueOffset]; directory.SetObject(tagType, i); } else { Debug.Write("Found a tag made of doubles but will use ints"); int[] ints = new int[componentCount]; for (int i = 0; i < componentCount; i++) { ints[i] = base.data[tagValueOffset + i]; } directory.SetIntArray(tagType, ints); } break; case FMT_USHORT: //goto case FMT_SSHORT; case FMT_SSHORT: if (componentCount == 1) { Debug.Write("Found a tag made of short but will use int"); int i = Get16Bits(tagValueOffset); directory.SetObject(tagType, i); } else { Debug.Write("Found a tag made of shorts but will use ints"); int[] ints = new int[componentCount]; for (int i = 0; i < componentCount; i++) { ints[i] = Get16Bits(tagValueOffset + (i * 2)); } directory.SetIntArray(tagType, ints); } break; case FMT_SLONG: //goto case FMT_ULONG; case FMT_ULONG: if (componentCount == 1) { Debug.Write("Found a tag made of long but will use int"); int i = Get32Bits(tagValueOffset); directory.SetObject(tagType, i); } else { Debug.Write("Found a tag made of longs but will use ints"); int[] ints = new int[componentCount]; for (int i = 0; i < componentCount; i++) { ints[i] = Get32Bits(tagValueOffset + (i * 4)); } directory.SetIntArray(tagType, ints); } break; default: Trace.TraceWarning("Unknown format code " + formatCode + " for tag " + tagType); break; } }