// Create and populate a world from a list of rules. golem_world *new_world(golem_rule *rules) { golem_world *world = mallocd(sizeof(golem_world)); world->items = NULL; golem_item *last = NULL; for (golem_rule *rule = rules; rule; rule = rule->next) { if (!rule->effects) { if (rule->target) { warn("ignoring target in no-effect rule."); } if (rule->others) { warn("ignoring others in no-effect rule."); } log("+ item: %s\n", rule->item->name); if (check_item(rule->item)) { if (last) { last->next_sibling = rule->item; } else { world->items = rule->item; } last = rule->item; } } } world->pc = find_pc(world->items); if (!world->pc) { die("no PC found."); } for (world->current = world->pc; world->current->parent; world->current = world->current->parent); return world; }
// Create a new tag with a sign and a name. golem_tag *new_tag(bool sign, char *name) { golem_tag *tag = mallocd(sizeof(golem_tag)); tag->name = name; tag->sign = sign; tag->next = NULL; return tag; }
// Create a new rule with the item set. golem_rule *new_rule(golem_item *item) { golem_rule *rule = mallocd(sizeof(golem_rule)); rule->item = item; rule->target = NULL; rule->others = NULL; rule->next = NULL; return rule; }
// Create a new item with a name. golem_item *new_item(char *name) { golem_item *item = mallocd(sizeof(golem_item)); item->name = name; item->tags = NULL; item->parent = NULL; item->first_child = NULL; item->next_sibling = NULL; return item; }
// Slurp a whole file into a string. char *slurp_file(FILE *fp) { size_t length = 0; char *string = mallocd(sizeof(char) * SLURP_CHUNK_SIZE); size_t read = fread(string, sizeof(char), SLURP_CHUNK_SIZE, fp); length += read; while (read == SLURP_CHUNK_SIZE) { string = (char *)realloc(string, sizeof(char) * length + SLURP_CHUNK_SIZE); read = fread(string + length, sizeof(char), SLURP_CHUNK_SIZE, fp); length += read; } string = (char *)realloc(string, sizeof(char) * (length + 1)); string[length] = '\0'; return string; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Input image and ouput image */ double *u, *u_new; /* Options structure variables */ mxArray *TempField; double *OptionsField; int field_num; struct options Options; /* Size input image */ int ndimsu; const mwSize *dimsu_const; int dimsu[3]; int npixels2; int npixels3; double *usigma; /* Gaussian filtered image */ double *ux, *uy; /* Gradients of smoothed image */ double *Jxx, *Jxy, *Jyy, *J[3]; /* Structure tensor */ double *Dxx, *Dxy, *Dyy; /* Diffusion tensor */ /* Check number of inputs/outputs */ if(nrhs<1) { mexErrMsgTxt("1 input variable is required, the other one is optional."); } if(nlhs<1) { mexErrMsgTxt("1 output variable is required"); } /* Check type of inputs */ if(!mxIsDouble(prhs[0])) { mexErrMsgTxt("Input Image must be of datatype Double");} if(nrhs==2){ if(!mxIsStruct(prhs[1])){ mexErrMsgTxt("Options must be of type structure"); } } /* Set Options struct */ setdefaultoptions(&Options); if(nrhs==2) { field_num = mxGetFieldNumber(prhs[1], "T"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("aValues in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.T=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "dt"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.dt=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "sigma"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.sigma=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "rho"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.rho=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "C"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.C=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "m"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.m=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "alpha"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.alpha=OptionsField[0]; } } /* Check and get input image dimensions */ ndimsu=mxGetNumberOfDimensions(prhs[0]); if((ndimsu<2)||(ndimsu>3)) { mexErrMsgTxt("Input Image must be 2D"); } dimsu_const = mxGetDimensions(prhs[0]); dimsu[0]=dimsu_const[0]; dimsu[1]=dimsu_const[1]; if(ndimsu==3) { dimsu[2]=dimsu_const[2]; } else { dimsu[2]=1; } npixels2=dimsu[0]*dimsu[1]; npixels3=dimsu[0]*dimsu[1]*dimsu[2]; /* Connect input */ u =(double *)mxGetData(prhs[0]); /* Gaussian Filtering of input image */ usigma = mallocd(npixels3); GaussianFiltering2Dcolor_double(u, usigma, dimsu, Options.sigma, 4*Options.sigma); /* Calculate the image gradients of the smoothed image */ ux = mallocd(npixels3); uy = mallocd(npixels3); gradient2Dx_color(usigma, dimsu, ux); gradient2Dy_color(usigma, dimsu, uy); /* remove usigma from memory */ free(usigma); /* Compute the 2D structure tensors J of the image */ StructureTensor2D(ux,uy, J, dimsu, Options.rho); Jxx=J[0]; Jyy=J[1] ;Jxy=J[2]; /* remove gradients from memory */ free(ux); free(uy); /* Structure to Diffusion Tensor Weickert */ Dxx = mallocd(npixels2); Dyy = mallocd(npixels2); Dxy = mallocd(npixels2); StructureTensor2DiffusionTensor(Jxx,Jxy,Jyy,Dxx,Dxy,Dyy,dimsu,Options.C,Options.m,Options.alpha); /* remove structure tensor from memory */ free(Jxx); free(Jyy); free(Jxy); /* Create output array */ if(dimsu[2]==1) { plhs[0] = mxCreateNumericArray(2, dimsu, mxDOUBLE_CLASS, mxREAL); } else { plhs[0] = mxCreateNumericArray(3, dimsu, mxDOUBLE_CLASS, mxREAL); } /* Assign pointer to output. */ u_new = (double *)mxGetData(plhs[0]); /* Perform the image diffusion */ diffusion_scheme_2D_rotation_invariance(u,u_new,dimsu,Dxx,Dxy,Dyy,Options.dt); /* remove diffusion tensor from memory */ free(Dxx); free(Dyy); free(Dxy); }
// Parse an effect from the list of effects. golem_effect *parse_effect(golem_tokenizer *tokenizer) { log("> parse effect [%d]\n", tokenizer->token); int token; golem_effect *effect = mallocd(sizeof(golem_effect)); effect->reference = 0; effect->param.reference = 0; effect->next = NULL; switch (tokenizer->token) { case token_name: effect->type = effect_item; effect->param.item = parse_item(tokenizer); log("- item effect (%s)\n", effect->param.item->name); break; case token_string: effect->type = effect_string; effect->param.string = get_token_string(tokenizer); log("- string effect (%s)\n", effect->param.string); break; case token_ref: effect->reference = get_token_ref(tokenizer); token = get_token(tokenizer); switch (token) { case '+': case '-': effect->type = effect_tag; effect->param.tag = parse_tag(tokenizer); log("- tag effect (%d/%c%s)\n", effect->reference, effect->param.tag->sign ? '+' : '-', effect->param.tag->name); break; case '[': token = get_token(tokenizer); switch (token) { case token_ref: effect->type = effect_move_ref_ref; effect->param.reference = get_token_ref(tokenizer); log("- move ref/ref effect (%d/%d)\n", effect->reference, effect->param.reference); break; case token_name: effect->type = effect_move_ref_item; effect->param.item = parse_item(tokenizer); log("- move ref/item effect (%d/%s)\n", effect->reference, effect->param.item->name); break; default: die("parse effect: error parsing move effect"); } token = get_token(tokenizer); if (token != ']') { die("parse effect: error parsing move effect, expected ]"); } break; default: die("parse effect: syntax error."); } break; case '-': token = get_token(tokenizer); if (token != token_ref) { die("parse effect: expected reference after -"); } effect->type = effect_remove; effect->reference = get_token_ref(tokenizer); log("- remove effect (%d)\n", effect->reference); break; default: die("parse effect: syntax error"); } if (effect->type != effect_item) { (void)get_token(tokenizer); } log("< parsed effect (%d) [%d]\n", effect->type, tokenizer->token); return effect; }