Exemple #1
0
        /// <summary>
        /// Some image editing apps such as Lightroom, On1, etc., do not persist the keyword metadata
        /// in the images by default. This can mean you keyword-tag them, but those keywords are only
        /// stored in the sidecars. Damselfly only scans keyword metadata from the EXIF image data
        /// itself.
        /// So to rectify this, we can either read the sidecar files for those keywords, and optionally
        /// write the missing keywords to the Exif Metadata as we index them.
        /// </summary>
        /// <param name="img"></param>
        /// <param name="keywords"></param>
        private void ProcessSideCarKeywords(Image img, string[] keywords)
        {
            var sideCarTags = new List <string>();

            var           sidecarSearch = Path.ChangeExtension(img.FileName, "*");
            DirectoryInfo dir           = new DirectoryInfo(img.Folder.Path);
            var           files         = dir.GetFiles(sidecarSearch);

            var on1Sidecar = files.FirstOrDefault(x => x.Extension.Equals(".on1", StringComparison.OrdinalIgnoreCase));

            if (on1Sidecar != null)
            {
                var on1MetaData = On1Sidecar.LoadMetadata(on1Sidecar);

                if (on1MetaData != null)
                {
                    var missingKeywords = on1MetaData.Keywords
                                          .Except(keywords, StringComparer.OrdinalIgnoreCase)
                                          .ToList();

                    if (missingKeywords.Any())
                    {
                        Logging.LogVerbose($"Image {img.FileName} is missing {missingKeywords.Count} keywords present in the On1 Sidecar.");
                        sideCarTags = sideCarTags.Union(missingKeywords, StringComparer.OrdinalIgnoreCase).ToList();
                    }
                }
            }

            var xmpSidecar = files.FirstOrDefault(x => x.Extension.Equals(".xmp", StringComparison.OrdinalIgnoreCase));

            if (xmpSidecar != null)
            {
                using var stream = File.OpenRead(xmpSidecar.FullName);
                IXmpMeta xmp = XmpMetaFactory.Parse(stream);

                var xmpKeywords = xmp.Properties.FirstOrDefault(x => x.Path == "pdf:Keywords");

                if (xmpKeywords != null)
                {
                    var missingKeywords = xmpKeywords.Value
                                          .Split(",")
                                          .Select(x => x.Trim())
                                          .Except(keywords)
                                          .ToList();

                    if (missingKeywords.Any())
                    {
                        Logging.LogVerbose($"Image {img.FileName} is missing {missingKeywords.Count} keywords present in the XMP Sidecar.");
                        sideCarTags = sideCarTags.Union(missingKeywords, StringComparer.OrdinalIgnoreCase).ToList();
                    }
                }
            }

            if (sideCarTags.Any())
            {
                // Now, submit the tags; note they won't get created immediately, but in batch.
                Logging.Log($"Applying {sideCarTags.Count} keywords from sidecar files to image {img.FileName}");
                _ = MetaDataService.Instance.UpdateTagsAsync(new[] { img }, sideCarTags, null);
            }
        }
Exemple #2
0
 /// <param name="xmp">Asserts that xmp is compatible to <c>XMPMetaImpl</c>.s</param>
 private static void AssertImplementation(IXmpMeta xmp)
 {
     if (!(xmp is XmpMeta))
     {
         throw new NotSupportedException("The serializing service works only with the XMPMeta implementation of this library");
     }
 }
Exemple #3
0
 // UTF-8
 /// <summary>The actual serialization.</summary>
 /// <param name="xmp">the metadata object to be serialized</param>
 /// <param name="stream">outputStream the output stream to serialize to</param>
 /// <param name="options">the serialization options</param>
 /// <exception cref="XmpException">If case of wrong options or any other serialization error.</exception>
 public void Serialize(IXmpMeta xmp, Stream stream, SerializeOptions options)
 {
     try
     {
         _stream   = stream;
         _startPos = _stream.Position;
         _writer   = new StreamWriter(_stream, options.GetEncoding());
         _xmp      = (XmpMeta)xmp;
         _options  = options;
         _padding  = options.Padding;
         _writer   = new StreamWriter(_stream, options.GetEncoding());
         CheckOptionsConsistence();
         // serializes the whole packet, but don't write the tail yet
         // and flush to make sure that the written bytes are calculated correctly
         var tailStr = SerializeAsRdf();
         _writer.Flush();
         // adds padding
         AddPadding(tailStr.Length);
         // writes the tail
         Write(tailStr);
         _writer.Flush();
     }
     catch (IOException)
     {
         throw new XmpException("Error writing to the OutputStream", XmpErrorCode.Unknown);
     }
 }
        /** Sets the identifier.
         *
         * @param xmpMeta
         * @param id
         */

        public static void SetIdentifiers(IXmpMeta xmpMeta, String[] id) {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, IDENTIFIER, true, true);
            for (int i = 0; i < id.Length; i++) {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, IDENTIFIER, new PropertyOptions(PropertyOptions.ARRAY), id[i],
                                        null);
            }
        }
        /**
         * Test doesPropertyExist, deleteProperty, and related methods.
         * @param meta a predefined <code>XmpMeta</code> object.
         */
        private static void CoverExistingProperties(IXmpMeta meta)
        {
            writeMajorLabel("Test doesPropertyExist, deleteProperty, and related methods");

            printXmpMeta(meta, "XMP object");

            log.WriteLine("doesPropertyExist ns1:Prop =    " + meta.DoesPropertyExist(TestData.NS1, "Prop"));
            log.WriteLine("doesPropertyExist ns1:Struct =    " + meta.DoesPropertyExist(TestData.NS1, "ns1:Struct"));
            log.WriteLine("doesArrayItemExist ns1:Bag[2] =    " + meta.DoesArrayItemExist(TestData.NS1, "Bag", 2));
            log.WriteLine("doesArrayItemExist ns1:Seq[last()] =    "
                          + meta.DoesArrayItemExist(TestData.NS1, "ns1:Seq", XmpConstants.ArrayLastItem));
            log.WriteLine("doesStructFieldExist ns1:Struct/ns2:Field1 =    "
                          + meta.DoesStructFieldExist(TestData.NS1, "Struct", TestData.NS2, "Field1"));
            log.WriteLine("doesQualifierExist ns1:QualProp1/?ns2:Qual1 =    "
                          + meta.DoesQualifierExist(TestData.NS1, "QualProp1", TestData.NS2, "Qual1"));
            log.WriteLine("doesQualifierExist ns1:QualProp2/?xml:lang =    "
                          + meta.DoesQualifierExist(TestData.NS1, "QualProp2", XmpConstants.NsXml, "lang"));
            log.WriteLine();
            log.WriteLine("doesPropertyExist (namespace is null) =    "
                          + meta.DoesPropertyExist(null, "ns1:Bag"));
            log.WriteLine("doesArrayItemExist (namespace is null) =    "
                          + meta.DoesArrayItemExist(null, "ns1:Bag", XmpConstants.ArrayLastItem));
            log.WriteLine("doesQualifierExist ns:Bogus (namespace not existing) =    "
                          + meta.DoesPropertyExist("ns:bogus/", "Bogus"));
            log.WriteLine("doesPropertyExist ns1:Bogus =    " + meta.DoesPropertyExist(TestData.NS1, "Bogus"));
            log.WriteLine("doesArrayItemExist ns1:Bag[99] =    " + meta.DoesArrayItemExist(TestData.NS1, "Bag", 99));
            log.WriteLine("doesStructFieldExist ns1:Struct/ns2:Bogus =    "
                          + meta.DoesStructFieldExist(TestData.NS1, "Struct", TestData.NS2, "Bogus"));
            log.WriteLine("doesQualifierExist ns1:Prop/?ns2:Bogus =    "
                          + meta.DoesQualifierExist(TestData.NS1, "Prop", TestData.NS2, "Bogus"));
        }
Exemple #6
0
        public override void Close(PdfWriter writer)
        {
            base.Close(writer);
            bool     ok      = false;
            IXmpMeta xmpMeta = writer.XmpWriter.XmpMeta;

            try {
                String docFileName = xmpMeta.GetPropertyString(PdfAXmpWriter.zugferdSchemaNS,
                                                               PdfAXmpWriter.zugferdDocumentFileName);
                foreach (PdfFileSpecification attachment in attachments)
                {
                    if (docFileName.Equals(attachment.GetAsString(PdfName.UF).ToString()))
                    {
                        PdfName relationship = attachment.GetAsName(PdfName.AFRELATIONSHIP);
                        if (!AFRelationshipValue.Alternative.Equals(relationship))
                        {
                            attachments.Clear();
                            throw new PdfAConformanceException(attachment,
                                                               MessageLocalization.GetComposedMessage("afrelationship.value.shall.be.alternative"));
                        }
                        ok = true;
                        break;
                    }
                }
            } catch (Exception e) {
                attachments.Clear();
                throw e;
            }
            attachments.Clear();
            if (!ok)
            {
                throw new PdfAConformanceException(xmpMeta,
                                                   MessageLocalization.GetComposedMessage("zugferd.xmp.schema.shall.contain.attachment.name"));
            }
        }
        /**
         * Adds information about the PDF/A conformance level to the XMP metadata.
         *
         * @param conformanceLevel
         * @throws IOException
         */
        private void AddRdfDescription(PdfAConformanceLevel conformanceLevel)
        {
            switch (conformanceLevel)
            {
            case PdfAConformanceLevel.PDF_A_1A:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "1");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "A");
                break;

            case PdfAConformanceLevel.PDF_A_1B:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "1");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "B");
                break;

            case PdfAConformanceLevel.PDF_A_2A:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "2");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "A");
                break;

            case PdfAConformanceLevel.PDF_A_2B:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "2");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "B");
                break;

            case PdfAConformanceLevel.PDF_A_2U:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "2");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "U");
                break;

            case PdfAConformanceLevel.PDF_A_3A:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "3");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "A");
                break;

            case PdfAConformanceLevel.PDF_A_3B:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "3");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "B");
                break;

            case PdfAConformanceLevel.PDF_A_3U:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "3");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "U");
                break;

            case PdfAConformanceLevel.ZUGFeRD:
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.PART, "3");
                xmpMeta.SetProperty(XmpConst.NS_PDFA_ID, PdfAProperties.CONFORMANCE, "B");
                IXmpMeta taggedExtensionMeta = XmpMetaFactory.ParseFromString(zugferdExtension);
                XmpUtils.AppendProperties(taggedExtensionMeta, xmpMeta, true, false);
                break;

            default:
                break;
            }
            if (writer.IsTagged())
            {
                IXmpMeta taggedExtensionMeta = XmpMetaFactory.ParseFromString(pdfUaExtension);
                XmpUtils.AppendProperties(taggedExtensionMeta, xmpMeta, true, false);
            }
        }
        /** Sets the identifier.
         *
         * @param xmpMeta
         * @param id
         */

        public static void SetIdentifiers(IXmpMeta xmpMeta, String[] id)
        {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, IDENTIFIER, true, true);
            for (int i = 0; i < id.Length; i++)
            {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, IDENTIFIER, new PropertyOptions(PropertyOptions.ARRAY), id[i],
                                        null);
            }
        }
Exemple #9
0
        /**
         * Sets a subject.
         *
         * @param xmpMeta
         * @param subject array of subjects
         */

        public static void SetSubject(IXmpMeta xmpMeta, String[] subject)
        {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, SUBJECT, true, true);
            for (int i = 0; i < subject.Length; i++)
            {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, SUBJECT, new PropertyOptions(PropertyOptions.ARRAY), subject[i],
                                        null);
            }
        }
Exemple #10
0
        /**
         * Sets an array of authors.
         *
         * @param xmpMeta
         * @param author
         */

        public static void SetAuthor(IXmpMeta xmpMeta, String[] author)
        {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, CREATOR, true, true);
            for (int i = 0; i < author.Length; i++)
            {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, CREATOR, new PropertyOptions(PropertyOptions.ARRAY_ORDERED),
                                        author[i], null);
            }
        }
Exemple #11
0
        private byte[] GetPropertyBase64(IXmpMeta meta, string schemaNs, string propName)
        {
            // Use System.Convert rather than IXmpMeta Base64 decoder.
            // The base64 strings have the padding removed which causes an exception in the IXmpMeta decoder.
            string base64 = meta.GetPropertyString(schemaNs, propName);

            base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
            return(Convert.FromBase64String(base64));
        }
Exemple #12
0
        /**
         * Sets an array of publishers.
         *
         * @param xmpMeta
         * @param publisher
         */

        public static void SetPublisher(IXmpMeta xmpMeta, String[] publisher)
        {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, PUBLISHER, true, true);
            for (int i = 0; i < publisher.Length; i++)
            {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, PUBLISHER, new PropertyOptions(PropertyOptions.ARRAY_ORDERED),
                                        publisher[i], null);
            }
        }
 /// <exception cref="XmpException"/>
 private static void ProcessXmpTags(XmpDirectory directory, IXmpMeta xmpMeta)
 {
     // store the XMPMeta object on the directory in case others wish to use it
     directory.SetXmpMeta(xmpMeta);
     // read all the tags and send them to the directory
     // I've added some popular tags, feel free to add more tags
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLensInfo, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLens, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagCameraSerialNumber, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFirmware, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagMake, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagModel, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagExposureTime, FormatType.String);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagExposureProgram, FormatType.Int);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagApertureValue, FormatType.Rational);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFNumber, FormatType.Rational);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFocalLength, FormatType.Rational);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagShutterSpeed, FormatType.Rational);
     ProcessXmpDateTag(xmpMeta, directory, XmpDirectory.TagDateTimeOriginal);
     ProcessXmpDateTag(xmpMeta, directory, XmpDirectory.TagDateTimeDigitized);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagRating, FormatType.Double);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLabel, FormatType.String);
     // this requires further research
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:title", XmpDirectory.TAG_TITLE, FMT_STRING);
     ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagSubject, FormatType.StringArray);
     // processXmpDateTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:date", XmpDirectory.TAG_DATE);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:type", XmpDirectory.TAG_TYPE, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:description", XmpDirectory.TAG_DESCRIPTION, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:relation", XmpDirectory.TAG_RELATION, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:coverage", XmpDirectory.TAG_COVERAGE, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:creator", XmpDirectory.TAG_CREATOR, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:publisher", XmpDirectory.TAG_PUBLISHER, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:contributor", XmpDirectory.TAG_CONTRIBUTOR, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:rights", XmpDirectory.TAG_RIGHTS, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:format", XmpDirectory.TAG_FORMAT, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:identifier", XmpDirectory.TAG_IDENTIFIER, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:language", XmpDirectory.TAG_LANGUAGE, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:audience", XmpDirectory.TAG_AUDIENCE, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:provenance", XmpDirectory.TAG_PROVENANCE, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:rightsHolder", XmpDirectory.TAG_RIGHTS_HOLDER, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:instructionalMethod", XmpDirectory.TAG_INSTRUCTIONAL_METHOD,
     // FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualMethod", XmpDirectory.TAG_ACCRUAL_METHOD, FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualPeriodicity", XmpDirectory.TAG_ACCRUAL_PERIODICITY,
     // FMT_STRING);
     // processXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualPolicy", XmpDirectory.TAG_ACCRUAL_POLICY, FMT_STRING);
     foreach (var prop in xmpMeta.Properties)
     {
         var path  = prop.Path;
         var value = prop.Value;
         if (path != null && value != null)
         {
             directory.AddProperty(path, value);
         }
     }
 }
 /// <summary>
 /// The initial support for WAV files mapped a legacy ID3 audio copyright
 /// into a new xmpDM:copyright property.
 /// </summary>
 /// <remarks>
 /// The initial support for WAV files mapped a legacy ID3 audio copyright
 /// into a new xmpDM:copyright property. This is special case code to migrate
 /// that into dc:rights['x-default']. The rules:
 /// <pre>
 /// 1. If there is no dc:rights array, or an empty array -
 /// Create one with dc:rights['x-default'] set from double linefeed and xmpDM:copyright.
 /// 2. If there is a dc:rights array but it has no x-default item -
 /// Create an x-default item as a copy of the first item then apply rule #3.
 /// 3. If there is a dc:rights array with an x-default item,
 /// Look for a double linefeed in the value.
 /// A. If no double linefeed, compare the x-default value to the xmpDM:copyright value.
 /// A1. If they match then leave the x-default value alone.
 /// A2. Otherwise, append a double linefeed and
 /// the xmpDM:copyright value to the x-default value.
 /// B. If there is a double linefeed, compare the trailing text to the xmpDM:copyright value.
 /// B1. If they match then leave the x-default value alone.
 /// B2. Otherwise, replace the trailing x-default text with the xmpDM:copyright value.
 /// 4. In all cases, delete the xmpDM:copyright property.
 /// </pre>
 /// </remarks>
 /// <param name="xmp">the metadata object</param>
 /// <param name="dmCopyright">the "dm:copyright"-property</param>
 private static void MigrateAudioCopyright(IXmpMeta xmp, XmpNode dmCopyright)
 {
     try
     {
         var dcSchema      = XmpNodeUtils.FindSchemaNode(((XmpMeta)xmp).GetRoot(), XmpConstants.NsDC, true);
         var dmValue       = dmCopyright.Value;
         var doubleLf      = "\n\n";
         var dcRightsArray = XmpNodeUtils.FindChildNode(dcSchema, "dc:rights", false);
         if (dcRightsArray == null || !dcRightsArray.HasChildren)
         {
             // 1. No dc:rights array, create from double linefeed and xmpDM:copyright.
             dmValue = doubleLf + dmValue;
             xmp.SetLocalizedText(XmpConstants.NsDC, "rights", string.Empty, XmpConstants.XDefault, dmValue, null);
         }
         else
         {
             var xdIndex = XmpNodeUtils.LookupLanguageItem(dcRightsArray, XmpConstants.XDefault);
             if (xdIndex < 0)
             {
                 // 2. No x-default item, create from the first item.
                 var firstValue = dcRightsArray.GetChild(1).Value;
                 xmp.SetLocalizedText(XmpConstants.NsDC, "rights", string.Empty, XmpConstants.XDefault, firstValue, null);
                 xdIndex = XmpNodeUtils.LookupLanguageItem(dcRightsArray, XmpConstants.XDefault);
             }
             // 3. Look for a double linefeed in the x-default value.
             var defaultNode  = dcRightsArray.GetChild(xdIndex);
             var defaultValue = defaultNode.Value;
             var lfPos        = defaultValue.IndexOf(doubleLf);
             if (lfPos < 0)
             {
                 // 3A. No double LF, compare whole values.
                 if (!dmValue.Equals(defaultValue))
                 {
                     // 3A2. Append the xmpDM:copyright to the x-default
                     // item.
                     defaultNode.Value = defaultValue + doubleLf + dmValue;
                 }
             }
             else
             {
                 // 3B. Has double LF, compare the tail.
                 if (!defaultValue.Substring(lfPos + 2).Equals(dmValue))
                 {
                     // 3B2. Replace the x-default tail.
                     defaultNode.Value = defaultValue.Substring(0, lfPos + 2 - 0) + dmValue;
                 }
             }
         }
         // 4. Get rid of the xmpDM:copyright.
         dmCopyright.Parent.RemoveChild(dmCopyright);
     }
     catch (XmpException)
     {
     }
 }
Exemple #15
0
 private void ParseExtendedDirectory(IXmpMeta meta)
 {
     try
     {
         ImageData = meta.GetPropertyBase64(nsImage, "GImage:Data");
         DepthData = meta.GetPropertyBase64(nsDepthmap, "GDepth:Data");
     }
     catch
     {
     }
 }
