225 #include <grass/shapefil.h> 
  234 SHP_CVSID(
"$Id: shpopen.c 59649 2014-04-08 20:44:17Z mmetz $")
 
  238 #if UINT_MAX == 65535 
  249 #define ByteCopy( a, b, c )     memcpy( b, a, c ) 
  251 #  define MIN(a,b)      ((a<b) ? a : b) 
  252 #  define MAX(a,b)      ((a>b) ? a : b) 
  255 static int      bBigEndian;
 
  264 static void     SwapWord( 
int length, 
void * wordP )
 
  270     for( i=0; i < length/2; i++ )
 
  272         temp = ((uchar *) wordP)[i];
 
  273         ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1];
 
  274         ((uchar *) wordP)[length-i-1] = temp;
 
  285 static void * SfRealloc( 
void * pMem, 
int nNewSize )
 
  289         return( (
void *) 
malloc(nNewSize) );
 
  291         return( (
void *) realloc(pMem,nNewSize) );
 
  304     uchar       abyHeader[100];
 
  312         psSHP->
sHooks.
Error( 
"SHPWriteHeader failed : SHX file is closed");
 
  319     for( i = 0; i < 100; i++ )
 
  327     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
 
  331     if( bBigEndian ) SwapWord( 4, abyHeader+28 );
 
  335     if( bBigEndian ) SwapWord( 4, abyHeader+32 );
 
  338     ByteCopy( &dValue, abyHeader+36, 8 );
 
  339     if( bBigEndian ) SwapWord( 8, abyHeader+36 );
 
  342     ByteCopy( &dValue, abyHeader+44, 8 );
 
  343     if( bBigEndian ) SwapWord( 8, abyHeader+44 );
 
  346     ByteCopy( &dValue, abyHeader+52, 8 );
 
  347     if( bBigEndian ) SwapWord( 8, abyHeader+52 );
 
  350     ByteCopy( &dValue, abyHeader+60, 8 );
 
  351     if( bBigEndian ) SwapWord( 8, abyHeader+60 );
 
  354     ByteCopy( &dValue, abyHeader+68, 8 );
 
  355     if( bBigEndian ) SwapWord( 8, abyHeader+68 );
 
  358     ByteCopy( &dValue, abyHeader+76, 8 );
 
  359     if( bBigEndian ) SwapWord( 8, abyHeader+76 );
 
  362     ByteCopy( &dValue, abyHeader+84, 8 );
 
  363     if( bBigEndian ) SwapWord( 8, abyHeader+84 );
 
  366     ByteCopy( &dValue, abyHeader+92, 8 );
 
  367     if( bBigEndian ) SwapWord( 8, abyHeader+92 );
 
  375         psSHP->
sHooks.
Error( 
"Failure writing .shp header" );
 
  384     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
 
  389         psSHP->
sHooks.
Error( 
"Failure writing .shx header" );
 
  398     for( i = 0; i < psSHP->
nRecords; i++ )
 
  402         if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
 
  403         if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
 
  409         psSHP->
