示例#1
0
文件: e00read.cpp 项目: hkaiser/TRiAS
/**********************************************************************
 *                          _E00ReadTestOpen()
 *
 * Given a pre-initialized E00ReadPtr, this function will make sure
 * that the file is really a E00 file, and also establish if it is
 * compressed or not... setting the structure members by the same way.
 *
 * Returns NULL (and destroys the E00ReadPtr) if the file does not
 * appear to be a valid E00 file.
 **********************************************************************/
static E00ReadPtr  _E00ReadTestOpen(E00ReadPtr psInfo)
{

    /* Check that the file is in E00 format.
     */
    _ReadNextSourceLine(psInfo);
    if (!psInfo->bEOF && strncmp(psInfo->szInBuf, "EXP ", 4) == 0)
    {
        /* We should be in presence of a valid E00 file... 
         * Is the file compressed or not?
         *
         * Note: we cannot really rely on the number that follows the EXP to
         * establish if the file is compressed since we sometimes encounter
         * uncompressed files that start with a "EXP 1" line!!!
         *
         * The best test is to read the first non-empty line: if the file is
         * compressed, the first line of data should be 79 or 80 characters 
         * long and contain several '~' characters.
         */
        do
        {
            _ReadNextSourceLine(psInfo);
        }while(!psInfo->bEOF && 
               (psInfo->szInBuf[0] == '\0' || isspace(psInfo->szInBuf[0])) );

         if (!psInfo->bEOF && 
             (strlen(psInfo->szInBuf)==79 || strlen(psInfo->szInBuf)==80) &&
             strchr(psInfo->szInBuf, '~') != NULL )
             psInfo->bIsCompressed = 1;

         /* Move the Read ptr ready to read at the beginning of the file
          */
         E00ReadRewind(psInfo);
    }
    else
    {
        CPLFree(psInfo);
        psInfo = NULL;
    }

    return psInfo;
}
示例#2
0
CPLErr E00GRIDRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
                                      int nBlockYOff,
                                      void * pImage )
{
    E00GRIDDataset *poGDS = (E00GRIDDataset *) poDS;

    char szVal[E00_FLOAT_SIZE+1];
    szVal[E00_FLOAT_SIZE] = 0;

    float* pafImage = (float*)pImage;
    int* panImage = (int*)pImage;
    const float fNoData = static_cast<float>(poGDS->dfNoData);

    /* A new data line begins on a new text line. So if the xsize */
    /* is not a multiple of VALS_PER_LINE, there are padding values */
    /* that must be ignored */
    const int nRoundedBlockXSize = ((nBlockXSize + VALS_PER_LINE - 1) /
                                            VALS_PER_LINE) * VALS_PER_LINE;

    if (poGDS->e00ReadPtr)
    {
        if (poGDS->nLastYOff < 0)
        {
            E00ReadRewind(poGDS->e00ReadPtr);
            for(int i=0;i<6;i++)
                E00ReadNextLine(poGDS->e00ReadPtr);
        }

        if (nBlockYOff == poGDS->nLastYOff + 1)
        {
        }
        else if (nBlockYOff <= poGDS->nMaxYOffset)
        {
            //CPLDebug("E00GRID", "Skip to %d from %d", nBlockYOff, poGDS->nLastYOff);
            VSIFSeekL(poGDS->fp, poGDS->panOffsets[nBlockYOff], SEEK_SET);
            poGDS->nPosBeforeReadLine = poGDS->panOffsets[nBlockYOff];
            poGDS->e00ReadPtr->iInBufPtr = 0;
            poGDS->e00ReadPtr->szInBuf[0] = '\0';
        }
        else if (nBlockYOff > poGDS->nLastYOff + 1)
        {
            //CPLDebug("E00GRID", "Forward skip to %d from %d", nBlockYOff, poGDS->nLastYOff);
            for(int i=poGDS->nLastYOff + 1; i < nBlockYOff;i++)
                IReadBlock(0, i, pImage);
        }

        if (nBlockYOff > poGDS->nMaxYOffset)
        {
            poGDS->panOffsets[nBlockYOff] = poGDS->nPosBeforeReadLine +
                                            poGDS->e00ReadPtr->iInBufPtr;
            poGDS->nMaxYOffset = nBlockYOff;
        }

        const char* pszLine = NULL;
        for(int i=0;i<nBlockXSize;i++)
        {
            if ((i % VALS_PER_LINE) == 0)
            {
                pszLine = E00ReadNextLine(poGDS->e00ReadPtr);
                if (pszLine == NULL || strlen(pszLine) < 5 * E00_FLOAT_SIZE)
                    return CE_Failure;
            }
            if (eDataType == GDT_Float32)
            {
                pafImage[i] = (float) CPLAtof(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE);
                /* Workaround single vs double precision problems */
                if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6)
                    pafImage[i] = fNoData;
            }
            else
            {
                panImage[i] = atoi(pszLine + (i%VALS_PER_LINE) * E00_FLOAT_SIZE);
            }
        }

        poGDS->nLastYOff = nBlockYOff;

        return CE_None;
    }

    vsi_l_offset nValsToSkip = (vsi_l_offset)nBlockYOff * nRoundedBlockXSize;
    vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE;
    int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + poGDS->nBytesEOL;
    vsi_l_offset nPos = poGDS->nDataStart + nLinesToSkip * nBytesPerLine;
    VSIFSeekL(poGDS->fp, nPos, SEEK_SET);

    for(int i=0;i<nBlockXSize;i++)
    {
        if (VSIFReadL(szVal, E00_FLOAT_SIZE, 1, poGDS->fp) != 1)
            return CE_Failure;

        if (eDataType == GDT_Float32)
        {
            pafImage[i] = (float) CPLAtof(szVal);
            /* Workaround single vs double precision problems */
            if (fNoData != 0 && fabs((pafImage[i] - fNoData)/fNoData) < 1e-6)
                pafImage[i] = fNoData;
        }
        else
        {
            panImage[i] = atoi(szVal);
        }

        if (((i+1) % VALS_PER_LINE) == 0)
            VSIFReadL(szVal, poGDS->nBytesEOL, 1, poGDS->fp);
    }

    return CE_None;
}