⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avc_bin.c

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 C
📖 第 1 页 / 共 5 页
字号:
 * 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 + -