sHooks.
Error( 
"Failure writing .shx contents" );
 
  426 SHPOpen( 
const char * pszLayer, 
const char * pszAccess )
 
  433     return SHPOpenLL( pszLayer, pszAccess, &sHooks );
 
  447     char                *pszFullname, *pszBasename;
 
  459     if( strcmp(pszAccess,
"rb+") == 0 || strcmp(pszAccess,
"r+b") == 0
 
  460         || strcmp(pszAccess,
"r+") == 0 )
 
  469     if( *((uchar *) &i) == 1 )
 
  486     pszBasename = (
char *) 
malloc(strlen(pszLayer)+5);
 
  487     strcpy( pszBasename, pszLayer );
 
  488     for( i = strlen(pszBasename)-1; 
 
  489          i > 0 && pszBasename[i] != 
'.' && pszBasename[i] != 
'/' 
  490                && pszBasename[i] != 
'\\';
 
  493     if( pszBasename[i] == 
'.' )
 
  494         pszBasename[i] = 
'\0';
 
  500     pszFullname = (
char *) 
malloc(strlen(pszBasename) + 5);
 
  501     sprintf( pszFullname, 
"%s.shp", pszBasename ) ;
 
  505         sprintf( pszFullname, 
"%s.SHP", pszBasename );
 
  512         CPLError( CE_Failure, CPLE_OpenFailed, 
 
  513                   "Unable to open %s.shp or %s.SHP.", 
 
  514                   pszBasename, pszBasename );
 
  522     sprintf( pszFullname, 
"%s.shx", pszBasename );
 
  526         sprintf( pszFullname, 
"%s.SHX", pszBasename );
 
  533         CPLError( CE_Failure, CPLE_OpenFailed, 
 
  534                   "Unable to open %s.shx or %s.SHX.", 
 
  535                   pszBasename, pszBasename );
 
  550     pabyBuf = (uchar *) 
malloc(100);
 
  553     psSHP->
nFileSize = (pabyBuf[24] * 256 * 256 * 256
 
  554                         + pabyBuf[25] * 256 * 256
 
  564         || pabyBuf[2] != 0x27 
 
  565         || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
 
  567         psSHP->
sHooks.
Error( 
".shx file is unreadable, or corrupt." );
 
  575     psSHP->
nRecords = pabyBuf[27] + pabyBuf[26] * 256
 
  576       + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
 
  586                  "Record count in .shp header is %d, which seems\n" 
  587                  "unreasonable.  Assuming header is corrupt.",
 
  601     if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
 
  602     memcpy( &dValue, pabyBuf+36, 8 );
 
  605     if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
 
  606     memcpy( &dValue, pabyBuf+44, 8 );
 
  609     if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
 
  610     memcpy( &dValue, pabyBuf+52, 8 );
 
  613     if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
 
  614     memcpy( &dValue, pabyBuf+60, 8 );
 
  617     if( bBigEndian ) SwapWord( 8, pabyBuf+68 );         
 
  618     memcpy( &dValue, pabyBuf+68, 8 );
 
  621     if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
 
  622     memcpy( &dValue, pabyBuf+76, 8 );
 
  625     if( bBigEndian ) SwapWord( 8, pabyBuf+84 );         
 
  626     memcpy( &dValue, pabyBuf+84, 8 );
 
  629     if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
 
  630     memcpy( &dValue, pabyBuf+92, 8 );
 
  654                 "Not enough memory to allocate requested memory (nRecords=%d).\n" 
  655                 "Probably broken SHP file", 
 
  662         if (pabyBuf) 
free( pabyBuf );
 
  673                  "Failed to read all values for %d records in .shx file.",
 
  689     if (strcmp(pszAccess, 
"rb") == 0)
 
  695     for( i = 0; i < psSHP->
nRecords; i++ )
 
  697         int32           nOffset, nLength;
 
  699         memcpy( &nOffset, pabyBuf + i * 8, 4 );
 
  700         if( !bBigEndian ) SwapWord( 4, &nOffset );
 
  702         memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
 
  703         if( !bBigEndian ) SwapWord( 4, &nLength );
 
  758            double * padfMinBound, 
double * padfMaxBound )
 
  766     if( pnEntities != 
NULL )
 
  769     if( pnShapeType != 
NULL )
 
  772     for( i = 0; i < 4; i++ )
 
  774         if( padfMinBound != 
NULL )
 
  776         if( padfMaxBound != 
NULL )
 
  796     return SHPCreateLL( pszLayer, nShapeType, &sHooks );
 
  810     char        *pszBasename, *pszFullname;
 
  813     uchar       abyHeader[100];
 
  821     if( *((uchar *) &i) == 1 )
 
  830     pszBasename = (
char *) 
malloc(strlen(pszLayer)+5);
 
  831     strcpy( pszBasename, pszLayer );
 
  832     for( i = strlen(pszBasename)-1; 
 
  833          i > 0 && pszBasename[i] != 
'.' && pszBasename[i] != 
'/' 
  834                && pszBasename[i] != 
'\\';
 
  837     if( pszBasename[i] == 
'.' )
 
  838         pszBasename[i] = 
'\0';
 
  843     pszFullname = (
char *) 
malloc(strlen(pszBasename) + 5);
 
  844     sprintf( pszFullname, 
"%s.shp", pszBasename );
 
  845     fpSHP = psHooks->
FOpen(pszFullname, 
"wb" );
 
  848         psHooks->
Error( 
"Failed to create file .shp file." );
 
  854     sprintf( pszFullname, 
"%s.shx", pszBasename );
 
  855     fpSHX = psHooks->
FOpen(pszFullname, 
"wb" );
 
  858         psHooks->
Error( 
"Failed to create file .shx file." );
 
  870     for( i = 0; i < 100; i++ )
 
  878     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
 
  882     if( bBigEndian ) SwapWord( 4, abyHeader+28 );
 
  886     if( bBigEndian ) SwapWord( 4, abyHeader+32 );
 
  889     ByteCopy( &dValue, abyHeader+36, 8 );
 
  890     ByteCopy( &dValue, abyHeader+44, 8 );
 
  891     ByteCopy( &dValue, abyHeader+52, 8 );
 
  892     ByteCopy( &dValue, abyHeader+60, 8 );
 
  897     if( psHooks->
FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
 
  899         psHooks->
Error( 
"Failed to write .shp header." );
 
  908     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
 
  910     if( psHooks->
FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
 
  912         psHooks->
Error( 
"Failed to write .shx header." );
 
  922     return( 
SHPOpenLL( pszLayer, 
"r+b", psHooks ) );
 
  942         SwapWord( 8, pabyRec + 0 );
 
  943         SwapWord( 8, pabyRec + 8 );
 
  944         SwapWord( 8, pabyRec + 16 );
 
  945         SwapWord( 8, pabyRec + 24 );
 
  973     for( i = 0; i < psObject->
nVertices; i++ )
 
  996                  const 
int * panPartStart, const 
int * panPartType,
 
  997                  int nVertices, const 
double *padfX, const 
double *padfY,
 
  998                  const 
double * padfZ, const 
double * padfM )
 
 1002     int         i, bHasM, 
bHasZ;
 
 1054         for( i = 0; i < nParts; i++ )
 
 1058             if( panPartType != 
NULL )
 
 1079         assert( padfX != 
NULL );
 
 1080         assert( padfY != 
NULL );
 
 1084             psObject->
padfX[i] = padfX[i];
 
 1085             psObject->
padfY[i] = padfY[i];
 
 1086             if( padfZ != 
NULL && bHasZ )
 
 1087                 psObject->
padfZ[i] = padfZ[i];
 
 1088             if( padfM != 
NULL && bHasM )
 
 1089                 psObject->
padfM[i] = padfM[i];
 
 1091         if( padfM != 
NULL && bHasM )
 
 1113                        const 
double * padfX, const 
double * padfY,
 
 1114                        const 
double * padfZ )
 
 1118                              nVertices, padfX, padfY, padfZ, 
NULL ) );
 
 1132     int         nRecordOffset, i, nRecordSize=0;
 
 1150     assert( nShapeId == -1 
 
 1151             || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
 
 1153     if( nShapeId != -1 && nShapeId >= psSHP->
nRecords )
 
 1173                                + psObject->
nParts * 8 + 128);
 
 1186         int32           nPoints, nParts;
 
 1190         nParts = psObject->
