static void SwapPtr64IfNecessary( bool bMustSwap, void* ptr ) { if( bMustSwap ) { CPL_SWAP64PTR( static_cast<GByte *>(ptr) ); } }
OGRErr OGRLineString::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 data count. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int i; if( getCoordinateDimension() == 3 ) { for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 ); memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 ); } } else memcpy( pabyData+9, paoPoints, 16 * nPointCount ); /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData+5, &nCount, 4 ); for( i = getCoordinateDimension() * nPointCount - 1; i >= 0; i-- ) { CPL_SWAP64PTR( pabyData + 9 + 8 * i ); } } 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 ); }