SEXP dotask(SEXP Sclient, SEXP Sfun, SEXP Swork, SEXP Suval, SEXP Sback, SEXP Shigh){ rgearman_client_t *client = (rgearman_client_t *)R_ExternalPtrAddr(Sclient); SEXP ret; const char *fun, *work, *uval; int back, high; fun = (Sfun != R_NilValue)? (const char *)CHAR(STRING_ELT(Sfun,0)) : NULL; work = (Swork != R_NilValue)? (const char *)CHAR(STRING_ELT(Swork,0)) : NULL; uval = (Suval != R_NilValue)? (const char *)CHAR(STRING_ELT(Suval,0)) : NULL; back = LOGICAL(Sback)[0]; high = (Shigh != R_NilValue) ? LOGICAL(Shigh)[0] : -1; if (back){ gearman_return_t (*gm_fun)(gearman_client_st *client, const char *function_name, const char *unique, const void *workload, size_t workload_size, gearman_job_handle_t job_handle); char *job = (char *)R_Calloc(1,gearman_job_handle_t); gm_fun = (high == -1)? gearman_client_do_background : (high)? gearman_client_do_high_background : gearman_client_do_low_background ; client->lastretcode = gm_fun(client->client,fun,uval,work,strlen(work),job); ret = PROTECT(allocVector(STRSXP,1)); SET_STRING_ELT(ret,0,mkChar(job)); R_Free(job); UNPROTECT(1); } else { void *(*gm_fun)(gearman_client_st *client, const char *function_name, const char *unique, const void *workload, size_t workload_size, size_t *result_size, gearman_return_t *ret_ptr); size_t resultsize; void *result; gm_fun = (high == -1)? gearman_client_do : (high)? gearman_client_do_high : gearman_client_do_low ; result = gm_fun(client->client,fun,uval,work,strlen(work),&resultsize,&client->lastretcode); ret = PROTECT(allocVector(STRSXP,1)); SET_STRING_ELT(ret,0,mkCharLen((char *)result,resultsize)); UNPROTECT(1); } return ret; }
SEXP createclient(void){ rgearman_client_t *client; client = (rgearman_client_t *)R_Calloc(1,rgearman_client_t); if (client) client->client = gearman_client_create(NULL); return (client) ? R_MakeExternalPtr(client,R_NilValue,R_NilValue) : R_NilValue; }
SEXP clahe (SEXP x, SEXP _uiNrX, SEXP _uiNrY, SEXP _uiNrBins, SEXP _fCliplimit, SEXP _keepRange) { int nx, ny, nz, i, j; unsigned int uiNrX, uiNrY, uiNrBins; float fCliplimit; int keepRange; double *src, *tgt; SEXP res; kz_pixel_t min = 0, max = uiNR_OF_GREY-1; kz_pixel_t *img; double maxPixelValue = uiNR_OF_GREY-1; PROTECT( res = allocVector(REALSXP, XLENGTH(x)) ); DUPLICATE_ATTRIB(res, x); nx = INTEGER(GET_DIM(x))[0]; ny = INTEGER(GET_DIM(x))[1]; nz = getNumberOfFrames(x, 0); uiNrX = INTEGER(_uiNrX)[0]; uiNrY = INTEGER(_uiNrY)[0]; uiNrBins = INTEGER(_uiNrBins)[0]; fCliplimit = REAL(_fCliplimit)[0]; keepRange = LOGICAL(_keepRange)[0]; img = R_Calloc(nx*ny, kz_pixel_t); // process channels separately for(j = 0; j < nz; j++) { src = &(REAL(x)[j*nx*ny]); tgt = &(REAL(res)[j*nx*ny]); if (keepRange) { min = uiNR_OF_GREY-1; max = 0; } // convert frame to CLAHE-compatible format for (i = 0; i < nx*ny; i++) { double el = src[i]; // clip if (el < 0.0) el = 0; else if (el > 1.0) el = 1.0; // convert to int kz_pixel_t nel = (kz_pixel_t) round(el * maxPixelValue); if (keepRange) { if (nel < min) min = nel; if (nel > max) max = nel; } img[i] = nel; } int val = CLAHE (img, (unsigned int) nx, (unsigned int) ny, min, max, uiNrX, uiNrY, uiNrBins, fCliplimit); // translate internal error codes switch (val) { case -1: error("# of regions x-direction too large"); break; case -2: error("# of regions y-direction too large"); break; case -3: error("x-resolution no multiple of 'nx'"); break; case -4: error("y-resolution no multiple of 'ny'"); break; case -5: error("maximum too large"); break; case -6: error("minimum equal or larger than maximum"); break; case -7: error("at least 4 contextual regions required"); break; case -8: error("not enough memory! (try reducing 'bins')"); break; } // convert back to [0:1] range for (i = 0; i < nx*ny; i++) { tgt[i] = (double) img[i] / maxPixelValue; } } R_Free(img); UNPROTECT(1); return res; }