📄 avc_bin.c
字号:
* Returns 0 on success or -1 on error. **********************************************************************/int _AVCBinReadHeader(AVCRawBinFile *psFile, AVCBinHeader *psHeader, AVCCoverType eCoverType){ int nStatus = 0; /*----------------------------------------------------------------- * For AVCCoverPC coverages, there is a first 256 bytes header * that we just skip and that precedes the 100 bytes header block. * * In AVCCoverV7, we only have the 100 bytes header. *----------------------------------------------------------------*/ if (eCoverType == AVCCoverPC) AVCRawBinFSeek(psFile, 256, SEEK_SET); else AVCRawBinFSeek(psFile, 0, SEEK_SET); psHeader->nSignature = AVCRawBinReadInt32(psFile); if (AVCRawBinEOF(psFile)) nStatus = -1; psHeader->nPrecision = AVCRawBinReadInt32(psFile); psHeader->nRecordSize= AVCRawBinReadInt32(psFile); /* Jump to 24th byte in header */ AVCRawBinFSeek(psFile, 12, SEEK_CUR); psHeader->nLength = AVCRawBinReadInt32(psFile); /*----------------------------------------------------------------- * File length, in words (16 bits)... pass the info to the RawBinFile * to prevent it from trying to read junk bytes at the end of files... * this problem happens specially with PC Arc/Info files. *----------------------------------------------------------------*/ if (eCoverType == AVCCoverPC) AVCRawBinSetFileDataSize(psFile, psHeader->nLength*2 + 256); else AVCRawBinSetFileDataSize(psFile, psHeader->nLength*2 ); /* Move the pointer at the end of the 100 bytes header */ AVCRawBinFSeek(psFile, 72, SEEK_CUR); return nStatus;}/********************************************************************** * AVCBinReadRewind() * * Rewind the read pointer, and read/skip the header if necessary so * that we are ready to read the data objects from the file after * this call. * * Returns 0 on success, -1 on error, and -2 if file has an invalid * signature and is possibly corrupted. **********************************************************************/int AVCBinReadRewind(AVCBinFile *psFile){ AVCBinHeader sHeader; int nStatus=0; /*----------------------------------------------------------------- * For AVCCoverPC coverages, there is a first 256 bytes header * that we just skip and that precedes the 100 bytes header block. * * In AVCCoverV7 and AVCCoverWeird, we only find the 100 bytes header. * * Note: it is the call to _AVCBinReadHeader() that takes care * of skipping the first 256 bytes header if necessary. *----------------------------------------------------------------*/ AVCRawBinFSeek(psFile->psRawBinFile, 0, SEEK_SET); if ( psFile->eFileType == AVCFileARC || psFile->eFileType == AVCFilePAL || psFile->eFileType == AVCFileRPL || psFile->eFileType == AVCFileCNT || psFile->eFileType == AVCFileLAB || psFile->eFileType == AVCFileTXT || psFile->eFileType == AVCFileTX6 ) { nStatus = _AVCBinReadHeader(psFile->psRawBinFile, &sHeader, psFile->eCoverType); /* Store the precision information inside the file handle. * * Of course, there had to be an exception... * At least PAL and TXT files in PC Arc/Info coverages sometimes * have a negative precision flag even if they contain single * precision data... why is that???? A PC Arc bug? * * 2000-06-05: Found a double-precision PAL file with a signature * of 1011 (should have been -11). So we'll assume * that signature > 1000 also means double precision. */ if ((sHeader.nPrecision < 0 || sHeader.nPrecision > 1000) && psFile->eCoverType != AVCCoverPC) psFile->nPrecision = AVC_DOUBLE_PREC; else psFile->nPrecision = AVC_SINGLE_PREC; /* Validate the signature value... this will allow us to detect * corrupted files or files that do not belong in the coverage. */ if (sHeader.nSignature != 9993 && sHeader.nSignature != 9994) { CPLError(CE_Warning, CPLE_AssertionFailed, "%s appears to have an invalid file header.", psFile->pszFilename); return -2; } /* In Weird coverages, TXT files can be stored in the PC or the V7 * format. Look at the 'precision' field in the header to tell which * type we have. * Weird TXT in PC format: nPrecision = 16 * Weird TXT in V7 format: nPrecision = +/-67 * Use AVCFileTXT for PC type, and AVCFileTX6 for V7 type. */ if (psFile->eCoverType == AVCCoverWeird && psFile->eFileType == AVCFileTXT && ABS(sHeader.nPrecision) == 67) { /* TXT file will be processed as V7 TXT/TX6/TX7 */ psFile->eFileType = AVCFileTX6; } } else if (psFile->eFileType == AVCFileTOL) { /*------------------------------------------------------------- * For some reason, the tolerance files do not follow the * general rules! * Single precision "tol.adf" have no header * Double precision "par.adf" have the usual 100 bytes header, * but the 3rd field, which usually defines the precision has * a positive value, even if the file is double precision! * * Also, we have a problem with PC Arc/Info TOL files since they * do not contain the first 256 bytes header either... so we will * just assume that double precision TOL files cannot exist in * PC Arc/Info coverages... this should be OK. *------------------------------------------------------------*/ int nSignature = 0; nSignature = AVCRawBinReadInt32(psFile->psRawBinFile); if (nSignature == 9993) { /* We have a double precision par.adf... read the 100 bytes * header and set the precision information inside the file * handle. */ nStatus = _AVCBinReadHeader(psFile->psRawBinFile, &sHeader, psFile->eCoverType); psFile->nPrecision = AVC_DOUBLE_PREC; } else { /* It's a single precision tol.adf ... just set the * precision field. */ AVCRawBinFSeek(psFile->psRawBinFile, 0, SEEK_SET); psFile->nPrecision = AVC_SINGLE_PREC; } } return nStatus;}/********************************************************************** * AVCBinReadObject() * * Read the object with a particular index. For fixed length record * files we seek directly to the object. For variable files we try to * get the offset from the corresponding index file. * * NOTE: Currently only implemented for ARC, PAL and TABLE files. * * Returns the read object on success or NULL on error. **********************************************************************/void *AVCBinReadObject(AVCBinFile *psFile, int iObjIndex ){ int bIndexed = FALSE; int nObjectOffset, nRecordSize=0, nRecordStart = 0, nLen; char *pszExt = NULL; if( iObjIndex < 0 ) return NULL; /*----------------------------------------------------------------- * Determine some information from based on the coverage type. *----------------------------------------------------------------*/ nLen = strlen(psFile->pszFilename); if( psFile->eFileType == AVCFileARC && ((nLen>=3 && EQUALN((pszExt=psFile->pszFilename+nLen-3), "arc", 3)) || (nLen>=7 && EQUALN((pszExt=psFile->pszFilename+nLen-7),"arc.adf",7)))) { bIndexed = TRUE; } else if( psFile->eFileType == AVCFilePAL && ((nLen>=3 && EQUALN((pszExt=psFile->pszFilename+nLen-3), "pal", 3)) || (nLen>=7 && EQUALN((pszExt=psFile->pszFilename+nLen-7),"pal.adf",7)))) { bIndexed = TRUE; } else if( psFile->eFileType == AVCFileTABLE ) { bIndexed = FALSE; nRecordSize = psFile->hdr.psTableDef->nRecSize; nRecordStart = 0; } else return NULL; /*----------------------------------------------------------------- * Ensure the index file is opened if an index file is required. *----------------------------------------------------------------*/ if( bIndexed && psFile->psIndexFile == NULL ) { char chOrig; if( pszExt == NULL ) return NULL; chOrig = pszExt[2]; if( chOrig > 'A' && chOrig < 'Z' ) pszExt[2] = 'X'; else pszExt[2] = 'x'; psFile->psIndexFile = AVCRawBinOpen( psFile->pszFilename, "rb", psFile->psRawBinFile->eByteOrder, psFile->psRawBinFile->psDBCSInfo); pszExt[2] = chOrig; if( psFile->psIndexFile == NULL ) return NULL; } /*----------------------------------------------------------------- * Establish the offset to read the object from. *----------------------------------------------------------------*/ if( bIndexed ) { int nIndexOffset; if (psFile->eCoverType == AVCCoverPC) nIndexOffset = 356 + (iObjIndex-1)*8; else nIndexOffset = 100 + (iObjIndex-1)*8; AVCRawBinFSeek( psFile->psIndexFile, nIndexOffset, SEEK_SET ); if( AVCRawBinEOF( psFile->psIndexFile ) ) return NULL; nObjectOffset = AVCRawBinReadInt32( psFile->psIndexFile ); nObjectOffset *= 2; if (psFile->eCoverType == AVCCoverPC) nObjectOffset += 256; } else nObjectOffset = nRecordStart + nRecordSize * (iObjIndex-1); /*----------------------------------------------------------------- * Seek to the start of the object in the data file. *----------------------------------------------------------------*/ AVCRawBinFSeek( psFile->psRawBinFile, nObjectOffset, SEEK_SET ); if( AVCRawBinEOF( psFile->psRawBinFile ) ) return NULL; /*----------------------------------------------------------------- * Read and return the object. *----------------------------------------------------------------*/ return AVCBinReadNextObject( psFile );}/********************************************************************** * AVCBinReadNextObject() * * Read the next structure from the file. This function is just a generic * cover on top of the AVCBinReadNextArc/Lab/Pal/Cnt() functions. * * Returns a (void*) to a static structure with the contents of the object * that was read. The contents of the structure will be valid only until * the next call. * If you use the returned value, then make sure that you cast it to * the right type for the current file! (AVCArc, AVCPal, AVCCnt, ...) * * Returns NULL if an error happened or if EOF was reached. **********************************************************************/void *AVCBinReadNextObject(AVCBinFile *psFile){ void *psObj = NULL; switch(psFile->eFileType) { case AVCFileARC: psObj = (void*)AVCBinReadNextArc(psFile); break; case AVCFilePAL: case AVCFileRPL: psObj = (void*)AVCBinReadNextPal(psFile); break; case AVCFileCNT: psObj = (void*)AVCBinReadNextCnt(psFile); break; case AVCFileLAB: psObj = (void*)AVCBinReadNextLab(psFile); break; case AVCFileTOL: psObj = (void*)AVCBinReadNextTol(psFile); break; case AVCFileTXT: case AVCFileTX6: psObj = (void*)AVCBinReadNextTxt(psFile); break; case AVCFileRXP: psObj = (void*)AVCBinReadNextRxp(psFile); break; case AVCFileTABLE: psObj = (void*)AVCBinReadNextTableRec(psFile); break; default: CPLError(CE_Failure, CPLE_IllegalArg, "AVCBinReadNextObject(): Unsupported file type!"); } return psObj;}/********************************************************************** * AVCBinReadNextTableRec() * * Reads the next record from an attribute table. * * Returns a pointer to an array of static AVCField structure whose * contents will be valid only until the next call, * or NULL if an error happened or if EOF was reached. **********************************************************************/AVCField *AVCBinReadNextTableRec(AVCBinFile *psFile){ if (psFile->eCoverType != AVCCoverPC && psFile->eFileType == AVCFileTABLE && psFile->hdr.psTableDef->numRecords > 0 && ! AVCRawBinEOF(psFile->psRawBinFile) && _AVCBinReadNextTableRec(psFile->psRawBinFile, psFile->hdr.psTableDef->numFields, psFile->hdr.psTableDef->pasFieldDef, psFile->cur.pasFields, psFile->hdr.psTableDef->nRecSize) == 0 ) { return psFile->cur.pasFields; } else if (psFile->eCoverType == AVCCoverPC && psFile->eFileType == AVCFileTABLE && psFile->hdr.psTableDef->numRecords > 0 && _AVCBinReadNextDBFTableRec(psFile->hDBFFile, &(psFile->nCurDBFRecord), psFile->hdr.psTableDef->numFields,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -