/*------------------------------------------------------------------------- Implementation file for translation table. Mark Koennecke, October 1997 copyright: see copyright.h ---------------------------------------------------------------------------*/ #include #include #include #include #include "table.h" /*-------------------------------------------------------------------------*/ typedef struct __SicsTable { float *fVal1; float *fVal2; int iLength; } STable; /*-------------------------------------------------------------------------*/ pSTable CreateTable(FILE * fd) { pSTable pNew = NULL; long lStart, lEnd, lData, i; char *pBuffer = NULL, *pEnd = NULL, *pEndLine, *pPtr; int iLength, iRet; float fVal1, fVal2; assert(fd); /* find length of file, create a buffer and read it in */ lStart = ftell(fd); fseek(fd, 0L, SEEK_END); lEnd = ftell(fd); lData = lEnd - lStart; pBuffer = (char *) malloc(lData * sizeof(char)); if (!pBuffer) { return NULL; } fseek(fd, lStart, SEEK_SET); fread(pBuffer, sizeof(char), lData, fd); /* find number of lines */ for (i = 0, iLength = 0; i < lData; i++) { if (pBuffer[i] == '\n') { iLength++; } } /* allocate the table structure */ pNew = (pSTable) malloc(sizeof(STable)); if (!pNew) { free(pBuffer); return NULL; } pNew->iLength = iLength; pNew->fVal1 = (float *) malloc(sizeof(float) * iLength); pNew->fVal2 = (float *) malloc(sizeof(float) * iLength); if ((!pNew->fVal1) || (!pNew->fVal2)) { free(pBuffer); free(pNew); return NULL; } memset(pNew->fVal1, 0, iLength * sizeof(float)); memset(pNew->fVal2, 0, iLength * sizeof(float)); /* dodge through the file reading pairs until end */ pPtr = pBuffer; pEnd = pBuffer + lData; pEndLine = pBuffer; i = 0; while (pEndLine < pEnd) { if (*pEndLine == '\n') { *pEndLine = '\0'; iRet = sscanf(pPtr, "%f %f", &fVal1, &fVal2); if (iRet == 2) { pNew->fVal1[i] = fVal1; pNew->fVal2[i] = fVal2; i++; } pEndLine++; pPtr = pEndLine; } else { pEndLine++; } } free(pBuffer); return pNew; } /*--------------------------------------------------------------------------*/ void DeleteTable(pSTable self) { if (self->fVal1) { free(self->fVal1); } if (self->fVal2) { free(self->fVal2); } free(self); } /*--------------------------------------------------------------------------*/ int InterpolateVal1(pSTable self, float fKey, float *fResult) { float fFrac; int i1, i; assert(self); assert(self->fVal1); assert(self->fVal2); /* search the entry point */ for (i = 0; i < self->iLength; i++) { if (self->fVal1[i] >= fKey) { i1 = i; break; } } if (i1 >= self->iLength) { return 0; } /* interpolate */ fFrac = (fKey - self->fVal1[i1 - 1]) / (self->fVal1[i1] - self->fVal1[i1 - 1]); *fResult = self->fVal2[i1 - 1] + fFrac * (self->fVal2[i1] - self->fVal2[i1 - 1]); return 1; } /*---------------------------------------------------------------------------*/ int InterpolateVal2(pSTable self, float fKey, float *fResult) { float fFrac; int i1, i; assert(self); assert(self->fVal1); assert(self->fVal2); /* search the entry point */ for (i = 0; i < self->iLength; i++) { if (self->fVal2[i] <= fKey) { i1 = i; break; } } if (i1 >= self->iLength) { return 0; } /* interpolate */ fFrac = (fKey - self->fVal2[i1 - 1]) / (self->fVal2[i1] - self->fVal2[i1 - 1]); *fResult = self->fVal1[i1 - 1] + fFrac * (self->fVal1[i1] - self->fVal1[i1 - 1]); return 1; }