Ejemplo n.º 1
0
static void set_xmp_prop(const char * filename, const std::string & value_name, 
			 const std::string & prop_value,
			 bool no_reconcile, bool is_an_xmp, bool write_in_place, FILE *outio)
{
	xmp::ScopedPtr<XmpPtr> xmp(get_xmp_from_file(filename, no_reconcile, is_an_xmp));
	
	std::string prefix;
	size_t idx = value_name.find(':');
	if(idx != std::string::npos) {
		prefix = std::string(value_name, 0, idx);
	}

	xmp::ScopedPtr<XmpStringPtr> ns(xmp_string_new());
	xmp_prefix_namespace_uri(prefix.c_str(), ns);
	if(!xmp_set_property(xmp, xmp_string_cstr(ns), value_name.c_str() + idx + 1, prop_value.c_str(), 0)) {
		fprintf(stderr, "set error = %d\n", xmp_get_error());
	}

	if(write_in_place) {
		xmp::ScopedPtr<XmpFilePtr> f(xmp_files_open_new(filename, 
						(XmpOpenFileOptions)(XMP_OPEN_FORUPDATE 
							| (no_reconcile ? XMP_OPEN_ONLYXMP : 0))));
	
		if(!xmp_files_can_put_xmp(f, xmp)) {
			fprintf(stderr, "can put xmp error = %d\n", xmp_get_error());		 				
		}
		if(!xmp_files_put_xmp(f, xmp)) {
			fprintf(stderr, "put xmp error = %d\n", xmp_get_error());		 	
		}
		if(!xmp_files_close(f, XMP_CLOSE_SAFEUPDATE)) {
			fprintf(stderr, "close error = %d\n", xmp_get_error());
		}
	}		
}
Ejemplo n.º 2
0
/**
* Is there any XMP metadata in the map file for us to worry about?
*/
int
msXmpWrite( mapObj *map, const char *filename )
{
#ifdef USE_EXEMPI

  /* Should hold our keys */
  hashTableObj hash_metadata = map->web.metadata;
  /* Temporary place for custom name spaces */
  hashTableObj hash_ns;
  /* We use regex to strip out the namespace and XMP key value from the metadata key */
  regex_t xmp_regex;
  const char *xmp_ns_str = "^xmp_(.+)_namespace$";
  const char *xmp_tag_str = "^xmp_(.+)_(.+)$";
  const char *key = NULL;
  static int regflags = REG_ICASE | REG_EXTENDED;

  /* XMP object and file pointers */
  XmpPtr xmp;
  XmpFilePtr f;

  /* Force the hash table to empty */
  hash_ns.numitems = 0;

  /* Prepare XMP library */
  xmp_init();
  f = xmp_files_open_new(filename, XMP_OPEN_FORUPDATE);
  if ( ! f ) {
    msSetError( MS_MISCERR,
                "Unable to open temporary file '%s' to write XMP info",
                "msXmpWrite()", filename );
    return MS_FAILURE;
  }

  /* Create a new XMP structure if the file doesn't already have one */
  xmp = xmp_files_get_new_xmp(f);
  if ( xmp == NULL )
    xmp = xmp_new_empty();

  /* Check we can write to the file */
  if ( ! xmp_files_can_put_xmp(f, xmp) ) {
    msSetError( MS_MISCERR,
                "Unable to write XMP information to '%s'",
                "msXmpWrite()", filename );
    return MS_FAILURE;
  }

  /* Compile our "xmp_*_namespace" regex */
  if ( regcomp(&xmp_regex, xmp_ns_str, regflags) ) {
    msSetError( MS_MISCERR,
                "Unable compile regex '%s'",
                "msXmpWrite()", xmp_ns_str );
    return MS_FAILURE;
  }

  /* Check all the keys for "xmp_*_namespace" pattern */
  initHashTable(&hash_ns);
  key = msFirstKeyFromHashTable(&hash_metadata);

  /* No first key? No license info. We shouldn't get here. */
  if ( ! key )
    return MS_SUCCESS;

  do {
    /* Our regex has one match slot */
    regmatch_t matches[2];

    /* Found a custom namespace entry! Store it for later. */
    if ( 0 == regexec(&xmp_regex, key, 2, matches, 0) ) {
      size_t ns_size = 0;
      char *ns_name = NULL;
      const char *ns_uri;

      /* Copy in the namespace name */
      ns_size = matches[1].rm_eo - matches[1].rm_so;
      ns_name = msSmallMalloc(ns_size + 1);
      memcpy(ns_name, key + matches[1].rm_so, ns_size);
      ns_name[ns_size] = 0; /* null terminate */

      /* Copy in the namespace uri */
      ns_uri = msLookupHashTable(&hash_metadata, key);
      msInsertHashTable(&hash_ns, ns_name, ns_uri);
      xmp_register_namespace(ns_uri, ns_name, NULL);
      msFree(ns_name);
    }
  } while( (key = msNextKeyFromHashTable(&hash_metadata, key)) );
  /* Clean up regex */
  regfree(&xmp_regex);


  /* Compile our "xmp_*_*" regex */
  if ( regcomp(&xmp_regex, xmp_tag_str, regflags) ) {
    msFreeHashItems(&hash_ns);
    msSetError( MS_MISCERR,
                "Unable compile regex '%s'",
                "msXmpWrite()", xmp_tag_str );
    return MS_FAILURE;
  }

  /* Check all the keys for "xmp_*_*" pattern */
  key = msFirstKeyFromHashTable(&hash_metadata);
  do {
    /* Our regex has two match slots */
    regmatch_t matches[3];

    /* Found a namespace entry! Write it into XMP. */
    if ( 0 == regexec(&xmp_regex, key, 3, matches, 0) ) {
      /* Get the namespace and tag name */
      size_t ns_name_size = matches[1].rm_eo - matches[1].rm_so;
      size_t ns_tag_size = matches[2].rm_eo - matches[2].rm_so;
      char *ns_name = msSmallMalloc(ns_name_size + 1);
      char *ns_tag = msSmallMalloc(ns_tag_size + 1);
      const char *ns_uri = NULL;
      memcpy(ns_name, key + matches[1].rm_so, ns_name_size);
      memcpy(ns_tag, key + matches[2].rm_so, ns_tag_size);
      ns_name[ns_name_size] = 0; /* null terminate */
      ns_tag[ns_tag_size] = 0; /* null terminate */

      if ( strcmp(ns_tag,"namespace") == 0 ) {
        msFree(ns_name);
        msFree(ns_tag);
        continue;
      }

      /* If this is a default name space?... */
      if ( (ns_uri = msXmpUri(ns_name)) ) {
        xmp_register_namespace(ns_uri, ns_name, NULL);
        xmp_set_property(xmp, ns_uri, ns_tag, msLookupHashTable(&hash_metadata, key), 0);
      }
      /* Or maybe it's a custom one?... */
      else if ( (ns_uri = msLookupHashTable(&hash_ns, ns_name)) ) {
        xmp_set_property(xmp, ns_uri, ns_tag, msLookupHashTable(&hash_metadata, key), 0);
      }
      /* Or perhaps we're screwed. */
      else {
        msSetError( MS_MISCERR,
                    "Unable to identify XMP namespace '%s' in metadata key '%s'",
                    "msXmpWrite()", ns_name, key );
        msFreeHashItems(&hash_ns);
        msFree(ns_name);
        msFree(ns_tag);
        return MS_FAILURE;
      }
      msFree(ns_name);
      msFree(ns_tag);
    }
  } while( (key = msNextKeyFromHashTable(&hash_metadata, key)) );

  /* Clean up regex */
  regfree(&xmp_regex);

  /* Write out the XMP */
  if ( !xmp_files_put_xmp(f, xmp) ) {
    msFreeHashItems(&hash_ns);
    msSetError( MS_MISCERR,
                "Unable to execute '%s' on pointer %p",
                "msXmpWrite()", "xmp_files_put_xmp", f );
    return MS_FAILURE;
  }

  /* Write out the file and flush */
  if ( !xmp_files_close(f, XMP_CLOSE_SAFEUPDATE) ) {
    msFreeHashItems(&hash_ns);
    msSetError( MS_MISCERR,
                "Unable to execute '%s' on pointer %p",
                "msXmpWrite()", "xmp_files_close", f );
    return MS_FAILURE;
  }

  msFreeHashItems(&hash_ns);
  xmp_free(xmp);
  xmp_terminate();

  return MS_SUCCESS;

#else
  return MS_FAILURE;
#endif
}