#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, "" } }; 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; ifp) != 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; iswapFl,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; ibeg; 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; imtxCnt; 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; krowCnt && 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.tm.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.tm.sampleIdx = sampleIdx; if( cmIsFlag(p->frame.f.flags,kSecondsTimeFl) ) p->frame.f.tm.seconds = seconds; return rc; } cmFfRC_t _cmFrameFileCheckForDuplicateMtxId( cmFrameFileH_t h ) { cmFfRC_t rc = kOkFfRC; cmFf_t* p = _cmFfHandleToPtr(h); unsigned i; for(i=0; iframe.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; iframe.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; iframe.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; iframe.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; iframe.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; jcolCnt*mtxDescPtr->rowCnt; k++) { printf("%2.0f ",ddp[k]); // if pass 1 modify the data if( modFl ) ++ddp[k]; } } else { for(k=0; kcolCnt*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; jrpt )) != 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; }