/********************************************************************** * _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; }
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; }