2211 рядки
65 KiB
C
2211 рядки
65 KiB
C
#include "cmPrefix.h"
|
|
#include "cmGlobal.h"
|
|
#include "cmFloatTypes.h"
|
|
#include "cmRpt.h"
|
|
#include "cmErr.h"
|
|
#include "cmCtx.h"
|
|
#include "cmMem.h"
|
|
#include "cmMallocDebug.h"
|
|
#include "cmJson.h"
|
|
#include "cmFrameFile.h"
|
|
#include "cmLinkedHeap.h"
|
|
#include "cmMath.h"
|
|
#include "cmVectOps.h"
|
|
|
|
/*
|
|
|
|
File Type: 4 0
|
|
Chunk Bytes: 4 4
|
|
Frame Count: 4 8
|
|
Version: 4 16
|
|
EOF Frm Offs:8 20
|
|
Sample Rate: 8 28 32
|
|
|
|
Frame Type: 4 36 // Note: Update cmFrameFileFrameSkip()
|
|
Chunk Bytes: 4 40 // if the size of this header changes.
|
|
Mtx Count: 4 44
|
|
Stream Id: 4 48
|
|
Flags: 4 52
|
|
Sample Idx 4 56
|
|
Seconds: 8 60 32
|
|
|
|
Mtx Type: 4 68
|
|
Data Bytes: 4 72
|
|
Format Id: 4 76
|
|
Units Id: 4 80
|
|
Row Cnt: 4 86
|
|
Col Cnt: 4 90 24
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
#define _cmFfSwap16(fl,v) ((fl) ? cmSwap16(v) : (v))
|
|
#define _cmFfSwap32(fl,v) ((fl) ? cmSwap32(v) : (v))
|
|
#define _cmFfSwap64(fl,v) ((fl) ? cmSwap64(v) : (v))
|
|
#define _cmFfWrSwapF(fl,v) ((fl) ? cmFfSwapFloatToUInt(v) : (*((unsigned*)&(v))))
|
|
#define _cmFfRdSwapF(fl,v) ((fl) ? cmFfSwapUIntToFloat(v) : (*((float*)&(v))))
|
|
#define _cmFfWrSwapD(fl,v) ((fl) ? cmFfSwapDoubleToULLong(v) : (*((unsigned long long*)&(v))))
|
|
#define _cmFfRdSwapD(fl,v) ((fl) ? cmFfSwapULLongToDouble(v) : (*((double*)&(v))))
|
|
|
|
|
|
enum
|
|
{
|
|
kSampleIdxTimeFl = 0x01,
|
|
kSecondsTimeFl = 0x02
|
|
};
|
|
|
|
|
|
typedef struct _cmFfOffs_str
|
|
{
|
|
unsigned frmIdx; // absolute frame index for this mtx
|
|
off_t offs; // file offset for mtx header
|
|
struct _cmFfOffs_str* linkPtr;
|
|
} _cmFfOffs_t;
|
|
|
|
typedef struct
|
|
{
|
|
_cmFfOffs_t* beg;
|
|
_cmFfOffs_t* end;
|
|
unsigned cnt;
|
|
} _cmFfOffsList_t;
|
|
|
|
typedef struct _cmFfToC_str
|
|
{
|
|
unsigned streamId; //
|
|
unsigned mtxType; // kInvalidMId when used with frmToC
|
|
unsigned mtxUnitsId; // kInvalidUId when used with frmToC
|
|
unsigned mtxFmtId; // kInvalidFmtId when used with frmToC
|
|
_cmFfOffsList_t offsList; //
|
|
unsigned lastFrmIdx; // used to prevent duplicate records during ToC creation
|
|
struct _cmFfToC_str* linkPtr;
|
|
} _cmFfToC_t;
|
|
|
|
// private matrix desc record
|
|
typedef struct
|
|
{
|
|
cmFfMtx_t m; // public mtx description record
|
|
unsigned byteCnt; // bytes in this->dataPtr block
|
|
void* dataPtr; // pointer to data for this mtx
|
|
} _cmFfMtx_t;
|
|
|
|
// private frame desc record
|
|
typedef struct
|
|
{
|
|
cmFfFrame_t f; // public frame description record
|
|
unsigned byteCnt; // byte count of frame file chunk
|
|
_cmFfMtx_t* mtxArray; // mtx ctl record array
|
|
char* dataPtr; // all memory used by all mtx's in this frame
|
|
} _cmFfFrame_t;
|
|
|
|
typedef struct
|
|
{
|
|
cmErr_t err;
|
|
cmCtx_t ctx;
|
|
FILE* fp; //
|
|
bool writeFl; // file is open for writing
|
|
unsigned fileChkByteCnt; //
|
|
unsigned nxtFrmIdx; // index of the next frame after the current frame
|
|
unsigned curFrmIdx; // write: not used read:index of currently loaded frame
|
|
off_t frameOffset; // read: offset to first mtx hdr in cur frame
|
|
// write:offset to cur frame hdr
|
|
off_t rewOffset; // rewind offset (first frame)
|
|
off_t eofOffset; // last frame (offset data frame)
|
|
cmFfFile_t f; // file header
|
|
_cmFfFrame_t frame; // cur frame
|
|
cmLHeapH_t lhH; // linked heap handle
|
|
_cmFfToC_t* mtxToC; // one ToC recd for each existing matrix stream/type/units/fmt combination
|
|
_cmFfToC_t* frmToC; // one ToC recd for each stream
|
|
void* writeMtxMem;
|
|
bool swapFl;
|
|
} cmFf_t;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned fmtId;
|
|
unsigned wordByteCnt;
|
|
const char* label;
|
|
} _cmFfFmt_t;
|
|
|
|
_cmFfFmt_t _cmFfFmtArray[] =
|
|
{
|
|
{ kUCharFmtId, 1, "char" },
|
|
{ kCharFmtId, 1, "uchar" },
|
|
{ kUShortFmtId, 2, "ushort" },
|
|
{ kShortFmtId, 2, "short" },
|
|
{ kULongFmtId, 4, "ulong" },
|
|
{ kLongFmtId, 4, "long" },
|
|
{ kUIntFmtId, 4, "uint" },
|
|
{ kIntFmtId, 4, "int" },
|
|
{ kLLongFmtId, 8, "llong" },
|
|
{ kULLongFmtId, 8, "ullong" },
|
|
{ kOff_tFmtId, sizeof(off_t), "off_t"},
|
|
{ kFloatFmtId, 4, "float" },
|
|
{ kDoubleFmtId, 8, "double" },
|
|
{ kStringZFmtId, 1, "string" },
|
|
{ kBlobFmtId, 1, "blob" },
|
|
{ kJsonFmtId, 1, "json" },
|
|
{ kInvalidFmtId, 0, "<invalid>" }
|
|
};
|
|
|
|
|
|
cmFrameFileH_t cmFrameFileNullHandle = { NULL };
|
|
/*
|
|
void _cmFfPrint( cmFf_t* p, const char* fmt, ... )
|
|
{
|
|
va_list vl;
|
|
va_start(vl,fmt);
|
|
|
|
if( p == NULL || p->vPrintFunc == NULL )
|
|
vfprintf(stderr,fmt,vl);
|
|
else
|
|
p->vPrintFunc(p->rptDataPtr,fmt,vl);
|
|
|
|
va_end(vl);
|
|
|
|
}
|
|
|
|
cmFfRC_t _cmFfVError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, va_list vl )
|
|
{
|
|
int bufCharCnt = 256;
|
|
char buf0[bufCharCnt+1];
|
|
char buf1[bufCharCnt+1];
|
|
char buf2[bufCharCnt+1];
|
|
|
|
snprintf(buf0,bufCharCnt,"cmFrameFile Error: (%i): ",rc );
|
|
vsnprintf(buf1,bufCharCnt,fmt,vl);
|
|
snprintf(buf2,bufCharCnt,"System Error: ");
|
|
|
|
|
|
unsigned sn = strlen(buf0) + strlen(buf1);
|
|
|
|
sn += sysErrCode == 0 ? 0 : strlen(buf2) + strlen(strerror(sysErrCode));
|
|
|
|
char buf3[sn+1];
|
|
buf3[sn] = 0;
|
|
buf3[0] = 0;
|
|
|
|
strncpy(buf3, buf0, sn-strlen(buf3) );
|
|
strncat(buf3, buf1, sn-strlen(buf3) );
|
|
if( sysErrCode )
|
|
{
|
|
strncat(buf3,buf2, sn - strlen(buf3) );
|
|
strncat(buf3,strerror(sysErrCode), sn - strlen(buf3) );
|
|
}
|
|
|
|
assert(strlen(buf3)==sn);
|
|
|
|
_cmFfPrint(p,"%s\n",buf3);
|
|
|
|
return rc;
|
|
|
|
}
|
|
*/
|
|
|
|
cmFfRC_t _cmFfVError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, va_list vl )
|
|
{
|
|
if( p != NULL )
|
|
return cmErrVSysMsg(&p->err,rc,sysErrCode,fmt,vl);
|
|
|
|
printf("cmFrameFile Error: rc=%i ",rc);
|
|
vprintf(fmt,vl);
|
|
printf("\n");
|
|
|
|
if( sysErrCode )
|
|
printf("cmFrameFile System Error code=%i %s\n\n",sysErrCode,strerror(sysErrCode));
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFfError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, ... )
|
|
{
|
|
va_list vl;
|
|
va_start(vl,fmt);
|
|
_cmFfVError( p, rc, sysErrCode, fmt, vl );
|
|
va_end(vl);
|
|
return rc;
|
|
}
|
|
|
|
cmFf_t* _cmFfHandleToPtr( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = (cmFf_t*)h.h;
|
|
if( p == NULL )
|
|
_cmFfError(NULL,kInvalidHandleFfRC,0,"Null handle.");
|
|
assert( p != NULL);
|
|
return p;
|
|
}
|
|
|
|
_cmFfFmt_t* _cmFfIdToFmtPtr( unsigned fmtId )
|
|
{
|
|
unsigned i;
|
|
for(i=0; _cmFfFmtArray[i].fmtId != kInvalidFmtId; ++i)
|
|
if( _cmFfFmtArray[i].fmtId == fmtId )
|
|
break;
|
|
|
|
return _cmFfFmtArray + i;
|
|
}
|
|
|
|
|
|
const void* _cmFfSwapVector( void* dV, const void* sV, unsigned n, unsigned bn )
|
|
{
|
|
unsigned i;
|
|
switch( bn )
|
|
{
|
|
case 1:
|
|
return sV;
|
|
|
|
case 2:
|
|
{
|
|
const unsigned short* x = (const unsigned short*)sV;
|
|
unsigned short* y = (unsigned short*)dV;
|
|
for(i=0; i<n; ++i)
|
|
y[i] = cmSwap16(x[i]);
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
{
|
|
const unsigned long* x = (const unsigned long*)sV;
|
|
unsigned long* y = (unsigned long*)dV;
|
|
for(i=0; i<n; ++i)
|
|
y[i] = cmSwap32(x[i]);
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
{
|
|
// on 32 bit linux this is very slow
|
|
const unsigned long long* x = (const unsigned long long*)sV;
|
|
unsigned long long* y = (unsigned long long*)dV;
|
|
for(i=0; i<n; ++i)
|
|
y[i] = cmSwap64(x[i]);
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{ assert(0); }
|
|
}
|
|
|
|
return dV;
|
|
}
|
|
|
|
|
|
cmFfRC_t _cmFfWrite( cmFf_t* p, const void* dataPtr, unsigned byteCnt )
|
|
{
|
|
if(fwrite(dataPtr,byteCnt,1,p->fp) != 1 )
|
|
return _cmFfError( p, kFileWriteFailFfRC, errno, "File write failed." );
|
|
|
|
p->fileChkByteCnt += byteCnt;
|
|
p->frame.byteCnt += byteCnt;
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteOff_t( cmFf_t* p, off_t v )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
assert(sizeof(off_t)==8);
|
|
|
|
v = _cmFfSwap64(p->swapFl,v);
|
|
|
|
if((rc = _cmFfWrite(p,&v,sizeof(v))) != kOkFfRC )
|
|
return rc;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteUInt( cmFf_t* p, unsigned v )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
v = _cmFfSwap32(p->swapFl,v);
|
|
|
|
if((rc = _cmFfWrite(p,&v,sizeof(v))) != kOkFfRC )
|
|
return rc;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteUIntV( cmFf_t* p, const unsigned* vp, unsigned n )
|
|
{
|
|
unsigned i;
|
|
cmFfRC_t rc;
|
|
|
|
for(i=0; i<n; ++i)
|
|
if((rc = _cmFfWriteUInt( p, vp[i] )) != kOkFfRC )
|
|
return rc;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteDouble( cmFf_t* p, double v )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
unsigned long long vv = _cmFfWrSwapD(p->swapFl,v);
|
|
|
|
if((rc = _cmFfWrite(p, &vv, sizeof(vv))) != kOkFfRC )
|
|
return rc;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfRead( cmFf_t* p, void* vp, unsigned bn )
|
|
{
|
|
if(fread(vp,bn,1,p->fp) != 1 )
|
|
{
|
|
if( feof(p->fp) )
|
|
return kEofFfRC;
|
|
|
|
return _cmFfError( p, kFileReadFailFfRC, errno, "File read failed.");
|
|
}
|
|
|
|
return kOkFfRC;
|
|
|
|
}
|
|
|
|
cmFfRC_t _cmFfReadOff_t( cmFf_t* p, off_t* vp )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
assert( sizeof(off_t)==8);
|
|
|
|
if((rc = _cmFfRead(p,vp,sizeof(*vp))) != kOkFfRC )
|
|
return rc;
|
|
|
|
*vp = _cmFfSwap64(p->swapFl,*vp);
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfReadUInt( cmFf_t* p, unsigned* vp )
|
|
{
|
|
cmFfRC_t rc;
|
|
if((rc = _cmFfRead(p,vp,sizeof(*vp))) != kOkFfRC )
|
|
return rc;
|
|
|
|
*vp = _cmFfSwap32(p->swapFl,*vp);
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfReadDouble( cmFf_t* p, double* vp )
|
|
{
|
|
cmFfRC_t rc;
|
|
unsigned long long v;
|
|
if((rc = _cmFfRead(p,&v,sizeof(v))) != kOkFfRC )
|
|
return rc;
|
|
|
|
*vp = _cmFfRdSwapD(p->swapFl,v);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
cmFfRC_t _cmFfTell( cmFf_t* p, off_t* offsPtr )
|
|
{
|
|
if((*offsPtr = ftello( p->fp )) == -1 )
|
|
return _cmFfError( p, kFileTellFailFfRC, errno, "File tell failed.");
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFfSeek( cmFf_t* p, int whence, off_t offset )
|
|
{
|
|
//if( p->writeFl )
|
|
// return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot seek on file opened for writing.");
|
|
|
|
if(fseeko(p->fp, offset, whence) != 0 )
|
|
return _cmFfError( p, kFileSeekFailFfRC, errno, "File seek failed.");
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
// append a _cmFfOffs_t record to a _cmFfOffsList
|
|
void _cmFfAppendOffsList( cmFf_t* p, _cmFfOffsList_t* lp, unsigned frmIdx, unsigned offs )
|
|
{
|
|
_cmFfOffs_t* op = (_cmFfOffs_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmFfOffs_t) );
|
|
|
|
op->frmIdx = frmIdx;
|
|
op->offs = offs;
|
|
|
|
if( lp->end != NULL )
|
|
lp->end->linkPtr = op;
|
|
else
|
|
{
|
|
assert( lp->beg == NULL );
|
|
}
|
|
|
|
lp->end = op;
|
|
|
|
if( lp->beg == NULL )
|
|
{
|
|
assert( lp->end == op );
|
|
lp->beg = op;
|
|
}
|
|
|
|
++lp->cnt;
|
|
}
|
|
|
|
// locate a ToC record in a ToC list
|
|
_cmFfToC_t* _cmFfFindToCPtr( cmFf_t* p, _cmFfToC_t* cp, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId )
|
|
{
|
|
|
|
while( cp != NULL )
|
|
{
|
|
if( cp->streamId==streamId && cp->mtxType==mtxType && cp->mtxUnitsId==mtxUnitsId && cp->mtxFmtId==mtxFmtId )
|
|
break;
|
|
|
|
cp = cp->linkPtr;
|
|
}
|
|
|
|
return cp;
|
|
}
|
|
|
|
|
|
cmFfRC_t _cmFfAppendToC( cmFf_t* p, _cmFfToC_t** tocPtrPtr, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId, unsigned absFrameIdx, off_t fileOffset )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
_cmFfToC_t* tocPtr = *tocPtrPtr;
|
|
_cmFfToC_t* cp;
|
|
|
|
// use p->eofOffset as a flags to prevent appending the TOC matrices themselves to the TOC
|
|
if( p->writeFl && p->eofOffset != cmInvalidIdx )
|
|
return rc;
|
|
|
|
// find the contents record associated with this matrix stream,type,fmt,units
|
|
if(( cp = _cmFfFindToCPtr(p,tocPtr,streamId,mtxType,mtxUnitsId,mtxFmtId)) == NULL )
|
|
{
|
|
// no existing contents recd was found so create a new one
|
|
cp = (_cmFfToC_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmFfToC_t));
|
|
cp->streamId = streamId;
|
|
cp->mtxType = mtxType;
|
|
cp->mtxUnitsId = mtxUnitsId;
|
|
cp->mtxFmtId = mtxFmtId;
|
|
cp->linkPtr = tocPtr;
|
|
cp->lastFrmIdx = cmInvalidIdx;
|
|
|
|
//printf("create : stream:%i type:0x%x units:%i fmt:%i\n",streamId,mtxType,mtxUnitsId,mtxFmtId);
|
|
|
|
*tocPtrPtr = cp;
|
|
}
|
|
|
|
assert( p->nxtFrmIdx > 0 );
|
|
|
|
// verify that this frame does not have multiple matrixes of the same type
|
|
// (this would result in multiple identical _cmFfOffs_t records being written for the same _cmFfToC_t record)
|
|
if( absFrameIdx == cp->lastFrmIdx )
|
|
rc = _cmFfError( p, kDuplicateMtxIdFfRC, 0, "Duplicate matrix types were found in the same frame: stream:%i type:%i units:%i fmt:%i.",streamId, mtxType, mtxUnitsId, mtxFmtId );
|
|
|
|
cp->lastFrmIdx = absFrameIdx;
|
|
|
|
_cmFfAppendOffsList(p, &cp->offsList, absFrameIdx, fileOffset );
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFfAppendMtxToC( cmFf_t* p, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId, unsigned absFrameIdx, off_t mtxFileOff )
|
|
{ return _cmFfAppendToC(p, &p->mtxToC, streamId, mtxType, mtxUnitsId, mtxFmtId, absFrameIdx, mtxFileOff ); }
|
|
|
|
|
|
cmFfRC_t _cmFfAppendFrameToC( cmFf_t* p, unsigned streamId, unsigned absFrameIdx, off_t frmFileOff )
|
|
{ return _cmFfAppendToC(p, &p->frmToC, streamId, kInvalidMId, kInvalidUId, kInvalidFmtId, absFrameIdx, frmFileOff ); }
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
cmFfRC_t _cmFfWriteOffsList( cmFrameFileH_t h, _cmFfOffsList_t* lp, unsigned mtxId, void** arrayPtrPtr, unsigned* extraV, unsigned extraN )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
unsigned i = 0;
|
|
unsigned j = 0;
|
|
unsigned n = (extraN + lp->cnt * sizeof(unsigned)) + (lp->cnt * sizeof(unsigned long long));
|
|
|
|
// allocate memory
|
|
*arrayPtrPtr = cmMemResizeZ( unsigned, *arrayPtrPtr, n );
|
|
|
|
unsigned *idxV = (unsigned*)(*arrayPtrPtr);
|
|
off_t* offV = (off_t*)(idxV + extraN + lp->cnt);
|
|
|
|
// store the extra values
|
|
for(i=0; i<extraN; ++i)
|
|
idxV[i] = extraV[i];
|
|
|
|
_cmFfOffs_t* op = lp->beg;
|
|
|
|
while( op != NULL )
|
|
{
|
|
idxV[i] = op->frmIdx;
|
|
++i;
|
|
|
|
offV[j] = op->offs;
|
|
++j;
|
|
|
|
op = op->linkPtr;
|
|
}
|
|
|
|
assert( i == extraN + lp->cnt );
|
|
assert( j == lp->cnt );
|
|
|
|
|
|
// write the frame index vector
|
|
if((rc = cmFrameFileWriteMtxUInt(h, mtxId, kInvalidUId, idxV, extraN + lp->cnt, 1 )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// write the frame offset vector
|
|
if((rc = cmFrameFileWriteMtxOff_t(h, mtxId, kInvalidUId, offV, lp->cnt, 1 )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
errLabel:
|
|
return rc;
|
|
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteToC( cmFrameFileH_t h, _cmFfToC_t* tocPtr, unsigned* mtxIdPtr, void** memPtr )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
|
|
// write the mtx offset matrix
|
|
_cmFfToC_t* cp = tocPtr;
|
|
|
|
while( cp != NULL )
|
|
{
|
|
enum { hdrN = 4 };
|
|
|
|
unsigned hdrV[hdrN];
|
|
|
|
// add 4 elements to the frame index vector containing header information
|
|
hdrV[0] = cp->streamId;
|
|
hdrV[1] = cp->mtxType;
|
|
hdrV[2] = cp->mtxUnitsId;
|
|
hdrV[3] = cp->mtxFmtId;
|
|
|
|
//printf("write : stream:%i type:0x%x units:%i fmt:%i\n",cp->streamId,cp->mtxType,cp->mtxUnitsId,cp->mtxFmtId);
|
|
|
|
if((rc = _cmFfWriteOffsList(h,&cp->offsList,*mtxIdPtr,memPtr,hdrV,hdrN)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
--(*mtxIdPtr);
|
|
|
|
cp = cp->linkPtr;
|
|
}
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFfWriteTocFrame( cmFrameFileH_t h )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
void* uV = NULL;
|
|
unsigned mtxId = kTocMId;
|
|
|
|
// seek to the end of the file
|
|
if((rc = _cmFfSeek(p,SEEK_END,0)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// store the offset to this frame
|
|
if((rc = _cmFfTell(p,&p->eofOffset)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// create the offset data frame
|
|
if((rc = cmFrameFileFrameCreate(h, kTocFrameTId, kTocStreamId, cmInvalidIdx, DBL_MAX)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// write the frame offset ToC
|
|
if((rc = _cmFfWriteToC(h, p->frmToC, &mtxId, &uV )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// write the mtx offset ToC
|
|
if((rc = _cmFfWriteToC(h, p->mtxToC, &mtxId, &uV )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// write the EOF frame
|
|
if((rc = cmFrameFileFrameClose(h)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// decrease the frameCnt so that the eof frame is not included in the file header frame count
|
|
//--p->f.frameCnt;
|
|
|
|
errLabel:
|
|
cmMemPtrFree(&uV);
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFfLoadTocFrame( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
cmFfRC_t rc = kOkFfRC;
|
|
const cmFfFrame_t* frmDescPtr = NULL;
|
|
off_t orgOff;
|
|
unsigned i,j,k;
|
|
|
|
if((rc = _cmFfTell(p,&orgOff)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfSeek(p,SEEK_SET,p->eofOffset)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = cmFrameFileFrameNext(h, kTocFrameTId, kTocStreamId )) != kOkFfRC )
|
|
{
|
|
rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Error reading EOF frame header.");
|
|
goto errLabel;
|
|
}
|
|
|
|
if((rc = cmFrameFileFrameLoad(h, &frmDescPtr)) != kOkFfRC )
|
|
{
|
|
rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Error loading EOF frame.");
|
|
goto errLabel;
|
|
}
|
|
|
|
for(i=0,j=0; i<frmDescPtr->mtxCnt; i+=2,++j)
|
|
{
|
|
const cmFfMtx_t* frmIdxMtxDescPtr = NULL;
|
|
const cmFfMtx_t* offsMtxDescPtr = NULL;
|
|
const unsigned* frmIdxV;
|
|
const off_t* frmOffV;
|
|
|
|
// read the frame index vector
|
|
if((frmIdxV = cmFrameFileMtxUInt( h, kTocMId-j, kInvalidUId, &frmIdxMtxDescPtr )) == NULL )
|
|
{
|
|
rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Matrix frame index read failed for matrix type id %i.",kTocMId-j);
|
|
goto errLabel;
|
|
}
|
|
|
|
// read the offset vector
|
|
if((frmOffV = cmFrameFileMtxOff_t( h, kTocMId-j, kInvalidUId, &offsMtxDescPtr )) == NULL )
|
|
{
|
|
rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Matrix frame offset read failed for matrix type id %i.",kTocMId-j);
|
|
goto errLabel;
|
|
}
|
|
|
|
assert( frmIdxMtxDescPtr->rowCnt>=4 && frmIdxMtxDescPtr->rowCnt-4 == offsMtxDescPtr->rowCnt );
|
|
|
|
// decode the frame index header
|
|
unsigned streamId = frmIdxV[0];
|
|
unsigned mtxType = frmIdxV[1];
|
|
unsigned mtxUnitsId = frmIdxV[2];
|
|
unsigned mtxFmtId = frmIdxV[3];
|
|
|
|
// increment the frame index vector passed the header
|
|
frmIdxV += 4;
|
|
|
|
|
|
bool frmTocFl = mtxType==kInvalidMId && mtxUnitsId==kInvalidUId && mtxFmtId==kInvalidUId;
|
|
|
|
for(k=0; k<offsMtxDescPtr->rowCnt && rc==kOkFfRC; ++k)
|
|
{
|
|
if( frmTocFl )
|
|
rc = _cmFfAppendFrameToC(p, streamId, frmIdxV[k], frmOffV[k] );
|
|
else
|
|
rc = _cmFfAppendMtxToC(p, streamId, mtxType, mtxUnitsId, mtxFmtId, frmIdxV[k], frmOffV[k] );
|
|
}
|
|
}
|
|
|
|
|
|
if((rc = _cmFfSeek(p,SEEK_SET,orgOff)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
cmFfRC_t _cmFrameFileFree( cmFf_t* p )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
|
|
if( p == NULL )
|
|
return rc;
|
|
|
|
// free the frame data ptr
|
|
cmMemPtrFree(&p->frame.dataPtr);
|
|
|
|
// free the mtx array ptr
|
|
cmMemPtrFree(&p->frame.mtxArray);
|
|
|
|
// close the file
|
|
if( p->fp != NULL )
|
|
{
|
|
if( fclose(p->fp) == EOF )
|
|
rc = _cmFfError(p,kFileCloseFailFfRC,errno,"File close failed.");
|
|
else
|
|
p->fp = NULL;
|
|
}
|
|
|
|
cmMemPtrFree(&p->writeMtxMem);
|
|
|
|
// release the filename string
|
|
cmMemPtrFree(&p->f.filenameStr);
|
|
|
|
cmLHeapDestroy(&p->lhH);
|
|
|
|
cmMemPtrFree(&p);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
cmFfRC_t cmFrameFileCreate( cmFrameFileH_t* hPtr, const char* fn, double srate, cmCtx_t* ctx )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
// be sure the handle is not already in use
|
|
if( (rc = cmFrameFileClose(hPtr)) != kOkFfRC )
|
|
return rc;
|
|
|
|
unsigned version = 0;
|
|
cmFf_t* p;
|
|
|
|
// allocate the file object
|
|
if((p = cmMemAllocZ( cmFf_t, 1 )) == NULL )
|
|
return _cmFfError(NULL,kMemAllocErrFfRC,0,"Memory allocation failed.");
|
|
|
|
cmErrSetup(&p->err,&ctx->rpt,"FrameFile");
|
|
p->ctx = *ctx;
|
|
|
|
// create the linked heap
|
|
if( cmLHeapIsValid(p->lhH = cmLHeapCreate( 16384, ctx )) == false )
|
|
{
|
|
rc = _cmFfError( p, kLHeapFailFfRC,0,"Linked heap create failed.");
|
|
goto errLabel;
|
|
}
|
|
|
|
// create the output file
|
|
if((p->fp = fopen(fn,"w+b")) == NULL )
|
|
{
|
|
rc = _cmFfError( p,kFileOpenFailFfRC,errno,"Unable to create the file:'%s'.",fn);
|
|
goto errLabel;
|
|
}
|
|
|
|
// type, byteCnt, frameCnt, , version
|
|
unsigned v[] = { kFileFfTId, 0, 0, version };
|
|
if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned) ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// eof frame offset
|
|
if((rc = _cmFfWriteOff_t( p, p->eofOffset)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// file sample rate
|
|
if((rc = _cmFfWriteDouble( p, srate ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
|
|
p->writeFl = true;
|
|
p->fileChkByteCnt = 4 * sizeof(unsigned); // hdr bytes after byteCnt
|
|
p->nxtFrmIdx = 1;
|
|
p->curFrmIdx = cmInvalidIdx;
|
|
p->frameOffset = cmInvalidIdx;
|
|
p->eofOffset = cmInvalidIdx;
|
|
p->f.frameCnt = 0;
|
|
p->f.srate = srate;
|
|
p->f.version = version;
|
|
p->f.filenameStr = cmMemResizeStr(p->f.filenameStr,fn);
|
|
p->swapFl = false;
|
|
hPtr->h = p;
|
|
|
|
if((rc = _cmFfTell( p, &p->rewOffset )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
return rc;
|
|
|
|
errLabel:
|
|
|
|
_cmFrameFileFree(p);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileOpen( cmFrameFileH_t* hPtr, const char* fn, cmCtx_t* ctx, const cmFfFile_t** fileDescPtrPtr )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p;
|
|
unsigned fileId;
|
|
|
|
if( fileDescPtrPtr != NULL )
|
|
*fileDescPtrPtr = NULL;
|
|
|
|
// be sure the handle is not already in use
|
|
if((rc = cmFrameFileClose(hPtr)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// allocate the file object
|
|
if((p = cmMemAllocZ( cmFf_t, 1 )) == NULL )
|
|
return _cmFfError(NULL,kMemAllocErrFfRC,0,"Memory allocation failed.");
|
|
|
|
cmErrSetup(&p->err,&ctx->rpt,"Frame File");
|
|
p->ctx = *ctx;
|
|
|
|
|
|
// create the linked heap
|
|
if( cmLHeapIsValid(p->lhH = cmLHeapCreate( 2048, ctx )) == false )
|
|
{
|
|
rc = _cmFfError( p, kLHeapFailFfRC,0,"Linked heap create failed.");
|
|
goto errLabel;
|
|
}
|
|
|
|
// open the file for reading
|
|
if((p->fp = fopen(fn,"r+b")) == NULL )
|
|
{
|
|
rc = _cmFfError( p,kFileOpenFailFfRC,errno,"Unable to open the file:'%s'.",fn);
|
|
goto errLabel;
|
|
}
|
|
|
|
p->writeFl = false;
|
|
|
|
// file type id
|
|
if((rc = _cmFfReadUInt( p, &fileId ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// verify that this is a frame file
|
|
if( fileId != kFileFfTId )
|
|
{
|
|
if( cmSwap32(fileId) == kFileFfTId )
|
|
p->swapFl = true;
|
|
else
|
|
{
|
|
rc = _cmFfError( p,kNotFrameFileFfRC,0,"'%s' is not a frame file.",fn);
|
|
goto errLabel;
|
|
}
|
|
}
|
|
|
|
// file chunk size
|
|
if((rc = _cmFfReadUInt( p, &p->fileChkByteCnt ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// file frame count
|
|
if((rc = _cmFfReadUInt( p, &p->f.frameCnt ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// file format version
|
|
if((rc = _cmFfReadUInt( p, &p->f.version ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// eof offset
|
|
if((rc = _cmFfReadOff_t( p, &p->eofOffset) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// file sample rate
|
|
if((rc = _cmFfReadDouble( p, &p->f.srate ) ) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
p->f.filenameStr = cmMemResizeStr(p->f.filenameStr,fn);
|
|
p->nxtFrmIdx = 0;
|
|
p->curFrmIdx = cmInvalidIdx;
|
|
p->frameOffset = cmInvalidIdx;
|
|
|
|
hPtr->h = p;
|
|
|
|
if((rc = _cmFfLoadTocFrame(*hPtr)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfTell(p,&p->rewOffset)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if( fileDescPtrPtr != NULL )
|
|
*fileDescPtrPtr = &p->f;
|
|
|
|
return rc;
|
|
|
|
errLabel:
|
|
|
|
_cmFrameFileFree(p);
|
|
|
|
hPtr->h = NULL;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
cmFfRC_t cmFrameFileClose( cmFrameFileH_t* hp )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
if( hp== NULL || cmFrameFileIsValid(*hp)==false)
|
|
return kOkFfRC;
|
|
|
|
cmFf_t* p = _cmFfHandleToPtr(*hp);
|
|
|
|
if( p->fp != NULL )
|
|
{
|
|
|
|
// update the file header
|
|
if( p->writeFl )
|
|
{
|
|
if((rc = _cmFfWriteTocFrame(*hp)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// rewind into the file header
|
|
if((rc = _cmFfSeek( p, SEEK_SET, sizeof(unsigned) )) != kOkFfRC )
|
|
return rc;
|
|
|
|
// update the file chunk size
|
|
if((rc = _cmFfWriteUInt( p, p->fileChkByteCnt ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
// update the file frame count
|
|
if((rc = _cmFfWriteUInt( p, p->f.frameCnt ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
// rewrite the version
|
|
if((rc = _cmFfWriteUInt( p, p->f.version ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
// update the eof frame offset
|
|
if((rc = _cmFfWriteOff_t(p, p->eofOffset ) ) != kOkFfRC )
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
_cmFrameFileFree(p);
|
|
|
|
hp->h = NULL;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
bool cmFrameFileIsValid( cmFrameFileH_t h )
|
|
{ return h.h != NULL; }
|
|
|
|
const cmFfFile_t* cmFrameFileDesc( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
return &p->f;
|
|
}
|
|
|
|
unsigned cmFrameFileFrameCount( cmFrameFileH_t h, unsigned streamId )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
_cmFfToC_t* cp = p->frmToC;
|
|
|
|
while(cp != NULL )
|
|
{
|
|
if( cp->streamId == streamId )
|
|
return cp->offsList.cnt;
|
|
|
|
cp = cp->linkPtr;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameCreate( cmFrameFileH_t h, unsigned frameType, unsigned streamId, unsigned sampleIdx, double secs )
|
|
{
|
|
cmFfRC_t rc;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned flags = sampleIdx == -1 ? kSecondsTimeFl : kSampleIdxTimeFl;
|
|
|
|
if( p->writeFl == false )
|
|
return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot create new frames on frame files opened in read mode.");
|
|
|
|
|
|
// save the frame offset for later use in cmFrameFileCloseFrame()
|
|
if((rc = _cmFfTell(p,&p->frameOffset)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// update the frame offset list
|
|
assert( p->nxtFrmIdx > 0 );
|
|
rc = _cmFfAppendFrameToC(p, streamId, p->nxtFrmIdx-1, p->frameOffset );
|
|
|
|
|
|
// frame: type, byteCnt, mtxCnt, streamId, flags, sampleIdx
|
|
unsigned v[] = { frameType, 0, 0, streamId, flags, sampleIdx };
|
|
if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned) ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
if((rc = _cmFfWriteDouble( p, secs)) != kOkFfRC )
|
|
return rc;
|
|
|
|
p->frame.f.type = frameType;
|
|
p->frame.byteCnt = 6 * sizeof(unsigned);
|
|
p->frame.f.mtxCnt = 0;
|
|
p->frame.f.streamId = streamId;
|
|
p->frame.f.flags = flags;
|
|
p->frame.f.time.seconds = 0;
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameClose( cmFrameFileH_t h )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
|
|
if( h.h == NULL )
|
|
return kOkFfRC;
|
|
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
// frames open in read-mode do not need to be closed
|
|
if( p->writeFl == false )
|
|
return kOkFfRC;
|
|
|
|
assert( p->frameOffset != 0 );
|
|
|
|
// store the current file position
|
|
off_t offs; // = ftello(p->fp);
|
|
if((rc = _cmFfTell(p,&offs)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// seek to the frame byte count
|
|
if((rc = _cmFfSeek( p, SEEK_SET, p->frameOffset+sizeof(unsigned) )) != kOkFfRC )
|
|
return rc;
|
|
|
|
// write frame byteCnt
|
|
if((rc = _cmFfWriteUInt( p, p->frame.byteCnt ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
// write frame mtxCnt
|
|
if((rc = _cmFfWriteUInt( p, p->frame.f.mtxCnt ) ) != kOkFfRC )
|
|
return rc;
|
|
|
|
p->f.frameCnt++;
|
|
p->nxtFrmIdx++;
|
|
p->frameOffset = 0;
|
|
|
|
p->frame.byteCnt = 0;
|
|
memset( &p->frame.f, 0, sizeof(p->frame.f));
|
|
|
|
|
|
|
|
// jump back to the end of the file
|
|
return _cmFfSeek(p, SEEK_SET, offs );
|
|
|
|
}
|
|
|
|
|
|
cmFfRC_t _cmFrameFileWriteMtx( cmFf_t* p, unsigned type, unsigned unitsId, unsigned fmtId, const void* dataPtr, unsigned rn, unsigned cn, bool writeTocFl )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
// track the file offset to this matrix
|
|
if( p->writeFl && writeTocFl )
|
|
{
|
|
off_t fileOff;
|
|
|
|
// get file offs to this mtx
|
|
if((rc = _cmFfTell(p,&fileOff)) != kOkFfRC )
|
|
return rc;
|
|
|
|
assert( p->nxtFrmIdx >= 1 );
|
|
|
|
// append a recd representing this matrix to the mtx TOC
|
|
rc = _cmFfAppendMtxToC(p, p->frame.f.streamId, type, unitsId, fmtId, p->nxtFrmIdx-1, fileOff );
|
|
}
|
|
|
|
unsigned wordByteCnt = _cmFfIdToFmtPtr(fmtId)->wordByteCnt;
|
|
unsigned byteCnt = rn*cn*wordByteCnt;
|
|
|
|
|
|
// write the mtx header
|
|
// mtx: type, byteCnt, fmtId, unitsId, rowCnt, colCnt
|
|
unsigned v[] = { type, byteCnt, fmtId, unitsId, rn, cn };
|
|
if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned))) != kOkFfRC )
|
|
return rc;
|
|
|
|
const void* src_buf = dataPtr;
|
|
|
|
if( p->swapFl )
|
|
{
|
|
p->writeMtxMem = cmMemResize( char, p->writeMtxMem, byteCnt );
|
|
src_buf = _cmFfSwapVector(p->writeMtxMem,src_buf,rn*cn,wordByteCnt);
|
|
}
|
|
|
|
// write the mtx data
|
|
if(( rc = _cmFfWrite(p,src_buf,byteCnt)) != kOkFfRC )
|
|
return rc;
|
|
|
|
|
|
// write pad - all matrices must end on 64 bit boundaries
|
|
unsigned n = byteCnt % 8;
|
|
|
|
if( n )
|
|
{
|
|
assert( n < 8 );
|
|
|
|
char v[8];
|
|
memset(v,0,8);
|
|
if(( rc = _cmFfWrite(p,v,n)) != kOkFfRC )
|
|
return rc;
|
|
|
|
}
|
|
|
|
++p->frame.f.mtxCnt;
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtx( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, unsigned dataFmtId, const void* dataPtr, unsigned rn, unsigned cn )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
return _cmFrameFileWriteMtx(p, mtxType, unitsId, dataFmtId, dataPtr, rn, cn, true );
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxUChar( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned char* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kUCharFmtId, dataPtr, rn, cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxChar( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kCharFmtId, dataPtr, rn, cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxUShort( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned short* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kUShortFmtId, dataPtr,rn,cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxShort( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const short* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kShortFmtId, dataPtr, rn, cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxULong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kULongFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kLongFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxUInt( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kUIntFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxInt( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const int* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kIntFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxULLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long long* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kULLongFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxLLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long long* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kLLongFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxOff_t( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const off_t* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kOff_tFmtId, dataPtr, rn, cn );}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxFloat( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const float* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kFloatFmtId, dataPtr, rn, cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxDouble( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const double* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kDoubleFmtId, dataPtr, rn, cn ); }
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxBlob( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const void* dataPtr, unsigned rn, unsigned cn )
|
|
{ return cmFrameFileWriteMtx( h, mtxType, unitsId, kBlobFmtId, dataPtr, rn, cn ); }
|
|
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxStringZ( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char* stringPtr )
|
|
{
|
|
unsigned n = strlen(stringPtr);
|
|
return cmFrameFileWriteMtx( h, mtxType, kInvalidUId, kStringZFmtId, stringPtr, n+1, 1 );
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileWriteMtxJson( cmFrameFileH_t h, unsigned mtxType, cmJsonH_t jsH, const cmJsonNode_t* nodePtr )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
void* buf = NULL;
|
|
unsigned bufByteCnt = 0;
|
|
|
|
if( cmJsonSerializeTree( jsH, nodePtr, &buf, &bufByteCnt ) != kOkJsRC )
|
|
return _cmFfError(p,kJsonFailFfRC,0,"JSON serialuze failed.");
|
|
|
|
return _cmFrameFileWriteMtx(p, mtxType, kNoUnitsUId, kJsonFmtId, buf, 1, bufByteCnt, true );
|
|
}
|
|
|
|
// Can only be called when p->fp is pointed to the beginning of a frame.
|
|
// Leaves file pointing to frame header 'flags' field.
|
|
cmFfRC_t _cmFrameFileFrameSeek( cmFf_t* p, unsigned keyFrameTypeId, unsigned keyFrameStreamId )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
|
|
while( rc == kOkFfRC )
|
|
{
|
|
// frame type
|
|
if((rc = _cmFfReadUInt(p,&p->frame.f.type)) != kOkFfRC )
|
|
break;
|
|
|
|
// frame byte count
|
|
if((rc = _cmFfReadUInt(p,&p->frame.byteCnt)) != kOkFfRC )
|
|
break;
|
|
|
|
// frame mtx count
|
|
if((rc = _cmFfReadUInt(p,&p->frame.f.mtxCnt)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// frame stream id
|
|
if((rc = _cmFfReadUInt(p,&p->frame.f.streamId)) != kOkFfRC )
|
|
break;
|
|
|
|
// condition: no match on type
|
|
if( (keyFrameTypeId == kInvalidFrameTId) && (keyFrameStreamId == kInvalidFrameTId || keyFrameStreamId == p->frame.f.streamId) )
|
|
break;
|
|
|
|
// condition: match on type
|
|
if( (keyFrameTypeId == p->frame.f.type) && (keyFrameStreamId == kInvalidFrameTId || keyFrameStreamId == p->frame.f.streamId) )
|
|
break;
|
|
|
|
// goto the next frame
|
|
if((rc = _cmFfSeek(p,SEEK_CUR,p->frame.byteCnt - (2*sizeof(unsigned)))) != kOkFfRC )
|
|
break;
|
|
|
|
++p->nxtFrmIdx;
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileRewind( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
p->nxtFrmIdx = 0;
|
|
|
|
return _cmFfSeek(p,SEEK_SET,p->rewOffset);
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileSeek( cmFrameFileH_t h, unsigned streamId, unsigned frameIdx )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned i = 0;
|
|
_cmFfToC_t* tocPtr;
|
|
|
|
|
|
|
|
// locate the frame TOC recd assoc'd with stream id
|
|
if((tocPtr = _cmFfFindToCPtr(p, p->frmToC, streamId, kInvalidMId, kInvalidUId, kInvalidFmtId )) == NULL )
|
|
{
|
|
rc = _cmFfError(p,kTocRecdNotFoundFfRC,0,"Unable to locate the TOC record for stream id %i.",streamId);
|
|
goto errLabel;
|
|
}
|
|
|
|
// locate the TOC offset recd assoc'd with frameIdx
|
|
_cmFfOffs_t* cp = tocPtr->offsList.beg;
|
|
for(; cp != NULL && i!=frameIdx; ++i )
|
|
cp = cp->linkPtr;
|
|
|
|
|
|
// if the frame index was not valid
|
|
if( cp == NULL )
|
|
{
|
|
rc = _cmFfError(p,kInvalidFrameIdxFfRC,0,"%i is an invalid frame index for stream id %i.",frameIdx,streamId);
|
|
goto errLabel;
|
|
}
|
|
|
|
// seek to the beginning of the frame
|
|
if((rc = _cmFfSeek(p,SEEK_SET,cp->offs)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
|
|
// Can only be called when p->fp is pointed to the beginning of a frame.
|
|
cmFfRC_t cmFrameFileFrameNext( cmFrameFileH_t h, unsigned keyFrameTypeId, unsigned keyFrameStreamId )
|
|
{
|
|
cmFfRC_t rc;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned sampleIdx;
|
|
double seconds;
|
|
|
|
// go to the requested frame
|
|
if((rc = _cmFrameFileFrameSeek(p, keyFrameTypeId, keyFrameStreamId)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// frame flags
|
|
if((rc = _cmFfReadUInt(p,&p->frame.f.flags)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// frame sample idx
|
|
if((rc = _cmFfReadUInt(p,&sampleIdx)) != kOkFfRC )
|
|
return rc;
|
|
|
|
// frame seconds
|
|
if((rc = _cmFfReadDouble(p,&seconds)) != kOkFfRC )
|
|
return rc;
|
|
|
|
if( cmIsFlag(p->frame.f.flags,kSampleIdxTimeFl) )
|
|
p->frame.f.time.sampleIdx = sampleIdx;
|
|
|
|
if( cmIsFlag(p->frame.f.flags,kSecondsTimeFl) )
|
|
p->frame.f.time.seconds = seconds;
|
|
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFrameFileCheckForDuplicateMtxId( cmFrameFileH_t h )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned i;
|
|
|
|
for(i=0; i<p->frame.f.mtxCnt; ++i)
|
|
{
|
|
unsigned mtxIdx = cmFrameFileMtxIndex(h, p->frame.mtxArray[i].m.type, p->frame.mtxArray[i].m.unitsId, p->frame.mtxArray[i].m.fmtId );
|
|
|
|
assert( mtxIdx != cmInvalidIdx );
|
|
|
|
if( mtxIdx != i )
|
|
{
|
|
rc = _cmFfError( p, kDuplicateMtxIdFfRC, 0, "Duplicate matrix signatures exist form type:%i units:%i fmt:%i at frame index %i.", p->frame.mtxArray[i].m.type, p->frame.mtxArray[i].m.unitsId, p->frame.mtxArray[i].m.fmtId,p->nxtFrmIdx );
|
|
goto errLabel;
|
|
}
|
|
|
|
}
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
// read a matrix header and data
|
|
cmFfRC_t _cmFfReadMtx( cmFf_t* p, _cmFfMtx_t* mp, void* buf, unsigned bufByteCnt )
|
|
{
|
|
cmFfRC_t rc;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->m.type)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->byteCnt)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->m.fmtId)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->m.unitsId)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->m.rowCnt)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadUInt(p,&mp->m.colCnt)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if( buf != NULL )
|
|
{
|
|
if( mp->byteCnt > bufByteCnt )
|
|
{
|
|
rc = _cmFfError(p,kBufTooSmallFfRC,0, "Matrix buffer too small to complete the read.");
|
|
goto errLabel;
|
|
}
|
|
|
|
// read in the mtx data
|
|
if((rc = _cmFfRead(p,buf,mp->byteCnt)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
|
|
if( p->swapFl )
|
|
{
|
|
// swap on read
|
|
_cmFfSwapVector(buf,buf,mp->m.rowCnt*mp->m.colCnt, _cmFfIdToFmtPtr(mp->m.fmtId)->wordByteCnt );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameLoad( cmFrameFileH_t h, const cmFfFrame_t** frameDescPtrPtr )
|
|
{
|
|
cmFfRC_t rc;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned i;
|
|
|
|
if(frameDescPtrPtr != NULL)
|
|
*frameDescPtrPtr = NULL;
|
|
|
|
// store pointer to matrix data offset - for use in cmFrameFileFrameUpdate()
|
|
if((rc = _cmFfTell(p,&p->frameOffset)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// create a block of memory large enough to hold the entire frame
|
|
// (this is more than is actually needed because it includes the mtx header records)
|
|
p->frame.dataPtr = cmMemResizeZ( char, p->frame.dataPtr, p->frame.byteCnt );
|
|
|
|
// create a mtx array to hold each mtx record
|
|
p->frame.mtxArray = cmMemResizeZ( _cmFfMtx_t, p->frame.mtxArray, p->frame.f.mtxCnt );
|
|
|
|
char* dp = p->frame.dataPtr;
|
|
unsigned emptyByteCnt = p->frame.byteCnt;
|
|
|
|
// for each matrix in this frame
|
|
for(i=0; i<p->frame.f.mtxCnt; ++i)
|
|
{
|
|
_cmFfMtx_t* mp = p->frame.mtxArray + i;
|
|
|
|
mp->dataPtr = dp;
|
|
|
|
// read the matrix header and data
|
|
if((rc = _cmFfReadMtx(p, mp, dp, emptyByteCnt )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// read any pad bytes
|
|
unsigned n = mp->byteCnt % 8;
|
|
|
|
if( n )
|
|
{
|
|
char v[8];
|
|
if((rc = _cmFfRead(p,v,n)) != kOkFfRC )
|
|
goto errLabel;
|
|
}
|
|
|
|
// verify the buffer size
|
|
if(mp->byteCnt > emptyByteCnt )
|
|
{
|
|
rc = _cmFfError(p,kBufTooSmallFfRC,0, "Matrix buffer too small to complete the read.");
|
|
goto errLabel;
|
|
}
|
|
|
|
emptyByteCnt -= mp->byteCnt; // decrement the available buffer space
|
|
dp += mp->byteCnt; // advance the matrix data buffer pointer
|
|
|
|
}
|
|
|
|
if(rc==kOkFfRC && frameDescPtrPtr != NULL)
|
|
*frameDescPtrPtr = &p->frame.f;
|
|
|
|
// verify that duplicate matrx signatures do not exist.
|
|
// (only the first of the duplicate will be accessable)
|
|
assert( _cmFrameFileCheckForDuplicateMtxId(h) == kOkFfRC );
|
|
|
|
p->curFrmIdx = p->nxtFrmIdx;
|
|
++p->nxtFrmIdx;
|
|
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameSkip( cmFrameFileH_t h )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned hdrBytes = 32 - 8; // sizeof(frame hdr) - (sizeof(hdr.type) + sizeof(hdr.chkbyteCnt))
|
|
|
|
assert(hdrBytes<=p->frame.byteCnt);
|
|
|
|
if((rc = _cmFfSeek( p, SEEK_CUR, p->frame.byteCnt - hdrBytes)) == kOkFfRC )
|
|
{
|
|
++p->nxtFrmIdx;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameLoadNext( cmFrameFileH_t h, unsigned frameTypeId, unsigned streamId, const cmFfFrame_t** frameDescPtrPtr )
|
|
{
|
|
cmFfRC_t rc;
|
|
if((rc = cmFrameFileFrameNext(h,frameTypeId,streamId)) != kOkFfRC )
|
|
return rc;
|
|
|
|
return cmFrameFileFrameLoad(h,frameDescPtrPtr);
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileFrameUpdate( cmFrameFileH_t h )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned i = 0;
|
|
off_t offs;
|
|
|
|
if((rc = _cmFfTell(p,&offs)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// seek to the matrix data
|
|
if((rc = _cmFfSeek(p, SEEK_SET, p->frameOffset )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// for each matrix
|
|
for(i=0; i<p->frame.f.mtxCnt; ++i)
|
|
{
|
|
const _cmFfMtx_t* m = p->frame.mtxArray + i;
|
|
|
|
// rewrite each matrix
|
|
if((rc = _cmFrameFileWriteMtx(p, m->m.type, m->m.unitsId, m->m.fmtId, m->dataPtr, m->m.rowCnt, m->m.colCnt, false )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// cmFrameFileWriteMtx increments the matrix count - so we decrement it here
|
|
--p->frame.f.mtxCnt;
|
|
}
|
|
|
|
// restore the file position
|
|
if((rc = _cmFfSeek(p, SEEK_SET, offs )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
errLabel:
|
|
return rc;
|
|
|
|
}
|
|
|
|
const cmFfFrame_t* cmFrameFileFrameDesc( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
return &p->frame.f;
|
|
}
|
|
|
|
unsigned cmFrameFileFrameLoadedIndex( cmFrameFileH_t h )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
return p->curFrmIdx;
|
|
|
|
}
|
|
|
|
unsigned cmFrameFileMtxIndex( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, unsigned fmtId )
|
|
{
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
unsigned i;
|
|
|
|
for(i=0; i<p->frame.f.mtxCnt; ++i)
|
|
{
|
|
if( mtxTypeId==kInvalidMId || mtxTypeId == p->frame.mtxArray[i].m.type )
|
|
if( unitsId==kInvalidUId || unitsId == p->frame.mtxArray[i].m.unitsId )
|
|
if( fmtId==kInvalidFmtId || fmtId == p->frame.mtxArray[i].m.fmtId )
|
|
return i;
|
|
|
|
}
|
|
|
|
return cmInvalidIdx;
|
|
}
|
|
|
|
const cmFfMtx_t* cmFrameFileMtxDesc( cmFrameFileH_t h, unsigned mtxIdx )
|
|
{ cmFf_t* p = _cmFfHandleToPtr(h);
|
|
assert( mtxIdx < p->frame.f.mtxCnt );
|
|
return &p->frame.mtxArray[ mtxIdx ].m;
|
|
}
|
|
|
|
void* _cmFrameFileMtxIndexDataPtr( cmFrameFileH_t h, unsigned dataFmtId, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{
|
|
if( mtxIdx == cmInvalidIdx )
|
|
return NULL;
|
|
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
assert( mtxIdx < p->frame.f.mtxCnt );
|
|
assert( p->frame.mtxArray[mtxIdx].m.fmtId == dataFmtId );
|
|
|
|
if( descPtrPtr != NULL )
|
|
*descPtrPtr = &p->frame.mtxArray[ mtxIdx ].m;
|
|
|
|
return p->frame.mtxArray[mtxIdx].dataPtr;
|
|
}
|
|
|
|
|
|
|
|
unsigned char* cmFrameFileMtxIndexUChar( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned char*)_cmFrameFileMtxIndexDataPtr( h, kUCharFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
char* cmFrameFileMtxIndexChar( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (char*)_cmFrameFileMtxIndexDataPtr( h, kCharFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
unsigned short* cmFrameFileMtxIndexUShort( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned short*) _cmFrameFileMtxIndexDataPtr( h, kUShortFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
short* cmFrameFileMtxIndexShort( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (short*)_cmFrameFileMtxIndexDataPtr( h, kShortFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
unsigned long* cmFrameFileMtxIndexULong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned long*)_cmFrameFileMtxIndexDataPtr( h, kULongFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
long* cmFrameFileMtxIndexLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (long*) _cmFrameFileMtxIndexDataPtr( h, kLongFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
unsigned* cmFrameFileMtxIndexUInt( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned*) _cmFrameFileMtxIndexDataPtr( h, kUIntFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
int* cmFrameFileMtxIndexInt( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (int*) _cmFrameFileMtxIndexDataPtr( h, kIntFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
unsigned long long* cmFrameFileMtxIndexULLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned long long*) _cmFrameFileMtxIndexDataPtr( h, kULLongFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
long long* cmFrameFileMtxIndexLLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (long long*) _cmFrameFileMtxIndexDataPtr( h, kLLongFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
off_t* cmFrameFileMtxIndexOff_t( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (off_t*) _cmFrameFileMtxIndexDataPtr( h, kOff_tFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
float* cmFrameFileMtxIndexFloat( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (float*)_cmFrameFileMtxIndexDataPtr( h, kFloatFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
double* cmFrameFileMtxIndexDouble( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (double*)_cmFrameFileMtxIndexDataPtr( h, kDoubleFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
char* cmFrameFileMtxIndexStringZ( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return (char*)_cmFrameFileMtxIndexDataPtr( h, kStringZFmtId, mtxIdx, descPtrPtr ); }
|
|
|
|
void* cmFrameFileMtxIndexBlob( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{ return _cmFrameFileMtxIndexDataPtr( h, kBlobFmtId, mtxIdx, descPtrPtr );}
|
|
|
|
cmJsonH_t cmFrameFileMtxIndexJson( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
const void* buf;
|
|
const cmFfMtx_t* dp = NULL;
|
|
cmJsRC_t jsRC;
|
|
cmJsonH_t jsH = cmJsonNullHandle;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
if( descPtrPtr != NULL )
|
|
*descPtrPtr = NULL;
|
|
|
|
if( (buf= _cmFrameFileMtxIndexDataPtr( h, kJsonFmtId, mtxIdx, &dp)) == NULL )
|
|
goto errLabel;
|
|
|
|
if((jsRC = cmJsonInitialize( &jsH, &p->ctx )) != kOkJsRC )
|
|
{
|
|
rc = _cmFfError(p,kJsonFailFfRC,0,"JSON object allocation failed.");
|
|
goto errLabel;
|
|
}
|
|
|
|
if((jsRC = cmJsonDeserialize( jsH, buf, NULL )) != kOkJsRC )
|
|
{
|
|
rc = _cmFfError(p, kJsonFailFfRC, 0, "JSON deserialization failed.");
|
|
goto errLabel;
|
|
}
|
|
|
|
errLabel:
|
|
|
|
if( rc != kOkFfRC )
|
|
cmJsonFinalize(&jsH);
|
|
else
|
|
if( descPtrPtr != NULL )
|
|
*descPtrPtr = dp;
|
|
|
|
return jsH;
|
|
}
|
|
|
|
|
|
|
|
unsigned char* cmFrameFileMtxUChar( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned char*)_cmFrameFileMtxIndexDataPtr( h, kUCharFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId, kUCharFmtId), descPtrPtr ); }
|
|
|
|
char* cmFrameFileMtxChar( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (char*)_cmFrameFileMtxIndexDataPtr( h, kCharFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kCharFmtId), descPtrPtr ); }
|
|
|
|
unsigned short* cmFrameFileMtxUShort( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned short*)_cmFrameFileMtxIndexDataPtr( h, kUShortFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kUShortFmtId), descPtrPtr); }
|
|
|
|
short* cmFrameFileMtxShort( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (short*)_cmFrameFileMtxIndexDataPtr( h, kShortFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kShortFmtId), descPtrPtr); }
|
|
|
|
unsigned long* cmFrameFileMtxULong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned long*)_cmFrameFileMtxIndexDataPtr( h, kULongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kULongFmtId), descPtrPtr ); }
|
|
|
|
long* cmFrameFileMtxLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (long*)_cmFrameFileMtxIndexDataPtr( h, kLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kLongFmtId), descPtrPtr ); }
|
|
|
|
unsigned* cmFrameFileMtxUInt( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned*)_cmFrameFileMtxIndexDataPtr( h, kUIntFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kUIntFmtId), descPtrPtr ); }
|
|
|
|
int* cmFrameFileMtxInt( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (int*)_cmFrameFileMtxIndexDataPtr( h, kIntFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kIntFmtId), descPtrPtr ); }
|
|
|
|
unsigned long long* cmFrameFileMtxULLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (unsigned long long*)_cmFrameFileMtxIndexDataPtr( h, kULLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kULLongFmtId), descPtrPtr ); }
|
|
|
|
long long* cmFrameFileMtxLLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (long long*)_cmFrameFileMtxIndexDataPtr( h, kLLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kLLongFmtId), descPtrPtr ); }
|
|
|
|
off_t* cmFrameFileMtxOff_t( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (off_t*)_cmFrameFileMtxIndexDataPtr( h, kOff_tFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kOff_tFmtId), descPtrPtr ); }
|
|
|
|
float* cmFrameFileMtxFloat( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (float*)_cmFrameFileMtxIndexDataPtr( h, kFloatFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kFloatFmtId), descPtrPtr ); }
|
|
|
|
double* cmFrameFileMtxDouble( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (double*)_cmFrameFileMtxIndexDataPtr( h, kDoubleFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kDoubleFmtId), descPtrPtr ); }
|
|
|
|
char* cmFrameFileMtxStringZ( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return (char*)_cmFrameFileMtxIndexDataPtr( h, kStringZFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kStringZFmtId), descPtrPtr ); }
|
|
|
|
void* cmFrameFileMtxBlob( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
|
|
{ return _cmFrameFileMtxIndexDataPtr( h, kBlobFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kBlobFmtId), descPtrPtr ); }
|
|
|
|
cmJsonH_t cmFrameFileMtxJson( cmFrameFileH_t h, unsigned mtxTypeId, const cmFfMtx_t** descPtrPtr )
|
|
{ return cmFrameFileMtxIndexJson(h, cmFrameFileMtxIndex(h,mtxTypeId,kNoUnitsUId,kJsonFmtId), descPtrPtr ); }
|
|
|
|
|
|
cmFfRC_t cmFrameFileMtxSize( cmFrameFileH_t h, unsigned streamId, unsigned mtxType, unsigned unitsId, unsigned fmtId, unsigned* frmCntPtr, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleCntPtr )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
_cmFfToC_t* tocPtr;
|
|
_cmFfOffs_t* op;
|
|
_cmFfMtx_t mtx;
|
|
|
|
*frmCntPtr = 0;
|
|
*eleCntPtr = 0;
|
|
*rowCntPtr = 0;
|
|
*colCntPtr = 0;
|
|
|
|
if((tocPtr = _cmFfFindToCPtr(p, p->mtxToC, streamId, mtxType, unitsId, fmtId )) == NULL )
|
|
{
|
|
rc = _cmFfError( p, kTocRecdNotFoundFfRC, 0, "Unable to locate the requested matrix in stream:%i mtx:%i units:%i fmt:%i.",streamId, mtxType, unitsId, fmtId );
|
|
goto errLabel;
|
|
}
|
|
|
|
op = tocPtr->offsList.beg;
|
|
|
|
while(op != NULL )
|
|
{
|
|
if((rc = _cmFfSeek(p,SEEK_SET, op->offs )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadMtx(p,&mtx,NULL,0)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
*frmCntPtr += 1;
|
|
|
|
*eleCntPtr += mtx.m.rowCnt * mtx.m.colCnt;
|
|
|
|
if( mtx.m.rowCnt > *rowCntPtr )
|
|
*rowCntPtr = mtx.m.rowCnt;
|
|
|
|
if( mtx.m.colCnt > *colCntPtr )
|
|
*colCntPtr = mtx.m.colCnt;
|
|
|
|
op = op->linkPtr;
|
|
}
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t _cmFrameFileMtxLoad( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned fmtId, unsigned frmIdx, unsigned frmCnt, void* buf, unsigned bufEleCnt, unsigned* outCntPtr )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
char* dp = buf;
|
|
unsigned wordByteCnt = _cmFfIdToFmtPtr(fmtId)->wordByteCnt;
|
|
int dpn = bufEleCnt*wordByteCnt;
|
|
_cmFfToC_t* tocPtr;
|
|
_cmFfMtx_t mtx;
|
|
unsigned fi;
|
|
|
|
if( outCntPtr != NULL )
|
|
*outCntPtr = 0;
|
|
|
|
if((tocPtr = _cmFfFindToCPtr(p, p->mtxToC, streamId, mtxTypeId, unitsId, fmtId )) == NULL )
|
|
{
|
|
rc = _cmFfError( p, kTocRecdNotFoundFfRC, 0, "Unable to locate the requested matrix in stream:%i mtx:%i units:%i fmt:%i.",streamId, mtxTypeId, unitsId, fmtId );
|
|
goto errLabel;
|
|
}
|
|
|
|
_cmFfOffs_t* op = tocPtr->offsList.beg;
|
|
|
|
for(fi=0; op != NULL && (frmCnt==-1 || fi<(frmIdx+frmCnt)); ++fi )
|
|
{
|
|
if( frmIdx<=fi )
|
|
{
|
|
if((rc = _cmFfSeek(p,SEEK_SET, op->offs )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFfReadMtx(p,&mtx,dp,dpn)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
int readByteCnt = mtx.m.rowCnt * mtx.m.colCnt * wordByteCnt;
|
|
|
|
if( readByteCnt > dpn )
|
|
{
|
|
rc = _cmFfError( p, kBufTooSmallFfRC, 0, "The matrix load buffer is too small.");
|
|
goto errLabel;
|
|
}
|
|
|
|
dpn -= readByteCnt;
|
|
dp += readByteCnt;
|
|
}
|
|
|
|
op = op->linkPtr;
|
|
}
|
|
|
|
if( outCntPtr != NULL )
|
|
*outCntPtr = bufEleCnt - (dpn/wordByteCnt);
|
|
|
|
errLabel:
|
|
return rc;
|
|
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadUChar( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned char* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadChar( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, char* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadUShort( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned short* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUShortFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadShort( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, short* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kShortFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadULong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned long* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kULongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, long* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadUInt( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned int* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUIntFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadInt( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, int* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kIntFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadULLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned long long* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kULLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadLLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, long long* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kLLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadFloat( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, float* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kFloatFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadDouble( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, double* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kDoubleFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadStringZ( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, char* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kStringZFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
cmFfRC_t cmFrameFileMtxLoadBlob( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, void* buf, unsigned eleCnt, unsigned* outCntPtr )
|
|
{ return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
|
|
|
|
|
|
void _cmFrameFilePrint( cmRpt_t* rpt, const char* fmt, ... )
|
|
{
|
|
assert(rpt != NULL);
|
|
|
|
va_list vl;
|
|
va_start(vl,fmt);
|
|
cmRptVPrintf(rpt,fmt,vl);
|
|
va_end(vl);
|
|
}
|
|
|
|
|
|
cmFfRC_t _cmFrameFileMtxReport( const cmFf_t* p, unsigned mtxIdx, cmRpt_t* rpt )
|
|
{
|
|
assert( mtxIdx < p->frame.f.mtxCnt );
|
|
|
|
const _cmFfMtx_t* mp = p->frame.mtxArray + mtxIdx;
|
|
|
|
_cmFrameFilePrint(rpt," type:0x%x units:0x%x fmtId:0x%x rowCnt:%i colCnt:%i byteCnt:%i\n",mp->m.type,mp->m.unitsId,mp->m.fmtId,mp->m.rowCnt,mp->m.colCnt,mp->byteCnt);
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
cmFfRC_t _cmFrameFileFrameReport( const cmFf_t* p, cmRpt_t* rpt )
|
|
{
|
|
unsigned i;
|
|
_cmFrameFilePrint(rpt,"type:0x%x mtxCnt:%i flags:0x%x streamId:%i byteCnt:%i\n", p->frame.f.type,p->frame.f.mtxCnt,p->frame.f.flags,p->frame.f.streamId,p->frame.byteCnt);
|
|
|
|
for(i=0; i<p->frame.f.mtxCnt; ++i)
|
|
_cmFrameFileMtxReport(p,i,rpt);
|
|
|
|
return kOkFfRC;
|
|
}
|
|
|
|
void _cmFrameFileContentsReport(const cmFf_t* p, const _cmFfToC_t* tocPtr, cmRpt_t* rpt )
|
|
{
|
|
const _cmFfToC_t* cp = tocPtr;
|
|
unsigned i;
|
|
|
|
for(i=0; cp != NULL; ++i )
|
|
{
|
|
bool frmFl = cp->mtxType==kInvalidMId && cp->mtxUnitsId==kInvalidUId && cp->mtxFmtId==kInvalidFmtId;
|
|
|
|
_cmFrameFilePrint( rpt, "%i streamId:%i ",i, cp->streamId );
|
|
|
|
if( !frmFl )
|
|
_cmFrameFilePrint( rpt, "type:%i units:%i fmt:%i ",cp->mtxType, cp->mtxUnitsId, cp->mtxFmtId );
|
|
|
|
_cmFrameFilePrint( rpt, "cnt:%i\n", cp->offsList.cnt );
|
|
|
|
cp = cp->linkPtr;
|
|
}
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileReport( cmFrameFileH_t h, bool summOnlyFl, cmRpt_t* rpt )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
cmFf_t* p = _cmFfHandleToPtr(h);
|
|
|
|
if(p->writeFl )
|
|
return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot report on files opened in write mode.");
|
|
|
|
_cmFrameFilePrint(rpt,"frames:%i srate:%f\n",p->f.frameCnt,p->f.srate);
|
|
|
|
_cmFrameFilePrint(rpt,"Frame Contents:\n");
|
|
_cmFrameFileContentsReport(p, p->frmToC, rpt );
|
|
|
|
_cmFrameFilePrint(rpt,"Matrix Contents:\n");
|
|
_cmFrameFileContentsReport(p, p->mtxToC, rpt );
|
|
|
|
if( summOnlyFl )
|
|
{
|
|
unsigned i;
|
|
|
|
if((rc = cmFrameFileRewind(h)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
for(i=0; cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,NULL) == kOkFfRC; ++i)
|
|
{
|
|
_cmFrameFilePrint(rpt," %i ",i);
|
|
if((rc = _cmFrameFileFrameReport(p,rpt)) != kOkFfRC )
|
|
break;
|
|
}
|
|
|
|
assert(i==p->f.frameCnt);
|
|
}
|
|
errLabel:
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileNameReport( const char* fn, bool summOnlyFl, cmCtx_t* ctx )
|
|
{
|
|
cmFrameFileH_t h;
|
|
cmFfRC_t rc0,rc1;
|
|
|
|
if((rc0 = cmFrameFileOpen( &h, fn, ctx, NULL)) != kOkFfRC )
|
|
return rc0;
|
|
|
|
rc0 = cmFrameFileReport(h,summOnlyFl,&ctx->rpt);
|
|
|
|
|
|
rc1 = cmFrameFileClose(&h);
|
|
return rc0 != kOkFfRC ? rc0 : rc1;
|
|
}
|
|
|
|
/*
|
|
void cmFrameFileVTestPrintFunc( void* userDataPtr, const char* fmt, va_list vl )
|
|
{
|
|
vfprintf(stdout,fmt,vl);
|
|
}
|
|
*/
|
|
|
|
|
|
cmFfRC_t _cmFrameFileTestMtx( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, unsigned mtxCnt, unsigned i, bool modFl )
|
|
{
|
|
cmFfRC_t rc = kOkFfRC;
|
|
const cmFfMtx_t* mtxDescPtr = NULL;
|
|
unsigned j,k;
|
|
|
|
for(j=0; j<mtxCnt; ++j)
|
|
{
|
|
long* dp = NULL;
|
|
double* ddp = NULL;
|
|
|
|
if( j == 3 )
|
|
{
|
|
if((ddp = cmFrameFileMtxDouble(h, mtxType + j, unitsId, &mtxDescPtr )) == NULL )
|
|
{
|
|
printf("READ ERROR\n");
|
|
goto errLabel;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if((dp = cmFrameFileMtxLong(h, mtxType + j, unitsId, &mtxDescPtr )) == NULL )
|
|
{
|
|
printf("READ ERROR\n");
|
|
goto errLabel;
|
|
}
|
|
}
|
|
|
|
printf("%2i %2i : ",i,j);
|
|
|
|
// print the mtx data
|
|
if( j == 3 )
|
|
{
|
|
for(k=0; k<mtxDescPtr->colCnt*mtxDescPtr->rowCnt; k++)
|
|
{
|
|
printf("%2.0f ",ddp[k]);
|
|
|
|
// if pass 1 modify the data
|
|
if( modFl )
|
|
++ddp[k];
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
for(k=0; k<mtxDescPtr->colCnt*mtxDescPtr->rowCnt; k++)
|
|
{
|
|
printf("%2li ",dp[k]);
|
|
|
|
// if pass 1 modify the data
|
|
if( modFl )
|
|
++dp[k];
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileTest2( const char* fn, cmCtx_t* ctx )
|
|
{
|
|
cmFfRC_t rc;
|
|
cmFrameFileH_t ffH;
|
|
const cmFfFile_t* descPtr;
|
|
|
|
if((rc = cmFrameFileOpen(&ffH, fn, ctx, &descPtr )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
|
|
rc = cmFrameFileClose(&ffH);
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
cmFfRC_t cmFrameFileTest( const char* fn, cmCtx_t* ctx )
|
|
{
|
|
//return cmFrameFileTest2("/media/disk/home/kevin/temp/temp0.ft");
|
|
|
|
cmFfRC_t rc = kOkFfRC;
|
|
double srate = 44100;
|
|
unsigned frameType = 0x32333435;
|
|
unsigned streamId = 1;
|
|
unsigned sampleIdx = 0;
|
|
unsigned unitsId = kNoUnitsUId;
|
|
cmFrameFileH_t h;
|
|
const cmFfFile_t* fileDescPtr = NULL;
|
|
const cmFfFrame_t* frmDescPtr = NULL;
|
|
unsigned mtxType = 0x40414243;
|
|
unsigned i,j,k,m;
|
|
|
|
if((rc = cmFrameFileCreate( &h, fn, srate, ctx )) != kOkFfRC )
|
|
return rc;
|
|
|
|
// create 3 frames
|
|
for(i=0; i<3; ++i,sampleIdx++)
|
|
{
|
|
if((rc = cmFrameFileFrameCreate(h, frameType, streamId, sampleIdx, 0 )) == kOkFfRC )
|
|
{
|
|
long data[] = { 0,1,2,3,4,5,6,7,8,9,10 };
|
|
double ddata[] = { 10,11,12,13,14,15,16,17,18,19,20 };
|
|
unsigned n = sizeof(data)/sizeof(data[0]);
|
|
|
|
for(j=0; j<n; ++j)
|
|
data[j] += i;
|
|
|
|
// write 3 matrices
|
|
for(k=0; k<3; ++k)
|
|
{
|
|
if((rc = cmFrameFileWriteMtxLong( h, mtxType + k, unitsId, data, n, 1 )) != kOkFfRC )
|
|
return rc;
|
|
}
|
|
|
|
if((rc = cmFrameFileWriteMtxDouble( h, mtxType + k, unitsId, ddata, n, 1 )) != kOkFfRC )
|
|
return rc;
|
|
|
|
if((rc = cmFrameFileFrameClose(h)) != kOkFfRC )
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
if((rc = cmFrameFileClose(&h)) != kOkFfRC )
|
|
return rc;
|
|
|
|
|
|
if((rc = cmFrameFileOpen( &h, fn, ctx,&fileDescPtr )) != kOkFfRC )
|
|
return rc;
|
|
|
|
// make two passes:
|
|
// pass 1: read/print/modify
|
|
// pass 2: read/print
|
|
for(m=0; m<2; ++m)
|
|
{
|
|
// report the overall file format and types
|
|
if((rc = cmFrameFileReport( h, false, &ctx->rpt )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// rewind the file
|
|
if((rc = cmFrameFileRewind(h)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// for each frame
|
|
for(i=0; cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,&frmDescPtr)==kOkFfRC; ++i)
|
|
{
|
|
if( frmDescPtr->type == kTocFrameTId )
|
|
break;
|
|
|
|
// print each matrix in this frame
|
|
if((rc = _cmFrameFileTestMtx( h, mtxType, unitsId, frmDescPtr->mtxCnt, i, m==0 )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
// if pass 1 write the modified data back to disk
|
|
if( m == 0 )
|
|
if((rc = cmFrameFileFrameUpdate(h)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
|
|
} // end frame loop
|
|
|
|
|
|
} // end pass loop
|
|
|
|
|
|
if((rc = cmFrameFileClose(&h)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
|
|
//
|
|
// test cmFrameFileSeek() by seeking to frame 'fi'
|
|
//
|
|
|
|
printf("seek test\n");
|
|
unsigned fi = 2;
|
|
|
|
if((rc = cmFrameFileOpen( &h, fn,ctx,&fileDescPtr )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = cmFrameFileSeek( h, streamId, fi )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,&frmDescPtr)) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
if((rc = _cmFrameFileTestMtx( h, mtxType, unitsId, frmDescPtr->mtxCnt, fi, false )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
//
|
|
// test cmFrameFileMtxSize
|
|
//
|
|
unsigned frmCnt = 0;
|
|
unsigned rowCnt = 0;
|
|
unsigned colCnt = 0;
|
|
unsigned eleCnt = 0;
|
|
if((rc = cmFrameFileMtxSize(h, streamId, mtxType, unitsId, kLongFmtId, &frmCnt, &rowCnt, &colCnt, &eleCnt )) != kOkFfRC )
|
|
goto errLabel;
|
|
|
|
printf("frames:%i rows:%i cols:%i eles:%i\n",frmCnt,rowCnt,colCnt,eleCnt);
|
|
|
|
if(1)
|
|
{
|
|
unsigned actualEleCnt;
|
|
unsigned eleCnt = frmCnt*rowCnt*colCnt;
|
|
long buf[ eleCnt ];
|
|
if((rc = cmFrameFileMtxLoadLong(h, streamId, mtxType, unitsId, 0, -1, buf, eleCnt, &actualEleCnt )) == kOkFfRC )
|
|
{
|
|
cmVOI_Print(&ctx->rpt,rowCnt,frmCnt,(int*)buf);
|
|
}
|
|
}
|
|
|
|
|
|
errLabel:
|
|
if( rc != kOkFfRC )
|
|
printf("ERROR:%i\n",rc);
|
|
|
|
if((rc = cmFrameFileClose(&h)) != kOkFfRC )
|
|
return rc;
|
|
|
|
return rc;
|
|
|
|
}
|