static VALUE image_hash_for(VALUE self, VALUE _filename) { char * filename = StringValuePtr(_filename); ulong64 hash; if (-1 == ph_dct_imagehash(filename, hash)) { rb_raise(rb_eRuntimeError, "Unknown pHash error"); } return ULL2NUM(hash); }
static void * nogvl_hash(struct nogvl_hash_args * args) { ulong64 hash; args->retval = ph_dct_imagehash(args->filename, hash); args->hash = hash; return NULL; }
void *ph_image_thread(void *p) { slice *s = (slice *)p; for(int i = 0; i < s->n; ++i) { DP *dp = (DP *)s->hash_p[i]; ulong64 hash; int ret = ph_dct_imagehash(dp->id, hash); dp->hash = (ulong64*)malloc(sizeof(hash)); memcpy(dp->hash, &hash, sizeof(hash)); dp->hash_length = 1; } }
JNIEXPORT jobject JNICALL Java_org_phash_pHash_dctImageHash (JNIEnv *e, jclass cl, jstring f) { const char *file = e->GetStringUTFChars(f,0); ulong64 hash; ph_dct_imagehash(file, hash); jobject imageHash = e->NewObject(dctImClass, dctImCtor); e->SetObjectField(imageHash, hash_filename, f); e->SetLongField(imageHash, dctImHash_hash, (jlong)hash); e->ReleaseStringUTFChars(f,file); return imageHash; }
int main(int argc, char **argv) { int option = 0; char *mvp_filename = NULL; char *image_filename = NULL; ulong64 hashvalue = 0; float radius = 21; const int knearest = 5; while ((option = getopt (argc, argv, "f:h:i:r:")) != -1) { switch (option) { case 'f': mvp_filename = optarg; break; case 'h': sscanf(optarg, "%llx", &hashvalue); break; case 'i': image_filename = optarg; break; case 'r': radius = atof(optarg); break; case '?': if (optopt == 'f' || optopt == 'h' || optopt == 'i' || optopt == 'r') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return -1; default: print_usage(); return -1; } } if (mvp_filename == NULL || (hashvalue == 0 && image_filename == NULL)) { print_usage(); return -1; } if (image_filename != NULL) { const char *name = strrchr(image_filename, '/') + 1; if (ph_dct_imagehash(image_filename, hashvalue) < 0) { return -1; } } MVPDP *points = dp_alloc(MVP_UINT64ARRAY); points->id = strdup("0"); points->data = malloc(1*MVP_UINT64ARRAY); points->datalen = 1; memcpy(points->data, &hashvalue, MVP_UINT64ARRAY); MVPError err; CmpFunc distance_func = hamming_distance_cb; MVPTree *tree = mvptree_read(mvp_filename, distance_func, MVP_BRANCHFACTOR, MVP_PATHLENGTH,\ MVP_LEAFCAP, &err); assert(tree); unsigned int nbresults; MVPDP **results = mvptree_retrieve(tree, points, knearest,\ radius, &nbresults, &err); if (nbresults > 0) { for (int j=0 ; j != nbresults; ++j) { printf("%s", results[j]->id); if (j < (nbresults-1)) printf(","); } } free(results); mvptree_clear(tree, free); return 0; }
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; }
int main(int argc, char **argv){ if (argc < 3){ printf("not enough input args\n"); printf("usage: %s directory dbname [radius] [knearest] [threshold]\n", argv[0]); return -1; } const char *dir_name = argv[1];/* name of files in directory of query images */ const char *filename = argv[2];/* name of file to save db */ MVPFile mvpfile; mvpfile.filename = strdup(filename); mvpfile.hashdist = distancefunc; mvpfile.hash_type = UINT64ARRAY; int nbfiles = 0; printf("using db %s\n", filename); printf("using dir %s for query files\n", dir_name); char **files = ph_readfilenames(dir_name,nbfiles); if (!files){ printf("unable to read files from directory\n"); return -2; } printf("nb query files = %d\n", nbfiles); DP *query = ph_malloc_datapoint(mvpfile.hash_type); if (query == NULL){ printf("mem alloc error\n"); return -3; } float radius = 30.0f; float threshold = 15.0f; int knearest = 20; if (argc >= 4){ radius = atof(argv[3]); } if (argc >= 5){ knearest = atoi(argv[4]); } if (argc >= 6){ threshold = atof(argv[5]); } printf("radius = %f\n", radius); printf("knearest = %d\n", knearest); printf("threshold = %f\n", threshold); DP **results = (DP**)malloc(knearest*sizeof(DP*)); if (results == NULL){ return -3; } ulong64 tmphash = 0x0000000000000000; int nbfound = 0, count = 0, sum_calcs = 0; for (int i=0;i<nbfiles;i++){ if (ph_dct_imagehash(files[i],tmphash) < 0){ printf("unable to get hash\n"); continue; } printf("query[%d]: %s %llx\n", i, files[i], tmphash); query->id = files[i]; query->hash = &tmphash; query->hash_length = 1; nb_calcs = 0; nbfound = 0; MVPRetCode retcode = ph_query_mvptree(&mvpfile,query,knearest,radius,threshold,results,nbfound); if (retcode != PH_SUCCESS && retcode != PH_ERRCAP){ printf("could not complete query, %d\n",retcode); continue; } count++; sum_calcs += nb_calcs; printf(" %d files found\n", nbfound); for (int j=0;j<nbfound;j++){ float d = distancefunc(query, results[j]); printf(" %d %s distance = %f\n", j, results[j]->id, d); } printf("nb distance calcs: %d\n", nb_calcs); for (int j=0;j<nbfound;j++){ free(results[j]->id); results[j]->id = NULL; free(results[j]->hash); results[j]->id = NULL; ph_free_datapoint(results[j]); } } float ave_calcs = (float)sum_calcs/(float)count; printf("ave calcs/query: %f\n", ave_calcs); for (int i=0;i<nbfiles;i++){ free(files[i]); } free(files); ph_free_datapoint(query); free(results); free(mvpfile.filename); return 0; }
ulong64 compute_hash(const char* file) { ulong64 hash = 0; ph_dct_imagehash(file, hash); return hash; }
int main(int argc, char **argv){ if (argc < 3){ printf("not enough input args\n"); printf("usage: %s directory filename\n", argv[0]); return -1; } const char *dir_name = argv[1];/* name of dir to retrieve image files */ const char *filename = argv[2];/* name of file to save db */ MVPFile mvpfile; mvpfile.filename = strdup(filename); mvpfile.hashdist = distancefunc; mvpfile.hash_type = UINT64ARRAY; int nbfiles = 0; printf("dir name: %s\n", dir_name); char **files = ph_readfilenames(dir_name,nbfiles); if (!files){ printf("mem alloc error\n"); return -2; } printf("nbfiles = %d\n", nbfiles); DP **hashlist = (DP**)malloc(nbfiles*sizeof(DP*)); if (!hashlist){ printf("mem alloc error\n"); return -3; } int count = 0; ulong64 tmphash = 0; for (int i=0;i<nbfiles;i++){ hashlist[count] = ph_malloc_datapoint(mvpfile.hash_type); if (hashlist[count] == NULL){ printf("mem alloc error\n"); return -4; } hashlist[count]->hash = malloc(sizeof(ulong64)); if (hashlist[count]->hash == NULL){ printf("mem alloc error\n"); return -5; } printf("file[%d] = %s\n", i, files[i]); if (ph_dct_imagehash(files[i],tmphash) < 0){ printf("unable to get hash\n"); free(hashlist[count]->hash); ph_free_datapoint(hashlist[count]); continue; } hashlist[count]->id = files[i]; *((ulong64*)hashlist[count]->hash) = tmphash; hashlist[count]->hash_length = 1; count++; } printf("add files to file %s\n", filename); int nbsaved; MVPRetCode ret = ph_add_mvptree(&mvpfile, hashlist, count,nbsaved); printf("number saved %d out of %d, ret code %d\n", nbsaved,count,ret); for (int i=0;i<nbfiles;i++){ free(files[i]); } free(files); for (int i=0;i<nbfiles;i++){ free(hashlist[i]->hash); ph_free_datapoint(hashlist[i]); } free(hashlist); return 0; }