static VALUE image_mhash_for(VALUE self, VALUE _filename) { char * filename = StringValuePtr(_filename); uint8_t *hash; int len; if (NULL == (hash = ph_mh_imagehash(filename, len))) { rb_raise(rb_eRuntimeError, "Unknown pHash error"); } VALUE array = rb_ary_new2(72); for (int i=0; i<72; i++) rb_ary_push(array, CHR2FIX(hash[i])); return array; }
static VALUE mh_hash_for(VALUE self, VALUE filename, VALUE alpha, VALUE lvl) { uint8_t* result; int n; VALUE array; result = ph_mh_imagehash(StringValuePtr(filename), n, NUM2DBL(alpha), NUM2DBL(lvl)); array = rb_ary_new2(n); for(int i = 0; i < n; i++) { rb_ary_push(array, INT2FIX(result[i])); } xfree(result); return array; }
JNIEXPORT jobject JNICALL Java_org_phash_pHash_mhImageHash (JNIEnv *e, jclass cl, jstring f) { const char *file = e->GetStringUTFChars(f,0); int N; uint8_t *hash = ph_mh_imagehash(file, N); jobject imageHash = NULL; if(hash && N > 0) { imageHash = e->NewObject(mhImClass, mhImCtor); e->SetObjectField(imageHash, hash_filename, f); jbyteArray hashVals = e->NewByteArray(N); e->SetByteArrayRegion(hashVals, 0, N, (jbyte *)hash); e->SetObjectField(imageHash, mhImHash_hash, hashVals); free(hash); } e->ReleaseStringUTFChars(f,file); return imageHash; }
JNIEXPORT jboolean JNICALL Java_org_phash_MVPTree_create (JNIEnv *e, jobject ob, jobjectArray hashArray) { jint hashLen; if(hashArray == NULL || (hashLen = e->GetArrayLength(hashArray)) == 0) return JNI_FALSE; jstring mvp = (jstring)e->GetObjectField(ob, e->GetFieldID(e->FindClass("org/phash/MVPTree"), "mvpFile", "Ljava/lang/String;")); MVPFile mvpfile; ph_mvp_init(&mvpfile); mvpfile.filename = strdup(e->GetStringUTFChars(mvp, 0)); jniHashType type; jobject htype = e->GetObjectArrayElement(hashArray, 0); for(int i = 0; i < sizeof(hashes)/sizeof(hashes[0]); i++) { if(e->IsInstanceOf(htype, *hashes[i].cl)) { mvpfile.hashdist = hashes[i].callback; mvpfile.hash_type = hashes[i].hashType; type = hashes[i].kind; break; } } DP **hashlist = (DP **)malloc(hashLen*sizeof(DP*)); for(jsize i = 0; i < hashLen; i++) { jobject hashObj = e->GetObjectArrayElement(hashArray, i); hashlist[i] = ph_malloc_datapoint(mvpfile.hash_type); if(!hashlist[i]) { free(hashlist); e->ReleaseStringUTFChars(mvp, mvpfile.filename); return JNI_FALSE; } jstring fname = (jstring)e->GetObjectField(hashObj, hash_filename); const char *path = e->GetStringUTFChars(fname, 0); hashlist[i]->id = strdup(path); switch(type) { case IMAGE_HASH: if(e->IsInstanceOf(hashObj, dctImClass)) { ulong64 tmphash; ph_dct_imagehash(path, tmphash); hashlist[i]->hash = (ulong64 *)malloc(sizeof(ulong64)); *(ulong64 *)hashlist[i]->hash = tmphash; hashlist[i]->hash_length = 1; } else if(e->IsInstanceOf(hashObj, mhImClass)) { int N; uint8_t *hash = ph_mh_imagehash(path, N); hashlist[i]->hash = hash; hashlist[i]->hash_length = N; } else if(e->IsInstanceOf(hashObj, radialImClass)) { Digest d; if(ph_image_digest(path, 1.0, 1.0, d, 180) >= 0) { hashlist[i]->hash = d.coeffs; hashlist[i]->hash_length = d.size; } } break; case VIDEO_HASH: { int len; ulong64 *vhash = ph_dct_videohash(path, len); if(!vhash) { for(int i = 0; i < hashLen; i++) { if(hashlist[i]) ph_free_datapoint(hashlist[i]); } free(hashlist); e->ReleaseStringUTFChars(mvp, mvpfile.filename); return JNI_FALSE; } hashlist[i]->hash = vhash; hashlist[i]->hash_length = len; } break; case AUDIO_HASH: const float threshold = 0.30; const int block_size = 256; const int sr = 8000; const int channels = 1; int nbframes, N; float *buf = ph_readaudio(path,sr,channels,NULL,N); if(buf) { uint32_t *audioHash = ph_audiohash(buf,N,sr,nbframes); free(buf); hashlist[i]->hash_length = nbframes; hashlist[i]->hash = audioHash; } else { free(hashlist); e->ReleaseStringUTFChars(mvp, mvpfile.filename); return JNI_FALSE; } break; } e->ReleaseStringUTFChars(fname, path); } MVPRetCode ret = ph_save_mvptree(&mvpfile, hashlist, hashLen); for(int i = 0; i < hashLen; i++) { if(hashlist[i]) { free(hashlist[i]->hash); free(hashlist[i]->id); } } free(hashlist); e->ReleaseStringUTFChars(mvp, mvpfile.filename); free(mvpfile.filename); return (int)ret; }