/* * filter eval function to create a thumbnail attribute */ static int f_eval_thumbnailer(lf_obj_handle_t ohandle, void *data) { struct filter_args *fargs = (struct filter_args *)data; RGBImage *img = NULL, *scaledimg = NULL; size_t img_size = 0; int err = 0; double scale = 1.0; int pass = 0; FILE *memstream; char *jpeg_data = NULL; size_t jpeg_len; lf_log(LOGL_TRACE, "f_thumbnailer: enter"); /* read RGB image data */ err = lf_read_attr(ohandle, RGB_IMAGE, &img_size, NULL); if (err && err != ENOMEM) { lf_log(LOGL_ERR, "f_thumbnailer: failed to read img attribute"); return 0; } img = (RGBImage *)malloc(img_size); assert(img); err = lf_read_attr(ohandle, RGB_IMAGE, &img_size, (unsigned char *)img); assert(!err); /* compute scale factor */ scale = dmax(scale, (double)img->width / fargs->width); scale = dmax(scale, (double)img->height / fargs->height); scaledimg = image_gen_image_scale(img, (int)ceil(scale)); if ((scaledimg->height == 0) || (scaledimg->width == 0)) { // fail pass = 1; goto done; } /* compress jpeg */ memstream = open_memstream(&jpeg_data, &jpeg_len); assert(memstream); compress_rgbimage(scaledimg, memstream); fclose(memstream); /* save thumbnail as an attribute */ err = lf_write_attr(ohandle, THUMBNAIL_ATTR, jpeg_len, (unsigned char *)jpeg_data); assert(!err); pass = 1; done: if (img) free(img); if (scaledimg) free(scaledimg); if (jpeg_data) free(jpeg_data); lf_log(LOGL_TRACE, "f_thumbnailer: done"); return pass; }
static int f_eval_xquery (lf_obj_handle_t ohandle, void *filter_args) { XQQuery *query = ((struct ctx *) filter_args)->query; XQQuery *post_query = ((struct ctx *) filter_args)->post_query; // create context objects AutoDelete<DynamicContext> context(query->createDynamicContext()); AutoDelete<DynamicContext> post_context(post_query->createDynamicContext()); // slurp in the entire object size_t len; const void *data; lf_ref_attr(ohandle, "", &len, &data); // parse the document, set it as context item xercesc::MemBufInputSource input_source((const XMLByte *) data, len, X("diamond")); Node::Ptr doc = context->parseDocument(input_source); context->setContextItem(doc); context->setContextPosition(1); context->setContextSize(1); // execute user query Result result = query->execute(context); // convert into diamond attributes, by executing our "post_query" post_context->setContextItem(result->toSequence(context).first()); post_context->setContextPosition(1); post_context->setContextSize(1); bool settingName = true; char *attributeName = NULL; try { Result post_result = post_query->execute(post_context); Item::Ptr item; while(item = post_result->next(post_context)) { char *str = strdup(UTF8(item->asString(post_context))); if (settingName) { attributeName = strdup(str); } else { //std::cout << "writing attribute '" << attributeName << "':'" << str << "'" << std::endl; lf_write_attr(ohandle, attributeName, strlen(str) + 1, (unsigned char *) str); free(attributeName); } free(str); settingName = !settingName; } } catch(XQException &e) { std::cerr << "XQException: " << UTF8(e.getError()) << std::endl; return 0; } return 1; }
static int f_eval_boostldm(lf_obj_handle_t ohandle, void *f_data) { int err; int i; boostldm_config_t *fconfig = (boostldm_config_t *) f_data; size_t featureLen = MAX_ATTR_VALUE; unsigned char featureStr[MAX_ATTR_VALUE]; int numFeatures; double f; double distance = 0; char fname[MAX_ATTR_NAME]; lf_log(LOGL_TRACE, "f_eval_boostldm: enter"); // extract the features for this object err = lf_read_attr(ohandle, NUM_BDMF, &featureLen, featureStr); assert(err == 0); numFeatures = atoi((char *)featureStr); assert(numFeatures == fconfig->numFeatures); for(i=0; i<numFeatures; i++) { sprintf(fname, "%s%02d", BDMF_PREFIX, i); featureLen = MAX_ATTR_VALUE; // reset, o.w. could be too small err = lf_read_attr(ohandle, fname, &featureLen, featureStr); assert(err == 0); f = atof((char *)featureStr); // Given two objects x1[] and x2[], each with 51 bits // The weights (alpha) for each bit are given in a file called attr/alpha. // We can hardcode them into the searchlet. distance += alpha[i] * (fconfig->features[i] != f); } // scale distance to spread out results // int similarity = 200.0 * exp(negDistance) / (1.0 + exp(negDistance)); int similarity = 5000.0 * (.2 - distance - 0.04); printf("distance = %f, similarity %d\n", distance, similarity); // save results as attributes err = lf_write_attr(ohandle, "similarity", sizeof(int), (unsigned char *) &similarity); assert(err == 0); return similarity; }
int f_eval_string (lf_obj_handle_t ohandle, void *filter_args) { context_t *ctx = (context_t *) filter_args; const char *target_str = ctx->target_str; int result = 0; // slurp in the object size_t len; const void *data; lf_ref_attr(ohandle, "", &len, &data); char *source = malloc(len + 1); if (source == NULL) { return 0; } memcpy(source, data, len); source[len] = '\0'; char *strstr_result = strstr(source, target_str); if (strstr_result != NULL) { // found, get index int index = strstr_result - source; // put into attribute char *index_str; asprintf(&index_str, "%d", index); lf_write_attr(ohandle, "string-index", strlen(index_str) + 1, (unsigned char *) index_str); free(index_str); result = 1; } free(source); return result; }