CEOSDataset::~CEOSDataset() { FlushCache(); if( psCEOS ) CEOSClose( psCEOS ); }
CEOSImage * CEOSOpen( const char * pszFilename, const char * pszAccess ) { VSILFILE *fp; CEOSRecord *psRecord; CEOSImage *psImage; int nSeqNum, i; GByte abyHeader[16]; /* -------------------------------------------------------------------- */ /* Try to open the imagery file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpenL( pszFilename, pszAccess ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open CEOS file `%s' with access `%s'.\n", pszFilename, pszAccess ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a CEOSImage structure, and initialize it. */ /* -------------------------------------------------------------------- */ psImage = (CEOSImage *) CPLCalloc(1,sizeof(CEOSImage)); psImage->fpImage = fp; psImage->nPixels = psImage->nLines = psImage->nBands = 0; /* -------------------------------------------------------------------- */ /* Preread info on the first record, to establish if it is */ /* little endian. */ /* -------------------------------------------------------------------- */ VSIFReadL( abyHeader, 16, 1, fp ); VSIFSeekL( fp, 0, SEEK_SET ); if( abyHeader[0] != 0 || abyHeader[1] != 0 ) psImage->bLittleEndian = TRUE; /* -------------------------------------------------------------------- */ /* Try to read the header record. */ /* -------------------------------------------------------------------- */ psRecord = CEOSReadRecord( psImage ); if( psRecord == NULL ) { CEOSClose( psImage ); return NULL; } if( psRecord->nRecordType != CRT_IMAGE_FDR ) { CPLError( CE_Failure, CPLE_AppDefined, "Got a %X type record, instead of the expected\n" "file descriptor record on file %s.\n", psRecord->nRecordType, pszFilename ); CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } /* -------------------------------------------------------------------- */ /* The sequence number should be 2 indicating this is the */ /* imagery file. */ /* -------------------------------------------------------------------- */ nSeqNum = CEOSScanInt( psRecord->pachData + 44, 4 ); if( nSeqNum != 2 ) { CPLError( CE_Warning, CPLE_AppDefined, "Got a %d file sequence number, instead of the expected\n" "2 indicating imagery on file %s.\n" "Continuing to access anyways.\n", nSeqNum, pszFilename ); } /* -------------------------------------------------------------------- */ /* Extract various information. */ /* -------------------------------------------------------------------- */ psImage->nImageRecCount = CEOSScanInt( psRecord->pachData+180, 6 ); psImage->nImageRecLength = CEOSScanInt( psRecord->pachData+186, 6 ); psImage->nBitsPerPixel = CEOSScanInt( psRecord->pachData+216, 4 ); psImage->nBands = CEOSScanInt( psRecord->pachData+232, 4 ); psImage->nLines = CEOSScanInt( psRecord->pachData+236, 8 ); psImage->nPixels = CEOSScanInt( psRecord->pachData+248, 8 ); psImage->nPrefixBytes = CEOSScanInt( psRecord->pachData+276, 4 ); psImage->nSuffixBytes = CEOSScanInt( psRecord->pachData+288, 4 ); if( psImage->nImageRecLength <= 0 || psImage->nPrefixBytes < 0 || psImage->nBands > INT_MAX / psImage->nImageRecLength || (size_t)psImage->nBands > INT_MAX / sizeof(int)) { CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to establish the layout of the imagery data. */ /* -------------------------------------------------------------------- */ psImage->nLineOffset = psImage->nBands * psImage->nImageRecLength; psImage->panDataStart = (int *) VSIMalloc(sizeof(int) * psImage->nBands); if( psImage->panDataStart == NULL ) { CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } for( i = 0; i < psImage->nBands; i++ ) { psImage->panDataStart[i] = psRecord->nLength + i * psImage->nImageRecLength + 12 + psImage->nPrefixBytes; } CEOSDestroyRecord( psRecord ); return psImage; }
GDALDataset *CEOSDataset::Open( GDALOpenInfo * poOpenInfo ) { CEOSImage *psCEOS; int i; /* -------------------------------------------------------------------- */ /* Before trying CEOSOpen() we first verify that the first */ /* record is in fact a CEOS file descriptor record. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 100 ) return NULL; if( poOpenInfo->pabyHeader[4] != 0x3f || poOpenInfo->pabyHeader[5] != 0xc0 || poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12 ) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ psCEOS = CEOSOpen( poOpenInfo->pszFilename, "rb" ); if( psCEOS == NULL ) return( NULL ); if( psCEOS->nBitsPerPixel != 8 ) { CPLError( CE_Failure, CPLE_NotSupported, "The CEOS driver cannot handle nBitsPerPixel = %d", psCEOS->nBitsPerPixel ); CEOSClose(psCEOS); return NULL; } if( !GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) || !GDALCheckBandCount(psCEOS->nBands, FALSE) ) { CEOSClose( psCEOS ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CEOSClose(psCEOS); CPLError( CE_Failure, CPLE_NotSupported, "The CEOS driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ CEOSDataset *poDS; poDS = new CEOSDataset(); poDS->psCEOS = psCEOS; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = psCEOS->nPixels; poDS->nRasterYSize = psCEOS->nLines; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = psCEOS->nBands;; for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new CEOSRasterBand( poDS, i+1 ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }