void Swap() { #ifdef CPL_LSB CPL_SWAP16PTR(&imagic); CPL_SWAP16PTR(&dim); CPL_SWAP16PTR(&xsize); CPL_SWAP16PTR(&ysize); CPL_SWAP16PTR(&zsize); CPL_SWAP32PTR(&min); CPL_SWAP32PTR(&max); #endif }
static void SwapPtr32IfNecessary( bool bMustSwap, void* ptr ) { if( bMustSwap ) { CPL_SWAP32PTR( static_cast<GByte *>(ptr) ); } }
void AVCRawBinWriteFloat(AVCRawBinFile *psFile, float fValue) { if (psFile->eByteOrder != geSystemByteOrder) { CPL_SWAP32PTR( &fValue ); } AVCRawBinWriteBytes(psFile, 4, (GByte*)&fValue); }
static void ConvertLong(GUInt32* array, GInt32 length) { #ifdef CPL_LSB GUInt32* ptr; ptr = (GUInt32*)array; while(length--) CPL_SWAP32PTR(ptr++); #endif }
static void ConvertLong(GUInt32* array, GInt32 length) { GUInt32* ptr = reinterpret_cast<GUInt32*>( array ); while(length--) { CPL_SWAP32PTR(ptr); ptr ++; } }
float AVCRawBinReadFloat(AVCRawBinFile *psFile) { float fValue; AVCRawBinReadBytes(psFile, 4, (GByte*)(&fValue)); if (psFile->eByteOrder != geSystemByteOrder) { CPL_SWAP32PTR( &fValue ); } return fValue; }
OGRErr OGRPoint::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nQual, 4 ); memcpy( pabyData+9, &x, 16 ); if( z != 0 ) { memcpy( pabyData + 9 + 16, &z, 8 ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { CPL_SWAP32PTR( pabyData + 5 ); CPL_SWAPDOUBLE( pabyData + 9 ); CPL_SWAPDOUBLE( pabyData + 9 + 8 ); if( z != 0 ) CPL_SWAPDOUBLE( pabyData + 9 + 16 ); } return OGRERR_NONE; }
void SAGARasterBand::SwapBuffer(void* pImage) { #ifdef CPL_LSB int bSwap = ( m_ByteOrder == 1); #else int bSwap = ( m_ByteOrder == 0); #endif if (bSwap) { if ( m_nBits == 16 ) { short* pImage16 = (short*) pImage; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { CPL_SWAP16PTR( pImage16 + iPixel ); } } else if ( m_nBits == 32 ) { int* pImage32 = (int*) pImage; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { CPL_SWAP32PTR( pImage32 + iPixel ); } } else if ( m_nBits == 64 ) { double* pImage64 = (double*) pImage; for( int iPixel=0; iPixel<nBlockXSize; iPixel++ ) { CPL_SWAP64PTR( pImage64 + iPixel ); } } } }
GDALDataset *RIKDataset::Open( GDALOpenInfo * poOpenInfo ) { if( Identify(poOpenInfo) == FALSE ) return NULL; bool rik3header = false; if( EQUALN((const char *) poOpenInfo->pabyHeader, "RIK3", 4) ) { rik3header = true; VSIFSeekL( poOpenInfo->fpL, 4, SEEK_SET ); } else VSIFSeekL( poOpenInfo->fpL, 0, SEEK_SET ); /* -------------------------------------------------------------------- */ /* Read the map name. */ /* -------------------------------------------------------------------- */ char name[1024]; GUInt16 nameLength = GetRikString( poOpenInfo->fpL, name, sizeof(name) ); if( nameLength > sizeof(name) - 1 ) { return NULL; } if( !rik3header ) { if( nameLength == 0 || nameLength != strlen(name) ) return NULL; } /* -------------------------------------------------------------------- */ /* Read the header. */ /* -------------------------------------------------------------------- */ RIKHeader header; double metersPerPixel; const char *headerType = "RIK3"; if( rik3header ) { /* -------------------------------------------------------------------- */ /* RIK3 header. */ /* -------------------------------------------------------------------- */ // Read projection name char projection[1024]; GUInt16 projLength = GetRikString( poOpenInfo->fpL, projection, sizeof(projection) ); if( projLength > sizeof(projection) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } // Read unknown string projLength = GetRikString( poOpenInfo->fpL, projection, sizeof(projection) ); // Read map north edge char tmpStr[16]; GUInt16 tmpLength = GetRikString( poOpenInfo->fpL, tmpStr, sizeof(tmpStr) ); if( tmpLength > sizeof(tmpStr) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } header.fNorth = CPLAtof( tmpStr ); // Read map west edge tmpLength = GetRikString( poOpenInfo->fpL, tmpStr, sizeof(tmpStr) ); if( tmpLength > sizeof(tmpStr) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } header.fWest = CPLAtof( tmpStr ); // Read binary values VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL ); VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL ); VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL ); VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL ); VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL ); VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iScale ); CPL_SWAP32PTR( &header.iMPPNum ); CPL_SWAP32PTR( &header.iBlockWidth ); CPL_SWAP32PTR( &header.iBlockHeight ); CPL_SWAP32PTR( &header.iHorBlocks ); CPL_SWAP32PTR( &header.iVertBlocks ); #endif VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL ); VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); header.iUnknown = header.iOptions; VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); header.fSouth = header.fNorth - header.iVertBlocks * header.iBlockHeight * header.iMPPNum; header.fEast = header.fWest + header.iHorBlocks * header.iBlockWidth * header.iMPPNum; metersPerPixel = header.iMPPNum; } else { /* -------------------------------------------------------------------- */ /* Old RIK header. */ /* -------------------------------------------------------------------- */ VSIFReadL( &header.iUnknown, 1, sizeof(header.iUnknown), poOpenInfo->fpL ); VSIFReadL( &header.fSouth, 1, sizeof(header.fSouth), poOpenInfo->fpL ); VSIFReadL( &header.fWest, 1, sizeof(header.fWest), poOpenInfo->fpL ); VSIFReadL( &header.fNorth, 1, sizeof(header.fNorth), poOpenInfo->fpL ); VSIFReadL( &header.fEast, 1, sizeof(header.fEast), poOpenInfo->fpL ); VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL ); VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP64PTR( &header.fSouth ); CPL_SWAP64PTR( &header.fWest ); CPL_SWAP64PTR( &header.fNorth ); CPL_SWAP64PTR( &header.fEast ); CPL_SWAP32PTR( &header.iScale ); CPL_SWAP32PTR( &header.iMPPNum ); #endif if (!CPLIsFinite(header.fSouth) | !CPLIsFinite(header.fWest) | !CPLIsFinite(header.fNorth) | !CPLIsFinite(header.fEast)) return NULL; bool offsetBounds; offsetBounds = header.fSouth < 4000000; header.iMPPDen = 1; if( offsetBounds ) { header.fSouth += 4002995; header.fNorth += 5004000; header.fWest += 201000; header.fEast += 302005; VSIFReadL( &header.iMPPDen, 1, sizeof(header.iMPPDen), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iMPPDen ); #endif headerType = "RIK1"; } else { headerType = "RIK2"; } metersPerPixel = header.iMPPNum / double(header.iMPPDen); VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL ); VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL ); VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iBlockWidth ); CPL_SWAP32PTR( &header.iBlockHeight ); CPL_SWAP32PTR( &header.iHorBlocks ); #endif if(( header.iBlockWidth > 2000 ) || ( header.iBlockWidth < 10 ) || ( header.iBlockHeight > 2000 ) || ( header.iBlockHeight < 10 )) return NULL; if( !offsetBounds ) { VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iVertBlocks ); #endif } if( offsetBounds || !header.iVertBlocks ) { header.iVertBlocks = (GUInt32) ceil( (header.fNorth - header.fSouth) / (header.iBlockHeight * metersPerPixel) ); } #if RIK_HEADER_DEBUG CPLDebug( "RIK", "Original vertical blocks %d\n", header.iVertBlocks ); #endif VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL ); if( header.iBitsPerPixel != 8 ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s has unsupported number of bits per pixel.\n", poOpenInfo->pszFilename ); return NULL; } VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); if( !header.iHorBlocks || !header.iVertBlocks ) return NULL; if( header.iOptions != 0x00 && // Uncompressed header.iOptions != 0x40 && // Uncompressed header.iOptions != 0x01 && // RLE header.iOptions != 0x41 && // RLE header.iOptions != 0x0B && // LZW header.iOptions != 0x0D ) // ZLIB { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Unknown map options.\n", poOpenInfo->pszFilename ); return NULL; } } /* -------------------------------------------------------------------- */ /* Read the palette. */ /* -------------------------------------------------------------------- */ GByte palette[768]; GUInt16 i; for( i = 0; i < 256; i++ ) { VSIFReadL( &palette[i * 3 + 2], 1, 1, poOpenInfo->fpL ); VSIFReadL( &palette[i * 3 + 1], 1, 1, poOpenInfo->fpL ); VSIFReadL( &palette[i * 3 + 0], 1, 1, poOpenInfo->fpL ); } /* -------------------------------------------------------------------- */ /* Find block offsets. */ /* -------------------------------------------------------------------- */ GUInt32 blocks; GUInt32 *offsets; blocks = header.iHorBlocks * header.iVertBlocks; offsets = (GUInt32 *)CPLMalloc( blocks * sizeof(GUInt32) ); if( !offsets ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Unable to allocate offset table.\n", poOpenInfo->pszFilename ); return NULL; } if( header.iOptions == 0x00 ) { offsets[0] = VSIFTellL( poOpenInfo->fpL ); for( GUInt32 i = 1; i < blocks; i++ ) { offsets[i] = offsets[i - 1] + header.iBlockWidth * header.iBlockHeight; } } else { for( GUInt32 i = 0; i < blocks; i++ ) { VSIFReadL( &offsets[i], 1, sizeof(offsets[i]), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &offsets[i] ); #endif if( rik3header ) { GUInt32 blockSize; VSIFReadL( &blockSize, 1, sizeof(blockSize), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &blockSize ); #endif } } } /* -------------------------------------------------------------------- */ /* Final checks. */ /* -------------------------------------------------------------------- */ // File size if( VSIFEofL( poOpenInfo->fpL ) ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Read past end of file.\n", poOpenInfo->pszFilename ); return NULL; } VSIFSeekL( poOpenInfo->fpL, 0, SEEK_END ); GUInt32 fileSize = VSIFTellL( poOpenInfo->fpL ); #if RIK_HEADER_DEBUG CPLDebug( "RIK", "File size %d\n", fileSize ); #endif // Make sure the offset table is valid GUInt32 lastoffset = 0; for( GUInt32 y = 0; y < header.iVertBlocks; y++) { for( GUInt32 x = 0; x < header.iHorBlocks; x++) { if( !offsets[x + y * header.iHorBlocks] ) { continue; } if( offsets[x + y * header.iHorBlocks] >= fileSize ) { if( !y ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s too short.\n", poOpenInfo->pszFilename ); return NULL; } header.iVertBlocks = y; break; } if( offsets[x + y * header.iHorBlocks] < lastoffset ) { if( !y ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Corrupt offset table.\n", poOpenInfo->pszFilename ); return NULL; } header.iVertBlocks = y; break; } lastoffset = offsets[x + y * header.iHorBlocks]; } } #if RIK_HEADER_DEBUG CPLDebug( "RIK", "first offset %d\n" "last offset %d\n", offsets[0], lastoffset ); #endif const char *compression = "RLE"; if( header.iOptions == 0x00 || header.iOptions == 0x40 ) compression = "Uncompressed"; if( header.iOptions == 0x0b ) compression = "LZW"; if( header.iOptions == 0x0d ) compression = "ZLIB"; CPLDebug( "RIK", "RIK file parameters:\n" " name: %s\n" " header: %s\n" " unknown: 0x%X\n" " south: %f\n" " west: %f\n" " north: %f\n" " east: %f\n" " original scale: %d\n" " meters per pixel: %f\n" " block width: %d\n" " block height: %d\n" " horizontal blocks: %d\n" " vertical blocks: %d\n" " bits per pixel: %d\n" " options: 0x%X\n" " compression: %s\n", name, headerType, header.iUnknown, header.fSouth, header.fWest, header.fNorth, header.fEast, header.iScale, metersPerPixel, header.iBlockWidth, header.iBlockHeight, header.iHorBlocks, header.iVertBlocks, header.iBitsPerPixel, header.iOptions, compression); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ RIKDataset *poDS; poDS = new RIKDataset(); poDS->fp = poOpenInfo->fpL; poOpenInfo->fpL = NULL; poDS->fTransform[0] = header.fWest - metersPerPixel / 2.0; poDS->fTransform[1] = metersPerPixel; poDS->fTransform[2] = 0.0; poDS->fTransform[3] = header.fNorth + metersPerPixel / 2.0; poDS->fTransform[4] = 0.0; poDS->fTransform[5] = -metersPerPixel; poDS->nBlockXSize = header.iBlockWidth; poDS->nBlockYSize = header.iBlockHeight; poDS->nHorBlocks = header.iHorBlocks; poDS->nVertBlocks = header.iVertBlocks; poDS->pOffsets = offsets; poDS->options = header.iOptions; poDS->nFileSize = fileSize; poDS->nRasterXSize = header.iBlockWidth * header.iHorBlocks; poDS->nRasterYSize = header.iBlockHeight * header.iVertBlocks; poDS->nBands = 1; GDALColorEntry oEntry; poDS->poColorTable = new GDALColorTable(); for( i = 0; i < 256; i++ ) { oEntry.c1 = palette[i * 3 + 2]; // Red oEntry.c2 = palette[i * 3 + 1]; // Green oEntry.c3 = palette[i * 3]; // Blue oEntry.c4 = 255; poDS->poColorTable->SetColorEntry( i, &oEntry ); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->SetBand( 1, new RIKRasterBand( poDS, 1 )); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() ); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The RIK driver does not support update access to existing" " datasets.\n" ); return NULL; } return( poDS ); }
CEOSRecord * CEOSReadRecord( CEOSImage *psImage ) { GByte abyHeader[12]; CEOSRecord *psRecord; /* -------------------------------------------------------------------- */ /* Read the standard CEOS header. */ /* -------------------------------------------------------------------- */ if( VSIFEofL( psImage->fpImage ) ) return NULL; if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Ran out of data reading CEOS record." ); return NULL; } /* -------------------------------------------------------------------- */ /* Extract this information. */ /* -------------------------------------------------------------------- */ psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord)); if( psImage->bLittleEndian ) { CPL_SWAP32PTR( abyHeader + 0 ); CPL_SWAP32PTR( abyHeader + 8 ); } psRecord->nRecordNum = abyHeader[0] * 256 * 256 * 256 + abyHeader[1] * 256 * 256 + abyHeader[2] * 256 + abyHeader[3]; psRecord->nRecordType = abyHeader[4] * 256 * 256 * 256 + abyHeader[5] * 256 * 256 + abyHeader[6] * 256 + abyHeader[7]; psRecord->nLength = abyHeader[8] * 256 * 256 * 256 + abyHeader[9] * 256 * 256 + abyHeader[10] * 256 + abyHeader[11]; /* -------------------------------------------------------------------- */ /* Does it look reasonable? We assume there can't be too many */ /* records and that the length must be between 12 and 200000. */ /* -------------------------------------------------------------------- */ if( psRecord->nRecordNum < 0 || psRecord->nRecordNum > 200000 || psRecord->nLength < 12 || psRecord->nLength > 200000 ) { CPLError( CE_Failure, CPLE_AppDefined, "CEOS record leader appears to be corrupt.\n" "Record Number = %d, Record Length = %d\n", psRecord->nRecordNum, psRecord->nLength ); CPLFree( psRecord ); return NULL; } /* -------------------------------------------------------------------- */ /* Read the remainder of the record into a buffer. Ensure that */ /* the first 12 bytes gets moved into this buffer as well. */ /* -------------------------------------------------------------------- */ psRecord->pachData = (char *) VSIMalloc(psRecord->nLength ); if( psRecord->pachData == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory allocated %d bytes for CEOS record data.\n" "Are you sure you aren't leaking CEOSRecords?\n", psRecord->nLength ); CPLFree( psRecord ); return NULL; } memcpy( psRecord->pachData, abyHeader, 12 ); if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, psImage->fpImage ) != psRecord->nLength - 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Short read on CEOS record data.\n" ); CPLFree( psRecord ); return NULL; } return psRecord; }
GDALDataset *GFFDataset::Open( GDALOpenInfo *poOpenInfo ) { /* Check that the dataset is indeed a GSAT File Format (GFF) file */ if (!GFFDataset::Identify(poOpenInfo)) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The GFF driver does not support update access to existing" " datasets.\n" ); return NULL; } GFFDataset *poDS = new GFFDataset(); poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r" ); if( poDS->fp == NULL ) { delete poDS; return NULL; } /* Check the endianness of the file */ VSIFSeekL(poDS->fp,54,SEEK_SET); VSIFReadL(&(poDS->nEndianness),2,1,poDS->fp); const bool bSwap = #if defined(CPL_LSB) false #else true #endif ; VSIFSeekL(poDS->fp,8,SEEK_SET); VSIFReadL(&poDS->nVersionMinor,2,1,poDS->fp); if (bSwap) CPL_SWAP16PTR(&poDS->nVersionMinor); VSIFReadL(&poDS->nVersionMajor,2,1,poDS->fp); if (bSwap) CPL_SWAP16PTR(&poDS->nVersionMajor); VSIFReadL(&poDS->nLength,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nLength); unsigned short nCreatorLength = 0; VSIFReadL(&nCreatorLength,2,1,poDS->fp); if (bSwap) CPL_SWAP16PTR(&nCreatorLength); /* Hack for now... I should properly load the date metadata, for * example */ VSIFSeekL(poDS->fp,56,SEEK_SET); /* By looking at the Matlab code, one should write something like the following test */ /* but the results don't seem to be the ones really expected */ /*if ((poDS->nVersionMajor == 1 && poDS->nVersionMinor > 7) || (poDS->nVersionMajor > 1)) { float fBPP; VSIFRead(&fBPP,4,1,poDS->fp); poDS->nBPP = fBPP; } else*/ { VSIFReadL(&poDS->nBPP,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nBPP); } VSIFReadL(&poDS->nFrameCnt,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nFrameCnt); VSIFReadL(&poDS->nImageType,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nImageType); VSIFReadL(&poDS->nRowMajor,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nRowMajor); VSIFReadL(&poDS->nRgCnt,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nRgCnt); VSIFReadL(&poDS->nAzCnt,4,1,poDS->fp); if (bSwap) CPL_SWAP32PTR(&poDS->nAzCnt); /* We now have enough information to determine the number format */ switch (poDS->nImageType) { case 0: poDS->eDataType = GDT_Byte; break; case 1: if (poDS->nBPP == 4) poDS->eDataType = GDT_CInt16; else poDS->eDataType = GDT_CInt32; break; case 2: poDS->eDataType = GDT_CFloat32; break; default: CPLError(CE_Failure, CPLE_AppDefined, "Unknown image type found!"); delete poDS; return NULL; } /* Set raster width/height * Note that the images that are complex are listed as having twice the * number of X-direction values than there are actual pixels. This is * because whoever came up with the format was crazy (actually, my * hunch is that they designed it very much for Matlab) * */ if (poDS->nRowMajor) { poDS->nRasterXSize = poDS->nRgCnt/(poDS->nImageType == 0 ? 1 : 2); poDS->nRasterYSize = poDS->nAzCnt; } else { poDS->nRasterXSize = poDS->nAzCnt/(poDS->nImageType == 0 ? 1 : 2); poDS->nRasterYSize = poDS->nRgCnt; } if (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid raster dimensions : %d x %d", poDS->nRasterXSize, poDS->nRasterYSize); delete poDS; return NULL; } poDS->SetBand(1, new GFFRasterBand(poDS, 1, poDS->eDataType)); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
int main( int argc, char ** argv ) { EnvisatFile *es_file; int ds_index; int ds_offset, ds_size, num_dsr, dsr_size, i_record; if( argc != 2 ) { printf( "Usage: dumpgeo filename\n" ); exit( 1 ); } if( EnvisatFile_Open( &es_file, argv[1], "r" ) != 0 ) { printf( "EnvisatFile_Open(%s) failed.\n", argv[1] ); exit( 2 ); } ds_index = EnvisatFile_GetDatasetIndex( es_file, "GEOLOCATION GRID ADS" ); if( ds_index == -1 ) { printf( "Can't find geolocation grid ads.\n" ); exit( 3 ); } EnvisatFile_GetDatasetInfo( es_file, ds_index, NULL, NULL, NULL, &ds_offset, &ds_size, &num_dsr, &dsr_size ); if( ds_offset == 0 ) { printf( "No data for geolocation grid ads.\n" ); exit( 4 ); } CPLAssert( dsr_size == 521 ); for( i_record = 0; i_record < num_dsr; i_record++ ) { GByte abyRecord[521]; GUInt32 unValue; float fValue; int sample; EnvisatFile_ReadDatasetRecord( es_file, ds_index, i_record, abyRecord ); printf( "<====================== Record %d ==================>\n", i_record ); /* field 1 */ CPL_SWAP32PTR( abyRecord + 0 ); CPL_SWAP32PTR( abyRecord + 4 ); CPL_SWAP32PTR( abyRecord + 8 ); printf( "start line: mjd_days = %d, sec = %d, msec = %d\n", ((int *) abyRecord)[0], ((unsigned int *) abyRecord)[1], ((unsigned int *) abyRecord)[2] ); /* field 2 */ printf( "Attachment flag = %d\n", abyRecord[12] ); /* field 3 */ memcpy( &unValue, abyRecord + 13, 4 ); printf( "range line (first in granule) = %d\n", CPL_SWAP32( unValue ) ); /* field 4 */ memcpy( &unValue, abyRecord + 17, 4 ); printf( "lines in granule = %d\n", CPL_SWAP32( unValue ) ); /* field 5 */ memcpy( &fValue, abyRecord + 21, 4 ); CPL_SWAP32PTR( &fValue ); printf( "track heading (first line) = %f\n", fValue ); /* field 6 */ printf( "first line of granule:\n" ); for( sample = 0; sample < 11; sample++ ) { memcpy( &unValue, abyRecord + 25 + sample*4, 4 ); printf( " sample=%d ", CPL_SWAP32(unValue) ); memcpy( &fValue, abyRecord + 25 + 44 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "time=%g ", fValue ); memcpy( &fValue, abyRecord + 25 + 88 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "angle=%g ", fValue ); memcpy( &unValue, abyRecord + 25 + 132 + sample*4, 4 ); printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 ); memcpy( &unValue, abyRecord + 25 + 176 + sample*4, 4 ); printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 ); } /* field 8 */ CPL_SWAP32PTR( abyRecord + 267 ); CPL_SWAP32PTR( abyRecord + 271 ); CPL_SWAP32PTR( abyRecord + 275 ); printf( "end line: mjd_days = %d, sec = %d, msec = %d\n", ((int *) (abyRecord + 267))[0], ((unsigned int *) (abyRecord + 267))[1], ((unsigned int *) (abyRecord + 267))[2] ); /* field 9 */ printf( "final line of granule:\n" ); for( sample = 0; sample < 11; sample++ ) { memcpy( &unValue, abyRecord + 279 + sample*4, 4 ); printf( " sample=%d ", CPL_SWAP32(unValue) ); memcpy( &fValue, abyRecord + 279 + 44 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "time=%g ", fValue ); memcpy( &fValue, abyRecord + 279 + 88 + sample * 4, 4 ); CPL_SWAP32PTR( &fValue ); printf( "angle=%g ", fValue ); memcpy( &unValue, abyRecord + 279 + 132 + sample*4, 4 ); printf( "(%.9f,", ((int) CPL_SWAP32(unValue)) * 0.000001 ); memcpy( &unValue, abyRecord + 279 + 176 + sample*4, 4 ); printf( "%.9f)\n", ((int) CPL_SWAP32(unValue)) * 0.000001 ); } } EnvisatFile_Close( es_file ); exit( 0 ); }
GDALDataset *LANDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the header (.pcb) file. */ /* Does this appear to be a pcb file? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < ERD_HEADER_SIZE ) return NULL; if( !STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader), "HEADER" ) && !STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader), "HEAD74" ) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ LANDataset *poDS = new LANDataset(); poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Adopt the openinfo file pointer for use with this file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); if( poDS->fpImage == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Do we need to byte swap the headers to local machine order? */ /* -------------------------------------------------------------------- */ int bBigEndian = poOpenInfo->pabyHeader[8] == 0; memcpy( poDS->pachHeader, poOpenInfo->pabyHeader, ERD_HEADER_SIZE ); #ifdef CPL_LSB const int bNeedSwap = bBigEndian; #else const int bNeedSwap = !bBigEndian; #endif if( bNeedSwap ) { CPL_SWAP16PTR( poDS->pachHeader + 6 ); CPL_SWAP16PTR( poDS->pachHeader + 8 ); CPL_SWAP32PTR( poDS->pachHeader + 16 ); CPL_SWAP32PTR( poDS->pachHeader + 20 ); CPL_SWAP32PTR( poDS->pachHeader + 24 ); CPL_SWAP32PTR( poDS->pachHeader + 28 ); CPL_SWAP16PTR( poDS->pachHeader + 88 ); CPL_SWAP16PTR( poDS->pachHeader + 90 ); CPL_SWAP16PTR( poDS->pachHeader + 106 ); CPL_SWAP32PTR( poDS->pachHeader + 108 ); CPL_SWAP32PTR( poDS->pachHeader + 112 ); CPL_SWAP32PTR( poDS->pachHeader + 116 ); CPL_SWAP32PTR( poDS->pachHeader + 120 ); CPL_SWAP32PTR( poDS->pachHeader + 124 ); } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ if( STARTS_WITH_CI(poDS->pachHeader,"HEADER") ) { float fTmp = 0.0; memcpy(&fTmp, poDS->pachHeader + 16, 4); CPL_LSBPTR32(&fTmp); poDS->nRasterXSize = (int) fTmp; memcpy(&fTmp, poDS->pachHeader + 20, 4); CPL_LSBPTR32(&fTmp); poDS->nRasterYSize = (int) fTmp; } else { GInt32 nTmp = 0; memcpy(&nTmp, poDS->pachHeader + 16, 4); CPL_LSBPTR32(&nTmp); poDS->nRasterXSize = nTmp; memcpy(&nTmp, poDS->pachHeader + 20, 4); CPL_LSBPTR32(&nTmp); poDS->nRasterYSize = nTmp; } GInt16 nTmp16 = 0; memcpy(&nTmp16, poDS->pachHeader + 6, 2); CPL_LSBPTR16(&nTmp16); int nPixelOffset = 0; GDALDataType eDataType = GDT_Unknown; if( nTmp16 == 0 ) { eDataType = GDT_Byte; nPixelOffset = 1; } else if( nTmp16 == 1 ) // 4 bit { eDataType = GDT_Byte; nPixelOffset = -1; } else if( nTmp16 == 2 ) { nPixelOffset = 2; eDataType = GDT_Int16; } else { CPLError( CE_Failure, CPLE_AppDefined, "Unsupported pixel type (%d).", nTmp16 ); delete poDS; return NULL; } memcpy(&nTmp16, poDS->pachHeader + 8, 2); CPL_LSBPTR16(&nTmp16); const int nBandCount = nTmp16; if( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBandCount, FALSE) ) { delete poDS; return NULL; } if( nPixelOffset != -1 && poDS->nRasterXSize > INT_MAX / (nPixelOffset * nBandCount) ) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow occurred." ); delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); for( int iBand = 1; iBand <= nBandCount; iBand++ ) { if( nPixelOffset == -1 ) /* 4 bit case */ poDS->SetBand( iBand, new LAN4BitRasterBand( poDS, iBand ) ); else poDS->SetBand( iBand, new RawRasterBand( poDS, iBand, poDS->fpImage, ERD_HEADER_SIZE + (iBand-1) * nPixelOffset * poDS->nRasterXSize, nPixelOffset, poDS->nRasterXSize*nPixelOffset*nBandCount, eDataType, !bNeedSwap, TRUE )); if( CPLGetLastErrorType() != CE_None ) { delete poDS; return NULL; } } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->CheckForStatistics(); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Try to interpret georeferencing. */ /* -------------------------------------------------------------------- */ float fTmp = 0.0; memcpy(&fTmp, poDS->pachHeader + 112, 4); CPL_LSBPTR32(&fTmp); poDS->adfGeoTransform[0] = fTmp; memcpy(&fTmp, poDS->pachHeader + 120, 4); CPL_LSBPTR32(&fTmp); poDS->adfGeoTransform[1] = fTmp; poDS->adfGeoTransform[2] = 0.0; memcpy(&fTmp, poDS->pachHeader + 116, 4); CPL_LSBPTR32(&fTmp); poDS->adfGeoTransform[3] = fTmp; poDS->adfGeoTransform[4] = 0.0; memcpy(&fTmp, poDS->pachHeader + 124, 4); CPL_LSBPTR32(&fTmp); poDS->adfGeoTransform[5] = - fTmp; // adjust for center of pixel vs. top left corner of pixel. poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5; /* -------------------------------------------------------------------- */ /* If we didn't get any georeferencing, try for a worldfile. */ /* -------------------------------------------------------------------- */ if( poDS->adfGeoTransform[1] == 0.0 || poDS->adfGeoTransform[5] == 0.0 ) { if( !GDALReadWorldFile( poOpenInfo->pszFilename, NULL, poDS->adfGeoTransform ) ) GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", poDS->adfGeoTransform ); } /* -------------------------------------------------------------------- */ /* Try to come up with something for the coordinate system. */ /* -------------------------------------------------------------------- */ memcpy(&nTmp16, poDS->pachHeader + 88, 2); CPL_LSBPTR16(&nTmp16); int nCoordSys = nTmp16; if( nCoordSys == 0 ) { poDS->pszProjection = CPLStrdup(SRS_WKT_WGS84); } else if( nCoordSys == 1 ) { poDS->pszProjection = CPLStrdup( "LOCAL_CS[\"UTM - Zone Unknown\",UNIT[\"Meter\",1]]" ); } else if( nCoordSys == 2 ) { poDS->pszProjection = CPLStrdup( "LOCAL_CS[\"State Plane - Zone Unknown\"," "UNIT[\"US survey foot\",0.3048006096012192]]" ); } else { poDS->pszProjection = CPLStrdup( "LOCAL_CS[\"Unknown\",UNIT[\"Meter\",1]]" ); } /* -------------------------------------------------------------------- */ /* Check for a trailer file with a colormap in it. */ /* -------------------------------------------------------------------- */ char *pszPath = CPLStrdup( CPLGetPath(poOpenInfo->pszFilename) ); char *pszBasename = CPLStrdup( CPLGetBasename(poOpenInfo->pszFilename) ); const char *pszTRLFilename = CPLFormCIFilename( pszPath, pszBasename, "trl" ); VSILFILE *fpTRL = VSIFOpenL( pszTRLFilename, "rb" ); if( fpTRL != NULL ) { char szTRLData[896] = { '\0' }; CPL_IGNORE_RET_VAL(VSIFReadL( szTRLData, 1, 896, fpTRL )); CPL_IGNORE_RET_VAL(VSIFCloseL( fpTRL )); GDALColorTable *poCT = new GDALColorTable(); for( int iColor = 0; iColor < 256; iColor++ ) { GDALColorEntry sEntry = { 0, 0, 0, 0}; sEntry.c2 = reinterpret_cast<GByte *>(szTRLData)[iColor+128]; sEntry.c1 = reinterpret_cast<GByte *>(szTRLData)[iColor+128+256]; sEntry.c3 = reinterpret_cast<GByte *>(szTRLData)[iColor+128+512]; sEntry.c4 = 255; poCT->SetColorEntry( iColor, &sEntry ); // Only 16 colors in 4bit files. if( nPixelOffset == -1 && iColor == 15 ) break; } poDS->GetRasterBand(1)->SetColorTable( poCT ); poDS->GetRasterBand(1)->SetColorInterpretation( GCI_PaletteIndex ); delete poCT; } CPLFree( pszPath ); CPLFree( pszBasename ); return poDS; }
OGRSQLiteSelectLayer::OGRSQLiteSelectLayer( OGRSQLiteDataSource *poDSIn, CPLString osSQLIn, sqlite3_stmt *hStmtIn, int bUseStatementForGetNextFeature, int bEmptyLayer, int bAllowMultipleGeomFieldsIn ) { poBehaviour = new OGRSQLiteSelectLayerCommonBehaviour(poDSIn, this, osSQLIn, bEmptyLayer); poDS = poDSIn; this->bAllowMultipleGeomFields = bAllowMultipleGeomFieldsIn; std::set<CPLString> aosEmpty; BuildFeatureDefn( "SELECT", hStmtIn, aosEmpty, aosEmpty ); SetDescription( "SELECT" ); if( bUseStatementForGetNextFeature ) { hStmt = hStmtIn; bDoStep = FALSE; // Try to extract SRS from first geometry for( int iField = 0; !bEmptyLayer && iField < poFeatureDefn->GetGeomFieldCount(); iField ++) { OGRSQLiteGeomFieldDefn* poGeomFieldDefn = poFeatureDefn->myGetGeomFieldDefn(iField); if( wkbFlatten(poGeomFieldDefn->GetType()) != wkbUnknown ) continue; int nBytes; if( sqlite3_column_type( hStmt, poGeomFieldDefn->iCol ) == SQLITE_BLOB && (nBytes = sqlite3_column_bytes( hStmt, poGeomFieldDefn->iCol )) > 39 ) { const GByte* pabyBlob = (const GByte*)sqlite3_column_blob( hStmt, poGeomFieldDefn->iCol ); int eByteOrder = pabyBlob[1]; if( pabyBlob[0] == 0x00 && (eByteOrder == wkbNDR || eByteOrder == wkbXDR) && pabyBlob[38] == 0x7C ) { int nSRSId; memcpy(&nSRSId, pabyBlob + 2, 4); #ifdef CPL_LSB if( eByteOrder != wkbNDR) CPL_SWAP32PTR(&nSRSId); #else if( eByteOrder == wkbNDR) CPL_SWAP32PTR(&nSRSId); #endif CPLPushErrorHandler(CPLQuietErrorHandler); OGRSpatialReference* poSRS = poDS->FetchSRS( nSRSId ); CPLPopErrorHandler(); if( poSRS != NULL ) { poGeomFieldDefn->nSRSId = nSRSId; poGeomFieldDefn->SetSpatialRef(poSRS); } else CPLErrorReset(); } #ifdef SQLITE_HAS_COLUMN_METADATA else if( iField == 0 ) { const char* pszTableName = sqlite3_column_table_name( hStmt, poGeomFieldDefn->iCol ); if( pszTableName != NULL ) { OGRSQLiteLayer* poLayer = (OGRSQLiteLayer*) poDS->GetLayerByName(pszTableName); if( poLayer != NULL && poLayer->GetLayerDefn()->GetGeomFieldCount() > 0) { OGRSQLiteGeomFieldDefn* poSrcGFldDefn = poLayer->myGetLayerDefn()->myGetGeomFieldDefn(0); poGeomFieldDefn->nSRSId = poSrcGFldDefn->nSRSId; poGeomFieldDefn->SetSpatialRef(poSrcGFldDefn->GetSpatialRef()); } } } #endif } } } else sqlite3_finalize( hStmtIn ); }
OGRSQLiteSelectLayer::OGRSQLiteSelectLayer( OGRSQLiteDataSource *poDSIn, CPLString osSQLIn, sqlite3_stmt *hStmtIn, int bUseStatementForGetNextFeature, int bEmptyLayer ) { poDS = poDSIn; iNextShapeId = 0; poFeatureDefn = NULL; bAllowResetReadingEvenIfIndexAtZero = FALSE; std::set<CPLString> aosEmpty; BuildFeatureDefn( "SELECT", hStmtIn, aosEmpty ); if( bUseStatementForGetNextFeature ) { hStmt = hStmtIn; bDoStep = FALSE; // Try to extract SRS from first geometry if( !bEmptyLayer && osGeomColumn.size() != 0 ) { int nRawColumns = sqlite3_column_count( hStmt ); for( int iCol = 0; iCol < nRawColumns; iCol++ ) { int nBytes; if( sqlite3_column_type( hStmt, iCol ) == SQLITE_BLOB && strcmp(OGRSQLiteParamsUnquote(sqlite3_column_name( hStmt, iCol )).c_str(), osGeomColumn.c_str()) == 0 && (nBytes = sqlite3_column_bytes( hStmt, iCol )) > 39 ) { const GByte* pabyBlob = (const GByte*)sqlite3_column_blob( hStmt, iCol ); int eByteOrder = pabyBlob[1]; if( pabyBlob[0] == 0x00 && (eByteOrder == wkbNDR || eByteOrder == wkbXDR) && pabyBlob[38] == 0x7C ) { memcpy(&nSRSId, pabyBlob + 2, 4); #ifdef CPL_LSB if( eByteOrder != wkbNDR) CPL_SWAP32PTR(&nSRSId); #else if( eByteOrder == wkbNDR) CPL_SWAP32PTR(&nSRSId); #endif CPLPushErrorHandler(CPLQuietErrorHandler); poSRS = poDS->FetchSRS( nSRSId ); CPLPopErrorHandler(); if( poSRS != NULL ) poSRS->Reference(); else CPLErrorReset(); } #ifdef SQLITE_HAS_COLUMN_METADATA else { const char* pszTableName = sqlite3_column_table_name( hStmt, iCol ); if( pszTableName != NULL ) { OGRLayer* poLayer = poDS->GetLayerByName(pszTableName); if( poLayer != NULL ) { poSRS = poLayer->GetSpatialRef(); if( poSRS != NULL ) poSRS->Reference(); } } } #endif break; } } } } else sqlite3_finalize( hStmtIn ); osSQLBase = osSQLIn; osSQLCurrent = osSQLIn; this->bEmptyLayer = bEmptyLayer; bSpatialFilterInSQL = TRUE; }
CEOSRecord * CEOSReadRecord( CEOSImage *psImage ) { GByte abyHeader[12]; CEOSRecord *psRecord; GUInt32 nRecordNumUInt32, nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the standard CEOS header. */ /* -------------------------------------------------------------------- */ if( VSIFEofL( psImage->fpImage ) ) return NULL; if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Ran out of data reading CEOS record." ); return NULL; } /* -------------------------------------------------------------------- */ /* Extract this information. */ /* -------------------------------------------------------------------- */ psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord)); if( psImage->bLittleEndian ) { CPL_SWAP32PTR( abyHeader + 0 ); CPL_SWAP32PTR( abyHeader + 8 ); } nRecordNumUInt32 = (abyHeader[0] << 24) + (abyHeader[1] << 16) + (abyHeader[2] << 8) + abyHeader[3]; psRecord->nRecordType = (abyHeader[4] << 24) + (abyHeader[5] << 16) + (abyHeader[6] << 8) + abyHeader[7]; nLengthUInt32 = (abyHeader[8] << 24) + (abyHeader[9] << 16) + (abyHeader[10] << 8) + abyHeader[11]; /* -------------------------------------------------------------------- */ /* Does it look reasonable? We assume there can't be too many */ /* records and that the length must be between 12 and 200000. */ /* -------------------------------------------------------------------- */ if( nRecordNumUInt32 > 200000 || nLengthUInt32 < 12 || nLengthUInt32 > 200000 ) { CPLError( CE_Failure, CPLE_AppDefined, "CEOS record leader appears to be corrupt.\n" "Record Number = %u, Record Length = %u\n", nRecordNumUInt32, nLengthUInt32 ); CPLFree( psRecord ); return NULL; } psRecord->nRecordNum = (int)nRecordNumUInt32; psRecord->nLength = (int)nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the remainder of the record into a buffer. Ensure that */ /* the first 12 bytes gets moved into this buffer as well. */ /* -------------------------------------------------------------------- */ psRecord->pachData = (char *) VSI_MALLOC_VERBOSE(psRecord->nLength ); if( psRecord->pachData == NULL ) { CPLFree( psRecord ); return NULL; } memcpy( psRecord->pachData, abyHeader, 12 ); if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, psImage->fpImage ) != psRecord->nLength - 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Short read on CEOS record data.\n" ); CPLFree( psRecord ); return NULL; } return psRecord; }