Exemple #16
0
 public static void AssertImplementation(IXmpMeta xmp)
 {
     if (xmp == null)
     {
         throw new XmpException("Parameter must not be null", XmpErrorCode.BadParam);
     }
     if (!(xmp is XmpMeta))
     {
         throw new XmpException("The XMPMeta-object is not compatible with this implementation", XmpErrorCode.BadParam);
     }
 }
        private static void ProcessXmpTags([NotNull] XmpDirectory directory, [NotNull] IXmpMeta xmpMeta)
        {
            // store the XMPMeta object on the directory in case others wish to use it
            directory.SetXmpMeta(xmpMeta);

            // extract selected XMP tags
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLensInfo, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLens, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagCameraSerialNumber, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFirmware, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagMake, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagModel, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagExposureTime, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagExposureProgram, FormatType.Int);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagApertureValue, FormatType.Rational);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFNumber, FormatType.Rational);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagFocalLength, FormatType.Rational);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagShutterSpeed, FormatType.Rational);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagDateTimeOriginal, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagDateTimeDigitized, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagBaseUrl, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagCreateDate, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagCreatorTool, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagIdentifier, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagMetadataDate, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagModifyDate, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagNickname, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagRating, FormatType.Double);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagLabel, FormatType.String);
            ProcessXmpTag(xmpMeta, directory, XmpDirectory.TagSubject, FormatType.StringArray);

            // this requires further research
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:title", XmpDirectory.TAG_TITLE, FMT_STRING);
            // ProcessXmpDateTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:date", XmpDirectory.TAG_DATE);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:type", XmpDirectory.TAG_TYPE, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:description", XmpDirectory.TAG_DESCRIPTION, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:relation", XmpDirectory.TAG_RELATION, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:coverage", XmpDirectory.TAG_COVERAGE, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:creator", XmpDirectory.TAG_CREATOR, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:publisher", XmpDirectory.TAG_PUBLISHER, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:contributor", XmpDirectory.TAG_CONTRIBUTOR, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:rights", XmpDirectory.TAG_RIGHTS, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:format", XmpDirectory.TAG_FORMAT, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:identifier", XmpDirectory.TAG_IDENTIFIER, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:language", XmpDirectory.TAG_LANGUAGE, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:audience", XmpDirectory.TAG_AUDIENCE, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:provenance", XmpDirectory.TAG_PROVENANCE, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:rightsHolder", XmpDirectory.TAG_RIGHTS_HOLDER, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:instructionalMethod", XmpDirectory.TAG_INSTRUCTIONAL_METHOD, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualMethod", XmpDirectory.TAG_ACCRUAL_METHOD, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualPeriodicity", XmpDirectory.TAG_ACCRUAL_PERIODICITY, FMT_STRING);
            // ProcessXmpTag(xmpMeta, directory, Schema.DUBLIN_CORE_SPECIFIC_PROPERTIES, "dc:accrualPolicy", XmpDirectory.TAG_ACCRUAL_POLICY, FMT_STRING);
        }
Exemple #18
0
        private void GenerateEAttachmentDocument(PdfAWriter writer, XmpWriter xmpWriter, EAttactment attachment)
        {
            // Use default intent if output intent of this instance was not set
            if (attachment.outputIntents == null)
            {
                //byte[] iccProfile = File.ReadAllBytes("/Resources/sRGB Color Space Profile.icm");
                byte[]      iccProfile = Properties.Resources.sRGB_Color_Space_Profile;
                ICC_Profile icc        = ICC_Profile.GetInstance(iccProfile);
                writer.SetOutputIntents("sRGB IEC61966-2.1", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
            }
            else
            {
                OutputIntents outputIntents       = attachment.outputIntents;
                byte[]        iccProfileByteArray = File.ReadAllBytes(outputIntents.colorProfilePath);
                ICC_Profile   icc = ICC_Profile.GetInstance(iccProfileByteArray);
                writer.SetOutputIntents(outputIntents.outputConditionIdentifier, outputIntents.outputCondition, outputIntents.registryName, outputIntents.info, icc);
            }

            //============= Create Exchange ECertificate =================
            // 1 add ContentInformation.xml to document
            PdfArray attachmentArray = new PdfArray();

            writer.ExtraCatalog.Put(new PdfName("AF"), attachmentArray);
            PdfFileSpecification contentSpec = this.EmbeddedAttachment(attachment.contentInformationXMLPath, attachment.attachmentName,
                                                                       attachment.attachmentMIME, new PdfName(attachment.attachmentType), writer, attachment.attachmentDescription);

            attachmentArray.Add(contentSpec.Reference);

            foreach (var item in attachment.fileAttachments)
            {
                contentSpec = this.EmbeddedAttachment(item.attachmentPath, item.attachmentName,
                                                      item.attachmentMIME, new PdfName(item.attachmentType), writer, item.attachmentDescription);
                attachmentArray.Add(contentSpec.Reference);
            }

            // 2 add Electronic Document XMP Metadata
            ElectronicDocumentSchema ed = ElectronicDocumentSchema.generateED(attachment.attachmentName, attachment.documentVersion, attachment.documentID, attachment.documentOID);

            xmpWriter.AddRdfDescription(ed);

            string pdfaSchema = Properties.Resources.EDocument_PDFAExtensionSchema;

            // convert string to stream
            byte[] byteArray = Encoding.UTF8.GetBytes(pdfaSchema);


            //byte[] byteArray = Encoding.ASCII.GetBytes(contents);
            MemoryStream stream          = new MemoryStream(byteArray);
            IXmpMeta     edPDFAextension = XmpMetaFactory.Parse(stream);
            IXmpMeta     originalXMP     = xmpWriter.XmpMeta;

            XmpUtils.AppendProperties(edPDFAextension, originalXMP, true, true);
        }
Exemple #19
0
        private void WriteXmpMetaData(string imageFilePath, MasterImage masterImage, bool alwaysWriteMetadata, bool preview)
        {
            bool writeMetadata = false;

            IXmpMeta xmp = XmpMetaFactory.Create();

            if ((!String.IsNullOrEmpty(masterImage.Caption) && !IsEquivalent(masterImage.Caption, imageFilePath)) || alwaysWriteMetadata)
            {
                xmp.AppendArrayItem(XmpConstants.NsDC, "dc:title", new PropertyOptions {
                    IsArrayAlternate = true
                }, masterImage.Caption, null);
                writeMetadata = true;
            }

            if (!String.IsNullOrEmpty(masterImage.Comment))
            {
                xmp.AppendArrayItem(XmpConstants.NsDC, "dc:description", new PropertyOptions {
                    IsArrayAlternate = true
                }, masterImage.Comment, null);
                writeMetadata = true;
            }

            if (masterImage.Rating != null && (int)masterImage.Rating > 0)
            {
                xmp.SetProperty(XmpConstants.NsXmp, "xmp:Rating", ((int)masterImage.Rating).ToString());
                writeMetadata = true;
            }

            // TODO: Handle faces.

            if (writeMetadata)
            {
                string metaFilePath = Path.ChangeExtension(imageFilePath, ".xmp");

                if (File.Exists(metaFilePath))
                {
                    Console.Error.WriteLine("ERROR: XMP meta file already exists, skipping '" + metaFilePath + "'.");
                }
                else if (!preview)
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(metaFilePath));

                    using (var stream = File.OpenWrite(metaFilePath))
                    {
                        XmpMetaFactory.Serialize(xmp, stream, new SerializeOptions {
                            OmitPacketWrapper = true
                        });
                    }

                    numMetadataFilesCreated++;
                }
            }
        }
Exemple #20
0
        public void SetXmpMeta([NotNull] IXmpMeta xmpMeta)
        {
            _xmpMeta = xmpMeta;

            try
            {
                Set(TagXmpValueCount, _xmpMeta.Properties.Count(prop => prop.Path != null));
            }
            catch (XmpException)
            {
            }
        }
Exemple #21
0
        /**
         * Print the content of an XmpMeta object a headline and its name.
         * @param meta an <code>XmpMeta</code> object
         * @param title the headline
         */
        private void PrintXmpMeta(IXmpMeta meta, string title)
        {
            var name = meta.GetObjectName();

            if (!string.IsNullOrEmpty(name))
            {
                _log.WriteLine("{0} (Name: '{1}'):", title, name);
            }
            else
            {
                _log.WriteLine("{0}:", title);
            }
            _log.WriteLine(meta.DumpObject());
        }
Exemple #22
0
        /// <seealso cref= XMPUtils#appendProperties(XMPMeta, XMPMeta, boolean, boolean) </seealso>
        /// <param name="source"> The source XMP object. </param>
        /// <param name="destination"> The destination XMP object. </param>
        /// <param name="doAllProperties"> Do internal properties in addition to external properties. </param>
        /// <param name="replaceOldValues"> Replace the values of existing properties. </param>
        /// <param name="deleteEmptyValues"> Delete destination values if source property is empty. </param>
        /// <exception cref="XmpException"> Forwards the Exceptions from the metadata processing </exception>
        public static void AppendProperties(IXmpMeta source, IXmpMeta destination, bool doAllProperties,
                                            bool replaceOldValues, bool deleteEmptyValues)
        {
            ParameterAsserts.AssertImplementation(source);
            ParameterAsserts.AssertImplementation(destination);

            XmpMetaImpl src  = (XmpMetaImpl)source;
            XmpMetaImpl dest = (XmpMetaImpl)destination;

            for (IEnumerator it = src.Root.IterateChildren(); it.MoveNext();)
            {
                XmpNode sourceSchema = (XmpNode)it.Current;
                if (sourceSchema == null)
                {
                    continue;
                }
                // Make sure we have a destination schema node
                XmpNode destSchema    = XmpNodeUtils.FindSchemaNode(dest.Root, sourceSchema.Name, false);
                bool    createdSchema = false;
                if (destSchema == null)
                {
                    PropertyOptions propertyOptions = new PropertyOptions();
                    propertyOptions.SchemaNode = true;
                    destSchema = new XmpNode(sourceSchema.Name, sourceSchema.Value,
                                             propertyOptions);
                    dest.Root.AddChild(destSchema);
                    createdSchema = true;
                }

                // Process the source schema's children.
                for (IEnumerator ic = sourceSchema.IterateChildren(); ic.MoveNext();)
                {
                    XmpNode sourceProp = (XmpNode)ic.Current;
                    if (sourceProp == null)
                    {
                        continue;
                    }
                    if (doAllProperties || !Utils.IsInternalProperty(sourceSchema.Name, sourceProp.Name))
                    {
                        AppendSubtree(dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues);
                    }
                }

                if (!destSchema.HasChildren() && (createdSchema || deleteEmptyValues))
                {
                    // Don't create an empty schema / remove empty schema.
                    dest.Root.RemoveChild(destSchema);
                }
            }
        }
        // ---------------------------------------------------------------------------------------------
        // Utilities for this example
        // ---------------------------------------------------------------------------------------------

        /**
         * Print the content of an XmpMeta object a headline and its name.
         * @param meta an <code>XmpMeta</code> object
         * @param title the headline
         */
        private static void printXmpMeta(IXmpMeta meta, string title)
        {
            string name = meta.GetObjectName();

            if (!string.IsNullOrEmpty(name))
            {
                log.WriteLine("{0} (Name: '{1}'):", title, name);
            }
            else
            {
                log.WriteLine("{0}:", title);
            }
            log.WriteLine(meta.DumpObject());
            log.WriteLine();
        }
