CPLErr COSARRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff, void *pImage) { unsigned long nRSFV = 0; unsigned long nRSLV = 0; COSARDataset *pCDS = (COSARDataset *) poDS; /* Find the line we want to be at */ /* To explain some magic numbers: * 4 bytes for an entire sample (2 I, 2 Q) * nBlockYOff + 4 = Y offset + 4 annotation lines at beginning * of file */ VSIFSeek(pCDS->fp,(this->nRTNB * (nBlockYOff + 4)), SEEK_SET); /* Read RSFV and RSLV (TX-GS-DD-3307) */ VSIFRead(&nRSFV,1,4,pCDS->fp); VSIFRead(&nRSLV,1,4,pCDS->fp); #ifdef CPL_LSB nRSFV = CPL_SWAP32(nRSFV); nRSLV = CPL_SWAP32(nRSLV); #endif if (nRSLV < nRSFV || nRSFV == 0 || nRSFV - 1 >= ((unsigned long) nBlockXSize) || nRSLV - nRSFV > ((unsigned long) nBlockXSize) || nRSFV >= this->nRTNB || nRSLV > this->nRTNB) { /* throw an error */ CPLError(CE_Failure, CPLE_AppDefined, "RSLV/RSFV values are not sane... oh dear.\n"); return CE_Failure; } /* zero out the range line */ for (int i = 0; i < this->nRasterXSize; i++) { ((GUInt32 *)pImage)[i] = 0; } /* properly account for validity mask */ if (nRSFV > 1) { VSIFSeek(pCDS->fp,(this->nRTNB*(nBlockYOff+4)+(nRSFV+1)*4), SEEK_SET); } /* Read the valid samples: */ VSIFRead(((char *)pImage)+((nRSFV - 1)*4),1,((nRSLV-1)*4)-((nRSFV-1)*4),pCDS->fp); #ifdef CPL_LSB // GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 ); GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize * 2, 2 ); #endif return CE_None; }
GDALDataset *COSARDataset::Open( GDALOpenInfo * pOpenInfo ) { long nRTNB; /* Check if we're actually a COSAR data set. */ if( pOpenInfo->nHeaderBytes < 4 ) return NULL; if (!EQUALN((char *)pOpenInfo->pabyHeader+MAGIC1_OFFSET, "CSAR",4)) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( pOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The COSAR driver does not support update access to existing" " datasets.\n" ); return NULL; } /* this is a cosar dataset */ COSARDataset *pDS; pDS = new COSARDataset(); /* steal fp */ pDS->fp = pOpenInfo->fp; pOpenInfo->fp = NULL; /* Calculate the file size */ VSIFSeek(pDS->fp,0,SEEK_END); pDS->nSize = VSIFTell(pDS->fp); VSIFSeek(pDS->fp, RS_OFFSET, SEEK_SET); VSIFRead(&pDS->nRasterXSize, 1, 4, pDS->fp); #ifdef CPL_LSB pDS->nRasterXSize = CPL_SWAP32(pDS->nRasterXSize); #endif VSIFRead(&pDS->nRasterYSize, 1, 4, pDS->fp); #ifdef CPL_LSB pDS->nRasterYSize = CPL_SWAP32(pDS->nRasterYSize); #endif VSIFSeek(pDS->fp, RTNB_OFFSET, SEEK_SET); VSIFRead(&nRTNB, 1, 4, pDS->fp); #ifdef CPL_LSB nRTNB = CPL_SWAP32(nRTNB); #endif /* Add raster band */ pDS->SetBand(1, new COSARRasterBand(pDS, nRTNB)); return pDS; }
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; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = wkbPolygon; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = wkbPolygon; } /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(); } return OGRERR_NONE; }
int TABRawBinBlock::WriteInt32(GInt32 n32Value) { #ifdef CPL_MSB n32Value = (GInt32)CPL_SWAP32(n32Value); #endif return WriteBytes(4, (GByte*)&n32Value); }
int TABRawBinBlock::WriteFloat(float fValue) { #ifdef CPL_MSB *(GUInt32*)(&fValue) = CPL_SWAP32(*(GUInt32*)(&fValue)); #endif return WriteBytes(4, (GByte*)&fValue); }
int TABRawBinBlock::WriteInt32(GInt32 n32Value) { #ifdef CPL_MSB n32Value = static_cast<GInt32>(CPL_SWAP32(n32Value)); #endif return WriteBytes(4, reinterpret_cast<GByte*>(&n32Value)); }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = getGeometryType(); pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = getGeometryType(); } /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->exportToWkb( eByteOrder, pabyData + nOffset ); nOffset += papoGeoms[iGeom]->WkbSize(); } return OGRERR_NONE; }
void AVCRawBinWriteInt32(AVCRawBinFile *psFile, GInt32 n32Value) { if (psFile->eByteOrder != geSystemByteOrder) { n32Value = (GInt32)CPL_SWAP32(n32Value); } AVCRawBinWriteBytes(psFile, 4, (GByte*)&n32Value); }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { int nOffset; int b3D = getCoordinateDimension() == 3; /* -------------------------------------------------------------------- */ /* 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. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, b3D, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(b3D); } return OGRERR_NONE; }
float TABRawBinBlock::ReadFloat() { float fValue; ReadBytes(4, (GByte*)(&fValue)); #ifdef CPL_MSB *(GUInt32*)(&fValue) = CPL_SWAP32(*(GUInt32*)(&fValue)); #endif return fValue; }
GInt32 TABRawBinBlock::ReadInt32() { GInt32 n32Value = 0; ReadBytes(4, reinterpret_cast<GByte*>(&n32Value)); #ifdef CPL_MSB return static_cast<GInt32>(CPL_SWAP32(n32Value)); #else return n32Value; #endif }
GInt32 TABRawBinBlock::ReadInt32() { GInt32 n32Value; ReadBytes(4, (GByte*)(&n32Value)); #ifdef CPL_MSB return (GInt32)CPL_SWAP32(n32Value); #else return n32Value; #endif }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type, ensuring that 3D flag is */ /* preserved. */ /* -------------------------------------------------------------------- */ 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. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->exportToWkb( eByteOrder, pabyData + nOffset ); nOffset += papoGeoms[iGeom]->WkbSize(); } return OGRERR_NONE; }
GInt32 AVCRawBinReadInt32(AVCRawBinFile *psFile) { GInt32 n32Value; AVCRawBinReadBytes(psFile, 4, (GByte*)(&n32Value)); if (psFile->eByteOrder != geSystemByteOrder) { return (GInt32)CPL_SWAP32(n32Value); } return n32Value; }
OGRErr OGRLinearRing::_exportToWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData ) const { int i, nWords; /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( b3D ) { nWords = 3 * nPointCount; for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfZ == NULL ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfZ + i, 8 ); } } else { nWords = 2 * nPointCount; memcpy( pabyData+4, paoPoints, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData, &nCount, 4 ); for( i = 0; i < nWords; i++ ) { CPL_SWAPDOUBLE( pabyData + 4 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantPostGIS1 ) { nGType = wkbFlatten(nGType); if( Is3D() ) // Explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); if( IsMeasured() ) nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000); } else if( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); if( OGR_SWAP( eByteOrder ) ) { nGType = CPL_SWAP32(nGType); } memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { const int nCount = CPL_SWAP32( oCC.nCurveCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &oCC.nCurveCount, 4 ); } /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ int nOffset = 9; for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing]; poLR->_exportToWkb( eByteOrder, flags, pabyData + nOffset ); nOffset += poLR->_WkbSize( flags ); } return OGRERR_NONE; }
OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData, int nBytesAvailable ) { if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); /* Check if the wkb stream buffer is big enough to store * fetched number of points. * 16 or 24 - size of point structure */ int nPointSize = (b3D ? 24 : 16); if (nNewNumPoints < 0 || nNewNumPoints > INT_MAX / nPointSize) return OGRERR_CORRUPT_DATA; int nBufferMinSize = nPointSize * nNewNumPoints; if( nBytesAvailable != -1 && nBufferMinSize > nBytesAvailable - 4 ) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); return OGRERR_NOT_ENOUGH_DATA; } /* (Re)Allocation of paoPoints buffer. */ setNumPoints( nNewNumPoints ); if( b3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ int i = 0; if( !b3D ) { memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); } else { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( b3D ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; int nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); CPLAssert( eByteOrder == wkbXDR || eByteOrder == wkbNDR ); /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ #ifdef DEBUG OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } CPLAssert( eGeometryType == wkbGeometryCollection || eGeometryType == wkbMultiPolygon || eGeometryType == wkbMultiLineString || eGeometryType == wkbMultiPoint ); #endif /* -------------------------------------------------------------------- */ /* Do we already have some existing geometry objects? */ /* -------------------------------------------------------------------- */ if( nGeomCount != 0 ) { for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) delete papoGeoms[iGeom]; OGRFree( papoGeoms ); papoGeoms = NULL; } /* -------------------------------------------------------------------- */ /* Get the geometry count. */ /* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); papoGeoms = (OGRGeometry **) OGRMalloc(sizeof(void*) * nGeomCount); nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; nCoordinateDimension = 0; // unknown /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; eErr = OGRGeometryFactory:: createFromWkb( pabyData + nDataOffset, NULL, papoGeoms + iGeom, nSize ); if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; return eErr; } if( nSize != -1 ) nSize -= papoGeoms[iGeom]->WkbSize(); nDataOffset += papoGeoms[iGeom]->WkbSize(); } return OGRERR_NONE; }
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 ); }
OGRErr OGRCurveCollection::exportToWkb( const OGRGeometry* poGeom, OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type, ensuring that 3D flag is */ /* preserved. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = poGeom->getIsoGeometryType(); if( eWkbVariant == wkbVariantPostGIS1 ) { int bIs3D = wkbHasZ((OGRwkbGeometryType)nGType); nGType = wkbFlatten(nGType); if( nGType == wkbCurvePolygon ) nGType = POSTGIS15_CURVEPOLYGON; if( bIs3D ) nGType = (OGRwkbGeometryType)(nGType | wkb25DBitInternalUse); /* yes we explicitly set wkb25DBit */ } if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nCurveCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nCurveCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ for( int iGeom = 0; iGeom < nCurveCount; iGeom++ ) { papoCurves[iGeom]->exportToWkb( eByteOrder, pabyData + nOffset, eWkbVariant ); nOffset += papoCurves[iGeom]->WkbSize(); } return OGRERR_NONE; }
//! @cond Doxygen_Suppress OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int _flags, const unsigned char * pabyData, int nBytesAvailable, int& nBytesConsumedOut ) { nBytesConsumedOut = -1; if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints = 0; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); // Check if the wkb stream buffer is big enough to store // fetched number of points. // 16, 24, or 32 - size of point structure. int nPointSize = 0; if( (_flags & OGR_G_3D) && (_flags & OGR_G_MEASURED) ) nPointSize = 32; else if( (_flags & OGR_G_3D) || (_flags & OGR_G_MEASURED) ) nPointSize = 24; else nPointSize = 16; if( nNewNumPoints < 0 || nNewNumPoints > INT_MAX / nPointSize ) return OGRERR_CORRUPT_DATA; int nBufferMinSize = nPointSize * nNewNumPoints; if( nBytesAvailable != -1 && nBufferMinSize > nBytesAvailable - 4 ) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); return OGRERR_NOT_ENOUGH_DATA; } // (Re)Allocation of paoPoints buffer. setNumPoints( nNewNumPoints, FALSE ); if( _flags & OGR_G_3D ) Make3D(); else Make2D(); if( _flags & OGR_G_MEASURED ) AddM(); else RemoveM(); nBytesConsumedOut = 4 + nPointCount * nPointSize; /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 32 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 32 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 32 * i + 16, 8 ); memcpy( padfM + i, pabyData + 4 + 32 * i + 24, 8 ); } } else if( flags & OGR_G_MEASURED ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfM + i, pabyData + 4 + 24 * i + 16, 8 ); } } else if( flags & OGR_G_3D ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } else { memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( int i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( flags & OGR_G_3D ) { CPL_SWAPDOUBLE( padfZ + i ); } if( flags & OGR_G_MEASURED ) { CPL_SWAPDOUBLE( padfM + i ); } } } return OGRERR_NONE; }
OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; int nDataOffset, b3D; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ #ifdef DEBUG OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) eGeometryType = (OGRwkbGeometryType) pabyData[1]; else eGeometryType = (OGRwkbGeometryType) pabyData[4]; if( eGeometryType != wkbPolygon ) return OGRERR_CORRUPT_DATA; #endif if( eByteOrder == wkbNDR ) b3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; else b3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; if( b3D ) nCoordDimension = 3; else nCoordDimension = 2; /* -------------------------------------------------------------------- */ /* Do we already have some rings? */ /* -------------------------------------------------------------------- */ if( nRingCount != 0 ) { for( int iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; OGRFree( papoRings ); papoRings = NULL; } /* -------------------------------------------------------------------- */ /* Get the ring count. */ /* -------------------------------------------------------------------- */ memcpy( &nRingCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nRingCount = CPL_SWAP32(nRingCount); if (nRingCount < 0 || nRingCount > INT_MAX / 4) { nRingCount = 0; return OGRERR_CORRUPT_DATA; } /* Each ring has a minimum of 4 bytes (point count) */ if (nSize != -1 && nSize - 9 < nRingCount * 4) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nRingCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoRings = (OGRLinearRing **) VSIMalloc2(sizeof(void*), nRingCount); if (nRingCount != 0 && papoRings == NULL) { nRingCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the rings. */ /* -------------------------------------------------------------------- */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { OGRErr eErr; papoRings[iRing] = new OGRLinearRing(); eErr = papoRings[iRing]->_importFromWkb( eByteOrder, b3D, pabyData + nDataOffset, nSize ); if( eErr != OGRERR_NONE ) { delete papoRings[iRing]; nRingCount = iRing; return eErr; } if( nSize != -1 ) nSize -= papoRings[iRing]->_WkbSize( b3D ); nDataOffset += papoRings[iRing]->_WkbSize( b3D ); } return OGRERR_NONE; }
OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData, int nBytesAvailable ) { if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); setNumPoints( nNewNumPoints ); if( b3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ int i; if( !b3D ) memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); else { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( b3D ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkbInternal( unsigned char * pabyData, int nSize, int nRecLevel ) { OGRwkbByteOrder eByteOrder; int nDataOffset; /* Arbitrary value, but certainly large enough for reasonable usages ! */ if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursiong level (%d) while parsing WKB geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } if ( eGeometryType != wkbFlatten(getGeometryType()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Get the geometry count. */ /* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); if (nGeomCount < 0 || nGeomCount > INT_MAX / 9) { nGeomCount = 0; return OGRERR_CORRUPT_DATA; } /* Each geometry has a minimum of 9 bytes */ if (nSize != -1 && nSize - 9 < nGeomCount * 9) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nGeomCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoGeoms = (OGRGeometry **) VSIMalloc2(sizeof(void*), nGeomCount); if (nGeomCount != 0 && papoGeoms == NULL) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; OGRGeometry* poSubGeom = NULL; /* Parses sub-geometry */ unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbByteOrder eSubGeomByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabySubData); if( eSubGeomByteOrder != wkbXDR && eSubGeomByteOrder != wkbNDR ) return OGRERR_CORRUPT_DATA; OGRwkbGeometryType eSubGeomType; if( eSubGeomByteOrder == wkbNDR ) eSubGeomType = (OGRwkbGeometryType) pabySubData[1]; else eSubGeomType = (OGRwkbGeometryType) pabySubData[4]; if( eSubGeomType == wkbPoint || eSubGeomType == wkbLineString || eSubGeomType == wkbPolygon) { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, NULL, &poSubGeom, nSize ); } else if (eSubGeomType == wkbGeometryCollection || eSubGeomType == wkbMultiPolygon || eSubGeomType == wkbMultiPoint || eSubGeomType == wkbMultiLineString) { poSubGeom = OGRGeometryFactory::createGeometry( eSubGeomType ); eErr = ((OGRGeometryCollection*)poSubGeom)-> importFromWkbInternal( pabySubData, nSize, nRecLevel + 1 ); } else return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; delete poSubGeom; return eErr; } if( (eGeometryType == wkbMultiPoint && eSubGeomType != wkbPoint) || (eGeometryType == wkbMultiLineString && eSubGeomType != wkbLineString) || (eGeometryType == wkbMultiPolygon && eSubGeomType != wkbPolygon) ) { nGeomCount = iGeom; CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, eGeometryType); delete poSubGeom; return OGRERR_CORRUPT_DATA; } papoGeoms[iGeom] = poSubGeom; if (papoGeoms[iGeom]->getCoordinateDimension() == 3) nCoordDimension = 3; int nSubGeomWkbSize = papoGeoms[iGeom]->WkbSize(); if( nSize != -1 ) nSize -= nSubGeomWkbSize; nDataOffset += nSubGeomWkbSize; } return OGRERR_NONE; }
OGRErr GPkgHeaderFromWKB(const GByte *pabyGpkg, GPkgHeader *poHeader) { CPLAssert( pabyGpkg != NULL ); CPLAssert( poHeader != NULL ); /* Magic (match required) */ if ( pabyGpkg[0] != 0x47 || pabyGpkg[1] != 0x50 || pabyGpkg[2] != 0 ) /* Version (only 0 supported at this time)*/ { return OGRERR_FAILURE; } /* Flags */ GByte byFlags = pabyGpkg[3]; poHeader->bEmpty = (byFlags & (0x01 << 4)) >> 4; poHeader->bExtended = (byFlags & (0x01 << 5)) >> 5; poHeader->eByteOrder = (OGRwkbByteOrder)(byFlags & 0x01); OGRBoolean bSwap = OGR_SWAP(poHeader->eByteOrder); /* Envelope */ int iEnvelope = (byFlags & (0x07 << 1)) >> 1; if ( iEnvelope == 1 ) poHeader->iDims = 2; /* 2D envelope */ else if ( iEnvelope == 2 ) poHeader->iDims = 3; /* 3D envelope */ else poHeader->iDims = 0; /* No envelope */ /* SrsId */ int iSrsId; memcpy(&iSrsId, pabyGpkg+4, 4); if ( bSwap ) { iSrsId = CPL_SWAP32(iSrsId); } poHeader->iSrsId = iSrsId; /* Envelope */ double *padPtr = (double*)(pabyGpkg+8); if ( poHeader->iDims >= 2 ) { poHeader->MinX = padPtr[0]; poHeader->MaxX = padPtr[1]; poHeader->MinY = padPtr[2]; poHeader->MaxY = padPtr[3]; if ( bSwap ) { CPL_SWAPDOUBLE(&(poHeader->MinX)); CPL_SWAPDOUBLE(&(poHeader->MaxX)); CPL_SWAPDOUBLE(&(poHeader->MinY)); CPL_SWAPDOUBLE(&(poHeader->MaxY)); } } if ( poHeader->iDims == 3 ) { poHeader->MinZ = padPtr[4]; poHeader->MaxZ = padPtr[5]; if ( bSwap ) { CPL_SWAPDOUBLE(&(poHeader->MinZ)); CPL_SWAPDOUBLE(&(poHeader->MaxZ)); } } /* Header size in byte stream */ poHeader->szHeader = 8 + 8*2*(poHeader->iDims); return OGRERR_NONE; }
OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nBytesAvailable ) { OGRwkbByteOrder eByteOrder; int nDataOffset; if( nBytesAvailable < 21 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = (OGRwkbByteOrder) *pabyData; CPLAssert( eByteOrder == wkbXDR || eByteOrder == wkbNDR ); /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ #ifdef DEBUG OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) eGeometryType = (OGRwkbGeometryType) pabyData[1]; else eGeometryType = (OGRwkbGeometryType) pabyData[4]; CPLAssert( eGeometryType == wkbPolygon ); #endif /* -------------------------------------------------------------------- */ /* Do we already have some rings? */ /* -------------------------------------------------------------------- */ if( nRingCount != 0 ) { for( int iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; OGRFree( papoRings ); papoRings = NULL; } /* -------------------------------------------------------------------- */ /* Get the ring count. */ /* -------------------------------------------------------------------- */ memcpy( &nRingCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nRingCount = CPL_SWAP32(nRingCount); papoRings = (OGRLinearRing **) OGRMalloc(sizeof(void*) * nRingCount); nDataOffset = 9; if( nBytesAvailable != -1 ) nBytesAvailable -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the rings. */ /* -------------------------------------------------------------------- */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { OGRErr eErr; papoRings[iRing] = new OGRLinearRing(); eErr = papoRings[iRing]->_importFromWkb( eByteOrder, pabyData + nDataOffset, nBytesAvailable ); if( eErr != OGRERR_NONE ) { nRingCount = iRing; return eErr; } if( nBytesAvailable != -1 ) nBytesAvailable -= papoRings[iRing]->_WkbSize(); nDataOffset += papoRings[iRing]->_WkbSize(); } return OGRERR_NONE; }
OGRErr OGRLinearRing::_exportToWkb( OGRwkbByteOrder eByteOrder, int _flags, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int nWords = 0; if( (_flags & OGR_G_3D) && (_flags & OGR_G_MEASURED) ) { nWords = 4 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*32, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*32+8, &(paoPoints[i].y), 8 ); if( padfZ == nullptr ) memset( pabyData+4+i*32+16, 0, 8 ); else memcpy( pabyData+4+i*32+16, padfZ + i, 8 ); if( padfM == nullptr ) memset( pabyData+4+i*32+24, 0, 8 ); else memcpy( pabyData+4+i*32+24, padfM + i, 8 ); } } else if( _flags & OGR_G_MEASURED ) { nWords = 3 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfM == nullptr ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfM + i, 8 ); } } else if( _flags & OGR_G_3D ) { nWords = 3 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfZ == nullptr ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfZ + i, 8 ); } } else { nWords = 2 * nPointCount; memcpy( pabyData+4, paoPoints, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData, &nCount, 4 ); for( int i = 0; i < nWords; i++ ) { CPL_SWAPDOUBLE( pabyData + 4 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { if( eWkbVariant == wkbVariantOldOgc && (wkbFlatten(getGeometryType()) == wkbMultiCurve || wkbFlatten(getGeometryType()) == wkbMultiSurface) ) { // Does not make sense for new geometries, so patch it. eWkbVariant = wkbVariantIso; } /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); /* -------------------------------------------------------------------- */ /* Set the geometry feature type, ensuring that 3D flag is */ /* preserved. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); else if( eWkbVariant == wkbVariantPostGIS1 ) { const bool bIs3D = wkbHasZ(static_cast<OGRwkbGeometryType>(nGType)); nGType = wkbFlatten(nGType); if( nGType == wkbMultiCurve ) nGType = POSTGIS15_MULTICURVE; else if( nGType == wkbMultiSurface ) nGType = POSTGIS15_MULTISURFACE; if( bIs3D ) // Yes, explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); } if( OGR_SWAP( eByteOrder ) ) { nGType = CPL_SWAP32(nGType); } memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } int nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ int iGeom = 0; for( auto&& poSubGeom: *this ) { poSubGeom->exportToWkb( eByteOrder, pabyData + nOffset, eWkbVariant ); // Should normally not happen if everyone else does its job, // but has happened sometimes. (#6332) if( poSubGeom->getCoordinateDimension() != getCoordinateDimension() ) { CPLError(CE_Warning, CPLE_AppDefined, "Sub-geometry %d has coordinate dimension %d, " "but container has %d", iGeom, poSubGeom->getCoordinateDimension(), getCoordinateDimension() ); } nOffset += poSubGeom->WkbSize(); iGeom ++; } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; int nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the geometry feature type. For now we assume that */ /* geometry type is between 0 and 255 so we only have to fetch */ /* one byte. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } if ( eGeometryType != wkbFlatten(getGeometryType()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Get the geometry count. */ /* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); if (nGeomCount < 0 || nGeomCount > INT_MAX / 9) { nGeomCount = 0; return OGRERR_CORRUPT_DATA; } /* Each geometry has a minimum of 9 bytes */ if (nSize != -1 && nSize - 9 < nGeomCount * 9) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nGeomCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoGeoms = (OGRGeometry **) VSIMalloc2(sizeof(void*), nGeomCount); if (nGeomCount != 0 && papoGeoms == NULL) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; OGRGeometry* poSubGeom = NULL; eErr = OGRGeometryFactory:: createFromWkb( pabyData + nDataOffset, NULL, &poSubGeom, nSize ); if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; return eErr; } OGRwkbGeometryType eSubGeomType = wkbFlatten(poSubGeom->getGeometryType()); if( (eGeometryType == wkbMultiPoint && eSubGeomType != wkbPoint) || (eGeometryType == wkbMultiLineString && eSubGeomType != wkbLineString) || (eGeometryType == wkbMultiPolygon && eSubGeomType != wkbPolygon) ) { nGeomCount = iGeom; CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, eGeometryType); delete poSubGeom; return OGRERR_CORRUPT_DATA; } papoGeoms[iGeom] = poSubGeom; if (papoGeoms[iGeom]->getCoordinateDimension() == 3) nCoordDimension = 3; int nSubGeomWkbSize = papoGeoms[iGeom]->WkbSize(); if( nSize != -1 ) nSize -= nSubGeomWkbSize; nDataOffset += nSubGeomWkbSize; } return OGRERR_NONE; }