📄 imdi.c
字号:
/* Integer Multi-Dimensional Interpolation *//* * Copyright 2000 - 2002 Graeme W. Gill * All rights reserved. * * This material is licenced under the GNU GENERAL PUBLIC LICENCE :- * see the Licence.txt file for licencing details. *//* This is the implementation of the run time code. */#include <stdio.h>#include <stdlib.h>#include <math.h>#include <stdarg.h>#include <string.h>#include "imdi_imp.h"#include "imdi_gen.h"#include "imdi_tab.h"#include "imdi_k.h" /* Declaration of all the kernel functions */#undef VERBOSEstatic void imdi_free(imdi *im);/* Create a new imdi *//* Return NULL if request is not supported */imdi *new_imdi( int id, /* Number of input dimensions */ int od, /* Number of output dimensions */ imdi_pixrep in, /* Input pixel representation */ int in_signed, /* Bit flag per channel, NZ if treat as signed */ imdi_pixrep out,/* Output pixel representation */ int out_signed, /* Bit flag per channel, NZ if treat as signed */ int res, /* Desired table resolution */ /* Callbacks to lookup the mdi table values */ double (*input_curve) (void *cntx, int ch, double in_val), void (*md_table) (void *cntx, double *out_vals, double *in_vals), double (*output_curve)(void *cntx, int ch, double in_val), void *cntx /* Context to callbacks */) { int i; int bk = -1; /* Best table */ int bfig = 0x7fffffff; /* Best tables figure of merit */ int bstres; /* Best tables target stres */ genspec bgs; /* Best gen spec */ tabspec ts; /* Table specifications */ imdi *im;#ifdef VERBOSE printf("new_imdi called with id %d, od %d, res %d\n", id, od, res); printf("about to checking %d kernels\n", no_kfuncs);#endif /* The first thing to do is see if there is an available kernel function */ for (i = 0; i < no_kfuncs; i++) { genspec gs; int stres; /* Computed stres needed */ int fig; ktable[i].gen(&gs); /* Get the kernel functions genspec */#ifdef VERBOSE printf("\n"); printf("kernel %d has id %d, od %d, irep %d orep %d\n", i, gs.id, gs.od, gs.irep, gs.orep); printf("Input req is id %d, od %d, irep %d orep %d\n", id, od, in, out);#endif /* First check mandatory things */ if (id != gs.id /* Input dimension */ || od != gs.od /* Output dimension */ || in != gs.irep /* Input dimension */ || out != gs.orep) { /* Output dimension */ continue; }#ifdef VERBOSE printf(" found match\n");#endif ktable[i].tab(&ts); /* Get the kernel functions tabspec */ if (ts.sort) { stres = 0;#ifdef VERBOSE printf("gres = %d\n",res);#endif /* We want one that is equals or exceeds the desired */ /* resolution, but doesn't exceed it too much, or the code */ /* will be inefficient. */ /* If there are no routines that can meet the desired precision, */ /* then it is ok to use the one closest to the desired precision. */ if (gs.itres >= res) { fig = 10 * (gs.itres - res); } { fig = 0; if (gs.itres < res) { fig += 10000 * (res - gs.itres); } } } else { /* compute the needed stres (Assumint not sort) */ stres = ((1 << gs.prec)-1 + res-2)/(res-1);// stres = ((1024)-1 + res-2)/(res-1);#ifdef VERBOSE printf("gres = %d, sres = %d\n",res,stres);#endif /* We want one that is equals or exceeds the desired */ /* resolution, but doesn't exceed it too much, or the code */ /* will be inefficient. */ /* If there are no routines that can meet the desired precision, */ /* then it is ok to use the one closest to the desired precision. */ if (gs.itres >= res && gs.stres >= stres) { fig = 10 * (gs.itres - res) + (gs.stres - stres); } { fig = 0; if (gs.itres < res) { fig += 10000 * (res - gs.itres); } if (gs.stres < stres) { fig += 1000 * (stres - gs.stres); } } }#ifdef VERBOSE printf(" figure of merit %d\n",fig);#endif /* Is this the best one so far ? */ if (fig < bfig) { bfig = fig; bk = i; bstres = stres; bgs = gs; /* Structure copy */#ifdef VERBOSE printf(" best so far\n");#endif } } if (bk < 0) {#ifdef VERBOSE printf("new_imdi failed - dimensionality or representations couldn't be matched\n");#endif return NULL; /* Nothing matches */ } if ((im = (imdi *)malloc(sizeof(imdi))) == NULL) {#ifdef VERBOSE printf("new_imdi malloc imdi failed\n");#endif /* Should we return an error somehow ? */ return NULL; } /* We've decided kernel function bk is going to be the best, */ /* so now setup the appropriate tables to use with it. */ ktable[bk].tab(&ts); /* Get the kernel functions tabspec */ if (bgs.itres > res) bgs.itres = res; /* Tell table create what the res is */ if (bgs.stres > bstres) bgs.stres = bstres; /* Tel table setup how to treat integer input in per channel lookups */ bgs.in_signed = in_signed; bgs.out_signed = out_signed;#ifdef VERBOSE if (!ts.sort) { if ((bgs.stres * (bgs.itres-1)) < ((1 << bgs.prec)-1)) { printf("Warning: table chosen doesn't reach desired precision!\n"); printf("Wanted %d, got %d\n", ((1 << bgs.prec)-1), (bgs.stres * (bgs.itres-1))); } }#endif /* Allocate and initialise the appropriate tables */ im->impl = (void *)imdi_tab(&bgs, &ts, input_curve, md_table, output_curve, cntx); if (im->impl == NULL) {#ifdef VERBOSE printf("imdi_tab failed\n");#endif imdi_free(im); return NULL; } im->interp = ktable[bk].interp; im->done = imdi_free;#ifdef VERBOSE printf("new_imdi returning 0x%x\n", im);#endif return im;}/* Free up the structure */static void imdi_free(imdi *im) { /* Free all the allocated tables */ if (im->impl != NULL) imdi_tab_free((imdi_imp *)im->impl); /* Free this structure */ free(im);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -