OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; if( nSize < 21 && 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. */ /* -------------------------------------------------------------------- */ OGRBoolean bIs3D; OGRwkbGeometryType eGeometryType; OGRErr err = OGRReadWKBGeometryType( pabyData, &eGeometryType, &bIs3D ); if( err != OGRERR_NONE || eGeometryType != wkbPoint ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData + 5, 8 ); memcpy( &y, pabyData + 5 + 8, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( bIs3D ) { if ( nSize < 29 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; memcpy( &z, pabyData + 5 + 16, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &z ); } nCoordDimension = 3; } else { z = 0; nCoordDimension = 2; } return OGRERR_NONE; }
OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; if( nSize < 21 && 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; int bIs3D; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; bIs3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; bIs3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; } if( eGeometryType != wkbPoint ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData + 5, 16 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( bIs3D ) { memcpy( &z, pabyData + 5 + 16, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &z ); } nCoordDimension = 3; } else { z = 0; nCoordDimension = 2; } 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; }
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; }
OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; int nDataOffset, b3D; if( nSize < 21 && 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 == wkbPolygon ); #endif if( eByteOrder == wkbNDR ) b3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; else b3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; /* -------------------------------------------------------------------- */ /* 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( 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 ) { nRingCount = iRing; return eErr; } if( nSize != -1 ) nSize -= papoRings[iRing]->_WkbSize( b3D ); nDataOffset += papoRings[iRing]->_WkbSize( b3D ); } 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 OGRGeometryFactory::createFromWkb(unsigned char *pabyData, OGRSpatialReference * poSR, OGRGeometry **ppoReturn, int nBytes ) { OGRwkbGeometryType eGeometryType; OGRwkbByteOrder eByteOrder; OGRErr eErr; OGRGeometry *poGeom; *ppoReturn = NULL; if( nBytes < 5 && nBytes != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. The extra tests are to work around */ /* bug sin the WKB of DB2 v7.2 as identified by Safe Software. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if( eByteOrder != wkbXDR && eByteOrder != wkbNDR ) { CPLDebug( "OGR", "OGRGeometryFactory::createFromWkb() - got corrupt data.\n" "%02X%02X%02X%02X%02X%02X%02X%02X\n", pabyData[0], pabyData[1], pabyData[2], pabyData[3], pabyData[4], pabyData[5], pabyData[6], pabyData[7], pabyData[8] ); 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. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) eGeometryType = (OGRwkbGeometryType) pabyData[1]; else eGeometryType = (OGRwkbGeometryType) pabyData[4]; /* -------------------------------------------------------------------- */ /* Instantiate a geometry of the appropriate type, and */ /* initialize from the input stream. */ /* -------------------------------------------------------------------- */ poGeom = createGeometry( eGeometryType ); if( poGeom == NULL ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; /* -------------------------------------------------------------------- */ /* Import from binary. */ /* -------------------------------------------------------------------- */ eErr = poGeom->importFromWkb( pabyData, nBytes ); /* -------------------------------------------------------------------- */ /* Assign spatial reference system. */ /* -------------------------------------------------------------------- */ if( eErr == OGRERR_NONE ) { poGeom->assignSpatialReference( poSR ); *ppoReturn = poGeom; } else { delete poGeom; } return eErr; }
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 OGRLineString::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; if( nSize < 21 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); assert( 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. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; int bIs3D; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; bIs3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; bIs3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; } #ifdef __WXOSX__ assert( eGeometryType == wkbLineString ); #else CPLAssert( eGeometryType == wkbLineString ); #endif /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); setNumPoints( nNewNumPoints ); if( bIs3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ int i; if( bIs3D ) { for( i = 0; i < nPointCount; i++ ) { memcpy( paoPoints + i, pabyData + 9 + i*24, 16 ); memcpy( padfZ + i, pabyData + 9 + 16 + i*24, 8 ); } } else { memcpy( paoPoints, pabyData + 9, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* 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( bIs3D ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }