/// <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);
            }
        }
Beispiel #2
0
 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)) }));
 }