/// <exception cref="System.IO.IOException"/> private void ProcessTag([NotNull] SequentialReader reader, [NotNull] Com.Drew.Metadata.Directory directory, int directoryType, int tagType, int tagByteCount) { int tagIdentifier = tagType | (directoryType << 8); // Some images have been seen that specify a zero byte tag, which cannot be of much use. // We elect here to completely ignore the tag. The IPTC specification doesn't mention // anything about the interpretation of this situation. // https://raw.githubusercontent.com/wiki/drewnoakes/metadata-extractor/docs/IPTC-IIMV4.2.pdf if (tagByteCount == 0) { directory.SetString(tagIdentifier, string.Empty); return; } string @string = null; switch (tagIdentifier) { case IptcDirectory.TagCodedCharacterSet: { sbyte[] bytes = reader.GetBytes(tagByteCount); string charset = Iso2022Converter.ConvertISO2022CharsetToJavaCharset(bytes); if (charset == null) { // Unable to determine the charset, so fall through and treat tag as a regular string @string = Sharpen.Runtime.GetStringForBytes(bytes); break; } directory.SetString(tagIdentifier, charset); return; } case IptcDirectory.TagEnvelopeRecordVersion: case IptcDirectory.TagApplicationRecordVersion: case IptcDirectory.TagFileVersion: case IptcDirectory.TagArmVersion: case IptcDirectory.TagProgramVersion: { // short if (tagByteCount >= 2) { int shortValue = reader.GetUInt16(); reader.Skip(tagByteCount - 2); directory.SetInt(tagIdentifier, shortValue); return; } break; } case IptcDirectory.TagUrgency: { // byte directory.SetInt(tagIdentifier, reader.GetUInt8()); reader.Skip(tagByteCount - 1); return; } case IptcDirectory.TagReleaseDate: case IptcDirectory.TagDateCreated: { // Date object if (tagByteCount >= 8) { @string = reader.GetString(tagByteCount); try { int year = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 0, 4)); int month = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 4, 6)) - 1; int day = System.Convert.ToInt32(Sharpen.Runtime.Substring(@string, 6, 8)); DateTime date = new Sharpen.GregorianCalendar(year, month, day).GetTime(); directory.SetDate(tagIdentifier, date); return; } catch (FormatException) { } } else { // fall through and we'll process the 'string' value below reader.Skip(tagByteCount); } goto case IptcDirectory.TagReleaseTime; } case IptcDirectory.TagReleaseTime: case IptcDirectory.TagTimeCreated: default: { break; } } // time... // fall through // If we haven't returned yet, treat it as a string // NOTE that there's a chance we've already loaded the value as a string above, but failed to parse the value if (@string == null) { string encoding = directory.GetString(IptcDirectory.TagCodedCharacterSet); if (encoding != null) { @string = reader.GetString(tagByteCount, encoding); } else { sbyte[] bytes_1 = reader.GetBytes(tagByteCount); encoding = Iso2022Converter.GuessEncoding(bytes_1); @string = encoding != null?Sharpen.Runtime.GetStringForBytes(bytes_1, encoding) : Sharpen.Runtime.GetStringForBytes(bytes_1); } } if (directory.ContainsTag(tagIdentifier)) { // this fancy string[] business avoids using an ArrayList for performance reasons string[] oldStrings = directory.GetStringArray(tagIdentifier); string[] newStrings; if (oldStrings == null) { newStrings = new string[1]; } else { newStrings = new string[oldStrings.Length + 1]; System.Array.Copy(oldStrings, 0, newStrings, 0, oldStrings.Length); } newStrings[newStrings.Length - 1] = @string; directory.SetStringArray(tagIdentifier, newStrings); } else { directory.SetString(tagIdentifier, @string); } }
public virtual void TestConvertISO2022CharsetToJavaCharset() { Sharpen.Tests.AreEqual("UTF-8", Iso2022Converter.ConvertISO2022CharsetToJavaCharset(new sbyte[] { unchecked ((int)(0x1B)), unchecked ((int)(0x25)), unchecked ((int)(0x47)) })); Sharpen.Tests.AreEqual("ISO-8859-1", Iso2022Converter.ConvertISO2022CharsetToJavaCharset(new sbyte[] { unchecked ((int)(0x1B)), unchecked ((sbyte)0xE2), unchecked ((sbyte)0x80), unchecked ((sbyte)0xA2), unchecked ((int)(0x41)) })); }