34
34
******************************************************************************
36
36
* $Log: shpopen.c,v $
37
* Revision 1.72 2011-12-11 22:45:28 fwarmerdam
38
* fix failure return from SHPOpenLL.
40
* Revision 1.71 2011-09-15 03:33:58 fwarmerdam
41
* fix missing cast (#2344)
43
* Revision 1.70 2011-07-24 05:59:25 fwarmerdam
44
* minimize use of CPLError in favor of SAHooks.Error()
46
* Revision 1.69 2011-07-24 03:24:22 fwarmerdam
47
* fix memory leaks in error cases creating shapefiles (#2061)
49
* Revision 1.68 2010-08-27 23:42:52 fwarmerdam
50
* add SHPAPI_CALL attribute in code
52
* Revision 1.67 2010-07-01 08:15:48 fwarmerdam
53
* do not error out on an object with zero vertices
55
* Revision 1.66 2010-07-01 07:58:57 fwarmerdam
56
* minor cleanup of error handling
58
* Revision 1.65 2010-07-01 07:27:13 fwarmerdam
59
* white space formatting adjustments
37
61
* Revision 1.64 2010-01-28 11:34:34 fwarmerdam
38
62
* handle the shape file length limits more gracefully (#3236)
419
443
for( i = 0; i < psSHP->nRecords; i++ )
421
panSHX[i*2 ] = psSHP->panRecOffset[i]/2;
422
panSHX[i*2+1] = psSHP->panRecSize[i]/2;
423
if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
424
if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
445
panSHX[i*2 ] = psSHP->panRecOffset[i]/2;
446
panSHX[i*2+1] = psSHP->panRecSize[i]/2;
447
if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
448
if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
427
451
if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )
507
531
pszBasename = (char *) malloc(strlen(pszLayer)+5);
508
532
strcpy( pszBasename, pszLayer );
509
533
for( i = strlen(pszBasename)-1;
510
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
511
&& pszBasename[i] != '\\';
534
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
535
&& pszBasename[i] != '\\';
514
538
if( pszBasename[i] == '.' )
515
539
pszBasename[i] = '\0';
530
554
if( psSHP->fpSHP == NULL )
533
CPLError( CE_Failure, CPLE_OpenFailed,
534
"Unable to open %s.shp or %s.SHP.",
556
char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
557
sprintf( pszMessage, "Unable to open %s.shp or %s.SHP.",
535
558
pszBasename, pszBasename );
559
psHooks->Error( pszMessage );
538
563
free( pszBasename );
539
564
free( pszFullname );
543
568
sprintf( pszFullname, "%s.shx", pszBasename );
551
576
if( psSHP->fpSHX == NULL )
554
CPLError( CE_Failure, CPLE_OpenFailed,
555
"Unable to open %s.shx or %s.SHX.",
578
char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
579
sprintf( pszMessage, "Unable to open %s.shx or %s.SHX.",
556
580
pszBasename, pszBasename );
581
psHooks->Error( pszMessage );
558
584
psSHP->sHooks.FClose( psSHP->fpSHP );
560
586
free( pszBasename );
572
598
psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
574
600
psSHP->nFileSize = ((unsigned int)pabyBuf[24] * 256 * 256 * 256
575
+ (unsigned int)pabyBuf[25] * 256 * 256
576
+ (unsigned int)pabyBuf[26] * 256
577
+ (unsigned int)pabyBuf[27]) * 2;
601
+ (unsigned int)pabyBuf[25] * 256 * 256
602
+ (unsigned int)pabyBuf[26] * 256
603
+ (unsigned int)pabyBuf[27]) * 2;
579
605
/* -------------------------------------------------------------------- */
580
606
/* Read SHX file Header info */
586
612
|| (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
588
614
psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
589
psSHP->sHooks.FClose( psSHP->fpSHP );
590
psSHP->sHooks.FClose( psSHP->fpSHX );
615
psSHP->sHooks.FClose( psSHP->fpSHP );
616
psSHP->sHooks.FClose( psSHP->fpSHX );
596
622
psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
597
+ pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
623
+ pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
598
624
psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
600
626
psSHP->nShapeType = pabyBuf[32];
606
632
sprintf( szError,
607
633
"Record count in .shp header is %d, which seems\n"
608
634
"unreasonable. Assuming header is corrupt.",
610
636
psSHP->sHooks.Error( szError );
611
psSHP->sHooks.FClose( psSHP->fpSHP );
612
psSHP->sHooks.FClose( psSHP->fpSHX );
637
psSHP->sHooks.FClose( psSHP->fpSHP );
638
psSHP->sHooks.FClose( psSHP->fpSHX );
619
645
/* -------------------------------------------------------------------- */
676
702
"Probably broken SHP file",
677
703
psSHP->nRecords );
678
704
psSHP->sHooks.Error( szError );
679
psSHP->sHooks.FClose( psSHP->fpSHP );
680
psSHP->sHooks.FClose( psSHP->fpSHX );
705
psSHP->sHooks.FClose( psSHP->fpSHP );
706
psSHP->sHooks.FClose( psSHP->fpSHX );
681
707
if (psSHP->panRecOffset) free( psSHP->panRecOffset );
682
708
if (psSHP->panRecSize) free( psSHP->panRecSize );
683
709
if (pabyBuf) free( pabyBuf );
696
722
psSHP->sHooks.Error( szError );
698
724
/* SHX is short or unreadable for some reason. */
699
psSHP->sHooks.FClose( psSHP->fpSHP );
700
psSHP->sHooks.FClose( psSHP->fpSHX );
725
psSHP->sHooks.FClose( psSHP->fpSHP );
726
psSHP->sHooks.FClose( psSHP->fpSHX );
701
727
free( psSHP->panRecOffset );
702
728
free( psSHP->panRecSize );
709
735
/* In read-only mode, we can close the SHX now */
716
742
for( i = 0; i < psSHP->nRecords; i++ )
718
int32 nOffset, nLength;
720
memcpy( &nOffset, pabyBuf + i * 8, 4 );
721
if( !bBigEndian ) SwapWord( 4, &nOffset );
723
memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
724
if( !bBigEndian ) SwapWord( 4, &nLength );
726
psSHP->panRecOffset[i] = nOffset*2;
727
psSHP->panRecSize[i] = nLength*2;
744
int32 nOffset, nLength;
746
memcpy( &nOffset, pabyBuf + i * 8, 4 );
747
if( !bBigEndian ) SwapWord( 4, &nOffset );
749
memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
750
if( !bBigEndian ) SwapWord( 4, &nLength );
752
psSHP->panRecOffset[i] = nOffset*2;
753
psSHP->panRecSize[i] = nLength*2;
851
877
pszBasename = (char *) malloc(strlen(pszLayer)+5);
852
878
strcpy( pszBasename, pszLayer );
853
879
for( i = strlen(pszBasename)-1;
854
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
855
&& pszBasename[i] != '\\';
880
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
881
&& pszBasename[i] != '\\';
858
884
if( pszBasename[i] == '.' )
859
885
pszBasename[i] = '\0';
875
901
if( fpSHX == NULL )
877
903
psHooks->Error( "Failed to create file .shx file." );
907
free( pszFullname ); pszFullname = NULL;
908
free( pszBasename ); pszBasename = NULL;
884
910
/* -------------------------------------------------------------------- */
885
911
/* Prepare header block for .shp file. */
886
912
/* -------------------------------------------------------------------- */
887
913
for( i = 0; i < 100; i++ )
890
916
abyHeader[2] = 0x27; /* magic cookie */
891
917
abyHeader[3] = 0x0a;
937
963
psHooks->FClose( fpSHX );
939
965
return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
968
if (pszFullname) free(pszFullname);
969
if (pszBasename) free(pszBasename);
970
if (fpSHP) psHooks->FClose( fpSHP );
971
if (fpSHX) psHooks->FClose( fpSHX );
942
975
/************************************************************************/
1175
1208
/* -------------------------------------------------------------------- */
1176
1209
if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
1178
psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
1211
psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
1180
psSHP->panRecOffset = (unsigned int *)
1213
psSHP->panRecOffset = (unsigned int *)
1181
1214
SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * psSHP->nMaxRecords );
1182
psSHP->panRecSize = (unsigned int *)
1215
psSHP->panRecSize = (unsigned int *)
1183
1216
SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * psSHP->nMaxRecords );
1200
1233
|| psObject->nSHPType == SHPT_ARCM
1201
1234
|| psObject->nSHPType == SHPT_MULTIPATCH )
1203
int32 nPoints, nParts;
1206
nPoints = psObject->nVertices;
1207
nParts = psObject->nParts;
1209
_SHPSetBounds( pabyRec + 12, psObject );
1211
if( bBigEndian ) SwapWord( 4, &nPoints );
1212
if( bBigEndian ) SwapWord( 4, &nParts );
1214
ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
1215
ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
1236
int32 nPoints, nParts;
1239
nPoints = psObject->nVertices;
1240
nParts = psObject->nParts;
1242
_SHPSetBounds( pabyRec + 12, psObject );
1244
if( bBigEndian ) SwapWord( 4, &nPoints );
1245
if( bBigEndian ) SwapWord( 4, &nParts );
1247
ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
1248
ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
1217
1250
nRecordSize = 52;
1220
1253
* Write part start positions.
1222
ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
1255
ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
1223
1256
4 * psObject->nParts );
1224
for( i = 0; i < psObject->nParts; i++ )
1226
if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
1257
for( i = 0; i < psObject->nParts; i++ )
1259
if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
1227
1260
nRecordSize += 4;
1231
1264
* Write multipatch part types if needed.
1245
1278
* Write the (x,y) vertex values.
1247
for( i = 0; i < psObject->nVertices; i++ )
1249
ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
1250
ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
1280
for( i = 0; i < psObject->nVertices; i++ )
1282
ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
1283
ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
1253
1286
SwapWord( 8, pabyRec + nRecordSize );
1256
1289
SwapWord( 8, pabyRec + nRecordSize + 8 );
1258
1291
nRecordSize += 2 * 8;
1262
1295
* Write the Z coordinates (if any).
1287
1320
if( psObject->bMeasureIsUsed
1288
1321
&& (psObject->nSHPType == SHPT_POLYGONM
1289
|| psObject->nSHPType == SHPT_ARCM
1322
|| psObject->nSHPType == SHPT_ARCM
1290
1323
#ifndef DISABLE_MULTIPATCH_MEASURE
1291
|| psObject->nSHPType == SHPT_MULTIPATCH
1324
|| psObject->nSHPType == SHPT_MULTIPATCH
1293
|| psObject->nSHPType == SHPT_POLYGONZ
1294
|| psObject->nSHPType == SHPT_ARCZ) )
1326
|| psObject->nSHPType == SHPT_POLYGONZ
1327
|| psObject->nSHPType == SHPT_ARCZ) )
1296
1329
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
1297
1330
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1317
1350
|| psObject->nSHPType == SHPT_MULTIPOINTZ
1318
1351
|| psObject->nSHPType == SHPT_MULTIPOINTM )
1323
nPoints = psObject->nVertices;
1356
nPoints = psObject->nVertices;
1325
1358
_SHPSetBounds( pabyRec + 12, psObject );
1327
if( bBigEndian ) SwapWord( 4, &nPoints );
1328
ByteCopy( &nPoints, pabyRec + 44, 4 );
1360
if( bBigEndian ) SwapWord( 4, &nPoints );
1361
ByteCopy( &nPoints, pabyRec + 44, 4 );
1330
for( i = 0; i < psObject->nVertices; i++ )
1332
ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
1333
ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
1335
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
1336
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
1339
nRecordSize = 48 + 16 * psObject->nVertices;
1363
for( i = 0; i < psObject->nVertices; i++ )
1365
ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
1366
ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
1368
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
1369
if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
1372
nRecordSize = 48 + 16 * psObject->nVertices;
1341
1374
if( psObject->nSHPType == SHPT_MULTIPOINTZ )
1359
1392
if( psObject->bMeasureIsUsed
1360
1393
&& (psObject->nSHPType == SHPT_MULTIPOINTZ
1361
|| psObject->nSHPType == SHPT_MULTIPOINTM) )
1394
|| psObject->nSHPType == SHPT_MULTIPOINTM) )
1363
1396
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
1364
1397
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1384
1417
|| psObject->nSHPType == SHPT_POINTZ
1385
1418
|| psObject->nSHPType == SHPT_POINTM )
1387
ByteCopy( psObject->padfX, pabyRec + 12, 8 );
1388
ByteCopy( psObject->padfY, pabyRec + 20, 8 );
1420
ByteCopy( psObject->padfX, pabyRec + 12, 8 );
1421
ByteCopy( psObject->padfY, pabyRec + 20, 8 );
1390
if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
1391
if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
1423
if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
1424
if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
1393
1426
nRecordSize = 28;
1402
1435
if( psObject->bMeasureIsUsed
1403
1436
&& (psObject->nSHPType == SHPT_POINTZ
1404
|| psObject->nSHPType == SHPT_POINTM) )
1437
|| psObject->nSHPType == SHPT_POINTM) )
1406
1439
ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
1407
1440
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
1437
1470
sprintf( str, "Failed to write shape object. "
1438
"File size cannot reach %u + %u.",
1439
psSHP->nFileSize, nRecordSize );
1471
"File size cannot reach %u + %u.",
1472
psSHP->nFileSize, nRecordSize );
1440
1473
psSHP->sHooks.Error( str );
1441
1474
free( pabyRec );
1515
1548
for( i = 0; i < psObject->nVertices; i++ )
1517
psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
1518
psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
1519
psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
1520
psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
1521
psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
1522
psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
1523
psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
1524
psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
1550
psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
1551
psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
1552
psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
1553
psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
1554
psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
1555
psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
1556
psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
1557
psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
1527
1560
return( nShapeId );
1554
1587
nEntitySize = psSHP->panRecSize[hEntity]+8;
1555
1588
if( nEntitySize > psSHP->nBufSize )
1557
psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
1590
psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
1558
1591
if (psSHP->pabyRec == NULL)
1560
1593
char szError[200];
1562
1595
/* Reallocate previous successfull size for following features */
1563
psSHP->pabyRec = malloc(psSHP->nBufSize);
1596
psSHP->pabyRec = (uchar *) malloc(psSHP->nBufSize);
1565
1598
sprintf( szError,
1566
1599
"Not enough memory to allocate requested memory (nBufSize=%d). "
1622
1655
if ( 8 + 4 > nEntitySize )
1624
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
1625
hEntity, nEntitySize);
1626
psSHP->sHooks.Error( pszErrorMsg );
1657
snprintf(szErrorMsg, sizeof(szErrorMsg),
1658
"Corrupted .shp file : shape %d : nEntitySize = %d",
1659
hEntity, nEntitySize);
1660
psSHP->sHooks.Error( szErrorMsg );
1627
1661
SHPDestroyObject(psShape);
1641
1675
|| psShape->nSHPType == SHPT_ARCM
1642
1676
|| psShape->nSHPType == SHPT_MULTIPATCH )
1644
int32 nPoints, nParts;
1678
int32 nPoints, nParts;
1647
1681
if ( 40 + 8 + 4 > nEntitySize )
1649
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
1683
snprintf(szErrorMsg, sizeof(szErrorMsg),
1684
"Corrupted .shp file : shape %d : nEntitySize = %d",
1650
1685
hEntity, nEntitySize);
1651
psSHP->sHooks.Error( pszErrorMsg );
1686
psSHP->sHooks.Error( szErrorMsg );
1652
1687
SHPDestroyObject(psShape);
1660
1695
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1661
1696
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1663
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1664
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
1665
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
1666
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
1698
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1699
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
1700
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
1701
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
1668
1703
/* -------------------------------------------------------------------- */
1669
1704
/* Extract part/point count, and build vertex and part arrays */
1670
1705
/* to proper size. */
1671
1706
/* -------------------------------------------------------------------- */
1672
memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1673
memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1707
memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1708
memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1675
if( bBigEndian ) SwapWord( 4, &nPoints );
1676
if( bBigEndian ) SwapWord( 4, &nParts );
1710
if( bBigEndian ) SwapWord( 4, &nPoints );
1711
if( bBigEndian ) SwapWord( 4, &nParts );
1678
1713
if (nPoints < 0 || nParts < 0 ||
1679
1714
nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
1681
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
1682
hEntity, nPoints, nParts);
1683
psSHP->sHooks.Error( pszErrorMsg );
1716
snprintf(szErrorMsg, sizeof(szErrorMsg),
1717
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
1718
hEntity, nPoints, nParts);
1719
psSHP->sHooks.Error( szErrorMsg );
1684
1720
SHPDestroyObject(psShape);
1690
1726
/* since 50 M * (16 + 8 + 8) = 1 600 MB */
1691
1727
nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
1692
1728
if ( psShape->nSHPType == SHPT_POLYGONZ
1693
|| psShape->nSHPType == SHPT_ARCZ
1694
|| psShape->nSHPType == SHPT_MULTIPATCH )
1729
|| psShape->nSHPType == SHPT_ARCZ
1730
|| psShape->nSHPType == SHPT_MULTIPATCH )
1696
1732
nRequiredSize += 16 + 8 * nPoints;
1702
1738
if (nRequiredSize > nEntitySize)
1704
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
1705
hEntity, nPoints, nParts, nEntitySize);
1706
psSHP->sHooks.Error( pszErrorMsg );
1740
snprintf(szErrorMsg, sizeof(szErrorMsg),
1741
"Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
1742
hEntity, nPoints, nParts, nEntitySize);
1743
psSHP->sHooks.Error( szErrorMsg );
1707
1744
SHPDestroyObject(psShape);
1711
psShape->nVertices = nPoints;
1748
psShape->nVertices = nPoints;
1712
1749
psShape->padfX = (double *) calloc(nPoints,sizeof(double));
1713
1750
psShape->padfY = (double *) calloc(nPoints,sizeof(double));
1714
1751
psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
1715
1752
psShape->padfM = (double *) calloc(nPoints,sizeof(double));
1717
psShape->nParts = nParts;
1754
psShape->nParts = nParts;
1718
1755
psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
1719
1756
psShape->panPartType = (int *) calloc(nParts,sizeof(int));
1725
1762
psShape->panPartStart == NULL ||
1726
1763
psShape->panPartType == NULL)
1728
snprintf(pszErrorMsg, 128,
1765
snprintf(szErrorMsg, sizeof(szErrorMsg),
1729
1766
"Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
1730
1767
"Probably broken SHP file", hEntity, nPoints, nParts );
1731
psSHP->sHooks.Error( pszErrorMsg );
1768
psSHP->sHooks.Error( szErrorMsg );
1732
1769
SHPDestroyObject(psShape);
1739
1776
/* -------------------------------------------------------------------- */
1740
1777
/* Copy out the part array from the record. */
1741
1778
/* -------------------------------------------------------------------- */
1742
memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1743
for( i = 0; i < nParts; i++ )
1745
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
1779
memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1780
for( i = 0; i < nParts; i++ )
1782
if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
1747
1784
/* We check that the offset is inside the vertex array */
1748
if (psShape->panPartStart[i] < 0 ||
1749
psShape->panPartStart[i] >= psShape->nVertices)
1785
if (psShape->panPartStart[i] < 0
1786
|| (psShape->panPartStart[i] >= psShape->nVertices
1787
&& psShape->nVertices > 0) )
1751
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
1789
snprintf(szErrorMsg, sizeof(szErrorMsg),
1790
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
1752
1791
hEntity, i, psShape->panPartStart[i], psShape->nVertices);
1753
psSHP->sHooks.Error( pszErrorMsg );
1792
psSHP->sHooks.Error( szErrorMsg );
1754
1793
SHPDestroyObject(psShape);
1757
1796
if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
1759
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
1798
snprintf(szErrorMsg, sizeof(szErrorMsg),
1799
"Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
1760
1800
hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);
1761
psSHP->sHooks.Error( pszErrorMsg );
1801
psSHP->sHooks.Error( szErrorMsg );
1762
1802
SHPDestroyObject(psShape);
1767
nOffset = 44 + 8 + 4*nParts;
1807
nOffset = 44 + 8 + 4*nParts;
1769
1809
/* -------------------------------------------------------------------- */
1770
1810
/* If this is a multipatch, we will also have parts types. */
1783
1823
/* -------------------------------------------------------------------- */
1784
1824
/* Copy out the vertices from the record. */
1785
1825
/* -------------------------------------------------------------------- */
1786
for( i = 0; i < nPoints; i++ )
1788
memcpy(psShape->padfX + i,
1789
psSHP->pabyRec + nOffset + i * 16,
1792
memcpy(psShape->padfY + i,
1793
psSHP->pabyRec + nOffset + i * 16 + 8,
1796
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1797
if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
1826
for( i = 0; i < nPoints; i++ )
1828
memcpy(psShape->padfX + i,
1829
psSHP->pabyRec + nOffset + i * 16,
1832
memcpy(psShape->padfY + i,
1833
psSHP->pabyRec + nOffset + i * 16 + 8,
1836
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1837
if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
1800
1840
nOffset += 16*nPoints;
1853
1893
|| psShape->nSHPType == SHPT_MULTIPOINTM
1854
1894
|| psShape->nSHPType == SHPT_MULTIPOINTZ )
1859
1899
if ( 44 + 4 > nEntitySize )
1861
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
1901
snprintf(szErrorMsg, sizeof(szErrorMsg),
1902
"Corrupted .shp file : shape %d : nEntitySize = %d",
1862
1903
hEntity, nEntitySize);
1863
psSHP->sHooks.Error( pszErrorMsg );
1904
psSHP->sHooks.Error( szErrorMsg );
1864
1905
SHPDestroyObject(psShape);
1867
memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
1908
memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
1869
if( bBigEndian ) SwapWord( 4, &nPoints );
1910
if( bBigEndian ) SwapWord( 4, &nPoints );
1871
1912
if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
1873
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d",
1914
snprintf(szErrorMsg, sizeof(szErrorMsg),
1915
"Corrupted .shp file : shape %d : nPoints = %d",
1874
1916
hEntity, nPoints);
1875
psSHP->sHooks.Error( pszErrorMsg );
1917
psSHP->sHooks.Error( szErrorMsg );
1876
1918
SHPDestroyObject(psShape);
1885
1927
if (nRequiredSize > nEntitySize)
1887
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
1929
snprintf(szErrorMsg, sizeof(szErrorMsg),
1930
"Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
1888
1931
hEntity, nPoints, nEntitySize);
1889
psSHP->sHooks.Error( pszErrorMsg );
1932
psSHP->sHooks.Error( szErrorMsg );
1890
1933
SHPDestroyObject(psShape);
1894
psShape->nVertices = nPoints;
1937
psShape->nVertices = nPoints;
1895
1938
psShape->padfX = (double *) calloc(nPoints,sizeof(double));
1896
1939
psShape->padfY = (double *) calloc(nPoints,sizeof(double));
1897
1940
psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
1902
1945
psShape->padfZ == NULL ||
1903
1946
psShape->padfM == NULL)
1905
snprintf(pszErrorMsg, 128,
1948
snprintf(szErrorMsg, sizeof(szErrorMsg),
1906
1949
"Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
1907
1950
"Probably broken SHP file", hEntity, nPoints );
1908
psSHP->sHooks.Error( pszErrorMsg );
1951
psSHP->sHooks.Error( szErrorMsg );
1909
1952
SHPDestroyObject(psShape);
1913
for( i = 0; i < nPoints; i++ )
1915
memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
1916
memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
1956
for( i = 0; i < nPoints; i++ )
1958
memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
1959
memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
1918
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1919
if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
1961
if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1962
if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
1922
1965
nOffset = 48 + 16*nPoints;
1929
1972
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1930
1973
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1932
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1933
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
1934
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
1935
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
1975
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1976
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
1977
if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
1978
if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
1937
1980
/* -------------------------------------------------------------------- */
1938
1981
/* If we have a Z coordinate, collect that now. */
1997
2040
if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
1999
snprintf(pszErrorMsg, 128, "Corrupted .shp file : shape %d : nEntitySize = %d",
2042
snprintf(szErrorMsg, sizeof(szErrorMsg),
2043
"Corrupted .shp file : shape %d : nEntitySize = %d",
2000
2044
hEntity, nEntitySize);
2001
psSHP->sHooks.Error( pszErrorMsg );
2045
psSHP->sHooks.Error( szErrorMsg );
2002
2046
SHPDestroyObject(psShape);
2005
memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
2006
memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
2049
memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
2050
memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
2008
if( bBigEndian ) SwapWord( 8, psShape->padfX );
2009
if( bBigEndian ) SwapWord( 8, psShape->padfY );
2052
if( bBigEndian ) SwapWord( 8, psShape->padfX );
2053
if( bBigEndian ) SwapWord( 8, psShape->padfY );
2011
2055
nOffset = 20 + 8;
2249
2293
if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY
2250
2294
&& dfTestY <= psObject->padfY[iNext+nVertStart] )
2251
|| ( psObject->padfY[iNext+nVertStart] < dfTestY
2252
&& dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
2295
|| ( psObject->padfY[iNext+nVertStart] < dfTestY
2296
&& dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
2255
* Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
2299
* Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
2257
2301
double const intersect =
2258
2302
( psObject->padfX[iEdge+nVertStart]
2259
2303
+ ( dfTestY - psObject->padfY[iEdge+nVertStart] )