Exemple #24
0
        /// <param name="xmp">The XMP object containing the array to be catenated.</param>
        /// <param name="schemaNs">
        /// The schema namespace URI for the array. Must not be null or
        /// the empty string.
        /// </param>
        /// <param name="arrayName">
        /// The name of the array. May be a general path expression, must
        /// not be null or the empty string. Each item in the array must
        /// be a simple string value.
        /// </param>
        /// <param name="separator">
        /// The string to be used to separate the items in the catenated
        /// string. Defaults to &quot;; &quot;, ASCII semicolon and space
        /// (U+003B, U+0020).
        /// </param>
        /// <param name="quotes">
        /// The characters to be used as quotes around array items that
        /// contain a separator. Defaults to &apos;&quot;&apos;
        /// </param>
        /// <param name="allowCommas">Option flag to control the catenation.</param>
        /// <returns>Returns the string containing the catenated array items.</returns>
        /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
        public static string CatenateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string separator, string quotes, bool allowCommas)
        {
            ParameterAsserts.AssertSchemaNs(schemaNs);
            ParameterAsserts.AssertArrayName(arrayName);
            ParameterAsserts.AssertImplementation(xmp);

            if (string.IsNullOrEmpty(separator))
                separator = "; ";
            if (string.IsNullOrEmpty(quotes))
                quotes = "\"";

            var xmpImpl = (XmpMeta)xmp;

            // Return an empty result if the array does not exist,
            // hurl if it isn't the right form.
            var arrayPath = XmpPathParser.ExpandXPath(schemaNs, arrayName);
            var arrayNode = XmpNodeUtils.FindNode(xmpImpl.GetRoot(), arrayPath, false, null);

            if (arrayNode == null)
                return string.Empty;
            if (!arrayNode.Options.IsArray || arrayNode.Options.IsArrayAlternate)
                throw new XmpException("Named property must be non-alternate array", XmpErrorCode.BadParam);

            // Make sure the separator is OK.
            CheckSeparator(separator);

            // Make sure the open and close quotes are a legitimate pair.
            var openQuote = quotes[0];
            var closeQuote = CheckQuotes(quotes, openQuote);

            // Build the result, quoting the array items, adding separators.
            // Hurl if any item isn't simple.
            var catenatedString = new StringBuilder();
            for (var it = arrayNode.IterateChildren(); it.HasNext(); )
            {
                var currItem = (XmpNode)it.Next();

                if (currItem.Options.IsCompositeProperty)
                    throw new XmpException("Array items must be simple", XmpErrorCode.BadParam);

                var str = ApplyQuotes(currItem.Value, openQuote, closeQuote, allowCommas);
                catenatedString.Append(str);

                if (it.HasNext())
                    catenatedString.Append(separator);
            }
            return catenatedString.ToString();
        }
Exemple #25
0
        private void ReadPdfAInfo()
        {
            byte[] metadata = null;

            IXmpProperty pdfaidConformance = null;
            IXmpProperty pdfaidPart        = null;

            try {
                metadata          = reader.Metadata;
                xmpMeta           = XmpMetaParser.Parse(metadata, null);
                pdfaidConformance = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:conformance");
                pdfaidPart        = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:part");
            } catch (Exception e) {
                throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.documents.can.be.opened.in.PdfAStamper"));
            }
            if (pdfaidConformance == null || pdfaidPart == null)
            {
                throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.documents.can.be.opened.in.PdfAStamper"));
            }
            switch (((IPdfAConformance)pdfIsoConformance).ConformanceLevel)
            {
            case PdfAConformanceLevel.PDF_A_1A:
            case PdfAConformanceLevel.PDF_A_1B:
                if (!"1".Equals(pdfaidPart.Value))
                {
                    throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "1"));
                }
                break;

            case PdfAConformanceLevel.PDF_A_2A:
            case PdfAConformanceLevel.PDF_A_2B:
            case PdfAConformanceLevel.PDF_A_2U:
                if (!"2".Equals(pdfaidPart.Value))
                {
                    throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "2"));
                }
                break;

            case PdfAConformanceLevel.PDF_A_3A:
            case PdfAConformanceLevel.PDF_A_3B:
            case PdfAConformanceLevel.PDF_A_3U:
                if (!"3".Equals(pdfaidPart.Value))
                {
                    throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "3"));
                }
                break;
            }
        }
Exemple #26
0
 virtual public void AddRdfDescription(XmpSchema s)
 {
     try {
         String str = "<rdf:RDF xmlns:rdf=\"" + XmpConst.NS_RDF + "\">" +
                      "<rdf:Description rdf:about=\"" + xmpMeta.ObjectName +
                      "\" " +
                      s.Xmlns +
                      ">" +
                      s.ToString() +
                      "</rdf:Description></rdf:RDF>\n";
         IXmpMeta extMeta = XmpMetaFactory.ParseFromString(str);
         XmpUtils.AppendProperties(extMeta, xmpMeta, true, true);
     }
     catch (XmpException xmpExc) {
         throw new IOException(xmpExc.Message);
     }
 }
        /// <exception cref="XmpException"/>
        private static void ProcessXmpDateTag([NotNull] IXmpMeta meta, [NotNull] XmpDirectory directory, int tagType)
        {
            string schemaNs;
            string propName;

            if (!XmpDirectory.TagSchemaMap.TryGetValue(tagType, out schemaNs) || !XmpDirectory.TagPropNameMap.TryGetValue(tagType, out propName))
            {
                return;
            }

            var cal = meta.GetPropertyCalendar(schemaNs, propName);

            if (cal != null)
            {
                directory.Set(tagType, cal.GetTime());
            }
        }
 public void AddRdfDescription(String xmlns, String content)
 {
     try {
         String str = "<rdf:RDF xmlns:rdf=\"" + XmpConst.NS_RDF + "\">" +
                      "<rdf:Description rdf:about=\"" + xmpMeta.ObjectName +
                      "\" " +
                      xmlns +
                      ">" +
                      content +
                      "</rdf:Description></rdf:RDF>\n";
         byte[]   bytes   = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(str));
         IXmpMeta extMeta = XmpMetaFactory.ParseFromString(str);
         XmpUtils.AppendProperties(extMeta, xmpMeta, true, true);
     }
     catch (XmpException xmpExc) {
         throw new IOException(xmpExc.Message);
     }
 }
Exemple #29
0
        private void ParseExtendedDirectory(IXmpMeta meta)
        {
            try
            {
                if (ImageMime != null && meta.DoesPropertyExist(nsImage, "GImage:Data"))
                {
                    ImageData = GetPropertyBase64(meta, nsImage, "GImage:Data");
                }

                if (AudioMime != null && meta.DoesPropertyExist(nsAudio, "GAudio:Data"))
                {
                    AudioData = GetPropertyBase64(meta, nsAudio, "GAudio:Data");
                }
            }
            catch
            {
            }
        }
Exemple #30
0
        private void GpsAltitudeRef(IXmpMeta xmp, FileIndexItem item)
        {
            string gpsAltitude    = null;
            string gpsAltitudeRef = null;

            foreach (var property in xmp.Properties)
            {
                // Path=exif:GPSAltitude Namespace=http://ns.adobe.com/exif/1.0/ Value=627/10
                // Path=exif:GPSAltitudeRef Namespace=http://ns.adobe.com/exif/1.0/ Value=0
                var gpsAltitudeLocal = GetContentNameSpace(property, "exif:GPSAltitude");
                if (gpsAltitudeLocal != null)
                {
                    gpsAltitude = gpsAltitudeLocal;
                }

                var gpsAltitudeRefLocal = GetContentNameSpace(property, "exif:GPSAltitudeRef");
                if (gpsAltitudeRefLocal != null)
                {
                    gpsAltitudeRef = gpsAltitudeRefLocal;
                }
            }
            if (gpsAltitude == null || gpsAltitudeRef == null)
            {
                return;
            }
            if (!gpsAltitude.Contains("/"))
            {
                return;
            }

            var locationAltitude = MathFraction.Fraction(gpsAltitude);

            if (Math.Abs(locationAltitude) < 0)
            {
                return;
            }
            item.LocationAltitude = locationAltitude;

            //For items under the sea level
            if (gpsAltitudeRef == "1")
            {
                item.LocationAltitude = item.LocationAltitude * -1;
            }
        }
Exemple #31
0
        public void SetXmpMeta(IXmpMeta xmpMeta)
        {
            XmpMeta = xmpMeta;

            int         valueCount = 0;
            XmpIterator i          = new XmpIterator((XmpMeta)XmpMeta, null, null, _iteratorOptions);

            while (i.HasNext())
            {
                var prop = (IXmpPropertyInfo)i.Next();

                if (prop.Path != null)
                {
                    valueCount++;
                }
            }

            Set(TagXmpValueCount, valueCount);
        }
        /// <param name="source">The source XMP object.</param>
        /// <param name="destination">The destination XMP object.</param>
        /// <param name="doAllProperties">Do internal properties in addition to external properties.</param>
        /// <param name="replaceOldValues">Replace the values of existing properties.</param>
        /// <param name="deleteEmptyValues">Delete destination values if source property is empty.</param>
        /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
        public static void AppendProperties(IXmpMeta source, IXmpMeta destination, bool doAllProperties, bool replaceOldValues, bool deleteEmptyValues)
        {
            ParameterAsserts.AssertImplementation(source);
            ParameterAsserts.AssertImplementation(destination);

            var src  = (XmpMeta)source;
            var dest = (XmpMeta)destination;

            for (var it = src.GetRoot().IterateChildren(); it.HasNext();)
            {
                var sourceSchema = (XmpNode)it.Next();

                // Make sure we have a destination schema node
                var destSchema    = XmpNodeUtils.FindSchemaNode(dest.GetRoot(), sourceSchema.Name, false);
                var createdSchema = false;

                if (destSchema == null)
                {
                    destSchema = new XmpNode(sourceSchema.Name, sourceSchema.Value, new PropertyOptions {
                        IsSchemaNode = true
                    });
                    dest.GetRoot().AddChild(destSchema);
                    createdSchema = true;
                }

                // Process the source schema's children.
                for (var ic = sourceSchema.IterateChildren(); ic.HasNext();)
                {
                    var sourceProp = (XmpNode)ic.Next();
                    if (doAllProperties || !Utils.IsInternalProperty(sourceSchema.Name, sourceProp.Name))
                    {
                        AppendSubtree(dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues);
                    }
                }

                if (!destSchema.HasChildren && (createdSchema || deleteEmptyValues))
                {
                    // Don't create an empty schema / remove empty schema.
                    dest.GetRoot().RemoveChild(destSchema);
                }
            }
        }
        /**
         * Sets a description.
         *
         * @param xmpMeta
         * @param desc
         * @param genericLang  The name of the generic language
         * @param specificLang The name of the specific language
         */

        public static void SetDescription(IXmpMeta xmpMeta, String desc, String genericLang, String specificLang) {
            xmpMeta.SetLocalizedText(XmpConst.NS_DC, DESCRIPTION, genericLang, specificLang, desc);
        }
