c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

embedded_xmp.rs (2206B)


      1 // Copyright 2022 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 // each license.
     13 
     14 use std::path::Path;
     15 
     16 use tracing::error;
     17 use xmp_toolkit::{OpenFileOptions, XmpError, XmpErrorType, XmpFile, XmpMeta};
     18 
     19 use crate::{Error, Result};
     20 
     21 /// Add the URI for the active manifest to the XMP packet for a file.
     22 ///
     23 /// This will replace any existing `dc:provenance` term
     24 /// in the file's metadata, or create a new one if necessary.
     25 ///
     26 /// This does not check the claim at all; it is presumed
     27 /// that the string that is passed is a valid signed claim.
     28 pub(crate) fn add_manifest_uri_to_file<P: AsRef<Path>>(path: P, manifest_uri: &str) -> Result<()> {
     29     XmpMeta::register_namespace("http://purl.org/dc/terms/", "dcterms").map_err(xmp_write_err)?;
     30 
     31     let mut f = XmpFile::new().map_err(xmp_write_err)?;
     32 
     33     f.open_file(path, OpenFileOptions::default().for_update())
     34         .map_err(xmp_write_err)?;
     35 
     36     let mut m = match f.xmp() {
     37         Some(m) => m,
     38         None => XmpMeta::new().map_err(xmp_write_err)?,
     39     };
     40 
     41     m.set_property(
     42         "http://purl.org/dc/terms/",
     43         "provenance",
     44         &manifest_uri.into(),
     45     )
     46     .map_err(xmp_write_err)?;
     47 
     48     f.put_xmp(&m).map_err(xmp_write_err)?;
     49     f.close();
     50 
     51     Ok(())
     52 }
     53 
     54 fn xmp_write_err(err: XmpError) -> crate::Error {
     55     error!("Unable to add manifest URI to file: {:?}", err);
     56     match err.error_type {
     57         // convert to OS permission error code so we can detect it correctly upstream
     58         XmpErrorType::FilePermission => Error::IoError(std::io::Error::from_raw_os_error(13)),
     59         XmpErrorType::NoFile => Error::NotFound,
     60         XmpErrorType::NoFileHandler => Error::UnsupportedType,
     61         _ => Error::XmpWriteError,
     62     }
     63 }