PostGIS  2.1.10dev-r@@SVN_REVISION@@
if ( bBigEndian  )

Definition at line 1659 of file shpopen.c.

1670  {
1671  uint32 nPoints, nParts;
1672  int i, nOffset;
1673 
1674  if ( 40 + 8 + 4 > nEntitySize )
1675  {
1676  snprintf(szErrorMsg, sizeof(szErrorMsg),
1677  "Corrupted .shp file : shape %d : nEntitySize = %d",
1678  hEntity, nEntitySize);
1679  psSHP->sHooks.Error( szErrorMsg );
1681  return NULL;
1682  }
1683 /* -------------------------------------------------------------------- */
1684 /* Get the X/Y bounds. */
1685 /* -------------------------------------------------------------------- */
1686  memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 );
1687  memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
1688  memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
1689  memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
1690 
1691  if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
1692  if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
1693  if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
1694  if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
1695 
1696 /* -------------------------------------------------------------------- */
1697 /* Extract part/point count, and build vertex and part arrays */
1698 /* to proper size. */
1699 /* -------------------------------------------------------------------- */
1700  memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
1701  memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
1702 
1703  if( bBigEndian ) SwapWord( 4, &nPoints );
1704  if( bBigEndian ) SwapWord( 4, &nParts );
1705 
1706  if ( nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000 )
1707  {
1708  snprintf(szErrorMsg, sizeof(szErrorMsg),
1709  "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
1710  hEntity, nPoints, nParts);
1711  psSHP->sHooks.Error( szErrorMsg );
1713  return NULL;
1714  }
1715 
1716  /* With the previous checks on nPoints and nParts, */
1717  /* we should not overflow here and after */
1718  /* since 50 M * (16 + 8 + 8) = 1 600 MB */
1719  nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
1720  if ( psShape->nSHPType == SHPT_POLYGONZ
1721  || psShape->nSHPType == SHPT_ARCZ
1722  || psShape->nSHPType == SHPT_MULTIPATCH )
1723  {
1724  nRequiredSize += 16 + 8 * nPoints;
1725  }
1726  if( psShape->nSHPType == SHPT_MULTIPATCH )
1727  {
1728  nRequiredSize += 4 * nParts;
1729  }
1730  if (nRequiredSize > nEntitySize)
1731  {
1732  snprintf(szErrorMsg, sizeof(szErrorMsg),
1733  "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
1734  hEntity, nPoints, nParts, nEntitySize);
1735  psSHP->sHooks.Error( szErrorMsg );
1737  return NULL;
1738  }
1739 
1740  psShape->nVertices = nPoints;
1741  psShape->padfX = (double *) calloc(nPoints,sizeof(double));
1742  psShape->padfY = (double *) calloc(nPoints,sizeof(double));
1743  psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
1744  psShape->padfM = (double *) calloc(nPoints,sizeof(double));
1745 
1746  psShape->nParts = nParts;
1747  psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
1748  psShape->panPartType = (int *) calloc(nParts,sizeof(int));
1749 
1750  if (psShape->padfX == NULL ||
1751  psShape->padfY == NULL ||
1752  psShape->padfZ == NULL ||
1753  psShape->padfM == NULL ||
1754  psShape->panPartStart == NULL ||
1755  psShape->panPartType == NULL)
1756  {
1757  snprintf(szErrorMsg, sizeof(szErrorMsg),
1758  "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
1759  "Probably broken SHP file", hEntity, nPoints, nParts );
1760  psSHP->sHooks.Error( szErrorMsg );
1762  return NULL;
1763  }
1764 
1765  for( i = 0; i < nParts; i++ )
1766  psShape->panPartType[i] = SHPP_RING;
1767 
1768 /* -------------------------------------------------------------------- */
1769 /* Copy out the part array from the record. */
1770 /* -------------------------------------------------------------------- */
1771  memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
1772  for( i = 0; i < nParts; i++ )
1773  {
1774  if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
1775 
1776  /* We check that the offset is inside the vertex array */
1777  if (psShape->panPartStart[i] < 0
1778  || (psShape->panPartStart[i] >= psShape->nVertices
1779  && psShape->nVertices > 0) )
1780  {
1781  snprintf(szErrorMsg, sizeof(szErrorMsg),
1782  "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
1783  hEntity, i, psShape->panPartStart[i], psShape->nVertices);
1784  psSHP->sHooks.Error( szErrorMsg );
1786  return NULL;
1787  }
1788  if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
1789  {
1790  snprintf(szErrorMsg, sizeof(szErrorMsg),
1791  "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
1792  hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);
1793  psSHP->sHooks.Error( szErrorMsg );
1795  return NULL;
1796  }
1797  }
1798 
1799  nOffset = 44 + 8 + 4*nParts;
1800 
1801 /* -------------------------------------------------------------------- */
1802 /* If this is a multipatch, we will also have parts types. */
1803 /* -------------------------------------------------------------------- */
1804  if( psShape->nSHPType == SHPT_MULTIPATCH )
1805  {
1806  memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
1807  for( i = 0; i < nParts; i++ )
1808  {
1809  if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
1810  }
1811 
1812  nOffset += 4*nParts;
1813  }
1814 
1815 /* -------------------------------------------------------------------- */
1816 /* Copy out the vertices from the record. */
1817 /* -------------------------------------------------------------------- */
1818  for( i = 0; i < nPoints; i++ )
1819  {
1820  memcpy(psShape->padfX + i,
1821  psSHP->pabyRec + nOffset + i * 16,
1822  8 );
1823 
1824  memcpy(psShape->padfY + i,
1825  psSHP->pabyRec + nOffset + i * 16 + 8,
1826  8 );
1827 
1828  if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
1829  if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
1830  }
1831 
1832  nOffset += 16*nPoints;
1833 
1834 /* -------------------------------------------------------------------- */
1835 /* If we have a Z coordinate, collect that now. */
1836 /* -------------------------------------------------------------------- */
1837  if( psShape->nSHPType == SHPT_POLYGONZ
1838  || psShape->nSHPType == SHPT_ARCZ
1839  || psShape->nSHPType == SHPT_MULTIPATCH )
1840  {
1841  memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
1842  memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
1843 
1844  if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
1845  if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
1846 
1847  for( i = 0; i < nPoints; i++ )
1848  {
1849  memcpy( psShape->padfZ + i,
1850  psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1851  if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
1852  }
1853 
1854  nOffset += 16 + 8*nPoints;
1855  }
1856 
1857 /* -------------------------------------------------------------------- */
1858 /* If we have a M measure value, then read it now. We assume */
1859 /* that the measure can be present for any shape if the size is */
1860 /* big enough, but really it will only occur for the Z shapes */
1861 /* (options), and the M shapes. */
1862 /* -------------------------------------------------------------------- */
1863  if( nEntitySize >= nOffset + 16 + 8*nPoints )
1864  {
1865  memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
1866  memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
1867 
1868  if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
1869  if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
1870 
1871  for( i = 0; i < nPoints; i++ )
1872  {
1873  memcpy( psShape->padfM + i,
1874  psSHP->pabyRec + nOffset + 16 + i*8, 8 );
1875  if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
1876  }
1877  psShape->bMeasureIsUsed = TRUE;
1878  }
1879  }
#define SHPT_MULTIPATCH
Definition: shapefil.h:320
void SHPAPI_CALL SHPDestroyObject(SHPObject *psShape)
Definition: shpopen.c:2183
#define SHPP_RING
Definition: shapefil.h:333
psShape
Definition: shpopen.c:1644
#define SHPT_ARCZ
Definition: shapefil.h:313
static int bBigEndian
Definition: shpopen.c:294
unsigned int uint32
Definition: shpopen.c:274
nEntitySize
Definition: shpopen.c:1580
#define SHPT_POLYGONZ
Definition: shapefil.h:314
#define TRUE
Definition: shpopen.c:279
static void SwapWord(int length, void *wordP)
Definition: shpopen.c:303