Exemple #34
0
        /// <summary>
        /// see {@link XMPUtils#separateArrayItems(XMPMeta, String, String, String, 
        /// PropertyOptions, boolean)}
        /// </summary>
        /// <param name="xmp">
        ///            The XMP object containing the array to be updated. </param>
        /// <param name="schemaNs">
        ///            The schema namespace URI for the array. Must not be null or
        ///            the empty string. </param>
        /// <param name="arrayName">
        ///            The name of the array. May be a general path expression, must
        ///            not be null or the empty string. Each item in the array must
        ///            be a simple string value. </param>
        /// <param name="catedStr">
        ///            The string to be separated into the array items. </param>
        /// <param name="arrayOptions">
        ///            Option flags to control the separation. </param>
        /// <param name="preserveCommas">
        ///            Flag if commas shall be preserved
        /// </param>
        /// <exception cref="XmpException">
        ///             Forwards the Exceptions from the metadata processing </exception>
        public static void SeparateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string catedStr,
                                              PropertyOptions arrayOptions, bool preserveCommas) {
            ParameterAsserts.AssertSchemaNs(schemaNs);
            ParameterAsserts.AssertArrayName(arrayName);
            if (catedStr == null) {
                throw new XmpException("Parameter must not be null", XmpError.BADPARAM);
            }
            ParameterAsserts.AssertImplementation(xmp);
            XmpMetaImpl xmpImpl = (XmpMetaImpl) xmp;

            // Keep a zero value, has special meaning below.
            XmpNode arrayNode = SeparateFindCreateArray(schemaNs, arrayName, arrayOptions, xmpImpl);

            // Extract the item values one at a time, until the whole input string is done.
            int charKind = UCK_NORMAL;
            char ch = (char) 0;

            int itemEnd = 0;
            int endPos = catedStr.Length;
            while (itemEnd < endPos) {
                
                string itemValue;
                int itemStart;
                // Skip any leading spaces and separation characters. Always skip commas here.
                // They can be kept when within a value, but not when alone between values.
                for (itemStart = itemEnd; itemStart < endPos; itemStart++) {
                    ch = catedStr[itemStart];
                    charKind = ClassifyCharacter(ch);
                    if (charKind == UCK_NORMAL || charKind == UCK_QUOTE) {
                        break;
                    }
                }
                if (itemStart >= endPos) {
                    break;
                }
                int nextKind;
                if (charKind != UCK_QUOTE) {
                    // This is not a quoted value. Scan for the end, create an array
                    // item from the substring.
                    for (itemEnd = itemStart; itemEnd < endPos; itemEnd++) {
                        ch = catedStr[itemEnd];
                        charKind = ClassifyCharacter(ch);

                        if (charKind == UCK_NORMAL || charKind == UCK_QUOTE || (charKind == UCK_COMMA && preserveCommas)) {
                            continue;
                        }
                        if (charKind != UCK_SPACE) {
                            break;
                        }
                        if ((itemEnd + 1) < endPos) {
                            ch = catedStr[itemEnd + 1];
                            nextKind = ClassifyCharacter(ch);
                            if (nextKind == UCK_NORMAL || nextKind == UCK_QUOTE ||
                                (nextKind == UCK_COMMA && preserveCommas)) {
                                continue;
                            }
                        }

                        // Anything left?
                        break; // Have multiple spaces, or a space followed by a
                        // separator.
                    }
                    itemValue = catedStr.Substring(itemStart, itemEnd - itemStart);
                }
                else {
                    // Accumulate quoted values into a local string, undoubling
                    // internal quotes that
                    // match the surrounding quotes. Do not undouble "unmatching"
                    // quotes.
                    
                    char openQuote = ch;
                    char closeQuote = GetClosingQuote(openQuote);

                    itemStart++; // Skip the opening quote;
                    itemValue = "";

                    for (itemEnd = itemStart; itemEnd < endPos; itemEnd++) {
                        ch = catedStr[itemEnd];
                        charKind = ClassifyCharacter(ch);

                        if (charKind != UCK_QUOTE || !IsSurroundingQuote(ch, openQuote, closeQuote)) {
                            // This is not a matching quote, just append it to the
                            // item value.
                            itemValue += ch;
                        }
                        else {
                            // This is a "matching" quote. Is it doubled, or the
                            // final closing quote?
                            // Tolerate various edge cases like undoubled opening
                            // (non-closing) quotes,
                            // or end of input.
                            char nextChar;
                            if ((itemEnd + 1) < endPos) {
                                nextChar = catedStr[itemEnd + 1];
                                nextKind = ClassifyCharacter(nextChar);
                            }
                            else {
                                nextKind = UCK_SEMICOLON;
                                nextChar = (char) 0x3B;
                            }

                            if (ch == nextChar) {
                                // This is doubled, copy it and skip the double.
                                itemValue += ch;
                                // Loop will add in charSize.
                                itemEnd++;
                            }
                            else if (!IsClosingingQuote(ch, openQuote, closeQuote)) {
                                // This is an undoubled, non-closing quote, copy it.
                                itemValue += ch;
                            }
                            else {
                                // This is an undoubled closing quote, skip it and
                                // exit the loop.
                                itemEnd++;
                                break;
                            }
                        }
                    }
                }

                // Add the separated item to the array. 
                // Keep a matching old value in case it had separators.
                int foundIndex = -1;
                for (int oldChild = 1; oldChild <= arrayNode.ChildrenLength; oldChild++) {
                    if (itemValue.Equals(arrayNode.GetChild(oldChild).Value)) {
                        foundIndex = oldChild;
                        break;
                    }
                }

                if (foundIndex < 0) {
                    XmpNode newItem = new XmpNode(ARRAY_ITEM_NAME, itemValue, null);
                    arrayNode.AddChild(newItem);
                }
            }
        }
Exemple #35
0
        /// <param name="source">The source XMP object.</param>
        /// <param name="destination">The destination XMP object.</param>
        /// <param name="doAllProperties">Do internal properties in addition to external properties.</param>
        /// <param name="replaceOldValues">Replace the values of existing properties.</param>
        /// <param name="deleteEmptyValues">Delete destination values if source property is empty.</param>
        /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
        public static void AppendProperties(IXmpMeta source, IXmpMeta destination, bool doAllProperties, bool replaceOldValues, bool deleteEmptyValues)
        {
            ParameterAsserts.AssertImplementation(source);
            ParameterAsserts.AssertImplementation(destination);

            var src = (XmpMeta)source;
            var dest = (XmpMeta)destination;
            for (var it = src.GetRoot().IterateChildren(); it.HasNext(); )
            {
                var sourceSchema = (XmpNode)it.Next();

                // Make sure we have a destination schema node
                var destSchema = XmpNodeUtils.FindSchemaNode(dest.GetRoot(), sourceSchema.Name, false);
                var createdSchema = false;

                if (destSchema == null)
                {
                    destSchema = new XmpNode(sourceSchema.Name, sourceSchema.Value, new PropertyOptions { IsSchemaNode = true });
                    dest.GetRoot().AddChild(destSchema);
                    createdSchema = true;
                }

                // Process the source schema's children.
                for (var ic = sourceSchema.IterateChildren(); ic.HasNext(); )
                {
                    var sourceProp = (XmpNode)ic.Next();
                    if (doAllProperties || !Utils.IsInternalProperty(sourceSchema.Name, sourceProp.Name))
                        AppendSubtree(dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues);
                }

                if (!destSchema.HasChildren && (createdSchema || deleteEmptyValues))
                {
                    // Don't create an empty schema / remove empty schema.
                    dest.GetRoot().RemoveChild(destSchema);
                }
            }
        }
Exemple #36
0
 /// <summary>Separate a single edit string into an array of strings.</summary>
 /// <param name="xmp">The XMP object containing the array to be updated.</param>
 /// <param name="schemaNs">
 /// The schema namespace URI for the array. Must not be null or
 /// the empty string.
 /// </param>
 /// <param name="arrayName">
 /// The name of the array. May be a general path expression, must
 /// not be null or the empty string. Each item in the array must
 /// be a simple string value.
 /// </param>
 /// <param name="catedStr">The string to be separated into the array items.</param>
 /// <param name="arrayOptions">Option flags to control the separation.</param>
 /// <param name="preserveCommas">Flag if commas shall be preserved</param>
 /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
 /// <exception cref="XmpException"/>
 public static void SeparateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string catedStr, PropertyOptions arrayOptions, bool preserveCommas)
 {
     Impl.XmpUtils.SeparateArrayItems(xmp, schemaNs, arrayName, catedStr, arrayOptions, preserveCommas);
 }
        /**
         * Adds a description.
         *
         * @param xmpMeta
         * @param desc
         */

        public static void AddDescription(IXmpMeta xmpMeta, String desc) {
            xmpMeta.AppendArrayItem(XmpConst.NS_DC, DESCRIPTION, new PropertyOptions(PropertyOptions.ARRAY_ALTERNATE),
                                    desc, null);

        }
        /**
         * Adds a single author.
         *
         * @param xmpMeta
         * @param author
         */

        public static void AddAuthor(IXmpMeta xmpMeta, String author) {
            xmpMeta.AppendArrayItem(XmpConst.NS_DC, CREATOR, new PropertyOptions(PropertyOptions.ARRAY_ORDERED), author,
                                    null);
        }
Exemple #39
0
 /// <summary>Append properties from one XMP object to another.</summary>
 /// <remarks>
 /// Append properties from one XMP object to another.
 /// <para />XMPUtils#appendProperties was created to support the File Info dialog's Append button, and
 /// has been been generalized somewhat from those specific needs. It appends information from one
 /// XMP object (source) to another (dest). The default operation is to append only external
 /// properties that do not already exist in the destination. The flag
 /// <c>doAllProperties</c> can be used to operate on all properties, external and internal.
 /// The flag <c>replaceOldValues</c> option can be used to replace the values
 /// of existing properties. The notion of external
 /// versus internal applies only to top level properties. The keep-or-replace-old notion applies
 /// within structs and arrays as described below.
 /// <list type="bullet">
 /// <item>If <c>replaceOldValues</c> is true then the processing is restricted to the top
 /// level properties. The processed properties from the source (according to
 /// <c>doAllProperties</c>) are propagated to the destination,
 /// replacing any existing values.Properties in the destination that are not in the source
 /// are left alone.</item>
 /// <item>If <c>replaceOldValues</c> is not passed then the processing is more complicated.
 /// Top level properties are added to the destination if they do not already exist.
 /// If they do exist but differ in form (simple/struct/array) then the destination is left alone.
 /// If the forms match, simple properties are left unchanged while structs and arrays are merged.</item>
 /// <item>If <c>deleteEmptyValues</c> is passed then an empty value in the source XMP causes
 /// the corresponding destination XMP property to be deleted. The default is to treat empty
 /// values the same as non-empty values. An empty value is any of a simple empty string, an array
 /// with no items, or a struct with no fields. Qualifiers are ignored.</item>
 /// </list>
 /// <para />The detailed behavior is defined by the following pseudo-code:
 /// <blockquote>
 /// <pre>
 /// appendProperties ( sourceXMP, destXMP, doAllProperties,
 /// replaceOldValues, deleteEmptyValues ):
 /// for all source schema (top level namespaces):
 /// for all top level properties in sourceSchema:
 /// if doAllProperties or prop is external:
 /// appendSubtree ( sourceNode, destSchema, replaceOldValues, deleteEmptyValues )
 /// appendSubtree ( sourceNode, destParent, replaceOldValues, deleteEmptyValues ):
 /// if deleteEmptyValues and source value is empty:
 /// delete the corresponding child from destParent
 /// else if sourceNode not in destParent (by name):
 /// copy sourceNode's subtree to destParent
 /// else if replaceOld:
 /// delete subtree from destParent
 /// copy sourceNode's subtree to destParent
 /// else:
 /// // Already exists in dest and not replacing, merge structs and arrays
 /// if sourceNode and destNode forms differ:
 /// return, leave the destNode alone
 /// else if form is a struct:
 /// for each field in sourceNode:
 /// AppendSubtree ( sourceNode.field, destNode, replaceOldValues )
 /// else if form is an alt-text array:
 /// copy new items by "xml:lang" value into the destination
 /// else if form is an array:
 /// copy new items by value into the destination, ignoring order and duplicates
 /// </pre>
 /// </blockquote>
 /// <para /><em>Note:</em> appendProperties can be expensive if replaceOldValues is not passed and
 /// the XMP contains large arrays. The array item checking described above is n-squared.
 /// Each source item is checked to see if it already exists in the destination,
 /// without regard to order or duplicates.
 /// <para />Simple items are compared by value and "xml:lang" qualifier, other qualifiers are ignored.
 /// Structs are recursively compared by field names, without regard to field order. Arrays are
 /// compared by recursively comparing all items.
 /// </remarks>
 /// <param name="source">The source XMP object.</param>
 /// <param name="dest">The destination XMP object.</param>
 /// <param name="doAllProperties">Do internal properties in addition to external properties.</param>
 /// <param name="replaceOldValues">Replace the values of existing properties.</param>
 /// <param name="deleteEmptyValues">Delete destination values if source property is empty.</param>
 /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
 /// <exception cref="XmpException"/>
 public static void AppendProperties(IXmpMeta source, IXmpMeta dest, bool doAllProperties, bool replaceOldValues, bool deleteEmptyValues = false)
 {
     Impl.XmpUtils.AppendProperties(source, dest, doAllProperties, replaceOldValues, deleteEmptyValues);
 }
 private void ReadPdfAInfo() {
     byte[] metadata = null;
     
     IXmpProperty pdfaidConformance = null;
     IXmpProperty pdfaidPart = null;
     try {
         metadata = reader.Metadata;
         xmpMeta = XmpMetaParser.Parse(metadata, null);
         pdfaidConformance = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:conformance");
         pdfaidPart = xmpMeta.GetProperty(XmpConst.NS_PDFA_ID, "pdfaid:part");
     } catch(Exception e) {
         throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.documents.can.be.opened.in.PdfAStamper"));
     }
     if(pdfaidConformance == null || pdfaidPart == null) {
         throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.documents.can.be.opened.in.PdfAStamper"));
     }
     switch(((IPdfAConformance)pdfIsoConformance).ConformanceLevel) {
         case PdfAConformanceLevel.PDF_A_1A:
         case PdfAConformanceLevel.PDF_A_1B:
             if(!"1".Equals(pdfaidPart.Value)) {
                 throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "1"));
             }
             break;
         case PdfAConformanceLevel.PDF_A_2A:
         case PdfAConformanceLevel.PDF_A_2B:
         case PdfAConformanceLevel.PDF_A_2U:
             if(!"2".Equals(pdfaidPart.Value)) {
                 throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "2"));
             }
             break;
         case PdfAConformanceLevel.PDF_A_3A:
         case PdfAConformanceLevel.PDF_A_3B:
         case PdfAConformanceLevel.PDF_A_3U:
             if(!"3".Equals(pdfaidPart.Value)) {
                 throw new PdfAConformanceException(MessageLocalization.GetComposedMessage("only.pdfa.1.documents.can.be.opened.in.PdfAStamper", "3"));
             }
             break;
     }
 }
Exemple #41
0
        /// <summary>
        /// The actual serialization.
        /// </summary>
        /// <param name="xmp"> the metadata object to be serialized </param>
        /// <param name="out"> outputStream the output stream to Serialize to </param>
        /// <param name="options"> the serialization options
        /// </param>
        /// <exception cref="XmpException"> If case of wrong options or any other serialization error. </exception>
        public virtual void Serialize(IXmpMeta xmp, Stream @out, SerializeOptions options) {
            try {
                _outputStream = new CountOutputStream(@out);
                _writer = new StreamWriter(_outputStream, Encoding.GetEncoding(options.Encoding));

                _xmp = (XmpMetaImpl) xmp;
                _options = options;
                _padding = options.Padding;

                _writer = new StreamWriter(_outputStream, Encoding.GetEncoding(options.Encoding));

                CheckOptionsConsistence();

                // serializes the whole packet, but don't write the tail yet 
                // and flush to make sure that the written bytes are calculated correctly
                string tailStr = SerializeAsRdf();
                _writer.Flush();

                // adds padding
                AddPadding(tailStr.Length);

                // writes the tail
                Write(tailStr);
                _writer.Flush();

                _outputStream.Close();
            }
            catch (IOException) {
                throw new XmpException("Error writing to the OutputStream", XmpError.UNKNOWN);
            }
        }
        /**
         * Sets an array of authors.
         *
         * @param xmpMeta
         * @param author
         */

        public static void SetAuthor(IXmpMeta xmpMeta, String[] author) {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, CREATOR, true, true);
            for (int i = 0; i < author.Length; i++) {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, CREATOR, new PropertyOptions(PropertyOptions.ARRAY_ORDERED),
                                        author[i], null);
            }
        }
        /**
         * Adds a single publisher.
         *
         * @param xmpMeta
         * @param publisher
         */

        public static void AddPublisher(IXmpMeta xmpMeta, String publisher) {
            xmpMeta.AppendArrayItem(XmpConst.NS_DC, PUBLISHER, new PropertyOptions(PropertyOptions.ARRAY_ORDERED),
                                    publisher, null);
        }
        /**
         * Sets an array of publishers.
         *
         * @param xmpMeta
         * @param publisher
         */

        public static void SetPublisher(IXmpMeta xmpMeta, String[] publisher) {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, PUBLISHER, true, true);
            for (int i = 0; i < publisher.Length; i++) {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, PUBLISHER, new PropertyOptions(PropertyOptions.ARRAY_ORDERED),
                                        publisher[i], null);
            }
        }
        /**
         * Creates an XmpWriter.
         * @param os
         * @param utfEncoding
         * @param extraSpace
         * @throws IOException
         */

        public XmpWriter(Stream os, String utfEncoding, int extraSpace) {
            outputStream = os;
            serializeOptions = new SerializeOptions();
            if (UTF16BE.Equals(utfEncoding) || UTF16.Equals(utfEncoding))
                serializeOptions.EncodeUtf16Be = true;
            else if (UTF16LE.Equals(utfEncoding))
                serializeOptions.EncodeUtf16Le = true;
            serializeOptions.Padding = extraSpace;
            xmpMeta = XmpMetaFactory.Create();
            xmpMeta.ObjectName = XmpConst.TAG_XMPMETA;
            xmpMeta.ObjectName = "";
            try {
                xmpMeta.SetProperty(XmpConst.NS_DC, DublinCoreProperties.FORMAT, "application/pdf");
                xmpMeta.SetProperty(XmpConst.NS_PDF, PdfProperties.PRODUCER, Version.GetInstance().GetVersion);
            }
            catch (XmpException) {}
        }
Exemple #46
0
        /**
         * Adds keywords.
         *
         * @param xmpMeta
         * @param keywords
         */

        public static void SetKeywords(IXmpMeta xmpMeta, String keywords) {
            xmpMeta.SetProperty(XmpConst.NS_PDF, KEYWORDS, keywords);
        }
Exemple #47
0
 /// <summary>Remove multiple properties from an XMP object.</summary>
 /// <remarks>
 /// Remove multiple properties from an XMP object.
 /// RemoveProperties was created to support the File Info dialog's Delete
 /// button, and has been been generalized somewhat from those specific needs.
 /// It operates in one of three main modes depending on the schemaNS and
 /// propName parameters:
 /// <list type="bullet">
 /// <item> Non-empty <c>schemaNS</c> and <c>propName</c> - The named property is
 /// removed if it is an external property, or if the
 /// flag <c>doAllProperties</c> option is true. It does not matter whether the
 /// named property is an actual property or an alias.</item>
 /// <item> Non-empty <c>schemaNS</c> and empty <c>propName</c> - The all external
 /// properties in the named schema are removed. Internal properties are also
 /// removed if the flag <c>doAllProperties</c> option is set. In addition,
 /// aliases from the named schema will be removed if the flag <c>includeAliases</c>
 /// option is set.</item>
 /// <item> Empty <c>schemaNS</c> and empty <c>propName</c> - All external properties in
 /// all schema are removed. Internal properties are also removed if the
 /// flag <c>doAllProperties</c> option is passed. Aliases are implicitly handled
 /// because the associated actuals are internal if the alias is.</item>
 /// </list>
 /// It is an error to pass an empty <c>schemaNS</c> and non-empty <c>propName</c>.
 /// </remarks>
 /// <param name="xmp">The XMP object containing the properties to be removed.</param>
 /// <param name="schemaNs">
 /// Optional schema namespace URI for the properties to be
 /// removed.
 /// </param>
 /// <param name="propName">Optional path expression for the property to be removed.</param>
 /// <param name="doAllProperties">
 /// Option flag to control the deletion: do internal properties in
 /// addition to external properties.
 /// </param>
 /// <param name="includeAliases">
 /// Option flag to control the deletion:
 /// Include aliases in the "named schema" case above.
 /// <em>Note:</em> Currently not supported.
 /// </param>
 /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
 /// <exception cref="XmpException"/>
 public static void RemoveProperties(IXmpMeta xmp, string schemaNs, string propName, bool doAllProperties, bool includeAliases)
 {
     Impl.XmpUtils.RemoveProperties(xmp, schemaNs, propName, doAllProperties, includeAliases);
 }
Exemple #48
0
        /**
         * Adds the producer.
         *
         * @param xmpMeta
         * @param producer
         */

        public static void SetProducer(IXmpMeta xmpMeta, String producer) {
            xmpMeta.SetProperty(XmpConst.NS_PDF, PRODUCER, producer);
        }
Exemple #49
0
 /// <summary>Create a single edit string from an array of strings.</summary>
 /// <param name="xmp">The XMP object containing the array to be catenated.</param>
 /// <param name="schemaNs">
 /// The schema namespace URI for the array. Must not be null or
 /// the empty string.
 /// </param>
 /// <param name="arrayName">
 /// The name of the array. May be a general path expression, must
 /// not be null or the empty string. Each item in the array must
 /// be a simple string value.
 /// </param>
 /// <param name="separator">
 /// The string to be used to separate the items in the catenated
 /// string. Defaults to &quot;; &quot;, ASCII semicolon and space
 /// (U+003B, U+0020).
 /// </param>
 /// <param name="quotes">
 /// The characters to be used as quotes around array items that
 /// contain a separator. Defaults to &apos;&quot;&apos;
 /// </param>
 /// <param name="allowCommas">Option flag to control the catenation.</param>
 /// <returns>Returns the string containing the catenated array items.</returns>
 /// <exception cref="XmpException">Forwards the Exceptions from the metadata processing</exception>
 /// <exception cref="XmpException"/>
 public static string CatenateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string separator, string quotes, bool allowCommas)
 {
     return Impl.XmpUtils.CatenateArrayItems(xmp, schemaNs, arrayName, separator, quotes, allowCommas);
 }
Exemple #50
0
        /**
         * Adds the version.
         *
         * @param xmpMeta
         * @param version
         */

        public static void SetVersion(IXmpMeta xmpMeta, String version) {
            xmpMeta.SetProperty(XmpConst.NS_PDF, VERSION, version);
        }
 /// <summary>
 /// The initial support for WAV files mapped a legacy ID3 audio copyright
 /// into a new xmpDM:copyright property.
 /// </summary>
 /// <remarks>
 /// The initial support for WAV files mapped a legacy ID3 audio copyright
 /// into a new xmpDM:copyright property. This is special case code to migrate
 /// that into dc:rights['x-default']. The rules:
 /// <pre>
 /// 1. If there is no dc:rights array, or an empty array -
 /// Create one with dc:rights['x-default'] set from double linefeed and xmpDM:copyright.
 /// 2. If there is a dc:rights array but it has no x-default item -
 /// Create an x-default item as a copy of the first item then apply rule #3.
 /// 3. If there is a dc:rights array with an x-default item,
 /// Look for a double linefeed in the value.
 /// A. If no double linefeed, compare the x-default value to the xmpDM:copyright value.
 /// A1. If they match then leave the x-default value alone.
 /// A2. Otherwise, append a double linefeed and
 /// the xmpDM:copyright value to the x-default value.
 /// B. If there is a double linefeed, compare the trailing text to the xmpDM:copyright value.
 /// B1. If they match then leave the x-default value alone.
 /// B2. Otherwise, replace the trailing x-default text with the xmpDM:copyright value.
 /// 4. In all cases, delete the xmpDM:copyright property.
 /// </pre>
 /// </remarks>
 /// <param name="xmp">the metadata object</param>
 /// <param name="dmCopyright">the "dm:copyright"-property</param>
 private static void MigrateAudioCopyright(IXmpMeta xmp, XmpNode dmCopyright)
 {
     try
     {
         var dcSchema = XmpNodeUtils.FindSchemaNode(((XmpMeta)xmp).GetRoot(), XmpConstants.NsDC, true);
         var dmValue = dmCopyright.Value;
         var doubleLf = "\n\n";
         var dcRightsArray = XmpNodeUtils.FindChildNode(dcSchema, "dc:rights", false);
         if (dcRightsArray == null || !dcRightsArray.HasChildren)
         {
             // 1. No dc:rights array, create from double linefeed and xmpDM:copyright.
             dmValue = doubleLf + dmValue;
             xmp.SetLocalizedText(XmpConstants.NsDC, "rights", string.Empty, XmpConstants.XDefault, dmValue, null);
         }
         else
         {
             var xdIndex = XmpNodeUtils.LookupLanguageItem(dcRightsArray, XmpConstants.XDefault);
             if (xdIndex < 0)
             {
                 // 2. No x-default item, create from the first item.
                 var firstValue = dcRightsArray.GetChild(1).Value;
                 xmp.SetLocalizedText(XmpConstants.NsDC, "rights", string.Empty, XmpConstants.XDefault, firstValue, null);
                 xdIndex = XmpNodeUtils.LookupLanguageItem(dcRightsArray, XmpConstants.XDefault);
             }
             // 3. Look for a double linefeed in the x-default value.
             var defaultNode = dcRightsArray.GetChild(xdIndex);
             var defaultValue = defaultNode.Value;
             var lfPos = defaultValue.IndexOf(doubleLf);
             if (lfPos < 0)
             {
                 // 3A. No double LF, compare whole values.
                 if (!dmValue.Equals(defaultValue))
                 {
                     // 3A2. Append the xmpDM:copyright to the x-default
                     // item.
                     defaultNode.Value = defaultValue + doubleLf + dmValue;
                 }
             }
             else
             {
                 // 3B. Has double LF, compare the tail.
                 if (!defaultValue.Substring (lfPos + 2).Equals(dmValue))
                 {
                     // 3B2. Replace the x-default tail.
                     defaultNode.Value = defaultValue.Substring (0, lfPos + 2 - 0) + dmValue;
                 }
             }
         }
         // 4. Get rid of the xmpDM:copyright.
         dmCopyright.Parent.RemoveChild(dmCopyright);
     }
     catch (XmpException)
     {
     }
 }
        /**
         * Sets a subject.
         *
         * @param xmpMeta
         * @param subject array of subjects
         */

        public static void SetSubject(IXmpMeta xmpMeta, String[] subject) {
            XmpUtils.RemoveProperties(xmpMeta, XmpConst.NS_DC, SUBJECT, true, true);
            for (int i = 0; i < subject.Length; i++) {
                xmpMeta.AppendArrayItem(XmpConst.NS_DC, SUBJECT, new PropertyOptions(PropertyOptions.ARRAY), subject[i],
                                        null);
            }
        }
        /**
         * Sets a title.
         *
         * @param xmpMeta
         * @param title
         * @param genericLang  The name of the generic language
         * @param specificLang The name of the specific language
         */

        public static void SetTitle(IXmpMeta xmpMeta, String title, String genericLang, String specificLang) {
            xmpMeta.SetLocalizedText(XmpConst.NS_DC, TITLE, genericLang, specificLang, title);
        }
        /**
         * Adds a subject.
         *
         * @param xmpMeta
         * @param subject
         */

        public static void AddSubject(IXmpMeta xmpMeta, String subject) {
            xmpMeta.AppendArrayItem(XmpConst.NS_DC, SUBJECT, new PropertyOptions(PropertyOptions.ARRAY), subject, null);
        }
Exemple #55
0
        /// <param name="xmp">The XMP object containing the properties to be removed.</param>
        /// <param name="schemaNs">
        /// Optional schema namespace URI for the properties to be
        /// removed.
        /// </param>
        /// <param name="propName">Optional path expression for the property to be removed.</param>
        /// <param name="doAllProperties">
        /// Option flag to control the deletion: do internal properties in
        /// addition to external properties.
        /// </param>
        /// <param name="includeAliases">
        /// Option flag to control the deletion: Include aliases in the
        /// "named schema" case above.
        /// </param>
        /// <exception cref="XmpException">If metadata processing fails</exception>
        public static void RemoveProperties(IXmpMeta xmp, string schemaNs, string propName, bool doAllProperties, bool includeAliases)
        {
            ParameterAsserts.AssertImplementation(xmp);

            var xmpImpl = (XmpMeta)xmp;
            if (!string.IsNullOrEmpty(propName))
            {
                // Remove just the one indicated property. This might be an alias,
                // the named schema might not actually exist. So don't lookup the
                // schema node.
                if (string.IsNullOrEmpty(schemaNs))
                    throw new XmpException("Property name requires schema namespace", XmpErrorCode.BadParam);

                var expPath = XmpPathParser.ExpandXPath(schemaNs, propName);
                var propNode = XmpNodeUtils.FindNode(xmpImpl.GetRoot(), expPath, false, null);
                if (propNode != null)
                {
                    if (doAllProperties || !Utils.IsInternalProperty(expPath.GetSegment(XmpPath.StepSchema).Name, expPath.GetSegment(XmpPath.StepRootProp).Name))
                    {
                        var parent = propNode.Parent;
                        parent.RemoveChild(propNode);
                        if (parent.Options.IsSchemaNode && !parent.HasChildren)
                        {
                            // remove empty schema node
                            parent.Parent.RemoveChild(parent);
                        }
                    }
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(schemaNs))
                {
                    // Remove all properties from the named schema. Optionally include
                    // aliases, in which case
                    // there might not be an actual schema node.
                    // XMP_NodePtrPos schemaPos;
                    var schemaNode = XmpNodeUtils.FindSchemaNode(xmpImpl.GetRoot(), schemaNs, false);

                    if (schemaNode != null && RemoveSchemaChildren(schemaNode, doAllProperties))
                        xmpImpl.GetRoot().RemoveChild(schemaNode);

                    if (includeAliases)
                    {
                        // We're removing the aliases also. Look them up by their namespace prefix.
                        // But that takes more code and the extra speed isn't worth it.
                        // Lookup the XMP node from the alias, to make sure the actual exists.
                        foreach (var info in XmpMetaFactory.SchemaRegistry.FindAliases(schemaNs))
                        {
                            var path = XmpPathParser.ExpandXPath(info.Namespace, info.PropName);
                            var actualProp = XmpNodeUtils.FindNode(xmpImpl.GetRoot(), path, false, null);
                            if (actualProp != null)
                                actualProp.Parent.RemoveChild(actualProp);
                        }
                    }
                }
                else
                {
                    // Remove all appropriate properties from all schema. In this case
                    // we don't have to be
                    // concerned with aliases, they are handled implicitly from the
                    // actual properties.
                    for (var it = xmpImpl.GetRoot().IterateChildren(); it.HasNext(); )
                    {
                        var schema = (XmpNode)it.Next();
                        if (RemoveSchemaChildren(schema, doAllProperties))
                            it.Remove();
                    }
                }
            }
        }
