static void load_location (NemoImagePropertiesPage *page, NemoFileInfo *info) { GFile *file; char *uri; FileOpenData *data; g_assert (NEMO_IS_IMAGE_PROPERTIES_PAGE (page)); g_assert (info != NULL); page->details->cancellable = g_cancellable_new (); uri = nemo_file_info_get_uri (info); file = g_file_new_for_uri (uri); #ifdef HAVE_EXEMPI { /* Current Exempi does not support setting custom IO to be able to use Gnome-vfs */ /* So it will only work with local files. Future version might remove this limitation */ XmpFilePtr xf; char *localname; localname = g_filename_from_uri (uri, NULL, NULL); if (localname) { xf = xmp_files_open_new (localname, 0); page->details->xmp = xmp_files_get_new_xmp (xf); /* only load when loading */ xmp_files_close (xf, 0); g_free (localname); } else { page->details->xmp = NULL; } } #endif /*HAVE_EXEMPI*/ data = g_new0 (FileOpenData, 1); data->page = page; data->info = info; g_file_read_async (file, 0, page->details->cancellable, file_open_callback, data); g_object_unref (file); g_free (uri); }
/** Helper to get the XMP for the file */ static XmpPtr get_xmp_from_file(const char * filename, bool no_reconcile, bool is_an_xmp) { if (is_an_xmp) { return get_xmp_from_sidecar(filename, is_an_xmp); } xmp::ScopedPtr<XmpFilePtr> f(xmp_files_open_new(filename, (XmpOpenFileOptions)(XMP_OPEN_READ | (no_reconcile ? XMP_OPEN_ONLYXMP : 0)))); if(f) { XmpPtr xmp = xmp_files_get_new_xmp(f); xmp_files_close(f, XMP_CLOSE_NOOPTION); return xmp; } return NULL; }
static void load_location (CajaImagePropertiesPage *page, const char *location) { GFile *file; g_assert (CAJA_IS_IMAGE_PROPERTIES_PAGE (page)); g_assert (location != NULL); page->details->cancellable = g_cancellable_new (); file = g_file_new_for_uri (location); #ifdef HAVE_EXEMPI { /* Current Exempi does not support setting custom IO to be able to use Mate-vfs */ /* So it will only work with local files. Future version might remove this limitation */ XmpFilePtr xf; char *localname; localname = g_filename_from_uri (location, NULL, NULL); if (localname) { xf = xmp_files_open_new (localname, 0); page->details->xmp = xmp_files_get_new_xmp (xf); /* only load when loading */ xmp_files_close (xf, 0); g_free (localname); } else { page->details->xmp = NULL; } } #endif /*HAVE_EXEMPI*/ g_file_read_async (file, 0, page->details->cancellable, file_open_callback, page); g_object_unref (file); }
//void test_tiff_leak() int test_main(int argc, char *argv[]) { prepare_test(argc, argv, "../../samples/testfiles/BlueSquare.jpg"); std::string orig_tiff_file = g_src_testdir + "../../samples/testfiles/BlueSquare.tif"; std::string command = "cp "; command += orig_tiff_file + " test.tif"; BOOST_CHECK(system(command.c_str()) >= 0); BOOST_CHECK(chmod("test.tif", S_IRUSR|S_IWUSR) == 0); BOOST_CHECK(xmp_init()); XmpFilePtr f = xmp_files_open_new("test.tif", XMP_OPEN_FORUPDATE); BOOST_CHECK(f != NULL); if (f == NULL) { return 1; } XmpPtr xmp; BOOST_CHECK(xmp = xmp_files_get_new_xmp(f)); BOOST_CHECK(xmp != NULL); xmp_set_localized_text(xmp, NS_DC, "description", "en", "en-US", "foo", 0); BOOST_CHECK(xmp_files_put_xmp(f, xmp)); BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_NOOPTION)); BOOST_CHECK(xmp_free(xmp)); BOOST_CHECK(xmp_files_free(f)); xmp_terminate(); BOOST_CHECK(unlink("test.tif") == 0); BOOST_CHECK(!g_lt->check_leaks()); BOOST_CHECK(!g_lt->check_errors()); return 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 }