Mercurial > cgi-bin > hgweb.cgi > JpegWasher
view src/name/blackcap/exifwasher/exiv2/native.cpp @ 60:d0b83fc1d62a default tip
Remember our input directory on a per-invocation basis.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 26 Jul 2020 15:14:03 -0700 |
parents | cd2ca4727b7f |
children |
line wrap: on
line source
#include <jni.h> #include <string.h> #include <exiv2/exiv2.hpp> #include <exception> #include <iostream> #include <iomanip> #include <cassert> /* Functions for class name_blackcap_exifwasher_exiv2_Image */ #ifndef _Included_name_blackcap_exifwasher_exiv2_Image #define _Included_name_blackcap_exifwasher_exiv2_Image #ifdef __cplusplus extern "C" { #endif /* * Utility function to get pointer field. */ Exiv2::Image *getPointer(JNIEnv *jEnv, jobject jThis) { return reinterpret_cast<Exiv2::Image *> (jEnv->GetLongField(jThis, jEnv->GetFieldID(jEnv->GetObjectClass(jThis), "pointer", "J"))); } /* * Class: name_blackcap_exifwasher_exiv2_Image * Method: _ctor * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1ctor (JNIEnv *jEnv, jobject jThis, jstring path) { const char *cPath = jEnv->GetStringUTFChars(path, NULL); jlong ret = 0; try { ret = reinterpret_cast<jlong> (Exiv2::ImageFactory::open(cPath).release()); } catch (std::exception& e) { jEnv->ExceptionClear(); jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception"); jEnv->ThrowNew(ex, e.what()); } jEnv->ReleaseStringUTFChars(path, cPath); return ret; } /* * Class: name_blackcap_exifwasher_exiv2_Image * Method: _writeMetadata * Signature: ()V */ JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1writeMetadata (JNIEnv *jEnv, jobject jThis) { Exiv2::Image *image = getPointer(jEnv, jThis); if (jEnv->ExceptionCheck()) return; try { image->writeMetadata(); } catch (std::exception& e) { jEnv->ExceptionClear(); jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception"); jEnv->ThrowNew(ex, e.what()); } } /* * Class: name_blackcap_exifwasher_exiv2_Image * Method: _getMetadata * Signature: ()J */ JNIEXPORT jlong JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1getMetadata (JNIEnv *jEnv, jobject jThis) { Exiv2::Image *image = getPointer(jEnv, jThis); if (jEnv->ExceptionCheck()) return 0; try { image->readMetadata(); } catch (std::exception& e) { jEnv->ExceptionClear(); jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception"); jEnv->ThrowNew(ex, e.what()); return 0; } return reinterpret_cast<jlong>(image); } /* * Class: name_blackcap_exifwasher_exiv2_Image * Method: _dtor * Signature: ()V */ JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1dtor (JNIEnv *jEnv, jobject jThis) { Exiv2::Image *image = getPointer(jEnv, jThis); if (jEnv->ExceptionCheck()) return; delete image; } #ifdef __cplusplus } #endif #endif /* Header for class name_blackcap_exifwasher_exiv2_ExifData */ /* * Utility function to parse out a type prefix from a key name. */ char *getType(const char *key) { const char *dot = strchr(key, '.'); if (dot == NULL) throw std::invalid_argument(std::string("invalid key: ") + std::string(key)); int length = dot - key; char *ret = (char *) malloc(length + 1); memcpy(ret, key, length); ret[length] = '\0'; return ret; } /* * Utility function to delete a (key, value) pair. */ template<class D, class K> void deleteValue(D &data, const char *key) { typename D::iterator found = data.findKey(K(std::string(key))); data.erase(found); } /* * Utility function to retrieve a value, given a key. */ template<class D, class K> jobject getValue(JNIEnv *jEnv, D &data, const char *key) { typename D::iterator found = data.findKey(K(std::string(key))); if (found == data.end()) { return NULL; } jclass klass = jEnv->FindClass("name/blackcap/exifwasher/exiv2/ExifData$Value"); if (jEnv->ExceptionCheck()) return NULL; jstring type = jEnv->NewStringUTF(found->typeName()); jstring value = jEnv->NewStringUTF(found->toString().c_str()); jmethodID method = jEnv->GetMethodID(klass, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V"); if (jEnv->ExceptionCheck()) return NULL; return jEnv->NewObject(klass, method, type, value); } /* * Utility function to read keys, given a target to put them and a collection * of data. */ template<class D> jsize getKeys(JNIEnv *jEnv, jobjectArray target, jsize start, D &data) { typename D::const_iterator end = data.end(); jsize j = start; for (typename D::const_iterator i = data.begin(); i != end; ++i) { jEnv->SetObjectArrayElement(target, j++, jEnv->NewStringUTF(i->key().c_str())); if (jEnv->ExceptionCheck()) break; } return j; } #ifndef _Included_name_blackcap_exifwasher_exiv2_ExifData #define _Included_name_blackcap_exifwasher_exiv2_ExifData #ifdef __cplusplus extern "C" { #endif /* * Class: name_blackcap_exifwasher_exiv2_ExifData * Method: _erase * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1erase (JNIEnv *jEnv, jobject jThis, jstring key) { Exiv2::Image *image = getPointer(jEnv, jThis); if (jEnv->ExceptionCheck()) return; const char *cKey = jEnv->GetStringUTFChars(key, NULL); char *type = NULL; try { type = getType(cKey); if (!strcmp(type, "Exif")) { deleteValue<Exiv2::ExifData, Exiv2::ExifKey>(image->exifData(), cKey); } else if (!strcmp(type, "Xmp")) { deleteValue<Exiv2::XmpData, Exiv2::XmpKey>(image->xmpData(), cKey); } else if (!strcmp(type, "Iptc")) { deleteValue<Exiv2::IptcData, Exiv2::IptcKey>(image->iptcData(), cKey); } else { throw std::invalid_argument(std::string("invalid key: ") + std::string(cKey)); } } catch (std::exception& e) { jEnv->ExceptionClear(); jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception"); jEnv->ThrowNew(ex, e.what()); } if (type != NULL) free(type); jEnv->ReleaseStringUTFChars(key, cKey); } /* * Class: name_blackcap_exifwasher_exiv2_ExifData * Method: _value * Signature: (Ljava/lang/String;)Lname/blackcap/exifwasher/exiv2/ExifData/Value; */ JNIEXPORT jobject JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1value (JNIEnv *jEnv, jobject jThis, jstring key) { Exiv2::Image *image = getPointer(jEnv, jThis); if (jEnv->ExceptionCheck()) return NULL; const char *cKey = jEnv->GetStringUTFChars(key, NULL); char *type = NULL; jobject ret = NULL; try { type = getType(cKey); if (!strcmp(type, "Exif")) { ret = getValue<Exiv2::ExifData, Exiv2::ExifKey>(jEnv, image->exifData(), cKey); } else if (!strcmp(type, "Xmp")) { ret = getValue<Exiv2::XmpData, Exiv2::XmpKey>(jEnv, image->xmpData(), cKey); } else if (!strcmp(type, "Iptc")) { ret = getValue<Exiv2::IptcData, Exiv2::IptcKey>(jEnv, image->iptcData(), cKey); } else { throw std::invalid_argument(std::string("invalid key: ") + std::string(cKey)); } } catch (std::exception& e) { jEnv->ExceptionClear(); jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception"); jEnv->ThrowNew(ex, e.what()); } if (type != NULL) free(type); jEnv->ReleaseStringUTFChars(key, cKey); return ret; } /* * Class: name_blackcap_exifwasher_exiv2_ExifData * Method: _keys * Signature: ()[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1keys (JNIEnv *jEnv, jobject jThis) { Exiv2::Image *image = getPointer(jEnv, jThis); Exiv2::ExifData eData = image->exifData(); Exiv2::XmpData xData = image->xmpData(); Exiv2::IptcData iData = image->iptcData(); if (jEnv->ExceptionCheck()) return NULL; jclass klass = jEnv->FindClass("java/lang/String"); if (jEnv->ExceptionCheck()) return NULL; jobjectArray ret = jEnv->NewObjectArray(eData.count() + iData.count() + xData.count(), klass, NULL); if (jEnv->ExceptionCheck()) return NULL; jsize start = getKeys(jEnv, ret, 0, eData); if (jEnv->ExceptionCheck()) return NULL; start = getKeys(jEnv, ret, start, xData); if (jEnv->ExceptionCheck()) return NULL; start = getKeys(jEnv, ret, start, iData); if (jEnv->ExceptionCheck()) return NULL; return ret; } #ifdef __cplusplus } #endif #endif