nParts;
 
 1192         _SHPSetBounds( pabyRec + 12, psObject );
 
 1194         if( bBigEndian ) SwapWord( 4, &nPoints );
 
 1195         if( bBigEndian ) SwapWord( 4, &nParts );
 
 1197         ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
 
 1198         ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
 
 1207         for( i = 0; i < psObject->
nParts; i++ )
 
 1209             if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
 
 1218             memcpy( pabyRec + nRecordSize, psObject->
panPartType,
 
 1220             for( i = 0; i < psObject->
nParts; i++ )
 
 1222                 if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
 
 1230         for( i = 0; i < psObject->
nVertices; i++ )
 
 1233             ByteCopy( psObject->
padfY + i, pabyRec + nRecordSize + 8, 8 );
 
 1236                 SwapWord( 8, pabyRec + nRecordSize );
 
 1239                 SwapWord( 8, pabyRec + nRecordSize + 8 );
 
 1241             nRecordSize += 2 * 8;
 
 1252             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1256             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1259             for( i = 0; i < psObject->
nVertices; i++ )
 
 1262                 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1280             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1284             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1287             for( i = 0; i < psObject->
nVertices; i++ )
 
 1290                 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1308         _SHPSetBounds( pabyRec + 12, psObject );
 
 1310         if( bBigEndian ) SwapWord( 4, &nPoints );
 
 1311         ByteCopy( &nPoints, pabyRec + 44, 4 );
 
 1313         for( i = 0; i < psObject->
nVertices; i++ )
 
 1316             ByteCopy( psObject->
padfY + i, pabyRec + 48 + i*16 + 8, 8 );
 
 1318             if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
 
 1319             if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
 
 1322         nRecordSize = 48 + 16 * psObject->
nVertices;
 
 1327             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1331             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1334             for( i = 0; i < psObject->
nVertices; i++ )
 
 1337                 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1347             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1351             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1354             for( i = 0; i < psObject->
nVertices; i++ )
 
 1357                 if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1373         if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
 
 1374         if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
 
 1381             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1390             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
 
 1414     if( nShapeId == -1 || psSHP->
panRecSize[nShapeId] < nRecordSize-8 )
 
 1416         if( nShapeId == -1 )
 
 1433     if( !bBigEndian ) SwapWord( 4, &i32 );
 
 1436     i32 = (nRecordSize-8)/2;                            
 
 1437     if( !bBigEndian ) SwapWord( 4, &i32 );
 
 1441     if( bBigEndian ) SwapWord( 4, &i32 );
 
 1450         psSHP->
sHooks.
Error( 
"Error in psSHP->sHooks.FSeek() or fwrite() writing object to .shp file." );
 
 1481     for( i = 0; i < psObject->
nVertices; i++ )
 
 1509     char                 pszErrorMsg[128];
 
 1514     if( hEntity < 0 || hEntity >= psSHP->nRecords )
 
 1520     nEntitySize = psSHP->panRecSize[hEntity]+8;
 
 1521     if( nEntitySize > psSHP->nBufSize )
 
 1523         psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
 
 1524         if (psSHP->pabyRec == 
NULL)
 
 1529             psSHP->pabyRec = 
malloc(psSHP->nBufSize);
 
 1532                      "Not enough memory to allocate requested memory (nBufSize=%d). " 
 1533                      "Probably broken SHP file", psSHP->nBufSize );
 
 1534             psSHP->sHooks.Error( szError );
 
 1551     if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 
 
 1552         || psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1, 
 
 1553                   psSHP->fpSHP ) != 1 )
 
 1560         psSHP->sHooks.Error( 
"Error in fseek() or fread() reading object from .shp file." );
 
 1571     if ( 8 + 4 > nEntitySize )
 
 1573         snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nEntitySize = %d",
 
 1574                     hEntity, nEntitySize); 
 
 1575         psSHP->sHooks.Error( pszErrorMsg );
 
 1579     memcpy( &psShape->
nSHPType, psSHP->pabyRec + 8, 4 );
 
 1593         int32           nPoints, nParts;
 
 1596         if ( 40 + 8 + 4 > nEntitySize )
 
 1598             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nEntitySize = %d",
 
 1599                      hEntity, nEntitySize); 
 
 1600             psSHP->sHooks.Error( pszErrorMsg );
 
 1607         memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 +  4, 8 );
 
 1608         memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
 
 1609         memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
 
 1610         memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
 
 1612         if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
 
 1613         if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
 
 1614         if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
 
 1615         if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
 
 1621         memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
 
 1622         memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
 
 1624         if( bBigEndian ) SwapWord( 4, &nPoints );
 
 1625         if( bBigEndian ) SwapWord( 4, &nParts );
 
 1627         if (nPoints < 0 || nParts < 0 ||
 
 1628             nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
 
 1630             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
 
 1631                         hEntity, nPoints, nParts);
 
 1632             psSHP->sHooks.Error( pszErrorMsg );
 
 1640         nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
 
 1645             nRequiredSize += 16 + 8 * nPoints;
 
 1649             nRequiredSize += 4 * nParts;
 
 1651         if (nRequiredSize > nEntitySize)
 
 1653             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
 
 1654                         hEntity, nPoints, nParts, nEntitySize);
 
 1655             psSHP->sHooks.Error( pszErrorMsg );
 
 1661         psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
 
 1662         psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
 
 1663         psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
 
 1664         psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
 
 1666         psShape->
nParts = nParts;
 
 1667         psShape->
panPartStart = (
int *) calloc(nParts,
sizeof(
int));
 
 1668         psShape->
panPartType = (
int *) calloc(nParts,
sizeof(
int));
 
 1677             snprintf(pszErrorMsg, 128,
 
 1678                      "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. " 
 1679                      "Probably broken SHP file", hEntity, nPoints, nParts );
 
 1680             psSHP->sHooks.Error( pszErrorMsg );
 
 1685         for( i = 0; i < nParts; i++ )
 
 1691         memcpy( psShape->
panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
 
 1692         for( i = 0; i < nParts; i++ )
 
 1694             if( bBigEndian ) SwapWord( 4, psShape->
panPartStart+i );
 
 1700                 snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
 
 1702                 psSHP->sHooks.Error( pszErrorMsg );
 
 1708                 snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
 
 1710                 psSHP->sHooks.Error( pszErrorMsg );
 
 1716         nOffset = 44 + 8 + 4*nParts;
 
 1723             memcpy( psShape->
panPartType, psSHP->pabyRec + nOffset, 4*nParts );
 
 1724             for( i = 0; i < nParts; i++ )
 
 1726                 if( bBigEndian ) SwapWord( 4, psShape->
panPartType+i );
 
 1729             nOffset += 4*nParts;
 
 1735         for( i = 0; i < nPoints; i++ )
 
 1737             memcpy(psShape->
padfX + i,
 
 1738                    psSHP->pabyRec + nOffset + i * 16,
 
 1741             memcpy(psShape->
padfY + i,
 
 1742                    psSHP->pabyRec + nOffset + i * 16 + 8,
 
 1745             if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
 
 1746             if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
 
 1749         nOffset += 16*nPoints;
 
 1758             memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
 
 1759             memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
 
 1761             if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
 
 1762             if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
 
 1764             for( i = 0; i < nPoints; i++ )
 
 1766                 memcpy( psShape->
padfZ + i,
 
 1767                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
 
 1768                 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
 
 1771             nOffset += 16 + 8*nPoints;
 
 1780         if( nEntitySize >= nOffset + 16 + 8*nPoints )
 
 1782             memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
 
 1783             memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
 
 1785             if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
 
 1786             if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
 
 1788             for( i = 0; i < nPoints; i++ )
 
 1790                 memcpy( psShape->
padfM + i,
 
 1791                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
 
 1792                 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
 
 1808         if ( 44 + 4 > nEntitySize )
 
 1810             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nEntitySize = %d",
 
 1811                      hEntity, nEntitySize); 
 
 1812             psSHP->sHooks.Error( pszErrorMsg );
 
 1816         memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
 
 1818         if( bBigEndian ) SwapWord( 4, &nPoints );
 
 1820         if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
 
 1822             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nPoints = %d",
 
 1824             psSHP->sHooks.Error( pszErrorMsg );
 
 1829         nRequiredSize = 48 + nPoints * 16;
 
 1832             nRequiredSize += 16 + nPoints * 8;
 
 1834         if (nRequiredSize > nEntitySize)
 
 1836             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
 
 1837                      hEntity, nPoints, nEntitySize); 
 
 1838             psSHP->sHooks.Error( pszErrorMsg );
 
 1844         psShape->
padfX = (
double *) calloc(nPoints,
sizeof(
double));
 
 1845         psShape->
padfY = (
double *) calloc(nPoints,
sizeof(
double));
 
 1846         psShape->
padfZ = (
double *) calloc(nPoints,
sizeof(
double));
 
 1847         psShape->
padfM = (
double *) calloc(nPoints,
sizeof(
double));
 
 1854             snprintf(pszErrorMsg, 128,
 
 1855                      "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. " 
 1856                      "Probably broken SHP file", hEntity, nPoints );
 
 1857             psSHP->sHooks.Error( pszErrorMsg );
 
 1862         for( i = 0; i < nPoints; i++ )
 
 1864             memcpy(psShape->
padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
 
 1865             memcpy(psShape->
padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
 
 1867             if( bBigEndian ) SwapWord( 8, psShape->
padfX + i );
 
 1868             if( bBigEndian ) SwapWord( 8, psShape->
padfY + i );
 
 1871         nOffset = 48 + 16*nPoints;
 
 1876         memcpy( &(psShape->
dfXMin), psSHP->pabyRec + 8 +  4, 8 );
 
 1877         memcpy( &(psShape->
dfYMin), psSHP->pabyRec + 8 + 12, 8 );
 
 1878         memcpy( &(psShape->
dfXMax), psSHP->pabyRec + 8 + 20, 8 );
 
 1879         memcpy( &(psShape->
dfYMax), psSHP->pabyRec + 8 + 28, 8 );
 
 1881         if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMin) );
 
 1882         if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMin) );
 
 1883         if( bBigEndian ) SwapWord( 8, &(psShape->
dfXMax) );
 
 1884         if( bBigEndian ) SwapWord( 8, &(psShape->
dfYMax) );
 
 1891             memcpy( &(psShape->
dfZMin), psSHP->pabyRec + nOffset, 8 );
 
 1892             memcpy( &(psShape->
dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
 
 1894             if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMin) );
 
 1895             if( bBigEndian ) SwapWord( 8, &(psShape->
dfZMax) );
 
 1897             for( i = 0; i < nPoints; i++ )
 
 1899                 memcpy( psShape->
padfZ + i,
 
 1900                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
 
 1901                 if( bBigEndian ) SwapWord( 8, psShape->
padfZ + i );
 
 1904             nOffset += 16 + 8*nPoints;
 
 1913         if( nEntitySize >= nOffset + 16 + 8*nPoints )
 
 1915             memcpy( &(psShape->
dfMMin), psSHP->pabyRec + nOffset, 8 );
 
 1916             memcpy( &(psShape->
dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
 
 1918             if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMin) );
 
 1919             if( bBigEndian ) SwapWord( 8, &(psShape->
dfMMax) );
 
 1921             for( i = 0; i < nPoints; i++ )
 
 1923                 memcpy( psShape->
padfM + i,
 
 1924                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
 
 1925                 if( bBigEndian ) SwapWord( 8, psShape->
padfM + i );
 
 1941         psShape->
padfX = (
double *) calloc(1,
sizeof(
double));
 
 1942         psShape->
padfY = (
double *) calloc(1,
sizeof(
double));
 
 1943         psShape->
padfZ = (
double *) calloc(1,
sizeof(
double));
 
 1944         psShape->
padfM = (
double *) calloc(1,
sizeof(
double));
 
 1948             snprintf(pszErrorMsg, 128, 
"Corrupted .shp file : shape %d : nEntitySize = %d",
 
 1949                      hEntity, nEntitySize); 
 
 1950             psSHP->sHooks.Error( pszErrorMsg );
 
 1954         memcpy( psShape->
padfX, psSHP->pabyRec + 12, 8 );
 
 1955         memcpy( psShape->
padfY, psSHP->pabyRec + 20, 8 );
 
 1957         if( bBigEndian ) SwapWord( 8, psShape->
padfX );
 
 1958         if( bBigEndian ) SwapWord( 8, psShape->
padfY );
 
 1967             memcpy( psShape->
padfZ, psSHP->pabyRec + nOffset, 8 );
 
 1969             if( bBigEndian ) SwapWord( 8, psShape->
padfZ );
 
 1980         if( nEntitySize >= nOffset + 8 )
 
 1982             memcpy( psShape->
padfM, psSHP->pabyRec + nOffset, 8 );
 
 1984             if( bBigEndian ) SwapWord( 8, psShape->
padfM );
 
 2024         return "MultiPoint";
 
 2036         return "MultiPointZ";
 
 2048         return "MultiPointM";
 
 2051         return "MultiPatch";
 
 2054         return "UnknownShapeType";
 
 2069         return "TriangleStrip";
 
 2072         return "TriangleFan";
 
 2087         return "UnknownPartType";
 
 2099     if( psShape == 
NULL )
 
 2130     int  iOpRing, bAltered = 0;
 
 2146     for( iOpRing = 0; iOpRing < psObject->
nParts; iOpRing++ )
 
 2148         int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
 
 2149         double   dfSum, dfTestX, dfTestY;
 
 2169         for( iCheckRing = 0; iCheckRing < psObject->
nParts; iCheckRing++ )
 
 2173             if( iCheckRing == iOpRing )
 
 2178             if( iCheckRing == psObject->
nParts-1 )
 
 2185             for( iEdge = 0; iEdge < nVertCount; iEdge++ )
 
 2189                 if( iEdge < nVertCount-1 )
 
 2198                 if ( ( psObject->
padfY[iEdge+nVertStart] < dfTestY
 
 2199                        && dfTestY <= psObject->padfY[iNext+nVertStart] )
 
 2200                     || ( psObject->
padfY[iNext+nVertStart] < dfTestY
 
 2201                          && dfTestY <= psObject->
padfY[iEdge+nVertStart] ) )
 
 2206                     double const intersect = 
 
 2207                         ( psObject->
padfX[iEdge+nVertStart]
 
 2208                           + ( dfTestY - psObject->
padfY[iEdge+nVertStart] ) 
 
 2209                           / ( psObject->
padfY[iNext+nVertStart] - psObject->
padfY[iEdge+nVertStart] )
 
 2210                           * ( psObject->
padfX[iNext+nVertStart] - psObject->
padfX[iEdge+nVertStart] ) );
 
 2212                     if (intersect  < dfTestX)
 
 2226         if( iOpRing == psObject->
nParts-1 )
 
 2233         for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
 
 2235             dfSum += psObject->
padfX[iVert] * psObject->
padfY[iVert+1]
 
 2236                 - psObject->
padfY[iVert] * psObject->
padfX[iVert+1];
 
 2239         dfSum += psObject->
padfX[iVert] * psObject->
padfY[nVertStart]
 
 2240                - psObject->
padfY[iVert] * psObject->
padfX[nVertStart];
 
 2245         if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
 
 2250             for( i = 0; i < nVertCount/2; i++ )
 
 2255                 dfSaved = psObject->
padfX[nVertStart+i];
 
 2256                 psObject->
padfX[nVertStart+i] = 
 
 2257                     psObject->
padfX[nVertStart+nVertCount-i-1];
 
 2258                 psObject->
padfX[nVertStart+nVertCount-i-1] = dfSaved;
 
 2261                 dfSaved = psObject->
padfY[nVertStart+i];
 
 2262                 psObject->
padfY[nVertStart+i] = 
 
 2263                     psObject->
padfY[nVertStart+nVertCount-i-1];
 
 2264                 psObject->
padfY[nVertStart+nVertCount-i-1] = dfSaved;
 
 2267                 if( psObject->
padfZ )
 
 2269                     dfSaved = psObject->
padfZ[nVertStart+i];
 
 2270                     psObject->
padfZ[nVertStart+i] = 
 
 2271                         psObject->
padfZ[nVertStart+nVertCount-i-1];
 
 2272                     psObject->
padfZ[nVertStart+nVertCount-i-1] = dfSaved;
 
 2276                 if( psObject->
padfM )
 
 2278                     dfSaved = psObject->
padfM[nVertStart+i];
 
 2279                     psObject->
padfM[nVertStart+i] = 
 
 2280                         psObject->
padfM[nVertStart+nVertCount-i-1];
 
 2281                     psObject->
padfM[nVertStart+nVertCount-i-1] = dfSaved;
 
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void SHPAPI_CALL SHPComputeExtents(SHPObject *psObject)
int SHPAPI_CALL SHPRewindObject(SHPHandle hSHP, SHPObject *psObject)
SAFile(* FOpen)(const char *filename, const char *path)
void SHPAPI_CALL SHPGetInfo(SHPHandle hSHP, int *pnEntities, int *pnShapeType, double *padfMinBound, double *padfMaxBound)
int(* FClose)(SAFile file)
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
void SHPAPI_CALL SHPClose(SHPHandle hSHP)
int(* FFlush)(SAFile file)
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject *psObject)
SHP_CVSID("$Id: safileio.c,v 1.4 2008/01/16 20:05:14 bram Exp $")
void SASetupDefaultHooks(SAHooks *psHooks)
SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszShapeFile, const char *pszAccess, SAHooks *psHooks)
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType)
void(* Error)(const char *message)
#define ByteCopy(a, b, c)
SHPObject SHPAPI_CALL1 * SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX, const double *padfY, const double *padfZ){return(SHPCreateObject(nSHPType,-1, 0, NULL, NULL, nVertices, padfX, padfY, padfZ, NULL)
SHPObject SHPAPI_CALL1 * SHPReadObject(SHPHandle hSHP, int iShape);int SHPAPI_CALLSHPWriteObject(SHPHandle hSHP, int iShape, SHPObject *psObject
SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszShapeFile, int nShapeType, SAHooks *psHooks)
SHPObject SHPAPI_CALL1 * SHPCreateObject(int nSHPType, int nShapeId, int nParts, const int *panPartStart, const int *panPartType, int nVertices, const double *padfX, const double *padfY, const double *padfZ, const double *padfM);SHPObject SHPAPI_CALL1(*) SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX, const double *padfY, const double *padfZ
const char SHPAPI_CALL1 * SHPPartTypeName(int nPartType){switch(nPartType
SHPHandle SHPAPI_CALL SHPOpen(const char *pszShapeFile, const char *pszAccess)
void SHPAPI_CALL SHPWriteHeader(SHPHandle hSHP)
#define DISABLE_MULTIPATCH_MEASURE
void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject)
const char SHPAPI_CALL1 * SHPTypeName(int nSHPType);const char SHPAPI_CALL1(*) SHPPartTypeName(int nPartType