Files
sicspsi/frame.c
koennecke 4127cbb166 - After a bug at TRICS I replaced all occurrences of strcpy, strcat, sprintf
by length limited versions wherever appropriate.
2009-12-04 12:58:45 +00:00

258 lines
6.9 KiB
C

/*-------------------------------------------------------------------------
A module implementing functionality for reading single time frames
from PSD time-of-flight datasets. This can be done either from
SINQHM histogram memories or from old data files visible from the
SICS server. The result is sent to the demanding client in UUencoded
format.
copyright: see file COPYRIGHT
Mark Koennecke, February-March 2003
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "fortify.h"
#include "sics.h"
#include "stringdict.h"
#include "counter.h"
#include "HistMem.h"
#include "HistMem.i"
#include "HistDriv.i"
#include "hardsup/sinqhm.h"
#include "sinqhmdriv.i"
#include "nxdict.h"
#include "frame.h"
/*======================================================================*/
static int readHMFrame(SConnection * pCon, pHistMem pHM, int nFrame)
{
HistInt *buffer = NULL;
int iDim[MAXDIM], rank, length, status, i, noTimeBins;
pSINQHM pHist;
SinqHMDriv *pTata;
const float *timeBin;
/*
find dimensions and allocate data
*/
GetHistDim(pHM, iDim, &rank);
timeBin = GetHistTimeBin(pHM, &noTimeBins);
if (rank < 2) {
SCWrite(pCon, "ERROR: no PSD data present, cannot send frame", eError);
return 0;
}
length = iDim[0] * iDim[1];
buffer = (HistInt *) malloc((length + 2) * sizeof(HistInt));
if (!buffer) {
SCWrite(pCon, "ERROR: out of memory in readHMFrame", eError);
return 0;
}
memset(buffer, 0, (length + 2) * sizeof(HistInt));
/*
first two values are dimensions
*/
buffer[0] = htonl(iDim[0]);
buffer[1] = htonl(iDim[1]);
if (isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) {
/*
read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h
Again: be friendly: fix out of range frames
*/
if (nFrame < 0) {
nFrame = 0;
}
if (nFrame >= noTimeBins) {
nFrame = noTimeBins - 1;
}
pTata = (SinqHMDriv *) pHM->pDriv->pPriv;
pHist = (pSINQHM) pTata->pMaster;
status = SINQHMProject(pHist, 0x0005, 0, nFrame,
0, iDim[1], buffer + 2,
length * sizeof(HistInt));
if (status != 1) {
SCWrite(pCon, "ERROR: SINQHM refused to deliver frame", eError);
free(buffer);
return 0;
}
} else {
/*
be friendly, just read the 2D data which is there
*/
status =
GetHistogram(pHM, pCon, 0, 0, length, buffer + 2,
length * sizeof(HistInt));
if (!status) {
free(buffer);
return status;
}
}
/*
enforce network byte order
*/
for (i = 0; i < length; i++) {
buffer[i + 2] = htonl(buffer[i + 2]);
}
SCWriteUUencoded(pCon, "framedata", buffer,
(length + 2) * sizeof(HistInt));
free(buffer);
return 1;
}
/*=======================================================================*/
static int readFileFrame(SConnection * pCon,
char *file, char *dictFile,
char *alias, int nFrame)
{
int status, iDim[NX_MAXRANK], rank = 0, type = 0;
int iStart[3], iSize[3], length, i;
int *buffer = NULL;
NXhandle fileHandle;
NXdict dictHandle;
char error[512];
status = NXopen(file, NXACC_READ, &fileHandle);
if (status != NX_OK) {
snprintf(error,511, "ERROR: failed to open %s", file);
SCWrite(pCon, error, eError);
return 0;
}
status = NXDinitfromfile(dictFile, &dictHandle);
if (status != NX_OK) {
snprintf(error,511, "ERROR: failed to open dictionary %s", dictFile);
NXclose(&fileHandle);
SCWrite(pCon, error, eError);
return 0;
}
status = NXDopenalias(fileHandle, dictHandle, alias);
if (status != NX_OK) {
snprintf(error,511, "ERROR: failed to open alias %s", alias);
NXclose(&fileHandle);
NXDclose(dictHandle, NULL);
SCWrite(pCon, error, eError);
return 0;
}
status = NXgetinfo(fileHandle, &rank, iDim, &type);
if (type != NX_INT32 && type != NX_UINT32)
type = -1;
if (status != NX_OK || rank < 2 || type < 0) {
sprintf(error, "ERROR: Dataset does not match!");
NXclose(&fileHandle);
NXDclose(dictHandle, NULL);
SCWrite(pCon, error, eError);
return 0;
}
/*
allocate space
*/
length = iDim[0] * iDim[1];
buffer = (int *) malloc((length + 2) * sizeof(int));
if (!buffer) {
NXclose(&fileHandle);
NXDclose(dictHandle, NULL);
SCWrite(pCon, "ERROR: out of memory in readFrameFromFile", eError);
return 0;
}
memset(buffer, 0, (length + 2) * sizeof(int));
/*
first two values: dimensions
*/
buffer[0] = htonl(iDim[0]);
buffer[1] = htonl(iDim[1]);
if (rank == 2) {
/*
be friendly
*/
status = NXgetdata(fileHandle, buffer + 2);
} else {
iStart[0] = iStart[1] = 0;
if (nFrame > iDim[2] - 2) {
nFrame = iDim[2] - 2;
}
iStart[2] = nFrame;
iSize[0] = iDim[0];
iSize[1] = iDim[1];
iSize[2] = 1;
status = NXgetslab(fileHandle, buffer + 2, iStart, iSize);
}
if (status != NX_OK) {
NXclose(&fileHandle);
NXDclose(dictHandle, NULL);
free(buffer);
SCWrite(pCon, "ERROR: failed to read data", eError);
return 0;
}
/*
enforce network byte order
*/
for (i = 0; i < length; i++) {
buffer[2 + i] = htonl(buffer[2 + i]);
}
SCWriteUUencoded(pCon, "framedata", buffer, (length + 2) * sizeof(int));
NXclose(&fileHandle);
NXDclose(dictHandle, NULL);
free(buffer);
return 1;
}
/*=======================================================================*/
int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pHistMem pHM;
int nFrame;
if (argc < 2) {
SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDFrame",
eError);
return 0;
}
strtolower(argv[1]);
if (strcmp(argv[1], "hm") == 0) {
if (argc < 4) {
SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDFrame",
eError);
return 0;
}
pHM = (pHistMem) FindCommandData(pSics, argv[2], "HistMem");
if (pHM == NULL) {
SCWrite(pCon, "ERROR: Did not find histogram memory", eError);
return 0;
}
nFrame = atoi(argv[3]);
return readHMFrame(pCon, pHM, nFrame);
} else if (strcmp(argv[1], "file") == 0) {
if (argc < 6) {
SCWrite(pCon,
"ERROR: Insufficient number of arguments to PSDframe file",
eError);
return 0;
}
nFrame = atoi(argv[5]);
return readFileFrame(pCon, argv[2], argv[3], argv[4], nFrame);
} else {
SCWrite(pCon, "ERROR: subcommand to PSDframe not recognised", eError);
return 0;
}
}
/*======================================================================*/
int MakeFrameFunc(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
return AddCommand(pSics, "PSDframe", PSDFrameAction, NULL, NULL);
}