Exemple #56
0
 /// <summary>
 /// Asserts that the xmp object is of this implemention
 /// (<seealso cref="XmpMetaImpl"/>). </summary>
 /// <param name="xmp"> the XMP object </param>
 /// <exception cref="XmpException"> A wrong implentaion is used. </exception>
 public static void AssertImplementation(IXmpMeta xmp) {
     if (xmp == null) {
         throw new XmpException("Parameter must not be null", XmpError.BADPARAM);
     }
     if (!(xmp is XmpMetaImpl)) {
         throw new XmpException("The XMPMeta-object is not compatible with this implementation",
                                XmpError.BADPARAM);
     }
 }
Exemple #57
0
        /// <seealso cref= XMPUtils#removeProperties(XMPMeta, String, String, boolean, boolean)
        /// </seealso>
        /// <param name="xmp">
        ///            The XMP object containing the properties to be removed.
        /// </param>
        /// <param name="schemaNs">
        ///            Optional schema namespace URI for the properties to be
        ///            removed.
        /// </param>
        /// <param name="propName">
        ///            Optional path expression for the property to be removed.
        /// </param>
        /// <param name="doAllProperties">
        ///            Option flag to control the deletion: do internal properties in
        ///            addition to external properties. </param>
        /// <param name="includeAliases">
        ///            Option flag to control the deletion: Include aliases in the
        ///            "named schema" case above. </param>
        /// <exception cref="XmpException"> If metadata processing fails </exception>
        public static void RemoveProperties(IXmpMeta xmp, string schemaNs, string propName, bool doAllProperties,
                                            bool includeAliases) {
            ParameterAsserts.AssertImplementation(xmp);
            XmpMetaImpl xmpImpl = (XmpMetaImpl) xmp;

            if (!string.IsNullOrEmpty(propName)) {
                // Remove just the one indicated property. This might be an alias,
                // the named schema might not actually exist. So don't lookup the
                // schema node.

                if (string.IsNullOrEmpty(schemaNs)) {
                    throw new XmpException("Property name requires schema namespace", XmpError.BADPARAM);
                }

                XmpPath expPath = XmpPathParser.ExpandXPath(schemaNs, propName);

                XmpNode propNode = XmpNodeUtils.FindNode(xmpImpl.Root, expPath, false, null);
                if (propNode != null) {
                    if (doAllProperties ||
                        !Utils.IsInternalProperty(expPath.GetSegment((int) XmpPath.STEP_SCHEMA).Name,
                                                  expPath.GetSegment((int) XmpPath.STEP_ROOT_PROP).Name)) {
                        XmpNode parent = propNode.Parent;
                        parent.RemoveChild(propNode);
                        if (parent.Options.SchemaNode && !parent.HasChildren()) {
                            // remove empty schema node
                            parent.Parent.RemoveChild(parent);
                        }
                    }
                }
            }
            else if (!string.IsNullOrEmpty(schemaNs)) {
                // Remove all properties from the named schema. Optionally include
                // aliases, in which case
                // there might not be an actual schema node.

                // XMP_NodePtrPos schemaPos;
                XmpNode schemaNode = XmpNodeUtils.FindSchemaNode(xmpImpl.Root, schemaNs, false);
                if (schemaNode != null) {
                    if (RemoveSchemaChildren(schemaNode, doAllProperties)) {
                        xmpImpl.Root.RemoveChild(schemaNode);
                    }
                }

                if (includeAliases) {
                    // We're removing the aliases also. Look them up by their
                    // namespace prefix.
                    // But that takes more code and the extra speed isn't worth it.
                    // Lookup the XMP node
                    // from the alias, to make sure the actual exists.

                    IXmpAliasInfo[] aliases = XmpMetaFactory.SchemaRegistry.FindAliases(schemaNs);
                    for (int i = 0; i < aliases.Length; i++) {
                        IXmpAliasInfo info = aliases[i];
                        XmpPath path = XmpPathParser.ExpandXPath(info.Namespace, info.PropName);
                        XmpNode actualProp = XmpNodeUtils.FindNode(xmpImpl.Root, path, false, null);
                        if (actualProp != null) {
                            XmpNode parent = actualProp.Parent;
                            parent.RemoveChild(actualProp);
                        }
                    }
                }
            }
            else {
                // Remove all appropriate properties from all schema. In this case
                // we don't have to be
                // concerned with aliases, they are handled implicitly from the
                // actual properties.
                ArrayList schemasToRemove = new ArrayList();
                for (IEnumerator it = xmpImpl.Root.IterateChildren(); it.MoveNext();) {
                    XmpNode schema = (XmpNode) it.Current;
                    if (schema == null)
                        continue;
                    if (RemoveSchemaChildren(schema, doAllProperties)) {
                        schemasToRemove.Add(schema);
                    }
                }
                foreach (XmpNode xmpNode in schemasToRemove) {
                    xmpImpl.Root.Children.Remove(xmpNode);
                }
                schemasToRemove.Clear();
            }
        }
Exemple #58
0
        /// <seealso cref= XMPUtils#catenateArrayItems(XMPMeta, String, String, String, String,
        ///      boolean)
        /// </seealso>
        /// <param name="xmp">
        ///            The XMP object containing the array to be catenated. </param>
        /// <param name="schemaNs">
        ///            The schema namespace URI for the array. Must not be null or
        ///            the empty string. </param>
        /// <param name="arrayName">
        ///            The name of the array. May be a general path expression, must
        ///            not be null or the empty string. Each item in the array must
        ///            be a simple string value. </param>
        /// <param name="separator">
        ///            The string to be used to separate the items in the catenated
        ///            string. Defaults to &quot;; &quot;, ASCII semicolon and space
        ///            (U+003B, U+0020). </param>
        /// <param name="quotes">
        ///            The characters to be used as quotes around array items that
        ///            contain a separator. Defaults to &apos;&quot;&apos; </param>
        /// <param name="allowCommas">
        ///            Option flag to control the catenation. </param>
        /// <returns> Returns the string containing the catenated array items. </returns>
        /// <exception cref="XmpException">
        ///             Forwards the Exceptions from the metadata processing </exception>
        public static string CatenateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string separator,
                                                string quotes, bool allowCommas) {
            ParameterAsserts.AssertSchemaNs(schemaNs);
            ParameterAsserts.AssertArrayName(arrayName);
            ParameterAsserts.AssertImplementation(xmp);
            if (string.IsNullOrEmpty(separator)) {
                separator = "; ";
            }
            if (string.IsNullOrEmpty(quotes)) {
                quotes = "\"";
            }

            XmpMetaImpl xmpImpl = (XmpMetaImpl) xmp;

            // Return an empty result if the array does not exist, 
            // hurl if it isn't the right form.
            XmpPath arrayPath = XmpPathParser.ExpandXPath(schemaNs, arrayName);
            XmpNode arrayNode = XmpNodeUtils.FindNode(xmpImpl.Root, arrayPath, false, null);
            if (arrayNode == null) {
                return "";
            }
            if (!arrayNode.Options.Array || arrayNode.Options.ArrayAlternate) {
                throw new XmpException("Named property must be non-alternate array", XmpError.BADPARAM);
            }

            // Make sure the separator is OK.
            CheckSeparator(separator);
            // Make sure the open and close quotes are a legitimate pair.
            char openQuote = quotes[0];
            char closeQuote = CheckQuotes(quotes, openQuote);

            // Build the result, quoting the array items, adding separators.
            // Hurl if any item isn't simple.

            StringBuilder catinatedString = new StringBuilder();

            for (IEnumerator it = arrayNode.IterateChildren(); it.MoveNext();) {
                XmpNode currItem = (XmpNode)it.Current;
                if (currItem == null)
                    continue;
                if (currItem.Options.CompositeProperty) {
                    throw new XmpException("Array items must be simple", XmpError.BADPARAM);
                }
                string str = ApplyQuotes(currItem.Value, openQuote, closeQuote, allowCommas);

                catinatedString.Append(str);
                if (it.MoveNext()) {
                    catinatedString.Append(separator);
                }
            }

            return catinatedString.ToString();
        }
        /**
         * Adds a title.
         *
         * @param xmpMeta
         * @param title
         */

        public static void AddTitle(IXmpMeta xmpMeta, String title) {
            xmpMeta.AppendArrayItem(XmpConst.NS_DC, TITLE, new PropertyOptions(PropertyOptions.ARRAY_ALTERNATE), title,
                                    null);
        }
Exemple #60
0
        /// <seealso cref= XMPUtils#appendProperties(XMPMeta, XMPMeta, boolean, boolean) </seealso>
        /// <param name="source"> The source XMP object. </param>
        /// <param name="destination"> The destination XMP object. </param>
        /// <param name="doAllProperties"> Do internal properties in addition to external properties. </param>
        /// <param name="replaceOldValues"> Replace the values of existing properties. </param>
        /// <param name="deleteEmptyValues"> Delete destination values if source property is empty. </param>
        /// <exception cref="XmpException"> Forwards the Exceptions from the metadata processing </exception>
        public static void AppendProperties(IXmpMeta source, IXmpMeta destination, bool doAllProperties,
                                            bool replaceOldValues, bool deleteEmptyValues) {
            ParameterAsserts.AssertImplementation(source);
            ParameterAsserts.AssertImplementation(destination);

            XmpMetaImpl src = (XmpMetaImpl) source;
            XmpMetaImpl dest = (XmpMetaImpl) destination;

            for (IEnumerator it = src.Root.IterateChildren(); it.MoveNext();) {
                XmpNode sourceSchema = (XmpNode) it.Current;
                if (sourceSchema == null)
                    continue;
                // Make sure we have a destination schema node
                XmpNode destSchema = XmpNodeUtils.FindSchemaNode(dest.Root, sourceSchema.Name, false);
                bool createdSchema = false;
                if (destSchema == null) {
                    PropertyOptions propertyOptions = new PropertyOptions();
                    propertyOptions.SchemaNode = true;
                    destSchema = new XmpNode(sourceSchema.Name, sourceSchema.Value,
                                             propertyOptions);
                    dest.Root.AddChild(destSchema);
                    createdSchema = true;
                }

                // Process the source schema's children.			
                for (IEnumerator ic = sourceSchema.IterateChildren(); ic.MoveNext();) {
                    XmpNode sourceProp = (XmpNode) ic.Current;
                    if (sourceProp == null)
                        continue;
                    if (doAllProperties || !Utils.IsInternalProperty(sourceSchema.Name, sourceProp.Name)) {
                        AppendSubtree(dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues);
                    }
                }

                if (!destSchema.HasChildren() && (createdSchema || deleteEmptyValues)) {
                    // Don't create an empty schema / remove empty schema.
                    dest.Root.RemoveChild(destSchema);
                }
            }
        }