From 6d3fc843f86b059d5b9259b4797c4526646fc80f Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Sun, 26 Jun 2022 11:41:20 -0300 Subject: [PATCH 001/170] bump default MapServer version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32c8a2692b..10716c3cf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,8 @@ include(CheckFunctionExists) include(CheckIncludeFile) include(CheckCSourceCompiles) -set (MapServer_VERSION_MAJOR 7) -set (MapServer_VERSION_MINOR 7) +set (MapServer_VERSION_MAJOR 8) +set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) set (MapServer_VERSION_SUFFIX "") From b95c61ca465e14a31f17bd8f41fe5342c3727cf8 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Sun, 26 Jun 2022 11:45:43 -0300 Subject: [PATCH 002/170] update for 8.0.0-beta1 release --- CMakeLists.txt | 2 +- HISTORY.TXT | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10716c3cf5..f50c2b75c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) -set (MapServer_VERSION_SUFFIX "") +set (MapServer_VERSION_SUFFIX "-beta1") # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user diff --git a/HISTORY.TXT b/HISTORY.TXT index 8e37bdfb32..1ce814084e 100644 --- a/HISTORY.TXT +++ b/HISTORY.TXT @@ -12,6 +12,31 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +8.0.0-beta1 release (2022-06-27) +-------------------------------- + +- add new MapServer config file requirement (RFC 135) + +- initial OGC API support (RFC 134) + +- rename shp2img utility to map2img (RFC 136) + +- make STYLES parameter mandatory for WMS GetMap requests (#6012) + +- improve SLD label conformance (#6017) + +- enable PHP 8 MapScript support, through SWIG, re-enable unit tests, and remove old native PHP MapScript (#6430) + +- remove deprecated mapfile parameters (RFC 133) + +- improve numerical validation of mapfile parameter values (#6458) + +- fix various security vulnerabilities found by libFuzzer (#6419) + +- add new GEOMTRANSFORM 'centerline' labeling method for polygons (#6417) + +- upgrade Travis and GitHub CI to run on Ubuntu Focal (#6430) + 7.6.4 release (2021-07-12) -------------------------- From cce7c950a1deaf895f7a3b7d28795d47c1a54e4a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Jun 2022 16:39:21 -0300 Subject: [PATCH 003/170] Also install coshp utility. (#6541) Co-authored-by: Bas Couwenberg --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f50c2b75c4..d857594fcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1005,7 +1005,7 @@ if(USE_MSSQL2008) endif(USE_MSSQL2008) -INSTALL(TARGETS sortshp shptree shptreevis msencrypt legend scalebar tile4ms shptreetst map2img mapserv +INSTALL(TARGETS coshp sortshp shptree shptreevis msencrypt legend scalebar tile4ms shptreetst map2img mapserv RUNTIME DESTINATION ${INSTALL_BIN_DIR} COMPONENT bin ) From 47f7c2a10e2473692dffd03eb1c205b2916a357e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 10:13:37 -0300 Subject: [PATCH 004/170] =?UTF-8?q?Improve=20error=20message=20in=20case?= =?UTF-8?q?=20of=20getcwd()=20failure=20(fixes=C2=A0#6543)=20(#6546)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Even Rouault --- mapfile.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/mapfile.c b/mapfile.c index 9e94ab761b..827d050b5d 100755 --- a/mapfile.c +++ b/mapfile.c @@ -6121,6 +6121,29 @@ static int loadMapInternal(mapObj *map) } /* next token */ } +static bool msGetCWD(char* szBuffer, size_t nBufferSize, const char* pszFunctionName) +{ + if(NULL == getcwd(szBuffer, nBufferSize)) { +#ifndef _WIN32 + if( errno == EACCES ) + msSetError(MS_MISCERR, + "getcwd() failed with EACCES: you may need to force the " + "current directory in the mapserver launcher " + "(e.g -d option of spawn-fcgi)", pszFunctionName); + else if( errno == ENAMETOOLONG ) + msSetError(MS_MISCERR, "getcwd() returned a too long path", + pszFunctionName); + else + msSetError(MS_MISCERR, "getcwd() failed with errno code %d", + pszFunctionName, errno); +#else + msSetError(MS_MISCERR, "getcwd() returned a too long path", pszFunctionName); +#endif + return FALSE; + } + return TRUE; +} + /* ** Sets up string-based mapfile loading and calls loadMapInternal to do the work. */ @@ -6164,8 +6187,7 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath) msyylineno = 1; /* start at line 1 (do lines mean anything here?) */ /* If new_mappath is provided then use it, otherwise use the CWD */ - if(NULL == getcwd(szCWDPath, MS_MAXPATHLEN)) { - msSetError(MS_MISCERR, "getcwd() returned a too long path", "msLoadMapFromString()"); + if(!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMapFromString()")) { msFreeMap(map); msReleaseLock( TLOCK_PARSER ); } @@ -6285,8 +6307,7 @@ mapObj *msLoadMap(const char *filename, const char *new_mappath, const configObj /* If new_mappath is provided then use it, otherwise use the location */ /* of the mapfile as the default path */ - if(NULL == getcwd(szCWDPath, MS_MAXPATHLEN)) { - msSetError(MS_MISCERR, "getcwd() returned a too long path", "msLoadMap()"); + if(!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMap()")) { msReleaseLock( TLOCK_PARSER ); msFreeMap(map); return NULL; From 3e22f74a5640d9f904460968b056c1bf4fc42809 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 10:31:11 -0300 Subject: [PATCH 005/170] Improve error messages about missing mandatory metadata (fixes #6542) (#6547) Co-authored-by: Even Rouault --- mapows.c | 143 +++++++++++------- .../misc/expected/runtime_sub_test_caps.xml | 20 +-- .../wxs/expected/ows_all_wms_capabilities.xml | 6 +- .../ows_all_wms_capabilities_post.xml | 6 +- .../wxs/expected/ows_wms_capabilities.xml | 4 +- .../ows_wms_rootlayer_name_capabilities.xml | 4 +- ..._wms_rootlayer_name_empty_capabilities.xml | 4 +- msautotest/wxs/expected/wcs_get_caps.xml | 2 +- .../wfs_200_insipire_missing_md_caps.xml | 14 +- msautotest/wxs/expected/wms_dimension_cap.xml | 4 +- .../wxs/expected/wms_dimension_cap130.xml | 4 +- .../wxs/expected/wms_layer_groups_caps111.xml | 14 +- msautotest/wxs/expected/wms_rast_cap.xml | 2 +- 13 files changed, 131 insertions(+), 96 deletions(-) diff --git a/mapows.c b/mapows.c index 4e72264ec0..f141a7b64c 100644 --- a/mapows.c +++ b/mapows.c @@ -816,6 +816,37 @@ int msOWSParseRequestMetadata(const char *metadata, const char *request, int *di return allFlag; } +/* +** msOWSGetPrefixFromNamespace() +** +** Return the metadata name prefix from a character identifying the OWS +** namespace. +*/ +static +const char* msOWSGetPrefixFromNamespace(char chNamespace) +{ + // Return should be a 3 character string, otherwise breaks assumption + // in msOWSLookupMetadata() + switch( chNamespace ) + { + case 'O': return "ows"; + case 'A': return "oga"; /* oga_... (OGC Geospatial API) */ + case 'M': return "wms"; + case 'F': return "wfs"; + case 'C': return "wcs"; + case 'G': return "gml"; + case 'S': return "sos"; + default: + /* We should never get here unless an invalid code (typo) is */ + /* present in the code, but since this happened before... */ + msSetError(MS_WMSERR, + "Unsupported metadata namespace code (%c).", + "msOWSGetPrefixFromNamespace()", chNamespace ); + assert(MS_FALSE); + return NULL; + } +} + /* ** msOWSLookupMetadata() ** @@ -839,52 +870,11 @@ const char *msOWSLookupMetadata(hashTableObj *metadata, strlcpy(buf+4, name, 96); while (value == NULL && *namespaces != '\0') { - switch (*namespaces) { - case 'O': /* ows_... */ - buf[0] = 'o'; - buf[1] = 'w'; - buf[2] = 's'; - break; - case 'A': /* oga_... (OGC Geospatial API) */ - buf[0] = 'o'; - buf[1] = 'g'; - buf[2] = 'a'; - break; - case 'M': /* wms_... */ - buf[0] = 'w'; - buf[1] = 'm'; - buf[2] = 's'; - break; - case 'F': /* wfs_... */ - buf[0] = 'w'; - buf[1] = 'f'; - buf[2] = 's'; - break; - case 'C': /* wcs_... */ - buf[0] = 'w'; - buf[1] = 'c'; - buf[2] = 's'; - break; - case 'G': /* gml_... */ - buf[0] = 'g'; - buf[1] = 'm'; - buf[2] = 'l'; - break; - case 'S': /* sos_... */ - buf[0] = 's'; - buf[1] = 'o'; - buf[2] = 's'; - break; - default: - /* We should never get here unless an invalid code (typo) is */ - /* present in the code, but since this happened before... */ - msSetError(MS_WMSERR, - "Unsupported metadata namespace code (%c).", - "msOWSLookupMetadata()", *namespaces ); - assert(MS_FALSE); + const char* prefix = msOWSGetPrefixFromNamespace(*namespaces); + if( prefix == NULL ) return NULL; - } - + assert(strlen(prefix) == 3); + memcpy(buf, prefix, 3); value = msLookupHashTable(metadata, buf); namespaces++; } @@ -1120,6 +1110,26 @@ const char *msOWSGetSchemasLocation(mapObj *map) return schemas_location; } +/* +** msOWSGetExpandedMetadataKey() +*/ +static +char* msOWSGetExpandedMetadataKey(const char *namespaces, const char *metadata_name) +{ + char* pszRet = msStringConcatenate(NULL, ""); + for( int i = 0; namespaces[i] != '\0'; ++i ) + { + if( i > 0 ) + pszRet = msStringConcatenate(pszRet, " or "); + pszRet = msStringConcatenate(pszRet, "\""); + pszRet = msStringConcatenate(pszRet, msOWSGetPrefixFromNamespace(namespaces[i])); + pszRet = msStringConcatenate(pszRet, "_"); + pszRet = msStringConcatenate(pszRet, metadata_name); + pszRet = msStringConcatenate(pszRet, "\""); + } + return pszRet; +} + /* ** msOWSGetOnlineResource() ** @@ -1144,7 +1154,9 @@ char * msOWSGetOnlineResource(mapObj *map, const char *namespaces, const char *m online_resource = msOWSTerminateOnlineResource(value); } else { if ((online_resource = msBuildOnlineResource(map, req)) == NULL) { - msSetError(MS_CGIERR, "Impossible to establish server URL. Please set \"%s\" metadata.", "msOWSGetOnlineResource()", metadata_name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, metadata_name); + msSetError(MS_CGIERR, "Please set %s metadata.", "msOWSGetOnlineResource()", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); return NULL; } } @@ -1511,7 +1523,9 @@ int msOWSPrintInspireCommonMetadata(FILE *stream, mapObj *map, const char *names } else { status = action_if_not_found; if (OWS_WARN == action_if_not_found) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), "inspire_metadataurl_href"); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, "inspire_metadataurl_href"); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); } } } else if (strcasecmp("embed",inspire_capabilities) == 0) { @@ -1579,7 +1593,9 @@ int msOWSPrintInspireCommonLanguages(FILE *stream, mapObj *map, const char *name } else { status = action_if_not_found; if (OWS_WARN == action_if_not_found) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), "languages"); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, "languages"); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); } } @@ -1609,7 +1625,9 @@ int msOWSPrintMetadata(FILE *stream, hashTableObj *metadata, msIO_fprintf(stream, format, value); } else { if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, name); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } @@ -1662,7 +1680,16 @@ int msOWSPrintEncodeMetadata2(FILE *stream, hashTableObj *metadata, free(pszEncodedValue); } else { if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name, (validated_language && validated_language[0]?".":""), (validated_language && validated_language[0]?validated_language:"")); + char* pszExpandedName = msStringConcatenate(NULL, name); + if( validated_language && validated_language[0] ) + { + pszExpandedName = msStringConcatenate(pszExpandedName, "."); + pszExpandedName = msStringConcatenate(pszExpandedName, validated_language); + } + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, pszExpandedName); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedName); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } @@ -1724,7 +1751,9 @@ int msOWSPrintValidateMetadata(FILE *stream, hashTableObj *metadata, msIO_fprintf(stream, format, value); } else { if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, name); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } @@ -1784,7 +1813,9 @@ int msOWSPrintGroupMetadata2(FILE *stream, mapObj *map, char* pszGroupName, } if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, name); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } @@ -1927,7 +1958,9 @@ int msOWSPrintURLType(FILE *stream, hashTableObj *metadata, (!urlfrmt && format_is_mandatory) || (!href && href_is_mandatory)) { msIO_fprintf(stream, "\n", tag_name); if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, name); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } } else { @@ -1978,7 +2011,9 @@ int msOWSPrintURLType(FILE *stream, hashTableObj *metadata, msFree(href); } else { if (action_if_not_found == OWS_WARN) { - msIO_fprintf(stream, "\n", (namespaces?"..._":""), name); + char* pszExpandedMetadataKey = msOWSGetExpandedMetadataKey(namespaces, name); + msIO_fprintf(stream, "\n", pszExpandedMetadataKey); + msFree(pszExpandedMetadataKey); status = action_if_not_found; } } diff --git a/msautotest/misc/expected/runtime_sub_test_caps.xml b/msautotest/misc/expected/runtime_sub_test_caps.xml index 8c4cc4706d..f5fd47e50d 100644 --- a/msautotest/misc/expected/runtime_sub_test_caps.xml +++ b/msautotest/misc/expected/runtime_sub_test_caps.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + runtime_sub @@ -34,7 +34,7 @@ Content-Type: text/xml; charset=UTF-8 runtime_sub - + runtime_sub runtime_sub EPSG:3857 @@ -48,7 +48,7 @@ Content-Type: text/xml; charset=UTF-8 minx="125000" miny="4.785e+06" maxx="789000" maxy="5.489e+06" /> layer1 - + layer1 @@ -58,7 +58,7 @@ Content-Type: text/xml; charset=UTF-8 layer2 - + layer2 @@ -68,7 +68,7 @@ Content-Type: text/xml; charset=UTF-8 layer3 - + layer3 @@ -78,7 +78,7 @@ Content-Type: text/xml; charset=UTF-8 layer5 - + layer5 1.108938 @@ -95,7 +95,7 @@ Content-Type: text/xml; charset=UTF-8 layer5b - + layer5b 1.108938 @@ -112,7 +112,7 @@ Content-Type: text/xml; charset=UTF-8 layer6 - + layer6 1.108938 @@ -129,7 +129,7 @@ Content-Type: text/xml; charset=UTF-8 layer7 - + layer7 1.108938 @@ -146,7 +146,7 @@ Content-Type: text/xml; charset=UTF-8 layer8 - + layer8 1.108938 diff --git a/msautotest/wxs/expected/ows_all_wms_capabilities.xml b/msautotest/wxs/expected/ows_all_wms_capabilities.xml index 0444bc0aff..39361b3baa 100644 --- a/msautotest/wxs/expected/ows_all_wms_capabilities.xml +++ b/msautotest/wxs/expected/ows_all_wms_capabilities.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + WMS_WFS_TEST Test WFS Abstract @@ -121,7 +121,7 @@ Content-Type: text/xml; charset=UTF-8 WMS_WFS_TEST - + WMS_WFS_TEST Test WFS Abstract @@ -166,7 +166,7 @@ Content-Type: text/xml; charset=UTF-8 province - + province -66.724329 diff --git a/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml b/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml index 0444bc0aff..39361b3baa 100644 --- a/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml +++ b/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + WMS_WFS_TEST Test WFS Abstract @@ -121,7 +121,7 @@ Content-Type: text/xml; charset=UTF-8 WMS_WFS_TEST - + WMS_WFS_TEST Test WFS Abstract @@ -166,7 +166,7 @@ Content-Type: text/xml; charset=UTF-8 province - + province -66.724329 diff --git a/msautotest/wxs/expected/ows_wms_capabilities.xml b/msautotest/wxs/expected/ows_wms_capabilities.xml index a929aa6c59..c8391db66c 100644 --- a/msautotest/wxs/expected/ows_wms_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_capabilities.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + WMS_TEST @@ -64,7 +64,7 @@ Content-Type: text/xml; charset=UTF-8 WMS_TEST - + WMS_TEST WMS_TEST EPSG:4326 diff --git a/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml b/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml index 281c46b115..a4f90b9529 100644 --- a/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + WMS_TEST @@ -64,7 +64,7 @@ Content-Type: text/xml; charset=UTF-8 foo - + WMS_TEST WMS_TEST EPSG:4326 diff --git a/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml b/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml index a8c451885c..2fc51170a9 100644 --- a/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + WMS_TEST @@ -63,7 +63,7 @@ Content-Type: text/xml; charset=UTF-8 - + WMS_TEST WMS_TEST EPSG:4326 diff --git a/msautotest/wxs/expected/wcs_get_caps.xml b/msautotest/wxs/expected/wcs_get_caps.xml index 1f4a99a134..148f0da69a 100644 --- a/msautotest/wxs/expected/wcs_get_caps.xml +++ b/msautotest/wxs/expected/wcs_get_caps.xml @@ -87,7 +87,7 @@ land_shallow_topo_2048 - + -180.3515625 -89.6484375 179.6484375 90.3515625 diff --git a/msautotest/wxs/expected/wfs_200_insipire_missing_md_caps.xml b/msautotest/wxs/expected/wfs_200_insipire_missing_md_caps.xml index 1b45750752..264130e79d 100644 --- a/msautotest/wxs/expected/wfs_200_insipire_missing_md_caps.xml +++ b/msautotest/wxs/expected/wfs_200_insipire_missing_md_caps.xml @@ -228,9 +228,9 @@ - + service - + @@ -242,19 +242,19 @@ notEvaluated - + - + - + download - + - + diff --git a/msautotest/wxs/expected/wms_dimension_cap.xml b/msautotest/wxs/expected/wms_dimension_cap.xml index f944fda85b..d43a7f9129 100644 --- a/msautotest/wxs/expected/wms_dimension_cap.xml +++ b/msautotest/wxs/expected/wms_dimension_cap.xml @@ -10,7 +10,7 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 OGC:WMS - + wms_dimesion @@ -78,7 +78,7 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 wms_dimesion - + wms_dimesion wms_dimesion EPSG:4326 diff --git a/msautotest/wxs/expected/wms_dimension_cap130.xml b/msautotest/wxs/expected/wms_dimension_cap130.xml index 2a01853de7..51848fecb9 100644 --- a/msautotest/wxs/expected/wms_dimension_cap130.xml +++ b/msautotest/wxs/expected/wms_dimension_cap130.xml @@ -5,7 +5,7 @@ Content-Type: text/xml; charset=UTF-8 WMS - + wms_dimesion @@ -96,7 +96,7 @@ Content-Type: text/xml; charset=UTF-8 wms_dimesion - + wms_dimesion wms_dimesion EPSG:4326 diff --git a/msautotest/wxs/expected/wms_layer_groups_caps111.xml b/msautotest/wxs/expected/wms_layer_groups_caps111.xml index e9746294b7..4d77273453 100644 --- a/msautotest/wxs/expected/wms_layer_groups_caps111.xml +++ b/msautotest/wxs/expected/wms_layer_groups_caps111.xml @@ -8,7 +8,7 @@ OGC:WMS - + TESTGROUP @@ -98,7 +98,7 @@ TESTGROUP - + TESTGROUP TESTGROUP EPSG:4326 @@ -113,7 +113,7 @@ sg1 g1sg1l1 - + g1sg1l1 @@ -123,7 +123,7 @@ g1sg1l2 - + g1sg1l2 @@ -137,7 +137,7 @@ sg2 g1sg2l1 - + g1sg2l1 @@ -155,7 +155,7 @@ sg3 g2sg3l1 - + g2sg3l1 @@ -178,7 +178,7 @@ sg4 g3sg4l1 - + g3sg4l1 diff --git a/msautotest/wxs/expected/wms_rast_cap.xml b/msautotest/wxs/expected/wms_rast_cap.xml index 0df07b424e..803d4370d2 100644 --- a/msautotest/wxs/expected/wms_rast_cap.xml +++ b/msautotest/wxs/expected/wms_rast_cap.xml @@ -141,7 +141,7 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 grey - + grey EPSG:32611 EPSG:4326 From cb3c58053583f51f41198bd24fff339026fb55d1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 11:49:01 -0300 Subject: [PATCH 006/170] [Backport branch-8-0] Coverity Scan fixes (#6556) * mapwcs: fix false positive Coverity warnings about memory leaks (CID 1518800) * mapmetadata: fix false positive Coverity warning about memory leaks (CID 1518799) * mapogcsos: fix memory leak in error code path (CID 1518798) * mapwcs20: fix false positive Coverity warning about memory leaks (CID 1518797) * mapwms: fix memory leak (CID 1518794) * mapwcs11: fix false positive Coverity warning about memory leaks (CID 1518791) * mapwcs: fix memory leak (CID 1518789) * mapcontext: fix memory leak (CID 1518788) * mapmetadata: fix false positive Covery warning about memory leak (CID 1518787) * mapogcsos: fix memory leaks in error code path (CID 1518785, 1518784) * maputil: fix false positive Coverity warning about nullptr deref (CID 1503569) * mapsos: avoid Coverity warning about nullptr deref (CID 1518790, 1518796) * mappostgis: fix memory leak (CID 1503579) * mapgdal: fix memory leaks in error code paths (CID 1503576) * mapogcfilter: fix false positive Coverity warning about memory leaks (CID 1503572) * mapwfs11: fix false positive Coverity warning about memory leaks (CID 1503571) * maptree: fix memory leaks in error code paths (CID 1503570) * mapogcsld: fix false positive Coverity warning about memory leaks (CID 1503568) * maplabel: fix memory leaks (CID 1194599) * maptemplate: fix memory leaks (CID 1175194) Co-authored-by: Even Rouault --- mapcontext.c | 11 +++++++---- mapgdal.cpp | 15 ++++++++++++++- maplabel.c | 17 ++++++++++++++--- mapmetadata.c | 10 ++++------ mapogcfilter.cpp | 3 +-- mapogcsld.c | 3 ++- mapogcsos.c | 14 +++++++++++--- mappostgis.cpp | 4 ++-- maptemplate.c | 9 --------- maptree.c | 2 ++ maputil.c | 7 +++---- mapwcs.cpp | 24 ++++++++++++------------ mapwcs11.cpp | 7 +++---- mapwcs20.cpp | 3 +-- mapwfs11.cpp | 19 ++++++++----------- mapwms.cpp | 5 ++--- 16 files changed, 86 insertions(+), 67 deletions(-) diff --git a/mapcontext.c b/mapcontext.c index e22d941f5c..1562eeb5f9 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -1311,7 +1311,7 @@ int msWriteMapContext(mapObj *map, FILE *stream) const char * version; char *pszEPSG; char * tabspace=NULL, *pszChar,*pszSLD=NULL,*pszSLD2=NULL; - char *pszStyle, *pszStyleItem, *pszSLDBody; + char *pszStyleItem, *pszSLDBody; char *pszEncodedVal; int i, nValue, nVersion=OWS_VERSION_NOTSET; /* Dimension element */ @@ -1799,12 +1799,15 @@ int msWriteMapContext(mapObj *map, FILE *stream) msIO_fprintf( stream, " \n"); /* Loop in each style in the style list */ while(pszValue != NULL) { - pszStyle = msStrdup(pszValue); + char* pszStyle = msStrdup(pszValue); pszChar = strchr(pszStyle, ','); if(pszChar != NULL) pszStyle[pszChar - pszStyle] = '\0'; - if(strcasecmp(pszStyle, "") == 0) + if(pszStyle[0] == '\0') + { + msFree(pszStyle); continue; + } if(pszCurrent && (strcasecmp(pszStyle, pszCurrent) == 0)) msIO_fprintf( stream," \n" ); - free(pszStyle); + msFree(pszStyle); pszValue = strchr(pszValue, ','); if(pszValue) pszValue++; diff --git a/mapgdal.cpp b/mapgdal.cpp index b61fb7b7fc..7ca5c94c65 100644 --- a/mapgdal.cpp +++ b/mapgdal.cpp @@ -211,6 +211,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); if(MS_UNLIKELY(MS_FAILURE == format->vtable->getRasterBufferHandle(image,&rb))) { msReleaseLock( TLOCK_GDAL ); + msFree( filenameToFree ); return MS_FAILURE; } } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { @@ -218,6 +219,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); if(MS_UNLIKELY(MS_FAILURE == format->vtable->getRasterBufferHandle(image,&rb))) { msReleaseLock( TLOCK_GDAL ); + msFree( filenameToFree ); return MS_FAILURE; } } else if( format->imagemode == MS_IMAGEMODE_INT16 ) { @@ -232,6 +234,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) } else { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Unknown format. This is a bug.", "msSaveImageGDAL()"); + msFree( filenameToFree ); return MS_FAILURE; } @@ -244,6 +247,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find MEM driver.", "msSaveImageGDAL()" ); + msFree( filenameToFree ); return MS_FAILURE; } @@ -254,6 +258,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create MEM dataset.", "msSaveImageGDAL()" ); + msFree( filenameToFree ); return MS_FAILURE; } @@ -307,6 +312,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msSetError( MS_MISCERR, "Missing RGB or A buffer.\n", "msSaveImageGDAL()" ); GDALClose(hMemDS); + msFree( filenameToFree ); return MS_FAILURE; } @@ -346,6 +352,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msSetError( MS_MISCERR, "GDALRasterIO() failed.\n", "msSaveImageGDAL()" ); GDALClose(hMemDS); + msFree( filenameToFree ); return MS_FAILURE; } } @@ -485,6 +492,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msSetError( MS_MISCERR, "Failed to create output %s file.\n%s", "msSaveImageGDAL()", format->driver+5, CPLGetLastErrorMsg() ); + msFree( filenameToFree ); return MS_FAILURE; } @@ -505,6 +513,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* Something bad happened. */ msSetError( MS_MISCERR, "XMP write to %s failed.\n", "msSaveImageGDAL()", filename); + msFree( filenameToFree ); return MS_FAILURE; } } @@ -520,7 +529,10 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) int bytes_read; if( msIO_needBinaryStdout() == MS_FAILURE ) + { + msFree( filenameToFree ); return MS_FAILURE; + } /* We aren't sure how far back GDAL exports the VSI*L API, so we only use it if we suspect we need it. But we do need it if @@ -530,6 +542,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) msSetError( MS_MISCERR, "Failed to open %s for streaming to stdout.", "msSaveImageGDAL()", filename ); + msFree( filenameToFree ); return MS_FAILURE; } @@ -541,8 +554,8 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) VSIUnlink( filename ); msCleanVSIDir( "/vsimem/msout" ); - msFree( filenameToFree ); } + msFree( filenameToFree ); return MS_SUCCESS; } diff --git a/maplabel.c b/maplabel.c index 0e078ae0ac..418a39a589 100644 --- a/maplabel.c +++ b/maplabel.c @@ -356,7 +356,8 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in int i; labelCacheSlotObj *cacheslot; labelCacheMemberObj *cachePtr=NULL; - char *annotext = NULL; + const char *annotext = NULL; + char *annotextToFree = NULL; layerObj *layerPtr; classObj *classPtr; @@ -371,7 +372,10 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in if(ts) annotext = ts->annotext; else if(shape) - annotext = msShapeGetLabelAnnotation(layerPtr,shape,label); + { + annotextToFree = msShapeGetLabelAnnotation(layerPtr,shape,label); + annotext = annotextToFree; + } if(!annotext) { /* check if we have a labelpnt style */ @@ -405,6 +409,7 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in rasterBufferObj rb; memset(&rb, 0, sizeof (rasterBufferObj)); if(MS_UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage, &rb))) { + msFree(annotextToFree); return MS_FAILURE; } assert(rb.type == MS_BUFFER_BYTE_RGBA); @@ -420,9 +425,11 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in freeTextSymbol(ts); free(ts); } + msFree(annotextToFree); return MS_SUCCESS; } } else { + msFree(annotextToFree); return MS_SUCCESS; /* label point does not intersect image extent, we cannot know if it intersects mask, so we discard it (#5237)*/ } @@ -436,11 +443,13 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in if (!*alphapixptr) { freeTextSymbol(ts); free(ts); + msFree(annotextToFree); return MS_SUCCESS; } } else { freeTextSymbol(ts); free(ts); + msFree(annotextToFree); return MS_SUCCESS; /* label point does not intersect image extent, we cannot know if it intersects mask, so we discard it (#5237)*/ } @@ -448,6 +457,7 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in } } else { msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msAddLabel()", layerPtr->name); + msFree(annotextToFree); return (MS_FAILURE); } } @@ -455,7 +465,8 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in if(!ts) { ts = msSmallMalloc(sizeof(textSymbolObj)); initTextSymbol(ts); - msPopulateTextSymbolForLabelAndString(ts,label,annotext,layerPtr->scalefactor,image->resolutionfactor, 1); + msPopulateTextSymbolForLabelAndString(ts,label,annotextToFree,layerPtr->scalefactor,image->resolutionfactor, 1); + // annotextToFree = NULL; } if(annotext && label->autominfeaturesize && featuresize > 0) { diff --git a/mapmetadata.c b/mapmetadata.c index 179b031cb8..01956e9a02 100644 --- a/mapmetadata.c +++ b/mapmetadata.c @@ -342,10 +342,9 @@ xmlNodePtr _msMetadataGetExtent(xmlNsPtr namespace, layerObj *layer, xmlNsPtr *p psTNode2 = xmlNewChild(psTNode, namespace, BAD_CAST "EX_TemporalExtent", NULL); psENode = xmlNewChild(psTNode2, namespace, BAD_CAST "extent", NULL); xmlAddChild(psENode, _msMetadataGetGMLTimePeriod(temporal)); - - msFreeCharArray(temporal, n); } } + msFreeCharArray(temporal, n); return psNode; } @@ -479,9 +478,7 @@ xmlNodePtr _msMetadataGetContact(xmlNsPtr namespace, char *contact_element, mapO static xmlNodePtr _msMetadataGetIdentificationInfo(xmlNsPtr namespace, mapObj *map, layerObj *layer, xmlNsPtr *ppsNsGco) { - int n; char *value; - char **tokens = NULL; xmlNodePtr psNode = NULL; xmlNodePtr psDINode = NULL; xmlNodePtr psCNode = NULL; @@ -521,13 +518,14 @@ xmlNodePtr _msMetadataGetIdentificationInfo(xmlNsPtr namespace, mapObj *map, lay psKWNode = xmlNewChild(psDINode, namespace, BAD_CAST "descriptiveKeywords", NULL); psMDKNode = xmlNewChild(psKWNode, namespace, BAD_CAST "MD_Keywords", NULL); - tokens = msStringSplit(value, ',', &n); + int n = 0; + char** tokens = msStringSplit(value, ',', &n); if (tokens && n > 0) { for (int i=0; imetadata), "S", "procedure_item"); for(i=0; inumitems; i++) { if (strcasecmp(lp->items[i], pszProcedureField) == 0) { @@ -920,8 +920,9 @@ char* msSOSReturnMemberResult(layerObj *lp, int iFeatureId, char **ppszProcedure "observedproperty_id")); - if (lp == lpfirst || (lpfirst && msLayerOpen(lpfirst) == MS_SUCCESS && - msLayerGetItems(lpfirst) == MS_SUCCESS)) { + if (sShape.values && + (lp == lpfirst || (lpfirst && msLayerOpen(lpfirst) == MS_SUCCESS && + msLayerGetItems(lpfirst) == MS_SUCCESS))) { pszSep = msOWSLookupMetadata(&(lp->map->web.metadata), "S", "encoding_tokenSeparator"); for(i=0; inumitems; i++) { @@ -1269,7 +1270,11 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re /*operation metadata */ if ((script_url=msOWSGetOnlineResource(map, "SO", "onlineresource", req)) == NULL) + { + free(xsi_schemaLocation); + free(schemalocation); return msSOSException(map, "NoApplicableCode", "NoApplicableCode"); + } psMainNode = xmlAddChild(psRootNode, msOWSCommonOperationsMetadata(psNsOws)); @@ -2277,7 +2282,10 @@ this request. Check sos/ows_enable_request settings.", "msSOSGetObservation()", schemalocation = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); if ((script_url=msOWSGetOnlineResource(map, "SO", "onlineresource", req)) == NULL) + { + free(schemalocation); return msSOSException(map, "NoApplicableCode", "NoApplicableCode"); + } xsi_schemaLocation = msStrdup("http://www.opengis.net/om/1.0 "); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, schemalocation); diff --git a/mappostgis.cpp b/mappostgis.cpp index c24316103b..f198996eb4 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -3735,8 +3735,7 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, break; case MS_TOKEN_LITERAL_TIME: { - char* snippet = (char *) msSmallMalloc(512); - + char* snippet = (char *) msSmallMalloc(512); if(comparisonToken == MS_TOKEN_COMPARISON_EQ) { // TODO: support != createPostgresTimeCompareEquals(node->tokensrc, snippet, 512); } else if(comparisonToken == MS_TOKEN_COMPARISON_GT || comparisonToken == MS_TOKEN_COMPARISON_GE) { @@ -3744,6 +3743,7 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, } else if(comparisonToken == MS_TOKEN_COMPARISON_LT || comparisonToken == MS_TOKEN_COMPARISON_LE) { createPostgresTimeCompareLessThan(node->tokensrc, snippet, 512); } else { + msFree(snippet); goto cleanup; } diff --git a/maptemplate.c b/maptemplate.c index 39a6fa161e..643e5c940e 100644 --- a/maptemplate.c +++ b/maptemplate.c @@ -1804,15 +1804,6 @@ static int processShplabelTag(layerObj *layer, char **line, shapeObj *origshape) msProjectShape(&layer->projection, &projection, &tShape); } - /* find the end of the tag */ - tagEnd = findTagEnd(tagStart); - tagEnd++; - - /* build the complete tag so we can do substitution */ - tagLength = tagEnd - tagStart; - tag = (char *) msSmallMalloc(tagLength + 1); - strlcpy(tag, tagStart, tagLength+1); - /* do the replacement */ tagValue = msStrdup(format); if(precision > 0) diff --git a/maptree.c b/maptree.c index 4dd4be2001..760cecfa28 100644 --- a/maptree.c +++ b/maptree.c @@ -516,6 +516,7 @@ static void searchDiskTreeNode(SHPTreeHandle disktree, rectObj aoi, ms_bitarray msSetBit(status, ids[i], 1); } free(ids); + ids = NULL; } if( fread( &numsubnodes, 4, 1, disktree->fp ) != 1 ) @@ -531,6 +532,7 @@ static void searchDiskTreeNode(SHPTreeHandle disktree, rectObj aoi, ms_bitarray error: msSetError(MS_IOERR, NULL, "searchDiskTreeNode()"); + free(ids); return; } diff --git a/maputil.c b/maputil.c index 2567500841..0e488fe9c3 100644 --- a/maputil.c +++ b/maputil.c @@ -1707,11 +1707,10 @@ imageObj *msImageCreate(int width, int height, outputFormatObj *format, image->imageurl = msStrdup(imageurl); /* initialize to requested nullvalue if there is one */ - if( msGetOutputFormatOption(image->format,"NULLVALUE",NULL) != NULL ) { - int i = image->width * image->height * format->bands; - const char *nullvalue = msGetOutputFormatOption(image->format, + const char *nullvalue = msGetOutputFormatOption(image->format, "NULLVALUE",NULL); - + if( nullvalue != NULL ) { + int i = image->width * image->height * format->bands; if( atof(nullvalue) == 0.0 ) /* nothing to do */; else if( format->imagemode == MS_IMAGEMODE_INT16 ) { diff --git a/mapwcs.cpp b/mapwcs.cpp index af84cd3475..ac0a9ad2ce 100644 --- a/mapwcs.cpp +++ b/mapwcs.cpp @@ -1109,10 +1109,8 @@ static int msWCSDescribeCoverage_AxisDescription(layerObj *layer, char *name) /* intervals, only one per axis for now, we do not support optional type, atomic and semantic attributes */ snprintf(tag, sizeof(tag), "%s_interval", name); if((value = msOWSLookupMetadata(&(layer->metadata), "CO", tag)) != NULL) { - char **tokens; - int numtokens; - - tokens = msStringSplit(value, '/', &numtokens); + int numtokens = 0; + char** tokens = msStringSplit(value, '/', &numtokens); if(tokens && numtokens > 0) { msIO_printf(" \n"); if(numtokens >= 1) msIO_printf(" %s\n", tokens[0]); /* TODO: handle closure */ @@ -1120,6 +1118,7 @@ static int msWCSDescribeCoverage_AxisDescription(layerObj *layer, char *name) if(numtokens >= 3) msIO_printf(" %s\n", tokens[2]); msIO_printf(" \n"); } + msFreeCharArray(tokens, numtokens); } /* TODO: add default (optional) */ @@ -1138,8 +1137,6 @@ static int msWCSDescribeCoverage_AxisDescription(layerObj *layer, char *name) static int msWCSDescribeCoverage_CoverageOffering(layerObj *layer, wcsParamsObj *params, char *script_url_encoded) { - char **tokens; - int numtokens; const char *value; char *epsg_buf, *encoded_format; coverageMetadataObj cm; @@ -1256,12 +1253,13 @@ static int msWCSDescribeCoverage_CoverageOffering(layerObj *layer, wcsParamsObj /* compound range sets */ if((value = msOWSLookupMetadata(&(layer->metadata), "CO", "rangeset_axes")) != NULL) { - tokens = msStringSplit(value, ',', &numtokens); + int numtokens = 0; + char** tokens = msStringSplit(value, ',', &numtokens); if(tokens && numtokens > 0) { for(i=0; imetadata), "CO", "rangeset_nullvalue")) != NULL) { @@ -1282,12 +1280,13 @@ static int msWCSDescribeCoverage_CoverageOffering(layerObj *layer, wcsParamsObj msOWSGetEPSGProj(&(layer->map->projection), &(layer->map->web.metadata), "CO", MS_FALSE, &epsg_buf); } if(epsg_buf) { - tokens = msStringSplit(epsg_buf, ' ', &numtokens); + int numtokens = 0; + char** tokens = msStringSplit(epsg_buf, ' ', &numtokens); if(tokens && numtokens > 0) { for(i=0; i%s\n", tokens[i]); - msFreeCharArray(tokens, numtokens); } + msFreeCharArray(tokens, numtokens); msFree(epsg_buf); } else { msIO_printf(" \n"); @@ -1315,12 +1314,13 @@ static int msWCSDescribeCoverage_CoverageOffering(layerObj *layer, wcsParamsObj if( (encoded_format = msOWSGetEncodeMetadata( &(layer->metadata), "CO", "formats", "GTiff" )) != NULL ) { - tokens = msStringSplit(encoded_format, ' ', &numtokens); + int numtokens = 0; + char** tokens = msStringSplit(encoded_format, ' ', &numtokens); if(tokens && numtokens > 0) { for(i=0; i%s\n", tokens[i]); - msFreeCharArray(tokens, numtokens); } + msFreeCharArray(tokens, numtokens); msFree(encoded_format); } msIO_printf(" \n"); diff --git a/mapwcs11.cpp b/mapwcs11.cpp index e73c8dde74..f07c809b79 100644 --- a/mapwcs11.cpp +++ b/mapwcs11.cpp @@ -296,9 +296,7 @@ static int msWCSGetCapabilities11_CoverageSummary( char *format_list; xmlNodePtr psCSummary; xmlNsPtr psOwsNs = xmlSearchNs( doc, psContents, BAD_CAST "ows" ); - char **tokens = NULL; int i = 0; - int n = 0; status = msWCSGetCoverageMetadata(layer, &cm); if(status != MS_SUCCESS) return MS_FAILURE; @@ -331,13 +329,14 @@ static int msWCSGetCapabilities11_CoverageSummary( psNode = xmlNewChild(psCSummary, psOwsNs, BAD_CAST "Keywords", NULL); - tokens = msStringSplit(value, ',', &n); + int n = 0; + char** tokens = msStringSplit(value, ',', &n); if (tokens && n > 0) { for (i=0; i 0 ) - msFreeCharArray(tokensNS, ntokensNS); + msFreeCharArray(tokensNS, ntokensNS); } } diff --git a/mapwfs11.cpp b/mapwfs11.cpp index 34580f71ee..bac4e78ad9 100644 --- a/mapwfs11.cpp +++ b/mapwfs11.cpp @@ -145,8 +145,7 @@ xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, xmlNodePtr psRootNode, psNode; const char *value = NULL; char *valueToFree; - char **tokens; - int n=0,i=0; + int i=0; psRootNode = xmlNewNode(NULL, BAD_CAST "FeatureType"); @@ -159,7 +158,7 @@ xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, value = MS_DEFAULT_NAMESPACE_PREFIX; if(value) { - n = strlen(value)+strlen(lp->name)+1+1; + int n = strlen(value)+strlen(lp->name)+1+1; valueToFree = (char *) msSmallMalloc(n); snprintf(valueToFree, n, "%s:%s", value, lp->name); @@ -206,7 +205,8 @@ xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, valueToFree = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", MS_FALSE); if (valueToFree) { - tokens = msStringSplit(valueToFree, ' ', &n); + int n = 0; + char** tokens = msStringSplit(valueToFree, ' ', &n); if (tokens && n > 0) { if( nWFSVersion == OWS_1_1_0 ) IGNORE_RET_VAL(xmlNewTextChild(psRootNode, NULL, BAD_CAST "DefaultSRS", BAD_CAST tokens[0])); @@ -219,9 +219,8 @@ xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, else IGNORE_RET_VAL(xmlNewTextChild(psRootNode, NULL, BAD_CAST "OtherCRS", BAD_CAST tokens[i])); } - - msFreeCharArray(tokens, n); } + msFreeCharArray(tokens, n); } else xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Mandatory mapfile parameter: (at least one of) MAP.PROJECTION, LAYER.PROJECTION or wfs/ows_srs metadata was missing in this context.")); @@ -235,11 +234,9 @@ xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, { char *formats_list = msWFSGetOutputFormatList( map, lp, nWFSVersion ); - int iformat, n; - char **tokens; - - n = 0; - tokens = msStringSplit(formats_list, ',', &n); + int iformat; + int n = 0; + char** tokens = msStringSplit(formats_list, ',', &n); for( iformat = 0; iformat < n; iformat++ ) xmlNewTextChild(psNode, NULL, BAD_CAST "Format", diff --git a/mapwms.cpp b/mapwms.cpp index 3707ffe287..d06f0bc514 100644 --- a/mapwms.cpp +++ b/mapwms.cpp @@ -4372,9 +4372,6 @@ int msWMSDescribeLayer(mapObj *map, int nVersion, char **names, pszLayerName, pszOnlineResEncoded); msIO_printf("\n", pszLayerName); msIO_printf("\n"); - - msFree(pszOnlineResEncoded); - msFree(pszLayerName); } else { msIO_printf(" \n"); msIO_printf(" wcs\n"); @@ -4385,6 +4382,8 @@ int msWMSDescribeLayer(mapObj *map, int nVersion, char **names, msIO_printf(" \n"); msIO_printf(" \n"); } + msFree(pszOnlineResEncoded); + msFree(pszLayerName); } else { char *pszLayerName = msEncodeHTMLEntities(lp->name); From e21f44c70831b742d35959326542c4b2b284fcc7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 08:34:57 -0300 Subject: [PATCH 007/170] msProjectShapeLine(): fix reprojection of lines crossing the antimeridian when source CRS is +proj=longlat +lon_wrap=0 (#6558) Co-authored-by: Even Rouault --- mapproject.c | 94 ++++++++++++++++++++++----- mapproject.h | 14 +++- msautotest/mspython/test_bug_check.py | 52 +++++++++++++++ 3 files changed, 143 insertions(+), 17 deletions(-) diff --git a/mapproject.c b/mapproject.c index 9b35b5f45d..3faad46d4a 100644 --- a/mapproject.c +++ b/mapproject.c @@ -418,7 +418,7 @@ reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* ou reprojectionObj* obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); obj->in = in; obj->out = out; - obj->should_do_line_cutting = -1; + obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; /* -------------------------------------------------------------------- */ /* If the source and destination are simple and equal, then do */ @@ -550,7 +550,7 @@ reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* ou obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); obj->in = in; obj->out = out; - obj->should_do_line_cutting = -1; + obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; /* -------------------------------------------------------------------- */ /* If the source and destination are equal, then do nothing. */ @@ -1212,24 +1212,68 @@ static int msProjectSegment( reprojectionObj* reprojector, } /************************************************************************/ -/* msProjectShapeShouldDoLineCutting() */ +/* msProjectGetLineCuttingCase() */ /************************************************************************/ /* Detect projecting from north polar stereographic to longlat or EPSG:3857 */ +/* or from lonlat lon_wrap = 0 */ #ifdef USE_GEOS -static int msProjectShapeShouldDoLineCutting(reprojectionObj* reprojector) +static msLineCuttingCase msProjectGetLineCuttingCase(reprojectionObj* reprojector) { - if( reprojector->should_do_line_cutting >= 0) - return reprojector->should_do_line_cutting; + if( reprojector->lineCuttingCase != LINE_CUTTING_UNKNOWN) + return reprojector->lineCuttingCase; projectionObj *in = reprojector->in; projectionObj *out = reprojector->out; + const double EPS = 1e-10; + + if( !in->gt.need_geotransform && msProjIsGeographicCRS(in) ) + { + int i; + for( i = 0; i < in->numargs; i++ ) + { + if( strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0 && + atof(in->args[i] + strlen("lon_wrap=")) == 0.0 ) + { + reprojector->lineCuttingCase = LINE_CUTTING_FROM_LONGLAT_WRAP0; + + msInitShape(&(reprojector->splitShape)); + reprojector->splitShape.type = MS_SHAPE_POLYGON; + int j; + for( j = -1; j <= 1; j += 2 ) + { + const double x = j * 180; + pointObj p = {0}; // initialize + lineObj newLine = {0,NULL}; + p.x = x - EPS; + p.y = 90; + msAddPointToLine(&newLine, &p ); + p.x = x + EPS; + p.y = 90; + msAddPointToLine(&newLine, &p ); + p.x = x + EPS; + p.y = -90; + msAddPointToLine(&newLine, &p ); + p.x = x - EPS; + p.y = -90; + msAddPointToLine(&newLine, &p ); + p.x = x - EPS; + p.y = 90; + msAddPointToLine(&newLine, &p ); + msAddLineDirectly(&(reprojector->splitShape), &newLine); + } + + return reprojector->lineCuttingCase; + } + } + } + if( !(!in->gt.need_geotransform && !msProjIsGeographicCRS(in) && (msProjIsGeographicCRS(out) || (out->numargs == 1 && strcmp(out->args[0], "init=epsg:3857") == 0))) ) { - reprojector->should_do_line_cutting = MS_FALSE; - return MS_FALSE; + reprojector->lineCuttingCase = LINE_CUTTING_NONE; + return reprojector->lineCuttingCase; } int srcIsPolar; @@ -1262,8 +1306,8 @@ static int msProjectShapeShouldDoLineCutting(reprojectionObj* reprojector) } if( !srcIsPolar ) { - reprojector->should_do_line_cutting = MS_FALSE; - return MS_FALSE; + reprojector->lineCuttingCase = LINE_CUTTING_NONE; + return reprojector->lineCuttingCase; } pointObj p = {0}; // initialize @@ -1273,7 +1317,6 @@ static int msProjectShapeShouldDoLineCutting(reprojectionObj* reprojector) double invgt4 = out->gt.need_geotransform ? out->gt.invgeotransform[4] : 0.0; lineObj newLine = {0,NULL}; - const double EPS = 1e-10; p.x = invgt0 + -extremeLongEasting * (1 - EPS) * invgt1; p.y = invgt3 + -extremeLongEasting * (1 - EPS) * invgt4; @@ -1298,8 +1341,8 @@ static int msProjectShapeShouldDoLineCutting(reprojectionObj* reprojector) reprojector->splitShape.type = MS_SHAPE_POLYGON; msAddLineDirectly(&(reprojector->splitShape), &newLine); - reprojector->should_do_line_cutting = MS_TRUE; - return MS_TRUE; + reprojector->lineCuttingCase = LINE_CUTTING_FROM_POLAR; + return reprojector->lineCuttingCase; } #endif @@ -1367,8 +1410,28 @@ msProjectShapeLine(reprojectionObj* reprojector, #endif #ifdef USE_GEOS + int use_splitShape = MS_FALSE; + int use_splitShape_check_intersects = MS_FALSE; if( shape->type == MS_SHAPE_LINE && - msProjectShapeShouldDoLineCutting(reprojector) ) + msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_POLAR ) + { + use_splitShape = MS_TRUE; + use_splitShape_check_intersects = MS_TRUE; + } + else if( shape->type == MS_SHAPE_LINE && + msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_LONGLAT_WRAP0 ) + { + for( i=0; i < numpoints_in; i++ ) + { + if( fabs(line->point[i].x) > 180 ) + { + use_splitShape = MS_TRUE; + break; + } + } + } + + if( use_splitShape ) { shapeObj tmpShapeInputLine; msInitShape(&tmpShapeInputLine); @@ -1377,7 +1440,8 @@ msProjectShapeLine(reprojectionObj* reprojector, tmpShapeInputLine.line = line; shapeObj* diff = NULL; - if( msGEOSIntersects(&tmpShapeInputLine, &(reprojector->splitShape)) ) + if( use_splitShape_check_intersects == MS_FALSE || + msGEOSIntersects(&tmpShapeInputLine, &(reprojector->splitShape)) ) { diff = msGEOSDifference(&tmpShapeInputLine, &(reprojector->splitShape)); } diff --git a/mapproject.h b/mapproject.h index c9e854801b..e229524979 100644 --- a/mapproject.h +++ b/mapproject.h @@ -55,6 +55,16 @@ extern "C" { typedef struct projectionContext projectionContext; +#ifndef SWIG +typedef enum +{ + LINE_CUTTING_UNKNOWN = -1, + LINE_CUTTING_NONE = 0, + LINE_CUTTING_FROM_POLAR = 1, + LINE_CUTTING_FROM_LONGLAT_WRAP0 = 2 +} msLineCuttingCase; +#endif + /** The :ref:`PROJECTION ` object MapServer's Maps and Layers have Projection attributes, and these are C projectionObj structures, @@ -93,7 +103,7 @@ but are not directly exposed by the mapscript module projectionObj* in; projectionObj* out; PJ* pj; - int should_do_line_cutting; + msLineCuttingCase lineCuttingCase; shapeObj splitShape; int bFreePJ; #endif @@ -101,7 +111,7 @@ but are not directly exposed by the mapscript module #ifndef SWIG projectionObj* in; projectionObj* out; - int should_do_line_cutting; + msLineCuttingCase lineCuttingCase; shapeObj splitShape; int no_op; #endif diff --git a/msautotest/mspython/test_bug_check.py b/msautotest/mspython/test_bug_check.py index 3a88fe43be..168820425d 100755 --- a/msautotest/mspython/test_bug_check.py +++ b/msautotest/mspython/test_bug_check.py @@ -180,3 +180,55 @@ def test_reprojection_rect_and_datum_shift(): rect = mapscript.rectObj(545287, 6867556, 545689, 6868025) assert rect.project(webmercator, epsg_28992) == 0 assert rect.minx == pytest.approx(121711, abs=2) + +############################################################################### +# Test reprojection of line crossing the antimeridian from a projection +# with +proj=longlat +lon_wrap=0 + +def test_reprojection_from_lonlat_wrap_0(): + + src = mapscript.projectionObj("+proj=longlat +lon_wrap=0 +datum=WGS84") + dst = mapscript.projectionObj("+proj=longlat +datum=WGS84") + + shape = mapscript.shapeObj( mapscript.MS_SHAPE_LINE ) + line = mapscript.lineObj() + line.add( mapscript.pointObj( 179, 45 ) ) + line.add( mapscript.pointObj( 182, 45 ) ) + shape.add( line ) + + assert shape.project(src, dst) == 0 + + part1 = shape.get(0) + assert part1 + part2 = shape.get(1) + assert part2 + + point11 = part1.get(0) + point12 = part1.get(1) + point21 = part2.get(0) + point22 = part2.get(1) + set_x = [point11.x, point12.x, point21.x, point22.x] + set_x.sort() + assert set_x == pytest.approx([-180, -178, 179, 180], abs=1e-2) + + + shape = mapscript.shapeObj( mapscript.MS_SHAPE_LINE ) + line = mapscript.lineObj() + line.add( mapscript.pointObj( -179, 45 ) ) + line.add( mapscript.pointObj( -182, 45 ) ) + shape.add( line ) + + assert shape.project(src, dst) == 0 + + part1 = shape.get(0) + assert part1 + part2 = shape.get(1) + assert part2 + + point11 = part1.get(0) + point12 = part1.get(1) + point21 = part2.get(0) + point22 = part2.get(1) + set_x = [point11.x, point12.x, point21.x, point22.x] + set_x.sort() + assert set_x == pytest.approx([-180, -179, 178, 180], abs=1e-2) From 27c5bae41985b08a4f655af4a19cbcd0a15b2a36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Jul 2022 17:13:48 -0300 Subject: [PATCH 008/170] =?UTF-8?q?[Backport=20branch-8-0]=20SLD:=20unset?= =?UTF-8?q?=20layer=20classgroup=20=E2=80=A6=20(#6560)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SLD: unset layer classgroup unless SLD content has a named class in UserStyle.IsDefault, in which case we use that named class (soften changes d89ac1fadbd34bed5e991c834c601d3e9026091c) * msSLDApplySLD(): fix memory leak Co-authored-by: Even Rouault --- mapogcsld.c | 17 +++---- msautotest/sld/data/grid.gif | Bin 0 -> 17589 bytes .../expected/sld_named_userstyle_raster.png | Bin 0 -> 584 bytes msautotest/sld/sld_named_userstyle.map | 5 +- msautotest/sld/sld_named_userstyle_raster.map | 48 ++++++++++++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 msautotest/sld/data/grid.gif create mode 100644 msautotest/sld/expected/sld_named_userstyle_raster.png create mode 100644 msautotest/sld/sld_named_userstyle_raster.map diff --git a/mapogcsld.c b/mapogcsld.c index 055bc8d82d..bbf2187a43 100644 --- a/mapogcsld.c +++ b/mapogcsld.c @@ -266,12 +266,10 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz } lp->numclasses = 0; - if( bSLDHasNamedClass ) { - if( sldLayer->classgroup ) { - /* Set the class group to the class that has UserStyle.IsDefault */ - msFree( lp->classgroup); - lp->classgroup = msStrdup(sldLayer->classgroup); - } + if( bSLDHasNamedClass && sldLayer->classgroup ) { + /* Set the class group to the class that has UserStyle.IsDefault */ + msFree( lp->classgroup); + lp->classgroup = msStrdup(sldLayer->classgroup); } else { /*unset the classgroup on the layer if it was set. This allows the layer to render @@ -292,9 +290,9 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz /*aliases may have been used as part of the sld text symbolizer for label element. Try to process it if that is the case #3114*/ - if (msLayerOpen(lp) == MS_SUCCESS && - msLayerGetItems(lp) == MS_SUCCESS) { - if (lp->class[iClass]->text.string) { + if (msLayerOpen(lp) == MS_SUCCESS) { + if (msLayerGetItems(lp) == MS_SUCCESS && + lp->class[iClass]->text.string) { int z; for(z=0; znumitems; z++) { const char* pszFullName; @@ -315,6 +313,7 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz msFree(pszTmp1); } } + msLayerClose(lp); } iClass++; diff --git a/msautotest/sld/data/grid.gif b/msautotest/sld/data/grid.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e9eac784e6c726db750039a47138d037c2b2359 GIT binary patch literal 17589 zcmd^HZ%h+s7{4Cpb~rb#kU&@#dM%BA5*4sp#Hg%Lr;w0E!oJMJi8@&(ALdLp|M8(X zCN(Z=X^6^#*~}6X&E{e@T()W!hYo~>4~q+I6YX?rVkXOIlr%=)-Cgf`@7sH5&=&38 z@rl5j>-)Rk^FDum&+~Ro-RjC^8v~YwmQG6iY2tY#{n%rSg`#q(h2meu|5G&T@fUS> zulYH4cLv-Ay~5&%L$z#D(z}^N0K2I575#v&VnDDAZD0X=_~c;YeUx)vA|KDcb7>tgbtGK z9dy~G!O6xszD|Desa$qOk-|WcHaHm+DGXHP9}o0}A^md-BZYzD{Oiwp9|bA476Xd$ zpVj9S+r8{KGILB(BBjk1k2F(AVW1-aGaqGO-}_{d!axQ7pFot!2Ba`hbSm_inM3w+ z3L}Mqs^?!SX@v?%nv@uJG@3k3IoOYH)Mh@y1f*XV*F=1 z!Oz?8KR$FP@5`R={y6aMl{5Fhu}1%MxT09E>88hdgRO4RmAz zy>R-Ly3vH<+tCIF(TSKq8AI_B*91smpfdkS6_9x}K$(BjYJepFSYd$G1z=n-NSl=8 z-^fT|Ef1+PZf0wJOB%4uzqT-V%y_D|a2n_TaWV(JA(aeW0~CqVoKHoo&yGeDasK5B z$V|zg#J{X4r8!Eb%Qh*&KU@JBAsOsA-+$@Gy^e<0*WJ1B=6hEjjQC!oQ|4km>?Mx4xy8 zs?0wu{206SEh$_m-RmzpPm##;pME@rqfGV&8JT~%^=ZCjkmUc#B!ix7n{RKw-#35W z*Y~b{we;VIE$3U$41`x;_qV|7w#lQ5@yW%BwfMbU*pH=Y3GIr<#)&CZwquUD5eMd>p$}s5Z}rmOeca)e2pGyT=k52n#*K*}KF4tZ+ZM6t+9S&x2sk^O|bYBj@VQ<#z+3rP>V0dreKjI(+w0@zBWl*CypLti6>=PJJxyIKa zzi6#vD*NxKEvIr^1x%3jvDKWFv#+h9XTK!=#{bUqJToY~o{)3-H2o>9=V|4Od&mUOpnQXtm@!Y3JwDHz~n1huPDjX_k&U zuTl{&&r)82Ix83CX{v_a(s%BNb)oRwAk{?AO>B6ddMh2X3jFQH4*z)hVfo;$fz}=} eNtx;vzUS|FdUMMjeV?575jss^MVYsNTK+%fB?6uR literal 0 HcmV?d00001 diff --git a/msautotest/sld/expected/sld_named_userstyle_raster.png b/msautotest/sld/expected/sld_named_userstyle_raster.png new file mode 100644 index 0000000000000000000000000000000000000000..e977386b4b113a938ff4ed2d453c2c07777875e5 GIT binary patch literal 584 zcmeAS@N?(olHy`uVBq!ia0vp^CxAGGg9%9bJb4krz`(@s>EaktG3V{1jl9f?0tY0f z{S7~{+)t`&`iDrjbr(eEe2kj^_3*vl|35wIk(l+$e1Fa{?WGq&#HX>$dUa@$LvU<_ zP{t~5ZzkW;M9&2)^>jE*uC}T+F59(1WmM7N3WEH)oAWBynSbO`@AjD!*;+b%va8y; rHHUVcKB**}9+r6bY0AV-<9Io%OY8hYZ&@Y+QwW2ntDnm{r-UW|b*$^- literal 0 HcmV?d00001 diff --git a/msautotest/sld/sld_named_userstyle.map b/msautotest/sld/sld_named_userstyle.map index 5b0a95181d..e6d533ca1c 100644 --- a/msautotest/sld/sld_named_userstyle.map +++ b/msautotest/sld/sld_named_userstyle.map @@ -10,7 +10,10 @@ # Selection of class with IsDefault set on the 'green' UserStyle # RUN_PARMS: sld_named_userstyle_3.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3&REQUEST=GetMap&CRS=EPSG:4326&BBOX=42,-5,52,9&FORMAT=image/png&WIDTH=200&HEIGHT=200&LAYERS=lline&SLD_BODY=llinered50.5#FF0000greentrue30.5#00FF00blue10.5#0000FF" > [RESULT_DEMIME] # - +# +# Selection of single UserStyle +# RUN_PARMS: sld_named_userstyle_3.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.3&REQUEST=GetMap&CRS=EPSG:4326&BBOX=42,-5,52,9&FORMAT=image/png&WIDTH=200&HEIGHT=200&LAYERS=lline&SLD_BODY=llinegreentrue30.5#00FF00blue10.5#0000FF" > [RESULT_DEMIME] +# MAP NAME TEST diff --git a/msautotest/sld/sld_named_userstyle_raster.map b/msautotest/sld/sld_named_userstyle_raster.map new file mode 100644 index 0000000000..8225770dbd --- /dev/null +++ b/msautotest/sld/sld_named_userstyle_raster.map @@ -0,0 +1,48 @@ +# +# REQUIRES: INPUT=GDAL OUTPUT=PNG SUPPORTS=WMS + +# RUN_PARMS: sld_named_userstyle_raster.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=grid&SRS=EPSG:4326&BBOX=-180,-90,180,90&FORMAT=image/png&WIDTH=200&HEIGHT=100&STYLES=&SLD_BODY=gridTEST1.0 " > [RESULT_DEMIME] + +MAP + +NAME TEST +SHAPEPATH ./data +SIZE 300 300 +IMAGECOLOR 100 100 100 +FONTSET "data/fonts.lst" +PROJECTION + "init=epsg:4326" +END +WEB + IMAGEPATH "/tmp/ms_tmp/" + IMAGEURL "/ms_tmp/" + METADATA + "wms_title" "Test SLD" + "wms_onlineresource" "http://localhost/path/to/wms_simple?" + "wms_srs" "EPSG:4326" + "ows_schemas_location" "http://ogc.dmsolutions.ca" + "ows_enable_request" "*" + "ows_sld_enabled" "true" + END +END + +LAYER + NAME "grid" + TYPE raster + DATA data/grid.gif + STATUS ON + PROJECTION + "init=epsg:4326" + END + EXTENT -180 -90 180 90 + CLASSGROUP "DefaultStyle" + CLASS + NAME "DefaultStyle" + EXPRESSION ([pixel] == 3) + STYLE + COLOR 255 0 0 + END + END +END + +END From b4a762f2107a2b6f30568296f389b38ec1c16337 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 22:45:28 +0200 Subject: [PATCH 009/170] FlatGeobuf: Rework null geom skip (#6563) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Björn Harrtell --- flatgeobuf/flatgeobuf_c.cpp | 11 ++++++++--- flatgeobuf/flatgeobuf_c.h | 1 + mapflatgeobuf.c | 12 +++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/flatgeobuf/flatgeobuf_c.cpp b/flatgeobuf/flatgeobuf_c.cpp index c959cc6c34..a327dd515d 100644 --- a/flatgeobuf/flatgeobuf_c.cpp +++ b/flatgeobuf/flatgeobuf_c.cpp @@ -31,6 +31,7 @@ ctx *flatgeobuf_init_ctx() { ctx *c = (ctx *) malloc(sizeof(ctx)); memset(c, 0, sizeof(ctx)); + c->is_null_geom = false; c->done = false; return c; } @@ -88,6 +89,8 @@ void flatgeobuf_ensure_buf(ctx *ctx, uint32_t size) int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) { + ctx->is_null_geom = false; + uint32_t featureSize; if (VSIFReadL(&featureSize, sizeof(featureSize), 1, ctx->file) != 1) { if (VSIFEofL(ctx->file)) { @@ -107,10 +110,12 @@ int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) ctx->offset += featureSize; auto feature = GetFeature(ctx->buf); const auto geometry = feature->geometry(); - if (geometry) + if (geometry) { GeometryReader(ctx, geometry).read(shape); - else - flatgeobuf_decode_feature(ctx, layer, shape); // skip to next if null geometry + } else { + ctx->is_null_geom = true; + return 0; + } auto properties = feature->properties(); if (properties && properties->size() != 0) { ctx->properties = (uint8_t *) properties->data(); diff --git a/flatgeobuf/flatgeobuf_c.h b/flatgeobuf/flatgeobuf_c.h index 20fd4f3d90..100865af2f 100644 --- a/flatgeobuf/flatgeobuf_c.h +++ b/flatgeobuf/flatgeobuf_c.h @@ -105,6 +105,7 @@ typedef struct flatgeobuf_ctx pointObj *point; uint32_t point_len; + bool is_null_geom; int ms_type; uint8_t *properties; uint32_t properties_size; diff --git a/mapflatgeobuf.c b/mapflatgeobuf.c index 1dbc1c49b3..345fae82c5 100644 --- a/mapflatgeobuf.c +++ b/mapflatgeobuf.c @@ -224,11 +224,13 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) ctx->search_index++; } - int ret = flatgeobuf_decode_feature(ctx, layer, shape); - if (ret == -1) - return MS_FAILURE; - if (ctx->done) - return MS_DONE; + do { + int ret = flatgeobuf_decode_feature(ctx, layer, shape); + if (ret == -1) + return MS_FAILURE; + if (ctx->done) + return MS_DONE; + } while(ctx->is_null_geom); return MS_SUCCESS; } From 61bbcfdfc93e46ef2aec402362c0d22bb4d1377a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Jul 2022 10:05:51 +0200 Subject: [PATCH 010/170] Fix feature access (#6564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Björn Harrtell --- flatgeobuf/flatgeobuf_c.cpp | 60 +++++++++++++++++--------------- flatgeobuf/flatgeobuf_c.h | 3 +- mapflatgeobuf.c | 46 ++++++++++++++---------- msautotest/misc/data/africa.fgb | Bin 46256 -> 46560 bytes msautotest/misc/flatgeobuf.map | 42 ++++++++++++++++++++-- 5 files changed, 100 insertions(+), 51 deletions(-) diff --git a/flatgeobuf/flatgeobuf_c.cpp b/flatgeobuf/flatgeobuf_c.cpp index a327dd515d..1e0b220817 100644 --- a/flatgeobuf/flatgeobuf_c.cpp +++ b/flatgeobuf/flatgeobuf_c.cpp @@ -15,15 +15,11 @@ uint8_t FLATGEOBUF_MAGICBYTES_SIZE = sizeof(flatgeobuf_magicbytes); uint32_t INIT_BUFFER_SIZE = 1024 * 4; template -char *to_string(uint8_t *data) { +void parse_value(uint8_t *data, char **values, uint16_t i, uint32_t &offset, bool found) +{ using std::to_string; - return msStrdup(to_string(*((T*)data)).c_str()); -} - -template -void parse_value(uint8_t *data, char **values, uint16_t i, uint32_t &offset, bool found) { if (found) - values[i] = to_string(data + offset); + values[i] = msStrdup(to_string(*((T*) (data + offset))).c_str()); offset += sizeof(T); } @@ -73,18 +69,21 @@ void flatgeobuf_ensure_point(ctx *ctx, uint32_t len) } } -void flatgeobuf_ensure_buf(ctx *ctx, uint32_t size) +int flatgeobuf_ensure_buf(ctx *ctx, uint32_t size) { + if (size > 100 * 1024 * 1024) + return -1; if (!ctx->buf) { ctx->buf_size = INIT_BUFFER_SIZE; ctx->buf = (uint8_t *) malloc(ctx->buf_size); - return; + return 0; } if (ctx->buf_size < size) { ctx->buf_size = ctx->buf_size * 2; ctx->buf = (uint8_t *) realloc(ctx->buf, ctx->buf_size); flatgeobuf_ensure_buf(ctx, size); } + return 0; } int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) @@ -101,7 +100,10 @@ int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) } ctx->offset += sizeof(uoffset_t); - flatgeobuf_ensure_buf(ctx, featureSize); + if (flatgeobuf_ensure_buf(ctx, featureSize) != 0) { + msSetError(MS_FGBERR, "Failed to allocate buffer for feature", "flatgeobuf_decode_feature"); + return -1; + } if (VSIFReadL(ctx->buf, 1, featureSize, ctx->file) != featureSize) { msSetError(MS_FGBERR, "Failed to read feature", "flatgeobuf_decode_feature"); @@ -168,37 +170,37 @@ int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) type = column.type; switch (type) { case flatgeobuf_column_type_bool: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_byte: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_ubyte: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_short: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_ushort: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_int: - parse_value(data + offset, values, ii, offset, found); - break; + parse_value(data, values, ii, offset, found); + break; case flatgeobuf_column_type_uint: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_long: - parse_value(data + offset, values, ii, offset, found); - break; + parse_value(data, values, ii, offset, found); + break; case flatgeobuf_column_type_ulong: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_float: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_double: - parse_value(data + offset, values, ii, offset, found); + parse_value(data, values, ii, offset, found); break; case flatgeobuf_column_type_datetime: case flatgeobuf_column_type_string: { @@ -230,7 +232,7 @@ int flatgeobuf_check_magicbytes(ctx *ctx) msSetError(MS_FGBERR, "Unexpected offset", "flatgeobuf_check_magicbytes"); return -1; } - ctx->buf = (uint8_t *) malloc(FLATGEOBUF_MAGICBYTES_SIZE); + flatgeobuf_ensure_buf(ctx, FLATGEOBUF_MAGICBYTES_SIZE); if (VSIFReadL(ctx->buf, 8, 1, ctx->file) != 1) { msSetError(MS_FGBERR, "Failed to read magicbytes", "flatgeobuf_check_magicbytes"); return -1; @@ -262,7 +264,9 @@ int flatgeobuf_decode_header(ctx *ctx) return -1; } ctx->offset += sizeof(uoffset_t); - flatgeobuf_ensure_buf(ctx, headerSize); + if (flatgeobuf_ensure_buf(ctx, headerSize) != -1) { + msSetError(MS_FGBERR, "Failed to allocate buffer for header", "flatgeobuf_decode_header"); + } if (VSIFReadL(ctx->buf, 1, headerSize, ctx->file) != headerSize) { msSetError(MS_FGBERR, "Failed to read header", "flatgeobuf_decode_header"); return -1; @@ -349,11 +353,9 @@ int flatgeobuf_index_skip(ctx *ctx) int flatgeobuf_read_feature_offset(ctx *ctx, uint64_t index, uint64_t *featureOffset) { - try - { - const auto treeSize = PackedRTree::size(ctx->features_count, ctx->index_node_size); + try { const auto levelBounds = PackedRTree::generateLevelBounds(ctx->features_count, ctx->index_node_size); - const auto bottomLevelOffset = ctx->index_offset - treeSize + (levelBounds.front().first * sizeof(NodeItem)); + const auto bottomLevelOffset = ctx->index_offset + (levelBounds.front().first * sizeof(NodeItem)); const auto nodeItemOffset = bottomLevelOffset + (index * sizeof(NodeItem)); const auto featureOffsetOffset = nodeItemOffset + (sizeof(double) * 4); if (VSIFSeekL(ctx->file, featureOffsetOffset, SEEK_SET) == -1) { diff --git a/flatgeobuf/flatgeobuf_c.h b/flatgeobuf/flatgeobuf_c.h index 100865af2f..a20e93064b 100644 --- a/flatgeobuf/flatgeobuf_c.h +++ b/flatgeobuf/flatgeobuf_c.h @@ -106,6 +106,7 @@ typedef struct flatgeobuf_ctx uint32_t point_len; bool is_null_geom; + uint64_t feature_index; int ms_type; uint8_t *properties; uint32_t properties_size; @@ -114,7 +115,7 @@ typedef struct flatgeobuf_ctx flatgeobuf_ctx *flatgeobuf_init_ctx(); void flatgeobuf_free_ctx(flatgeobuf_ctx *ctx); -void flatgeobuf_ensure_buf(flatgeobuf_ctx *ctx, uint32_t size); +int flatgeobuf_ensure_buf(flatgeobuf_ctx *ctx, uint32_t size); void flatgeobuf_ensure_line(flatgeobuf_ctx *ctx, uint32_t len); void flatgeobuf_ensure_point(flatgeobuf_ctx *ctx, uint32_t len); diff --git a/mapflatgeobuf.c b/mapflatgeobuf.c index 345fae82c5..b3576ef649 100644 --- a/mapflatgeobuf.c +++ b/mapflatgeobuf.c @@ -42,12 +42,12 @@ static void msFGBPassThroughFieldDefinitions(layerObj *layer, flatgeobuf_ctx *ctx) { for (int i = 0; i < ctx->columns_len; i++) { - char item[16]; - //int nWidth=0, nPrecision=0; + char item[255]; char gml_width[32], gml_precision[32]; const char *gml_type = NULL; flatgeobuf_column column = ctx->columns[i]; + strncpy(item, column.name, 255 - 1); gml_width[0] = '\0'; gml_precision[0] = '\0'; @@ -61,25 +61,25 @@ static void msFGBPassThroughFieldDefinitions(layerObj *layer, flatgeobuf_ctx *ct case flatgeobuf_column_type_int: case flatgeobuf_column_type_uint: gml_type = "Integer"; - //sprintf( gml_width, "%d", nWidth ); + sprintf( gml_width, "%d", 4 ); break; case flatgeobuf_column_type_long: case flatgeobuf_column_type_ulong: gml_type = "Long"; - //sprintf( gml_width, "%d", nWidth ); + sprintf( gml_width, "%d", 8 ); break; case flatgeobuf_column_type_float: case flatgeobuf_column_type_double: gml_type = "Real"; - //sprintf( gml_width, "%d", nWidth ); - //sprintf( gml_precision, "%d", nPrecision ); + sprintf( gml_width, "%d", 8 ); + sprintf( gml_precision, "%d", 15 ); break; case flatgeobuf_column_type_string: case flatgeobuf_column_type_json: case flatgeobuf_column_type_datetime: default: gml_type = "Character"; - //sprintf( gml_width, "%d", nWidth ); + sprintf( gml_width, "%d", 4096 ); break; } @@ -212,22 +212,25 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) if (!ctx) return MS_FAILURE; - if (ctx->search_result) { - if (ctx->search_index >= ctx->search_result_len - 1) - return MS_DONE; - flatgeobuf_search_item item = ctx->search_result[ctx->search_index]; - if (VSIFSeekL(ctx->file, ctx->feature_offset + item.offset, SEEK_SET) == -1) { - msSetError(MS_FGBERR, "Unable to seek in file", "msFlatGeobufLayerNextShape"); - return MS_FAILURE; - } - ctx->offset = ctx->feature_offset + item.offset; - ctx->search_index++; - } - do { + if (ctx->search_result) { + if (ctx->search_index >= ctx->search_result_len - 1) + return MS_DONE; + flatgeobuf_search_item item = ctx->search_result[ctx->search_index]; + if (VSIFSeekL(ctx->file, ctx->feature_offset + item.offset, SEEK_SET) == -1) { + msSetError(MS_FGBERR, "Unable to seek in file", "msFlatGeobufLayerNextShape"); + return MS_FAILURE; + } + ctx->offset = ctx->feature_offset + item.offset; + ctx->search_index++; + ctx->feature_index = item.index; + } int ret = flatgeobuf_decode_feature(ctx, layer, shape); if (ret == -1) return MS_FAILURE; + shape->index = ctx->feature_index; + if (!ctx->search_result) + ctx->feature_index++; if (ctx->done) return MS_DONE; } while(ctx->is_null_geom); @@ -237,6 +240,7 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { + (void)shape; (void)record; flatgeobuf_ctx *ctx; @@ -244,6 +248,10 @@ int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *recor if (!ctx) return MS_FAILURE; long i = record->shapeindex; + if (i < 0 || (uint64_t) i >= ctx->features_count) { + msSetError(MS_MISCERR, "Invalid feature id", "msFlatGeobufLayerGetShape"); + return MS_FAILURE; + } uint64_t offset; flatgeobuf_read_feature_offset(ctx, i, &offset); if (VSIFSeekL(ctx->file, ctx->feature_offset + offset, SEEK_SET) == -1) { diff --git a/msautotest/misc/data/africa.fgb b/msautotest/misc/data/africa.fgb index f1697c66791b33cc780643637bd8290d80810988..b334827c8e6bd8a64aa87212786f7118a25357d1 100644 GIT binary patch delta 2226 zcmZ8idrXs86u|#FxXIk!+i5HSP;=W#S6pD#n%gH2C8ol9A|(F-_Lx zM~@!iL6RPcP**Sz(`kL29|wPuhuh&zq#GcL^c>toIuE$c!^>eB(mtq0+72B^ufPeN zN7!9(S?A{aU<{A$LUyu;S3ya#M-&u8W3rn+fCz3D&xZ@R*$ltnrs_FJ(YyHpDAId` zsT6#Ax7bhyJMnA~&g#kURiroIACzx?3GxkYejk<_JYwE@XvNKWID#8%J$!9&i}H;y zima*$CZ)KAz8MxEvu}o4WaVMlpW^1j5KTel?eHU>o!6)*0D>BM%!DrCcZpcC2J zeQ*-l;9GDxm3)q+dc=Kz9HWQ#!t+RvK%)^&ybJFj8|;S*$PS!@UyW{q{(Zy~zhmIA zS-{kzM<@%^rf3A?P#vv|^`)6KybDfvrO;ugyKMjVL!3BgDM()kb^15e23y+d1QXD* zW<|_v9@p}PP!h56JSfS^O%e=iNg^1?it`GTxN?u)orK73`hp{*o&V^++VovGtSHSlyOvt^-Br>MsUY`X+{QnP{$5nZl# z)P+_O9#{G|1#5$TA>GTcKgu5x{1&vhDA#m2>>_*Eb5c0&S}UN`XM)d7dbnuSS&o19 zw`vVtG9N*J#ticENWl#aT<@K@441r_2x$rmr^X(75uE^x6 z{u#-Y;@5;W`I~}G=w2|hRO%`l;1ek733wt@5d{P!BC_4Tf9m5QfPKPu}Wb4w-2Lg}H{H z$WkH**9Ms_#&t;h)!$rF{a~3{O{gv0V6SNl_?rdG!2<=n zzyqZWha0F2x$oAmJUqhms$%Bwdm63hXR&D4pH%e6 zN(+}>r=FQg0ntctc8_!3^uHW_bGFc*fto`}lbVAwp>pgE#6-eIb4@nl>Ahr>rhqi6 z-6zpDO-vXkWcN4_cefPp>OtHeCZclKQH`;CFVB};oqhf`Y&w54f#;D*BX740h`0Y| zb1L{FcEqEA#kwOqIPa0YZHFm9Q+Ar-3AFr)VKsW~XVnk2c1>M#UA@0au<5vwD#k-N ztV-c(uhN}=^-?irsKScAAuUF3?$4M=EguT|X?S|oD+l|-0s%FrJ=vzC$t`M)s6&=- z4YhXImxTOV!h#hhocA2RE7W2~PEoOEDnX5(I>_;5KUT-w*Ls$rR-#Jyx|B|vl`v&I z9q0THh_*i->Q84V)Y)pNrGpJh3nfPHha108ZPM^t))s80S6?J?@qW;tRYQw@OrgzD eLd*Q*0gVEap#oLt3C)0M(E^kgvsiWX70tiyAxORe delta 1951 zcmZuxT})I*6yCYJEW5xOh`7JdWhvgJ77~g)AeBZbBFK+W(6%dvF0$$^vMeYOR2sLz zRIP@e4;wIQptX$(w&>UA2ij`VGj|ueZoSFO$(cKI z=6v7z&dl7CChkhMox2*fG+41tqsh=LeRfS+zs;FiL4F#IL>l!pR?`rlL}TX4cCO`_ zy4M&RLNLb75^<5{Qrx1s4}YmEF1?#sQAYC{XrnnF!!-BdhTbjBWMEz|vvo*{byJ8n zG;83EbxS|x;&`mgMsS6kxqRFvClSm*P9atqWR`{+a)w^U0fQ{fY{2`pmWgi+ZkB@w zG*`oBq|IAVWR&S*g`5l9F+fflJ}0MhCw?=^(#V^LizCyFTr$-y@Q~Tvinq!1?Zu@y znHg{^&MgHF;BQ)+dkg9DvXmdhCNeoaXeV?32u_pfdEd*QZ<924hZjtd;f^^SeBAk+M6u|{vrG3_)HJi^SE`n2V#!u{Ta-q{%fCoB zY1uT|N+RRjUFqNn@`!|<^5pcTC}#Ea$Y+0sqv*+cye$+2s{&O#=ecPurW2DNqcbBl z+r|sB%`vPVHMtfXZZ=Sz+j3X)@!SLhs}p#ma?~w;9F8t>Eb3_Q@HZ*^p8^*{ojE#{ ztka)Hr1HvsufNGF_{W*GbJ$n%UnVPXw$O^%(#_oPQnkdUqFC!%=iq17^=ZYKD70Je zW-xIF(+ISc-aX#^3Oq^`pD4c0SO$WHqQw0rp%OnVInScFwBSam9r1D{&ncs;^AIeL zBzm-5tv^qwxF!_yq&Q|bhs04)y+8$xtdIrX8auWrmHdaADTX{#B-YEdq$^W7Pp_>d6WtteW6-r~5mnXgYy_Th5*0bE0M~gz6$#~?k@RV)$)uKkl=)Jv0 zyd*@6h*8_o#wSl1E|N61X6uhOrg-{EDBq9lXOtFFXda0xjJkmZ!VVi^@@T zqNHqqADtS!;n5=du3~T>y90* zeC+6Y9YIP#z^q5y$rQfoBvHK(mg(!gsr*3iO$mdRba)0Fs!FB?@)+wOdR%yB(8>!2 ztJqUtkNF>e4bvj>tM&PPyS#h&x2Nd!SW7S6^0ddoQMVP&C59VEh>03U5$_zYAD+@t zJ}$+DqH}f}>aE}t=K_L}{#sfZCEYm7`1t6YBq|d@_vQ0M_rcBF`e7fVF8V*+-6u9i zPn2S!Hb#X$iWK^GzHGdgCE&6<8hvN6CPYJId+btN4Oy!qP YLX|I`SX5h274b@Jxths?R~xkd0yC-I!vFvP diff --git a/msautotest/misc/flatgeobuf.map b/msautotest/misc/flatgeobuf.map index d14c77538e..8092054f36 100644 --- a/msautotest/misc/flatgeobuf.map +++ b/msautotest/misc/flatgeobuf.map @@ -15,9 +15,32 @@ MAP IMAGECOLOR 255 255 255 IMAGETYPE png + WEB + METADATA + "wfs_title" "Test FlatGeobuf WFS output" + "wfs_abstract" "Longer text describing the FlatGeobuf WFS service." + "wfs_onlineresource" "http://localhost/path/to/flatgeobuf?" + "wfs_srs" "EPSG:4326 EPSG:4269 EPSG:3978 EPSG:3857" + "wfs_enable_request" "*" + END + END + + PROJECTION + "init=epsg:4326" + END + /* Africa Continent */ LAYER NAME "africa-continent" + METADATA + "wfs_title" "Africa Continent" + "wfs_srs" "EPSG:4326" + "gml_include_items" "all" + "gml_featureid" "id" + "gml_types" "auto" + "wfs_enable_request" "*" + "wfs_use_default_extent_for_getfeature" "false" + END TYPE POLYGON STATUS ON CONNECTIONTYPE flatgeobuf @@ -28,12 +51,24 @@ MAP COLOR 50 50 50 OUTLINECOLOR 120 120 120 END #style - END #class + END #class + PROJECTION + "init=epsg:4326" + END END # layer /* Africa classes */ LAYER NAME "africa-classes" + METADATA + "wfs_title" "Africa Classes" + "wfs_srs" "EPSG:4326" + "gml_include_items" "all" + "gml_featureid" "id" + "gml_types" "auto" + "wfs_enable_request" "*" + "wfs_use_default_extent_for_getfeature" "false" + END TYPE POLYGON STATUS ON CONNECTIONTYPE flatgeobuf @@ -64,7 +99,10 @@ MAP OUTLINECOLOR 120 120 120 END #style END #class - TEMPLATE "ttt.html" + TEMPLATE "ttt.html" + PROJECTION + "init=epsg:4326" + END END # layer END # map From 97fd1f0e4eeeaab4cd9c320ee0857b702b3880e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:47:50 -0300 Subject: [PATCH 011/170] Config file parsing: use msSetPROJ_LIB() when ENV PROJ_LIB is set (#6568) Co-authored-by: Even Rouault --- mapserv-config.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mapserv-config.cpp b/mapserv-config.cpp index c8a1e6d12f..9b57651388 100644 --- a/mapserv-config.cpp +++ b/mapserv-config.cpp @@ -105,6 +105,14 @@ static int loadConfig(configObj *config) } } +static void msConfigSetConfigOption(const char* key, const char* value) +{ + CPLSetConfigOption(key, value); + if( strcasecmp(key,"PROJ_LIB") == 0 ) { + msSetPROJ_LIB( value, nullptr ); + } +} + configObj *msLoadConfig(const char* ms_config_file) { configObj *config = NULL; @@ -162,11 +170,11 @@ configObj *msLoadConfig(const char* ms_config_file) // load all env key/values using CPLSetConfigOption() - only do this *after* we have a good config const char *key = msFirstKeyFromHashTable(&config->env); if(key != NULL) { - CPLSetConfigOption(key, msLookupHashTable(&config->env, key)); + msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); const char *last_key = key; while((key = msNextKeyFromHashTable(&config->env, last_key)) != NULL) { - CPLSetConfigOption(key, msLookupHashTable(&config->env, key)); + msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); last_key = key; } } From bb73f45d8086d040b5df7ac91a5a8194562c7e66 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 8 Jul 2022 21:57:45 +0200 Subject: [PATCH 012/170] [msautotest] add FlatGeobuf WFS tests (#6566) (#6569) * flatgeobuf: fix memory leak and issue in column mapping Co-authored-by: Even Rouault Co-authored-by: Jeff McKenna --- flatgeobuf/flatgeobuf_c.cpp | 28 +- mapflatgeobuf.c | 26 +- .../misc/expected/flatgeobuf-wfs-cap.xml | 111 ++ .../misc/expected/flatgeobuf-wfs-describe.xml | 50 + .../flatgeobuf-wfs-get-feature-id.xml | 39 + ...-wfs-get-feature-propertyname-geometry.xml | 1005 +++++++++++++++ ...latgeobuf-wfs-get-feature-propertyname.xml | 273 ++++ .../expected/flatgeobuf-wfs-get-feature.xml | 1111 +++++++++++++++++ msautotest/misc/flatgeobuf.map | 24 +- 9 files changed, 2647 insertions(+), 20 deletions(-) create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-cap.xml create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-describe.xml create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-get-feature-id.xml create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname-geometry.xml create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname.xml create mode 100644 msautotest/misc/expected/flatgeobuf-wfs-get-feature.xml diff --git a/flatgeobuf/flatgeobuf_c.cpp b/flatgeobuf/flatgeobuf_c.cpp index 1e0b220817..6eb4036f14 100644 --- a/flatgeobuf/flatgeobuf_c.cpp +++ b/flatgeobuf/flatgeobuf_c.cpp @@ -19,7 +19,10 @@ void parse_value(uint8_t *data, char **values, uint16_t i, uint32_t &offset, boo { using std::to_string; if (found) + { + msFree(values[i]); values[i] = msStrdup(to_string(*((T*) (data + offset))).c_str()); + } offset += sizeof(T); } @@ -132,9 +135,6 @@ int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) { - uint16_t i; - int32_t ii; - flatgeobuf_column column; uint8_t type; uint32_t offset = 0; uint8_t *data = ctx->properties; @@ -146,10 +146,8 @@ int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) if (numvalues == 0) return 0; - values = (char **) malloc(sizeof(char *) * numvalues); - - //memset(values, 0, sizeof(char *) * numvalues); - + values = (char **) msSmallCalloc(sizeof(char *), numvalues); + if (shape->values) msFreeCharArray(shape->values, shape->numvalues); shape->numvalues = numvalues; shape->values = values; @@ -158,14 +156,15 @@ int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) return -1; } while (offset + 1 < size) { + uint16_t i; memcpy(&i, data + offset, sizeof(uint16_t)); offset += sizeof(uint16_t); if (i >= ctx->columns_len) { msSetError(MS_FGBERR, "Column index out of range", "flatgeobuf_decode_properties"); return -1; } - column = ctx->columns[i]; - ii = column.itemindex; + const auto& column = ctx->columns[i]; + const int32_t ii = column.itemindex; found = ii != -1; type = column.type; switch (type) { @@ -212,9 +211,10 @@ int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) memcpy(&len, data + offset, sizeof(uint32_t)); offset += sizeof(len); if (found) { - char *str = (char *) malloc(len + 1); + char *str = (char *) msSmallMalloc(len + 1); memcpy(str, data + offset, len); str[len] = '\0'; + msFree(values[ii]); values[ii] = str; } offset += len; @@ -222,7 +222,13 @@ int flatgeobuf_decode_properties(ctx *ctx, layerObj *layer, shapeObj *shape) } } } - // TODO: set missing (null) values to msStrdup("")? + + for(int i = 0; i < shape->numvalues; i++) + { + if( shape->values[i] == NULL) + shape->values[i] = msStrdup(""); + } + return 0; } diff --git a/mapflatgeobuf.c b/mapflatgeobuf.c index b3576ef649..ca4a12b586 100644 --- a/mapflatgeobuf.c +++ b/mapflatgeobuf.c @@ -46,13 +46,13 @@ static void msFGBPassThroughFieldDefinitions(layerObj *layer, flatgeobuf_ctx *ct char gml_width[32], gml_precision[32]; const char *gml_type = NULL; - flatgeobuf_column column = ctx->columns[i]; - strncpy(item, column.name, 255 - 1); + const flatgeobuf_column* column = &(ctx->columns[i]); + strncpy(item, column->name, 255 - 1); gml_width[0] = '\0'; gml_precision[0] = '\0'; - switch( column.type ) { + switch( column->type ) { case flatgeobuf_column_type_byte: case flatgeobuf_column_type_ubyte: case flatgeobuf_column_type_bool: @@ -109,10 +109,18 @@ int msFlatGeobufLayerInitItemInfo(layerObj *layer) if (!ctx) return MS_FAILURE; - for (int i = 0; i < layer->numitems; i++) - for (int j = 0; j < ctx->columns_len; j++) - if (strcasecmp(layer->items[i], ctx->columns[j].name) == 0) - ctx->columns[j].itemindex = i; + for (int j = 0; j < ctx->columns_len; j++) + { + ctx->columns[j].itemindex = -1; + for (int i = 0; i < layer->numitems; i++) + { + if (strcasecmp(layer->items[i], ctx->columns[j].name) == 0) + { + ctx->columns[j].itemindex = i; + break; + } + } + } return MS_SUCCESS; } @@ -233,6 +241,10 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) ctx->feature_index++; if (ctx->done) return MS_DONE; + if (ctx->is_null_geom) { + msFreeCharArray(shape->values, shape->numvalues); + shape->values = NULL; + } } while(ctx->is_null_geom); return MS_SUCCESS; diff --git a/msautotest/misc/expected/flatgeobuf-wfs-cap.xml b/msautotest/misc/expected/flatgeobuf-wfs-cap.xml new file mode 100644 index 0000000000..bc04a427a6 --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-cap.xml @@ -0,0 +1,111 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + MapServer WFS + Test FlatGeobuf WFS output + Longer text describing the FlatGeobuf WFS service. + http://localhost/path/to/flatgeobuf? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + africa-continent + Africa Continent + EPSG:4326 + + http://localhost/path/to/flatgeobuf?request=GetMetadata&layer=africa-continent + + + africa-classes + Africa Classes + EPSG:4326 + + http://localhost/path/to/flatgeobuf?request=GetMetadata&layer=africa-classes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msautotest/misc/expected/flatgeobuf-wfs-describe.xml b/msautotest/misc/expected/flatgeobuf-wfs-describe.xml new file mode 100644 index 0000000000..712fbf1c10 --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-describe.xml @@ -0,0 +1,50 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msautotest/misc/expected/flatgeobuf-wfs-get-feature-id.xml b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-id.xml new file mode 100644 index 0000000000..8aa57ca584 --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-id.xml @@ -0,0 +1,39 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 0.023803,11.018682 -0.049785,10.706918 0.367580,10.191213 0.365901,9.465004 0.461192,8.677223 0.712029,8.312465 0.490957,7.411744 0.570384,6.914359 0.836931,6.279979 1.060122,5.928837 -0.507638,5.343473 -1.063625,5.000548 -1.964707,4.710462 -2.856125,4.994476 -2.810701,5.389051 -3.244370,6.250472 -2.983585,7.379705 -2.562190,8.219628 -2.827496,9.642461 -2.963896,10.395335 -2.940409,10.962690 -1.203358,11.009819 -0.761576,10.936930 -0.438702,11.098341 0.023803,11.018682 + + + + + 27499924 + Ghana + 46 + + + + diff --git a/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname-geometry.xml b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname-geometry.xml new file mode 100644 index 0000000000..f271e5cb24 --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname-geometry.xml @@ -0,0 +1,1005 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 49.543519,-12.469833 49.808981,-12.895285 50.056511,-13.555761 50.217431,-14.758789 50.476537,-15.226512 50.377111,-15.706069 50.200275,-16.000263 49.860606,-15.414253 49.672607,-15.710204 49.863344,-16.451037 49.774564,-16.875042 49.498612,-17.106036 49.435619,-17.953064 49.041792,-19.118781 48.548541,-20.496888 47.930749,-22.391501 47.547723,-23.781959 47.095761,-24.941630 46.282478,-25.178463 45.409508,-25.601434 44.833574,-25.346101 44.039720,-24.988345 43.763768,-24.460677 43.697778,-23.574116 43.345654,-22.776904 43.254187,-22.057413 43.433298,-21.336475 43.893683,-21.163307 43.896370,-20.830459 44.374325,-20.072366 44.464397,-19.435454 44.232422,-18.961995 44.042976,-18.331387 43.963084,-17.409945 44.312469,-16.850496 44.446517,-16.216219 44.944937,-16.179374 45.502732,-15.974373 45.872994,-15.793454 46.312243,-15.780018 46.882183,-15.210182 47.705130,-14.594303 48.005215,-14.091233 47.869047,-13.663869 48.293828,-13.784068 48.845060,-13.089175 48.863509,-12.487868 49.194651,-12.040557 49.543519,-12.469833 + + + + + Madagascar + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 34.559989,-11.520020 35.312398,-11.439146 36.514082,-11.720938 36.775151,-11.594537 37.471290,-11.568760 37.827640,-11.268790 38.427557,-11.285202 39.521000,-10.896880 40.316590,-10.317100 40.316586,-10.317098 40.316589,-10.317096 40.478387,-10.765441 40.437253,-11.761711 40.560811,-12.639177 40.599620,-14.201975 40.775475,-14.691764 40.477251,-15.406294 40.089264,-16.100774 39.452559,-16.720891 38.538351,-17.101023 37.411133,-17.586368 36.281279,-18.659688 35.896497,-18.842260 35.198400,-19.552811 34.786383,-19.784012 34.701893,-20.497043 35.176127,-21.254361 35.373428,-21.840837 35.385848,-22.140000 35.562546,-22.090000 35.533935,-23.070788 35.371774,-23.535359 35.607470,-23.706563 35.458746,-24.122610 35.040735,-24.478351 34.215824,-24.816314 33.013210,-25.357573 32.574632,-25.727318 32.660363,-26.148584 32.915955,-26.215867 32.830120,-26.742192 32.071665,-26.733820 31.985779,-26.291780 31.837778,-25.843332 31.752408,-25.484284 31.930589,-24.369417 31.670398,-23.658969 31.191409,-22.251510 32.244988,-21.116489 32.508693,-20.395292 32.659743,-20.304290 32.772708,-19.715592 32.611994,-19.419383 32.654886,-18.672090 32.849861,-17.979057 32.847639,-16.713398 32.328239,-16.392074 31.852041,-16.319417 31.636498,-16.071990 31.173064,-15.860944 30.338955,-15.880839 30.274256,-15.507787 30.179481,-14.796099 33.214025,-13.971860 33.789700,-14.451831 34.064825,-14.359950 34.459633,-14.613010 34.517666,-15.013709 34.307291,-15.478641 34.381292,-16.183560 35.033810,-16.801300 35.339063,-16.107440 35.771905,-15.896859 35.686845,-14.611046 35.267956,-13.887834 34.907151,-13.565425 34.559989,-13.579998 34.280006,-12.280025 34.559989,-11.520020 + + + + + Mozambique + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 32.071665,-26.733820 31.868060,-27.177927 31.282773,-27.285879 30.685962,-26.743845 30.676609,-26.398078 30.949667,-26.022649 31.044080,-25.731452 31.333158,-25.660191 31.837778,-25.843332 31.985779,-26.291780 32.071665,-26.733820 + + + + + eSwatini + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 28.978263,-28.955597 29.325166,-29.257387 29.018415,-29.743766 28.848400,-30.070051 28.291069,-30.226217 28.107205,-30.545732 27.749397,-30.645106 26.999262,-29.875954 27.532511,-29.242711 28.074338,-28.851469 28.541700,-28.647502 28.978263,-28.955597 + + + + + Lesotho + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 16.344977,-28.576705 16.824017,-28.082162 17.218929,-28.355943 17.387497,-28.783514 17.836152,-28.856378 18.464899,-29.045462 19.002127,-28.972443 19.894734,-28.461105 19.895768,-24.767790 20.165726,-24.917962 20.758609,-25.868136 20.666470,-26.477453 20.889609,-26.828543 21.605896,-26.726534 22.105969,-26.280256 22.579532,-25.979448 22.824271,-25.500459 23.312097,-25.268690 23.733570,-25.390129 24.211267,-25.670216 25.025171,-25.719670 25.664666,-25.486816 25.765849,-25.174845 25.941652,-24.696373 26.485753,-24.616327 26.786407,-24.240691 27.119410,-23.574323 28.017236,-22.827754 29.432188,-22.091313 29.839037,-22.102216 30.322883,-22.271612 30.659865,-22.151567 31.191409,-22.251510 31.670398,-23.658969 31.930589,-24.369417 31.752408,-25.484284 31.837778,-25.843332 31.333158,-25.660191 31.044080,-25.731452 30.949667,-26.022649 30.676609,-26.398078 30.685962,-26.743845 31.282773,-27.285879 31.868060,-27.177927 32.071665,-26.733820 32.830120,-26.742192 32.580265,-27.470158 32.462133,-28.301011 32.203389,-28.752405 31.521001,-29.257387 31.325561,-29.401978 30.901763,-29.909957 30.622813,-30.423776 30.055716,-31.140269 28.925553,-32.172041 28.219756,-32.771953 27.464608,-33.226964 26.419452,-33.614950 25.909664,-33.667040 25.780628,-33.944646 25.172862,-33.796851 24.677853,-33.987176 23.594043,-33.794474 22.988189,-33.916431 22.574157,-33.864083 21.542799,-34.258839 20.689053,-34.417175 20.071261,-34.795137 19.616405,-34.819166 19.193278,-34.462599 18.855315,-34.444306 18.424643,-33.997873 18.377411,-34.136521 18.244499,-33.867752 18.250080,-33.281431 17.925190,-32.611291 18.247910,-32.429131 18.221762,-31.661633 17.566918,-30.725721 17.064416,-29.878641 17.062918,-29.875954 16.344977,-28.576705 + + + + + 28.978263,-28.955597 28.541700,-28.647502 28.074338,-28.851469 27.532511,-29.242711 26.999262,-29.875954 27.749397,-30.645106 28.107205,-30.545732 28.291069,-30.226217 28.848400,-30.070051 29.018415,-29.743766 29.325166,-29.257387 28.978263,-28.955597 + + + + + South Africa + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 29.432188,-22.091313 28.017236,-22.827754 27.119410,-23.574323 26.786407,-24.240691 26.485753,-24.616327 25.941652,-24.696373 25.765849,-25.174845 25.664666,-25.486816 25.025171,-25.719670 24.211267,-25.670216 23.733570,-25.390129 23.312097,-25.268690 22.824271,-25.500459 22.579532,-25.979448 22.105969,-26.280256 21.605896,-26.726534 20.889609,-26.828543 20.666470,-26.477453 20.758609,-25.868136 20.165726,-24.917962 19.895768,-24.767790 19.895458,-21.849157 20.881134,-21.814327 20.910641,-18.252219 21.655040,-18.219146 23.196858,-17.869038 23.579006,-18.281261 24.217365,-17.889347 24.520705,-17.887125 25.084443,-17.661816 25.264226,-17.736540 25.649163,-18.536026 25.850391,-18.714413 26.164791,-19.293086 27.296505,-20.391520 27.724747,-20.499059 27.727228,-20.851802 28.021370,-21.485975 28.794656,-21.639454 29.432188,-22.091313 + + + + + Botswana + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 19.895768,-24.767790 19.894734,-28.461105 19.002127,-28.972443 18.464899,-29.045462 17.836152,-28.856378 17.387497,-28.783514 17.218929,-28.355943 16.824017,-28.082162 16.344977,-28.576705 15.601818,-27.821247 15.210472,-27.090956 14.989711,-26.117372 14.743214,-25.392920 14.408144,-23.853014 14.385717,-22.656653 14.257714,-22.111208 13.868642,-21.699037 13.352498,-20.872834 12.826845,-19.673166 12.608564,-19.045349 11.794919,-18.069129 11.734199,-17.301889 12.215461,-17.111668 12.814081,-16.941343 13.462362,-16.971212 14.058501,-17.423381 14.209707,-17.353101 18.263309,-17.309951 18.956187,-17.789095 21.377176,-17.930636 23.215048,-17.523116 24.033862,-17.295843 24.682349,-17.353411 25.076950,-17.578823 25.084443,-17.661816 24.520705,-17.887125 24.217365,-17.889347 23.579006,-18.281261 23.196858,-17.869038 21.655040,-18.219146 20.910641,-18.252219 20.881134,-21.814327 19.895458,-21.849157 19.895768,-24.767790 + + + + + Namibia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 31.191409,-22.251510 30.659865,-22.151567 30.322883,-22.271612 29.839037,-22.102216 29.432188,-22.091313 28.794656,-21.639454 28.021370,-21.485975 27.727228,-20.851802 27.724747,-20.499059 27.296505,-20.391520 26.164791,-19.293086 25.850391,-18.714413 25.649163,-18.536026 25.264226,-17.736540 26.381935,-17.846042 26.706773,-17.961229 27.044427,-17.938026 27.598243,-17.290831 28.467906,-16.468400 28.825869,-16.389749 28.947463,-16.043051 29.516834,-15.644678 30.274256,-15.507787 30.338955,-15.880839 31.173064,-15.860944 31.636498,-16.071990 31.852041,-16.319417 32.328239,-16.392074 32.847639,-16.713398 32.849861,-17.979057 32.654886,-18.672090 32.611994,-19.419383 32.772708,-19.715592 32.659743,-20.304290 32.508693,-20.395292 32.244988,-21.116489 31.191409,-22.251510 + + + + + Zimbabwe + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.740010,-8.340006 31.157751,-8.594579 31.556348,-8.762049 32.191865,-8.930359 32.759375,-9.230599 33.231388,-9.676722 33.485688,-10.525559 33.315310,-10.796550 33.114289,-11.607198 33.306422,-12.435778 32.991764,-12.783871 32.688165,-13.712858 33.214025,-13.971860 30.179481,-14.796099 30.274256,-15.507787 29.516834,-15.644678 28.947463,-16.043051 28.825869,-16.389749 28.467906,-16.468400 27.598243,-17.290831 27.044427,-17.938026 26.706773,-17.961229 26.381935,-17.846042 25.264226,-17.736540 25.084443,-17.661816 25.076950,-17.578823 24.682349,-17.353411 24.033862,-17.295843 23.215048,-17.523116 22.562478,-16.898451 21.887843,-16.080310 21.933886,-12.898437 24.016137,-12.911046 23.930922,-12.565848 24.079905,-12.191297 23.904154,-11.722282 24.017894,-11.237298 23.912215,-10.926826 24.257155,-10.951993 24.314516,-11.262826 24.783170,-11.238694 25.418118,-11.330936 25.752310,-11.784965 26.553088,-11.924440 27.164420,-11.608748 27.388799,-12.132747 28.155109,-12.272481 28.523562,-12.698604 28.934286,-13.248958 29.699614,-13.257227 29.616001,-12.178895 29.341548,-12.360744 28.642417,-11.971569 28.372253,-11.793647 28.496070,-10.789884 28.673682,-9.605925 28.449871,-9.164918 28.734867,-8.526559 29.002912,-8.407032 30.346086,-8.238257 30.740010,-8.340006 + + + + + Zambia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + + + 12.995517,-4.781103 12.631612,-4.991271 12.468004,-5.248362 12.436688,-5.684304 12.182337,-5.789931 11.914963,-5.037987 12.318608,-4.606230 12.620760,-4.438023 12.995517,-4.781103 + + + + + + + + + 12.322432,-6.100092 12.735171,-5.965682 13.024869,-5.984389 13.375597,-5.864241 16.326528,-5.877470 16.573180,-6.622645 16.860191,-7.222298 17.089996,-7.545689 17.472970,-8.068551 18.134222,-7.987678 18.464176,-7.847014 19.016752,-7.988246 19.166613,-7.738184 19.417502,-7.155429 20.037723,-7.116361 20.091622,-6.943090 20.601823,-6.939318 20.514748,-7.299606 21.728111,-7.290872 21.746456,-7.920085 21.949131,-8.305901 21.801801,-8.908707 21.875182,-9.523708 22.208753,-9.894796 22.155268,-11.084801 22.402798,-10.993075 22.837345,-11.017622 23.456791,-10.867863 23.912215,-10.926826 24.017894,-11.237298 23.904154,-11.722282 24.079905,-12.191297 23.930922,-12.565848 24.016137,-12.911046 21.933886,-12.898437 21.887843,-16.080310 22.562478,-16.898451 23.215048,-17.523116 21.377176,-17.930636 18.956187,-17.789095 18.263309,-17.309951 14.209707,-17.353101 14.058501,-17.423381 13.462362,-16.971212 12.814081,-16.941343 12.215461,-17.111668 11.734199,-17.301889 11.640096,-16.673142 11.778537,-15.793816 12.123581,-14.878316 12.175619,-14.449144 12.500095,-13.547700 12.738479,-13.137906 13.312914,-12.483630 13.633721,-12.038645 13.738728,-11.297863 13.686379,-10.731076 13.387328,-10.373578 13.120988,-9.766897 12.875370,-9.166934 12.929061,-8.959091 13.236433,-8.562629 12.933040,-7.596539 12.728298,-6.927122 12.227347,-6.294448 12.322432,-6.100092 + + + + + + + Angola + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 29.339998,-4.499983 29.519987,-5.419979 29.419993,-5.939999 29.620032,-6.520015 30.199997,-7.079981 30.740015,-8.340007 30.740010,-8.340006 30.346086,-8.238257 29.002912,-8.407032 28.734867,-8.526559 28.449871,-9.164918 28.673682,-9.605925 28.496070,-10.789884 28.372253,-11.793647 28.642417,-11.971569 29.341548,-12.360744 29.616001,-12.178895 29.699614,-13.257227 28.934286,-13.248958 28.523562,-12.698604 28.155109,-12.272481 27.388799,-12.132747 27.164420,-11.608748 26.553088,-11.924440 25.752310,-11.784965 25.418118,-11.330936 24.783170,-11.238694 24.314516,-11.262826 24.257155,-10.951993 23.912215,-10.926826 23.456791,-10.867863 22.837345,-11.017622 22.402798,-10.993075 22.155268,-11.084801 22.208753,-9.894796 21.875182,-9.523708 21.801801,-8.908707 21.949131,-8.305901 21.746456,-7.920085 21.728111,-7.290872 20.514748,-7.299606 20.601823,-6.939318 20.091622,-6.943090 20.037723,-7.116361 19.417502,-7.155429 19.166613,-7.738184 19.016752,-7.988246 18.464176,-7.847014 18.134222,-7.987678 17.472970,-8.068551 17.089996,-7.545689 16.860191,-7.222298 16.573180,-6.622645 16.326528,-5.877470 13.375597,-5.864241 13.024869,-5.984389 12.735171,-5.965682 12.322432,-6.100092 12.182337,-5.789931 12.436688,-5.684304 12.468004,-5.248362 12.631612,-4.991271 12.995517,-4.781103 13.258240,-4.882957 13.600235,-4.500138 14.144956,-4.510009 14.209035,-4.793092 14.582604,-4.970239 15.170992,-4.343507 15.753540,-3.855165 16.006290,-3.535133 15.972803,-2.712392 16.407092,-1.740927 16.865307,-1.225816 17.523716,-0.743830 17.638645,-0.424832 17.663553,-0.058084 17.826540,0.288923 17.774192,0.855659 17.898835,1.741832 18.094276,2.365722 18.393792,2.900443 18.453065,3.504386 18.542982,4.201785 18.932312,4.709506 19.467784,5.031528 20.290679,4.691678 20.927591,4.322786 21.659123,4.224342 22.405124,4.029160 22.704124,4.633051 22.841480,4.710126 23.297214,4.609693 24.410531,5.108784 24.805029,4.897247 25.128833,4.927245 25.278798,5.170408 25.650455,5.256088 26.402761,5.150875 27.044065,5.127853 27.374226,5.233944 27.979977,4.408413 28.428994,4.287155 28.696678,4.455077 29.159078,4.389267 29.715995,4.600805 29.953500,4.173699 30.833852,3.509172 30.833860,3.509166 30.773347,2.339883 31.174149,2.204465 30.852670,1.849396 30.468508,1.583805 30.086154,1.062313 29.875779,0.597380 29.819503,-0.205310 29.587838,-0.587406 29.579466,-1.341313 29.291887,-1.620056 29.254835,-2.215110 29.117479,-2.292211 29.024926,-2.839258 29.276384,-3.293907 29.339998,-4.499983 + + + + + Democratic Republic of the Congo + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.469674,-2.413855 30.527660,-2.807620 30.743010,-3.034310 30.752240,-3.359310 30.505540,-3.568580 30.116320,-4.090120 29.753512,-4.452389 29.339998,-4.499983 29.276384,-3.293907 29.024926,-2.839258 29.632176,-2.917858 29.938359,-2.348487 30.469674,-2.413855 + + + + + Burundi + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.419105,-1.134659 30.816135,-1.698914 30.758309,-2.287250 30.469670,-2.413830 30.469674,-2.413855 29.938359,-2.348487 29.632176,-2.917858 29.024926,-2.839258 29.117479,-2.292211 29.254835,-2.215110 29.291887,-1.620056 29.579466,-1.341313 29.821519,-1.443322 30.419105,-1.134659 + + + + + Rwanda + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 39.202220,-4.676770 37.766900,-3.677120 37.698690,-3.096990 34.072620,-1.059820 33.903711,-0.950000 33.893569,0.109814 34.180000,0.515000 34.672100,1.176940 35.035990,1.905840 34.596070,3.053740 34.479130,3.555600 34.005000,4.249885 34.620196,4.847123 35.298007,5.506000 35.817448,5.338232 35.817448,4.776966 36.159079,4.447864 36.855093,4.447864 38.120915,3.598605 38.436970,3.588510 38.671140,3.616070 38.892510,3.500740 39.559384,3.422060 39.854940,3.838790 40.768480,4.257020 41.171800,3.919090 41.855083,3.918912 40.981050,2.784520 40.993000,-0.858290 41.585130,-1.683250 40.884770,-2.082550 40.637850,-2.499790 40.263040,-2.573090 40.121190,-3.277680 39.800060,-3.681160 39.604890,-4.346530 39.202220,-4.676770 + + + + + Kenya + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 33.903711,-0.950000 34.072620,-1.059820 37.698690,-3.096990 37.766900,-3.677120 39.202220,-4.676770 38.740540,-5.908950 38.799770,-6.475660 39.440000,-6.840000 39.470000,-7.100000 39.194690,-7.703900 39.252030,-8.007810 39.186520,-8.485510 39.535740,-9.112370 39.949600,-10.098400 40.316586,-10.317098 40.316590,-10.317100 39.521000,-10.896880 38.427557,-11.285202 37.827640,-11.268790 37.471290,-11.568760 36.775151,-11.594537 36.514082,-11.720938 35.312398,-11.439146 34.559989,-11.520020 34.280000,-10.160000 33.940838,-9.693674 33.739720,-9.417150 32.759375,-9.230599 32.191865,-8.930359 31.556348,-8.762049 31.157751,-8.594579 30.740010,-8.340006 30.740015,-8.340007 30.199997,-7.079981 29.620032,-6.520015 29.419993,-5.939999 29.519987,-5.419979 29.339998,-4.499983 29.753512,-4.452389 30.116320,-4.090120 30.505540,-3.568580 30.752240,-3.359310 30.743010,-3.034310 30.527660,-2.807620 30.469674,-2.413855 30.469670,-2.413830 30.758309,-2.287250 30.816135,-1.698914 30.419105,-1.134659 30.769860,-1.014550 31.866170,-1.027360 33.903711,-0.950000 + + + + + Tanzania + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 32.759375,-9.230599 33.739720,-9.417150 33.940838,-9.693674 34.280000,-10.160000 34.559989,-11.520020 34.280006,-12.280025 34.559989,-13.579998 34.907151,-13.565425 35.267956,-13.887834 35.686845,-14.611046 35.771905,-15.896859 35.339063,-16.107440 35.033810,-16.801300 34.381292,-16.183560 34.307291,-15.478641 34.517666,-15.013709 34.459633,-14.613010 34.064825,-14.359950 33.789700,-14.451831 33.214025,-13.971860 32.688165,-13.712858 32.991764,-12.783871 33.306422,-12.435778 33.114289,-11.607198 33.315310,-10.796550 33.485688,-10.525559 33.231388,-9.676722 32.759375,-9.230599 + + + + + Malawi + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 48.948205,11.410617 48.948205,11.410617 48.942005,11.394266 48.938491,10.982327 48.938233,9.973500 48.938130,9.451749 48.486736,8.837626 47.789420,8.003000 46.948340,7.996880 43.678750,9.183580 43.296990,9.540480 42.928120,10.021940 42.558760,10.572580 42.776852,10.926879 43.145305,11.462040 43.470660,11.277710 43.666668,10.864169 44.117804,10.445538 44.614259,10.442205 45.556941,10.698029 46.645401,10.816549 47.525658,11.127228 48.021596,11.193064 48.378784,11.375482 48.948206,11.410622 48.948205,11.410617 + + + + + Somaliland + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 41.585130,-1.683250 40.993000,-0.858290 40.981050,2.784520 41.855083,3.918912 42.128610,4.234130 42.769670,4.252590 43.660870,4.957550 44.963600,5.001620 47.789420,8.003000 48.486736,8.837626 48.938130,9.451749 48.938233,9.973500 48.938491,10.982327 48.942005,11.394266 48.948205,11.410617 48.948205,11.410617 49.267760,11.430330 49.728620,11.578900 50.258780,11.679570 50.732020,12.021900 51.111200,12.024640 51.133870,11.748150 51.041530,11.166510 51.045310,10.640900 50.834180,10.279720 50.552390,9.198740 50.070920,8.081730 49.452700,6.804660 48.594550,5.339110 47.740790,4.219400 46.564760,2.855290 45.563990,2.045760 44.068150,1.052830 43.135970,0.292200 42.041570,-0.919160 41.810950,-1.446470 41.585130,-1.683250 + + + + + Somalia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 47.789420,8.003000 44.963600,5.001620 43.660870,4.957550 42.769670,4.252590 42.128610,4.234130 41.855083,3.918912 41.171800,3.919090 40.768480,4.257020 39.854940,3.838790 39.559384,3.422060 38.892510,3.500740 38.671140,3.616070 38.436970,3.588510 38.120915,3.598605 36.855093,4.447864 36.159079,4.447864 35.817448,4.776966 35.817448,5.338232 35.298007,5.506000 34.707020,6.594220 34.250320,6.826070 34.075100,7.225950 33.568290,7.713340 32.954180,7.784970 33.294800,8.354580 33.825500,8.379160 33.974980,8.684560 33.961620,9.583580 34.257450,10.630090 34.731150,10.910170 34.831630,11.318960 35.260490,12.082860 35.863630,12.578280 36.270220,13.563330 36.429510,14.422110 37.593770,14.213100 37.906070,14.959430 38.512950,14.505470 39.099400,14.740640 39.340610,14.531550 40.026250,14.519590 40.896600,14.118640 41.155200,13.773330 41.598560,13.452090 42.009750,12.865820 42.351560,12.542230 42.000000,12.100000 41.661760,11.631200 41.739590,11.355110 41.755570,11.050910 42.314140,11.034200 42.554930,11.105110 42.776852,10.926879 42.558760,10.572580 42.928120,10.021940 43.296990,9.540480 43.678750,9.183580 46.948340,7.996880 47.789420,8.003000 + + + + + Ethiopia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 42.351560,12.542230 42.779642,12.455416 43.081226,12.699639 43.317852,12.390148 43.286381,11.974928 42.715874,11.735641 43.145305,11.462040 42.776852,10.926879 42.554930,11.105110 42.314140,11.034200 41.755570,11.050910 41.739590,11.355110 41.661760,11.631200 42.000000,12.100000 42.351560,12.542230 + + + + + Djibouti + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 36.429510,14.422110 36.323220,14.822490 36.753890,16.291860 36.852530,16.956550 37.167470,17.263140 37.904000,17.427540 38.410090,17.998307 38.990623,16.840626 39.266110,15.922723 39.814294,15.435647 41.179275,14.491080 41.734952,13.921037 42.276831,13.343992 42.589576,13.000421 43.081226,12.699639 42.779642,12.455416 42.351560,12.542230 42.009750,12.865820 41.598560,13.452090 41.155200,13.773330 40.896600,14.118640 40.026250,14.519590 39.340610,14.531550 39.099400,14.740640 38.512950,14.505470 37.906070,14.959430 37.593770,14.213100 36.429510,14.422110 + + + + + Eritrea + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 36.866230,22.000000 32.900000,22.000000 29.020000,22.000000 25.000000,22.000000 25.000000,25.682500 25.000000,29.238655 24.700070,30.044190 24.957620,30.661600 24.802870,31.089290 25.164820,31.569150 26.495330,31.585680 27.457620,31.321260 28.450480,31.025770 28.913530,30.870050 29.683420,31.186860 30.095030,31.473400 30.976930,31.555860 31.687960,31.429600 31.960410,30.933600 32.192470,31.260340 32.993920,31.024070 33.773400,30.967460 34.265435,31.219357 34.265440,31.219360 34.823243,29.761081 34.922600,29.501330 34.641740,29.099420 34.426550,28.343990 34.154510,27.823300 33.921360,27.648700 33.588110,27.971360 33.136760,28.417650 32.423230,29.851080 32.320460,29.760430 32.734820,28.705230 33.348760,27.699890 34.104550,26.142270 34.473870,25.598560 34.795070,25.033750 35.692410,23.926710 35.493720,23.752370 35.525980,23.102440 36.690690,22.204850 36.866230,22.000000 + + + + + Egypt + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 25.000000,22.000000 25.000000,20.003040 23.850000,20.000000 23.837660,19.580470 19.849260,21.495090 15.860850,23.409720 14.851300,22.862950 14.143871,22.491289 13.581425,23.040506 11.999506,23.471668 11.560669,24.097909 10.771364,24.562532 10.303847,24.379313 9.948261,24.936954 9.910693,25.365455 9.319411,26.094325 9.716286,26.512206 9.629056,27.140953 9.756128,27.688259 9.683885,28.144174 9.859998,28.959990 9.805634,29.424638 9.482140,30.307556 9.970017,30.539325 10.056575,30.961831 9.950225,31.376070 10.636901,31.761421 10.944790,32.081815 11.432253,32.368903 11.488787,33.136996 12.663310,32.792780 13.083260,32.878820 13.918680,32.711960 15.245630,32.265080 15.713940,31.376260 16.611620,31.182180 18.021090,30.763570 19.086410,30.266390 19.574040,30.525820 20.053350,30.985760 19.820330,31.751790 20.133970,32.238200 20.854520,32.706800 21.542980,32.843200 22.895760,32.638580 23.236800,32.191490 23.609130,32.187260 23.927500,32.016670 24.921140,31.899360 25.164820,31.569150 24.802870,31.089290 24.957620,30.661600 24.700070,30.044190 25.000000,29.238655 25.000000,25.682500 25.000000,22.000000 + + + + + Libya + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 23.837660,19.580470 23.886890,15.610840 23.024590,15.680720 22.567950,14.944290 22.303510,14.326820 22.512020,14.093180 22.183290,13.786480 22.296580,13.372320 22.037590,12.955460 21.936810,12.588180 22.288010,12.646050 22.497620,12.260240 22.508690,11.679360 22.876220,11.384610 22.864165,11.142395 22.231129,10.971889 21.723822,10.567056 21.000868,9.475985 20.059685,9.012706 19.094008,9.074847 18.812010,8.982915 18.911022,8.630895 18.389555,8.281304 17.964930,7.890914 16.705988,7.508328 16.456185,7.734774 16.290562,7.754307 16.106232,7.497088 15.279460,7.421925 15.436092,7.692812 15.120866,8.382150 14.979996,8.796104 14.544467,8.965861 13.954218,9.549495 14.171466,10.021378 14.627201,9.920919 14.909354,9.992129 15.467873,9.982337 14.923565,10.891325 14.960152,11.555574 14.893360,12.219050 14.495787,12.859396 14.595781,13.330427 13.954477,13.353449 13.956699,13.996691 13.540394,14.367134 13.972170,15.684370 15.247731,16.627306 15.300441,17.927950 15.685741,19.957180 15.903247,20.387619 15.487148,20.730415 15.471060,21.048450 15.096888,21.308519 14.851300,22.862950 15.860850,23.409720 19.849260,21.495090 23.837660,19.580470 + + + + + Chad + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 24.567369,8.229188 23.805813,8.666319 23.459013,8.954286 23.394779,9.265068 23.557250,9.681218 23.554304,10.089255 22.977544,10.714463 22.864165,11.142395 22.876220,11.384610 22.508690,11.679360 22.497620,12.260240 22.288010,12.646050 21.936810,12.588180 22.037590,12.955460 22.296580,13.372320 22.183290,13.786480 22.512020,14.093180 22.303510,14.326820 22.567950,14.944290 23.024590,15.680720 23.886890,15.610840 23.837660,19.580470 23.850000,20.000000 25.000000,20.003040 25.000000,22.000000 29.020000,22.000000 32.900000,22.000000 36.866230,22.000000 37.188720,21.018850 36.969410,20.837440 37.114700,19.807960 37.481790,18.614090 37.862760,18.367860 38.410090,17.998307 37.904000,17.427540 37.167470,17.263140 36.852530,16.956550 36.753890,16.291860 36.323220,14.822490 36.429510,14.422110 36.270220,13.563330 35.863630,12.578280 35.260490,12.082860 34.831630,11.318960 34.731150,10.910170 34.257450,10.630090 33.961620,9.583580 33.974980,8.684560 33.963393,9.464285 33.824963,9.484061 33.842131,9.981915 33.721959,10.325262 33.206938,10.720112 33.086766,11.441141 33.206938,12.179338 32.743419,12.248008 32.674750,12.024832 32.073892,11.973330 32.314235,11.681484 32.400072,11.080626 31.850716,10.531271 31.352862,9.810241 30.837841,9.707237 29.996639,10.290927 29.618957,10.084919 29.515953,9.793074 29.000932,9.604232 28.966597,9.398224 27.970890,9.398224 27.833551,9.604232 27.112521,9.638567 26.752006,9.466893 26.477328,9.552730 25.962307,10.136421 25.790633,10.411099 25.069604,10.273760 24.794926,9.810241 24.537415,8.917538 24.194068,8.728696 23.886980,8.619730 24.567369,8.229188 + + + + + Sudan + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.833852,3.509172 29.953500,4.173699 29.715995,4.600805 29.159078,4.389267 28.696678,4.455077 28.428994,4.287155 27.979977,4.408413 27.374226,5.233944 27.213409,5.550953 26.465909,5.946717 26.213418,6.546603 25.796648,6.979316 25.124131,7.500085 25.114932,7.825104 24.567369,8.229188 23.886980,8.619730 24.194068,8.728696 24.537415,8.917538 24.794926,9.810241 25.069604,10.273760 25.790633,10.411099 25.962307,10.136421 26.477328,9.552730 26.752006,9.466893 27.112521,9.638567 27.833551,9.604232 27.970890,9.398224 28.966597,9.398224 29.000932,9.604232 29.515953,9.793074 29.618957,10.084919 29.996639,10.290927 30.837841,9.707237 31.352862,9.810241 31.850716,10.531271 32.400072,11.080626 32.314235,11.681484 32.073892,11.973330 32.674750,12.024832 32.743419,12.248008 33.206938,12.179338 33.086766,11.441141 33.206938,10.720112 33.721959,10.325262 33.842131,9.981915 33.824963,9.484061 33.963393,9.464285 33.974980,8.684560 33.825500,8.379160 33.294800,8.354580 32.954180,7.784970 33.568290,7.713340 34.075100,7.225950 34.250320,6.826070 34.707020,6.594220 35.298007,5.506000 34.620196,4.847123 34.005000,4.249885 33.390000,3.790000 32.686420,3.792320 31.881450,3.558270 31.245560,3.781900 30.833852,3.509172 + + + + + South Sudan + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 33.903711,-0.950000 31.866170,-1.027360 30.769860,-1.014550 30.419105,-1.134659 29.821519,-1.443322 29.579466,-1.341313 29.587838,-0.587406 29.819503,-0.205310 29.875779,0.597380 30.086154,1.062313 30.468508,1.583805 30.852670,1.849396 31.174149,2.204465 30.773347,2.339883 30.833860,3.509166 30.833852,3.509172 31.245560,3.781900 31.881450,3.558270 32.686420,3.792320 33.390000,3.790000 34.005000,4.249885 34.479130,3.555600 34.596070,3.053740 35.035990,1.905840 34.672100,1.176940 34.180000,0.515000 33.893569,0.109814 33.903711,-0.950000 + + + + + Uganda + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 27.374226,5.233944 27.044065,5.127853 26.402761,5.150875 25.650455,5.256088 25.278798,5.170408 25.128833,4.927245 24.805029,4.897247 24.410531,5.108784 23.297214,4.609693 22.841480,4.710126 22.704124,4.633051 22.405124,4.029160 21.659123,4.224342 20.927591,4.322786 20.290679,4.691678 19.467784,5.031528 18.932312,4.709506 18.542982,4.201785 18.453065,3.504386 17.809900,3.560196 17.133042,3.728197 16.537058,3.198255 16.012852,2.267640 15.907381,2.557389 15.862732,3.013537 15.405396,3.335301 15.036220,3.851367 14.950953,4.210389 14.478372,4.732605 14.558936,5.030598 14.459407,5.451761 14.536560,6.226959 14.776545,6.408498 15.279460,7.421925 16.106232,7.497088 16.290562,7.754307 16.456185,7.734774 16.705988,7.508328 17.964930,7.890914 18.389555,8.281304 18.911022,8.630895 18.812010,8.982915 19.094008,9.074847 20.059685,9.012706 21.000868,9.475985 21.723822,10.567056 22.231129,10.971889 22.864165,11.142395 22.977544,10.714463 23.554304,10.089255 23.557250,9.681218 23.394779,9.265068 23.459013,8.954286 23.805813,8.666319 24.567369,8.229188 25.114932,7.825104 25.124131,7.500085 25.796648,6.979316 26.213418,6.546603 26.465909,5.946717 27.213409,5.550953 27.374226,5.233944 + + + + + Central African Republic + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 14.495787,12.859396 14.893360,12.219050 14.960152,11.555574 14.923565,10.891325 15.467873,9.982337 14.909354,9.992129 14.627201,9.920919 14.171466,10.021378 13.954218,9.549495 14.544467,8.965861 14.979996,8.796104 15.120866,8.382150 15.436092,7.692812 15.279460,7.421925 14.776545,6.408498 14.536560,6.226959 14.459407,5.451761 14.558936,5.030598 14.478372,4.732605 14.950953,4.210389 15.036220,3.851367 15.405396,3.335301 15.862732,3.013537 15.907381,2.557389 16.012852,2.267640 15.940919,1.727673 15.146342,1.964015 14.337813,2.227875 13.075822,2.267097 12.951334,2.321616 12.359380,2.192812 11.751665,2.326758 11.276449,2.261051 9.649158,2.283866 9.795196,3.073404 9.404367,3.734527 8.948116,3.904129 8.744924,4.352215 8.488816,4.495617 8.500288,4.771983 8.757533,5.479666 9.233163,6.444491 9.522706,6.453482 10.118277,7.038770 10.497375,7.055358 11.058788,6.644427 11.745774,6.981383 11.839309,7.397042 12.063946,7.799808 12.218872,8.305824 12.753672,8.717763 12.955468,9.417772 13.167600,9.640626 13.308676,10.160362 13.572950,10.798566 14.415379,11.572369 14.468192,11.904752 14.577178,12.085361 14.181336,12.483657 14.213531,12.802035 14.495787,12.859396 + + + + + Cameroon + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 2.691702,6.258817 2.749063,7.870734 2.723793,8.506845 2.912308,9.137608 3.220352,9.444153 3.705438,10.063210 3.600070,10.332186 3.797112,10.734746 3.572216,11.327939 3.611180,11.660167 3.680634,12.552903 3.967283,12.956109 4.107946,13.531216 4.368344,13.747482 5.443058,13.865924 6.445426,13.492768 6.820442,13.115091 7.330747,13.098038 7.804671,13.343527 9.014933,12.826659 9.524928,12.851102 10.114814,13.277252 10.701032,13.246918 10.989593,13.387323 11.527803,13.328980 12.302071,13.037189 13.083987,13.596147 13.318702,13.556356 13.995353,12.461565 14.181336,12.483657 14.577178,12.085361 14.468192,11.904752 14.415379,11.572369 13.572950,10.798566 13.308676,10.160362 13.167600,9.640626 12.955468,9.417772 12.753672,8.717763 12.218872,8.305824 12.063946,7.799808 11.839309,7.397042 11.745774,6.981383 11.058788,6.644427 10.497375,7.055358 10.118277,7.038770 9.522706,6.453482 9.233163,6.444491 8.757533,5.479666 8.500288,4.771983 7.462108,4.412108 7.082596,4.464689 6.698072,4.240594 5.898173,4.262453 5.362805,4.887971 5.033574,5.611802 4.325607,6.270651 3.574180,6.258300 2.691702,6.258817 + + + + + Nigeria + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 9.649158,2.283866 11.276449,2.261051 11.285079,1.057662 9.830284,1.067894 9.492889,1.010120 9.305613,1.160911 9.649158,2.283866 + + + + + Equatorial Guinea + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 0.899563,10.997339 0.772336,10.470808 1.077795,10.175607 1.425061,9.825395 1.463043,9.334624 1.664478,9.128590 1.618951,6.832038 1.865241,6.142158 1.060122,5.928837 0.836931,6.279979 0.570384,6.914359 0.490957,7.411744 0.712029,8.312465 0.461192,8.677223 0.365901,9.465004 0.367580,10.191213 -0.049785,10.706918 0.023803,11.018682 0.899563,10.997339 + + + + + Togo + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 2.691702,6.258817 1.865241,6.142158 1.618951,6.832038 1.664478,9.128590 1.463043,9.334624 1.425061,9.825395 1.077795,10.175607 0.772336,10.470808 0.899563,10.997339 1.243470,11.110511 1.447178,11.547719 1.935986,11.641150 2.154474,11.940150 2.490164,12.233052 2.848643,12.235636 3.611180,11.660167 3.572216,11.327939 3.797112,10.734746 3.600070,10.332186 3.705438,10.063210 3.220352,9.444153 2.912308,9.137608 2.723793,8.506845 2.749063,7.870734 2.691702,6.258817 + + + + + Benin + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 14.851300,22.862950 15.096888,21.308519 15.471060,21.048450 15.487148,20.730415 15.903247,20.387619 15.685741,19.957180 15.300441,17.927950 15.247731,16.627306 13.972170,15.684370 13.540394,14.367134 13.956699,13.996691 13.954477,13.353449 14.595781,13.330427 14.495787,12.859396 14.213531,12.802035 14.181336,12.483657 13.995353,12.461565 13.318702,13.556356 13.083987,13.596147 12.302071,13.037189 11.527803,13.328980 10.989593,13.387323 10.701032,13.246918 10.114814,13.277252 9.524928,12.851102 9.014933,12.826659 7.804671,13.343527 7.330747,13.098038 6.820442,13.115091 6.445426,13.492768 5.443058,13.865924 4.368344,13.747482 4.107946,13.531216 3.967283,12.956109 3.680634,12.552903 3.611180,11.660167 2.848643,12.235636 2.490164,12.233052 2.154474,11.940150 2.177108,12.625018 1.024103,12.851826 0.993046,13.335750 0.429928,13.988733 0.295646,14.444235 0.374892,14.928908 1.015783,14.968182 1.385528,15.323561 2.749993,15.409525 3.638259,15.568120 3.723422,16.184284 4.270210,16.852227 4.267419,19.155265 5.677566,19.601207 8.572893,21.565661 11.999506,23.471668 13.581425,23.040506 14.143871,22.491289 14.851300,22.862950 + + + + + Niger + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 9.482140,30.307556 9.055603,32.102692 8.439103,32.506285 8.430473,32.748337 7.612642,33.344115 7.524482,34.097376 8.140981,34.655146 8.376368,35.479876 8.217824,36.433177 8.420964,36.946427 9.509994,37.349994 10.210002,37.230002 10.180650,36.724038 11.028867,37.092103 11.100026,36.899996 10.600005,36.410000 10.593287,35.947444 10.939519,35.698984 10.807847,34.833507 10.149593,34.330773 10.339659,33.785742 10.856836,33.768740 11.108501,33.293343 11.488787,33.136996 11.432253,32.368903 10.944790,32.081815 10.636901,31.761421 9.950225,31.376070 10.056575,30.961831 9.970017,30.539325 9.482140,30.307556 + + + + + Tunisia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.684400,27.395744 -8.665124,27.589479 -8.665590,27.656426 -8.674116,28.841289 -7.059228,29.579228 -6.060632,29.731700 -5.242129,30.000443 -4.859646,30.501188 -3.690441,30.896952 -3.647498,31.637294 -3.068980,31.724498 -2.616605,32.094346 -1.307899,32.262889 -1.124551,32.651522 -1.388049,32.864015 -1.733455,33.919713 -1.792986,34.527919 -2.169914,35.168396 -1.208603,35.714849 -0.127454,35.888662 0.503877,36.301273 1.466919,36.605647 3.161699,36.783905 4.815758,36.865037 5.320120,36.716519 6.261820,37.110655 7.330385,37.118381 7.737078,36.885708 8.420964,36.946427 8.217824,36.433177 8.376368,35.479876 8.140981,34.655146 7.524482,34.097376 7.612642,33.344115 8.430473,32.748337 8.439103,32.506285 9.055603,32.102692 9.482140,30.307556 9.805634,29.424638 9.859998,28.959990 9.683885,28.144174 9.756128,27.688259 9.629056,27.140953 9.716286,26.512206 9.319411,26.094325 9.910693,25.365455 9.948261,24.936954 10.303847,24.379313 10.771364,24.562532 11.560669,24.097909 11.999506,23.471668 8.572893,21.565661 5.677566,19.601207 4.267419,19.155265 3.158133,19.057364 3.146661,19.693579 2.683588,19.856230 2.060991,20.142233 1.823228,20.610809 -1.550055,22.792666 -4.923337,24.974574 -8.684400,27.395744 + + + + + Algeria + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -2.169914,35.168396 -1.792986,34.527919 -1.733455,33.919713 -1.388049,32.864015 -1.124551,32.651522 -1.307899,32.262889 -2.616605,32.094346 -3.068980,31.724498 -3.647498,31.637294 -3.690441,30.896952 -4.859646,30.501188 -5.242129,30.000443 -6.060632,29.731700 -7.059228,29.579228 -8.674116,28.841289 -8.665590,27.656426 -8.817828,27.656426 -8.794884,27.120696 -9.413037,27.088476 -9.735343,26.860945 -10.189424,26.860945 -10.551263,26.990808 -11.392555,26.883424 -11.718220,26.104092 -12.030759,26.030866 -12.500963,24.770116 -13.891110,23.691009 -14.221168,22.310163 -14.630833,21.860940 -14.750955,21.500600 -17.002962,21.420734 -17.020428,21.422310 -16.973248,21.885745 -16.589137,22.158234 -16.261922,22.679340 -16.326414,23.017768 -15.982611,23.723358 -15.426004,24.359134 -15.089332,24.520261 -14.824645,25.103533 -14.800926,25.636265 -14.439940,26.254418 -13.773805,26.618892 -13.139942,27.640148 -13.121613,27.654148 -12.618837,28.038186 -11.688919,28.148644 -10.900957,28.832142 -10.399592,29.098586 -9.564811,29.933574 -9.814718,31.177736 -9.434793,32.038096 -9.300693,32.564679 -8.657476,33.240245 -7.654178,33.697065 -6.912544,34.110476 -6.244342,35.145865 -5.929994,35.759988 -5.193863,35.755182 -4.591006,35.330712 -3.640057,35.399855 -2.604306,35.179093 -2.169914,35.168396 + + + + + Morocco + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.665590,27.656426 -8.665124,27.589479 -8.684400,27.395744 -8.687294,25.881056 -11.969419,25.933353 -11.937224,23.374594 -12.874222,23.284832 -13.118754,22.771220 -12.929102,21.327071 -16.845194,21.333323 -17.063423,20.999752 -17.020428,21.422310 -17.002962,21.420734 -14.750955,21.500600 -14.630833,21.860940 -14.221168,22.310163 -13.891110,23.691009 -12.500963,24.770116 -12.030759,26.030866 -11.718220,26.104092 -11.392555,26.883424 -10.551263,26.990808 -10.189424,26.860945 -9.735343,26.860945 -9.413037,27.088476 -8.794884,27.120696 -8.817828,27.656426 -8.665590,27.656426 + + + + + Western Sahara + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -17.063423,20.999752 -16.845194,21.333323 -12.929102,21.327071 -13.118754,22.771220 -12.874222,23.284832 -11.937224,23.374594 -11.969419,25.933353 -8.687294,25.881056 -8.684400,27.395744 -4.923337,24.974574 -6.453787,24.956591 -5.971129,20.640833 -5.488523,16.325102 -5.315277,16.201854 -5.537744,15.501690 -9.550238,15.486497 -9.700255,15.264107 -10.086846,15.330486 -10.650791,15.132746 -11.349095,15.411256 -11.666078,15.388208 -11.834208,14.799097 -12.170750,14.616834 -12.830658,15.303692 -13.435738,16.039383 -14.099521,16.304302 -14.577348,16.598264 -15.135737,16.587282 -15.623666,16.369337 -16.120690,16.455663 -16.463098,16.135036 -16.549708,16.673892 -16.270552,17.166963 -16.146347,18.108482 -16.256883,19.096716 -16.377651,19.593817 -16.277838,20.092521 -16.536324,20.567866 -17.063423,20.999752 + + + + + Mauritania + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.677452,12.384852 -16.147717,12.547762 -15.816574,12.515567 -15.548477,12.628170 -13.700476,12.586183 -13.718744,12.247186 -13.828272,12.142644 -13.743161,11.811269 -13.900800,11.678719 -14.121406,11.677117 -14.382192,11.509272 -14.685687,11.527824 -15.130311,11.040412 -15.664180,11.458474 -16.085214,11.524594 -16.314787,11.806515 -16.308947,11.958702 -16.613838,12.170911 -16.677452,12.384852 + + + + + Guinea-Bissau + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.713729,13.594959 -15.624596,13.623587 -15.398770,13.860369 -15.081735,13.876492 -14.687031,13.630357 -14.376714,13.625680 -14.046992,13.794068 -13.844963,13.505042 -14.277702,13.280585 -14.712197,13.298207 -15.141163,13.509512 -15.511813,13.278570 -15.691001,13.270353 -15.931296,13.130284 -16.841525,13.151394 -16.713729,13.594959 + + + + + The Gambia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.713729,13.594959 -17.126107,14.373516 -17.625043,14.729541 -17.185173,14.919477 -16.700706,15.621527 -16.463098,16.135036 -16.120690,16.455663 -15.623666,16.369337 -15.135737,16.587282 -14.577348,16.598264 -14.099521,16.304302 -13.435738,16.039383 -12.830658,15.303692 -12.170750,14.616834 -12.124887,13.994727 -11.927716,13.422075 -11.553398,13.141214 -11.467899,12.754519 -11.513943,12.442988 -11.658301,12.386583 -12.203565,12.465648 -12.278599,12.354440 -12.499051,12.332090 -13.217818,12.575874 -13.700476,12.586183 -15.548477,12.628170 -15.816574,12.515567 -16.147717,12.547762 -16.677452,12.384852 -16.841525,13.151394 -15.931296,13.130284 -15.691001,13.270353 -15.511813,13.278570 -15.141163,13.509512 -14.712197,13.298207 -14.277702,13.280585 -13.844963,13.505042 -14.046992,13.794068 -14.376714,13.625680 -14.687031,13.630357 -15.081735,13.876492 -15.398770,13.860369 -15.624596,13.623587 -16.713729,13.594959 + + + + + Senegal + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -11.513943,12.442988 -11.467899,12.754519 -11.553398,13.141214 -11.927716,13.422075 -12.124887,13.994727 -12.170750,14.616834 -11.834208,14.799097 -11.666078,15.388208 -11.349095,15.411256 -10.650791,15.132746 -10.086846,15.330486 -9.700255,15.264107 -9.550238,15.486497 -5.537744,15.501690 -5.315277,16.201854 -5.488523,16.325102 -5.971129,20.640833 -6.453787,24.956591 -4.923337,24.974574 -1.550055,22.792666 1.823228,20.610809 2.060991,20.142233 2.683588,19.856230 3.146661,19.693579 3.158133,19.057364 4.267419,19.155265 4.270210,16.852227 3.723422,16.184284 3.638259,15.568120 2.749993,15.409525 1.385528,15.323561 1.015783,14.968182 0.374892,14.928908 -0.266257,14.924309 -0.515854,15.116158 -1.066363,14.973815 -2.001035,14.559008 -2.191825,14.246418 -2.967694,13.798150 -3.103707,13.541267 -3.522803,13.337662 -4.006391,13.472485 -4.280405,13.228444 -4.427166,12.542646 -5.220942,11.713859 -5.197843,11.375146 -5.470565,10.951270 -5.404342,10.370737 -5.816926,10.222555 -6.050452,10.096361 -6.205223,10.524061 -6.493965,10.411303 -6.666461,10.430811 -6.850507,10.138994 -7.622759,10.147236 -7.899590,10.297382 -8.029944,10.206535 -8.335377,10.494812 -8.282357,10.792597 -8.407311,10.909257 -8.620321,10.810891 -8.581305,11.136246 -8.376305,11.393646 -8.786099,11.812561 -8.905265,12.088358 -9.127474,12.308060 -9.327616,12.334286 -9.567912,12.194243 -9.890993,12.060479 -10.165214,11.844084 -10.593224,11.923975 -10.870830,12.177887 -11.036556,12.211245 -11.297574,12.077971 -11.456169,12.076834 -11.513943,12.442988 + + + + + Mali + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -5.404342,10.370737 -5.470565,10.951270 -5.197843,11.375146 -5.220942,11.713859 -4.427166,12.542646 -4.280405,13.228444 -4.006391,13.472485 -3.522803,13.337662 -3.103707,13.541267 -2.967694,13.798150 -2.191825,14.246418 -2.001035,14.559008 -1.066363,14.973815 -0.515854,15.116158 -0.266257,14.924309 0.374892,14.928908 0.295646,14.444235 0.429928,13.988733 0.993046,13.335750 1.024103,12.851826 2.177108,12.625018 2.154474,11.940150 1.935986,11.641150 1.447178,11.547719 1.243470,11.110511 0.899563,10.997339 0.023803,11.018682 -0.438702,11.098341 -0.761576,10.936930 -1.203358,11.009819 -2.940409,10.962690 -2.963896,10.395335 -2.827496,9.642461 -3.511899,9.900326 -3.980449,9.862344 -4.330247,9.610835 -4.779884,9.821985 -4.954653,10.152714 -5.404342,10.370737 + + + + + Burkina Faso + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.029944,10.206535 -7.899590,10.297382 -7.622759,10.147236 -6.850507,10.138994 -6.666461,10.430811 -6.493965,10.411303 -6.205223,10.524061 -6.050452,10.096361 -5.816926,10.222555 -5.404342,10.370737 -4.954653,10.152714 -4.779884,9.821985 -4.330247,9.610835 -3.980449,9.862344 -3.511899,9.900326 -2.827496,9.642461 -2.562190,8.219628 -2.983585,7.379705 -3.244370,6.250472 -2.810701,5.389051 -2.856125,4.994476 -3.311084,4.984296 -4.008820,5.179813 -4.649917,5.168264 -5.834496,4.993701 -6.528769,4.705088 -7.518941,4.338288 -7.712159,4.364566 -7.635368,5.188159 -7.539715,5.313345 -7.570153,5.707352 -7.993693,6.126190 -8.311348,6.193033 -8.602880,6.467564 -8.385452,6.911801 -8.485446,7.395208 -8.439298,7.686043 -8.280703,7.687180 -8.221792,8.123329 -8.299049,8.316444 -8.203499,8.455453 -7.832100,8.575704 -8.079114,9.376224 -8.309616,9.789532 -8.229337,10.129020 -8.029944,10.206535 + + + + + Ivory Coast + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 0.023803,11.018682 -0.049785,10.706918 0.367580,10.191213 0.365901,9.465004 0.461192,8.677223 0.712029,8.312465 0.490957,7.411744 0.570384,6.914359 0.836931,6.279979 1.060122,5.928837 -0.507638,5.343473 -1.063625,5.000548 -1.964707,4.710462 -2.856125,4.994476 -2.810701,5.389051 -3.244370,6.250472 -2.983585,7.379705 -2.562190,8.219628 -2.827496,9.642461 -2.963896,10.395335 -2.940409,10.962690 -1.203358,11.009819 -0.761576,10.936930 -0.438702,11.098341 0.023803,11.018682 + + + + + Ghana + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.439298,7.686043 -8.485446,7.395208 -8.385452,6.911801 -8.602880,6.467564 -8.311348,6.193033 -7.993693,6.126190 -7.570153,5.707352 -7.539715,5.313345 -7.635368,5.188159 -7.712159,4.364566 -7.974107,4.355755 -9.004794,4.832419 -9.913420,5.593561 -10.765384,6.140711 -11.438779,6.785917 -11.199802,7.105846 -11.146704,7.396706 -10.695595,7.939464 -10.230094,8.406206 -10.016567,8.428504 -9.755342,8.541055 -9.337280,7.928534 -9.403348,7.526905 -9.208786,7.313921 -8.926065,7.309037 -8.722124,7.711674 -8.439298,7.686043 + + + + + Liberia + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -13.246550,8.903049 -12.711958,9.342712 -12.596719,9.620188 -12.425929,9.835834 -12.150338,9.858572 -11.917277,10.046984 -11.117481,10.045873 -10.839152,9.688246 -10.622395,9.267910 -10.654770,8.977178 -10.494315,8.715541 -10.505477,8.348896 -10.230094,8.406206 -10.695595,7.939464 -11.146704,7.396706 -11.199802,7.105846 -11.438779,6.785917 -11.708195,6.860098 -12.428099,7.262942 -12.949049,7.798646 -13.124025,8.163946 -13.246550,8.903049 + + + + + Sierra Leone + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -13.700476,12.586183 -13.217818,12.575874 -12.499051,12.332090 -12.278599,12.354440 -12.203565,12.465648 -11.658301,12.386583 -11.513943,12.442988 -11.456169,12.076834 -11.297574,12.077971 -11.036556,12.211245 -10.870830,12.177887 -10.593224,11.923975 -10.165214,11.844084 -9.890993,12.060479 -9.567912,12.194243 -9.327616,12.334286 -9.127474,12.308060 -8.905265,12.088358 -8.786099,11.812561 -8.376305,11.393646 -8.581305,11.136246 -8.620321,10.810891 -8.407311,10.909257 -8.282357,10.792597 -8.335377,10.494812 -8.029944,10.206535 -8.229337,10.129020 -8.309616,9.789532 -8.079114,9.376224 -7.832100,8.575704 -8.203499,8.455453 -8.299049,8.316444 -8.221792,8.123329 -8.280703,7.687180 -8.439298,7.686043 -8.722124,7.711674 -8.926065,7.309037 -9.208786,7.313921 -9.403348,7.526905 -9.337280,7.928534 -9.755342,8.541055 -10.016567,8.428504 -10.230094,8.406206 -10.505477,8.348896 -10.494315,8.715541 -10.654770,8.977178 -10.622395,9.267910 -10.839152,9.688246 -11.117481,10.045873 -11.917277,10.046984 -12.150338,9.858572 -12.425929,9.835834 -12.596719,9.620188 -12.711958,9.342712 -13.246550,8.903049 -13.685154,9.494744 -14.074045,9.886167 -14.330076,10.015720 -14.579699,10.214467 -14.693232,10.656301 -14.839554,10.876572 -15.130311,11.040412 -14.685687,11.527824 -14.382192,11.509272 -14.121406,11.677117 -13.900800,11.678719 -13.743161,11.811269 -13.828272,12.142644 -13.718744,12.247186 -13.700476,12.586183 + + + + + Guinea + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 11.276449,2.261051 11.751665,2.326758 12.359380,2.192812 12.951334,2.321616 13.075822,2.267097 13.003114,1.830896 13.282631,1.314184 14.026669,1.395677 14.276266,1.196930 13.843321,0.038758 14.316418,-0.552627 14.425456,-1.333407 14.299210,-1.998276 13.992407,-2.470805 13.109619,-2.428740 12.575284,-1.948511 12.495703,-2.391688 11.820964,-2.514161 11.478039,-2.765619 11.855122,-3.426871 11.093773,-3.978827 10.066135,-2.969483 9.405245,-2.144313 8.797996,-1.111301 8.830087,-0.779074 9.048420,-0.459351 9.291351,0.268666 9.492889,1.010120 9.830284,1.067894 11.285079,1.057662 11.276449,2.261051 + + + + + Gabon + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 18.453065,3.504386 18.393792,2.900443 18.094276,2.365722 17.898835,1.741832 17.774192,0.855659 17.826540,0.288923 17.663553,-0.058084 17.638645,-0.424832 17.523716,-0.743830 16.865307,-1.225816 16.407092,-1.740927 15.972803,-2.712392 16.006290,-3.535133 15.753540,-3.855165 15.170992,-4.343507 14.582604,-4.970239 14.209035,-4.793092 14.144956,-4.510009 13.600235,-4.500138 13.258240,-4.882957 12.995517,-4.781103 12.620760,-4.438023 12.318608,-4.606230 11.914963,-5.037987 11.093773,-3.978827 11.855122,-3.426871 11.478039,-2.765619 11.820964,-2.514161 12.495703,-2.391688 12.575284,-1.948511 13.109619,-2.428740 13.992407,-2.470805 14.299210,-1.998276 14.425456,-1.333407 14.316418,-0.552627 13.843321,0.038758 14.276266,1.196930 14.026669,1.395677 13.282631,1.314184 13.003114,1.830896 13.075822,2.267097 14.337813,2.227875 15.146342,1.964015 15.940919,1.727673 16.012852,2.267640 16.537058,3.198255 17.133042,3.728197 17.809900,3.560196 18.453065,3.504386 + + + + + Republic of the Congo + + + + diff --git a/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname.xml b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname.xml new file mode 100644 index 0000000000..5c3f08daeb --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-get-feature-propertyname.xml @@ -0,0 +1,273 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + Madagascar + + + + + Mozambique + + + + + eSwatini + + + + + Lesotho + + + + + South Africa + + + + + Botswana + + + + + Namibia + + + + + Zimbabwe + + + + + Zambia + + + + + Angola + + + + + Democratic Republic of the Congo + + + + + Burundi + + + + + Rwanda + + + + + Kenya + + + + + Tanzania + + + + + Malawi + + + + + Somaliland + + + + + Somalia + + + + + Ethiopia + + + + + Djibouti + + + + + Eritrea + + + + + Egypt + + + + + Libya + + + + + Chad + + + + + Sudan + + + + + South Sudan + + + + + Uganda + + + + + Central African Republic + + + + + Cameroon + + + + + Nigeria + + + + + Equatorial Guinea + + + + + Togo + + + + + Benin + + + + + Niger + + + + + Tunisia + + + + + Algeria + + + + + Morocco + + + + + Western Sahara + + + + + Mauritania + + + + + Guinea-Bissau + + + + + The Gambia + + + + + Senegal + + + + + Mali + + + + + Burkina Faso + + + + + Ivory Coast + + + + + Ghana + + + + + Liberia + + + + + Sierra Leone + + + + + Guinea + + + + + Gabon + + + + + Republic of the Congo + + + + diff --git a/msautotest/misc/expected/flatgeobuf-wfs-get-feature.xml b/msautotest/misc/expected/flatgeobuf-wfs-get-feature.xml new file mode 100644 index 0000000000..94ad259ce2 --- /dev/null +++ b/msautotest/misc/expected/flatgeobuf-wfs-get-feature.xml @@ -0,0 +1,1111 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 49.543519,-12.469833 49.808981,-12.895285 50.056511,-13.555761 50.217431,-14.758789 50.476537,-15.226512 50.377111,-15.706069 50.200275,-16.000263 49.860606,-15.414253 49.672607,-15.710204 49.863344,-16.451037 49.774564,-16.875042 49.498612,-17.106036 49.435619,-17.953064 49.041792,-19.118781 48.548541,-20.496888 47.930749,-22.391501 47.547723,-23.781959 47.095761,-24.941630 46.282478,-25.178463 45.409508,-25.601434 44.833574,-25.346101 44.039720,-24.988345 43.763768,-24.460677 43.697778,-23.574116 43.345654,-22.776904 43.254187,-22.057413 43.433298,-21.336475 43.893683,-21.163307 43.896370,-20.830459 44.374325,-20.072366 44.464397,-19.435454 44.232422,-18.961995 44.042976,-18.331387 43.963084,-17.409945 44.312469,-16.850496 44.446517,-16.216219 44.944937,-16.179374 45.502732,-15.974373 45.872994,-15.793454 46.312243,-15.780018 46.882183,-15.210182 47.705130,-14.594303 48.005215,-14.091233 47.869047,-13.663869 48.293828,-13.784068 48.845060,-13.089175 48.863509,-12.487868 49.194651,-12.040557 49.543519,-12.469833 + + + + + 25054161 + Madagascar + 1 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 34.559989,-11.520020 35.312398,-11.439146 36.514082,-11.720938 36.775151,-11.594537 37.471290,-11.568760 37.827640,-11.268790 38.427557,-11.285202 39.521000,-10.896880 40.316590,-10.317100 40.316586,-10.317098 40.316589,-10.317096 40.478387,-10.765441 40.437253,-11.761711 40.560811,-12.639177 40.599620,-14.201975 40.775475,-14.691764 40.477251,-15.406294 40.089264,-16.100774 39.452559,-16.720891 38.538351,-17.101023 37.411133,-17.586368 36.281279,-18.659688 35.896497,-18.842260 35.198400,-19.552811 34.786383,-19.784012 34.701893,-20.497043 35.176127,-21.254361 35.373428,-21.840837 35.385848,-22.140000 35.562546,-22.090000 35.533935,-23.070788 35.371774,-23.535359 35.607470,-23.706563 35.458746,-24.122610 35.040735,-24.478351 34.215824,-24.816314 33.013210,-25.357573 32.574632,-25.727318 32.660363,-26.148584 32.915955,-26.215867 32.830120,-26.742192 32.071665,-26.733820 31.985779,-26.291780 31.837778,-25.843332 31.752408,-25.484284 31.930589,-24.369417 31.670398,-23.658969 31.191409,-22.251510 32.244988,-21.116489 32.508693,-20.395292 32.659743,-20.304290 32.772708,-19.715592 32.611994,-19.419383 32.654886,-18.672090 32.849861,-17.979057 32.847639,-16.713398 32.328239,-16.392074 31.852041,-16.319417 31.636498,-16.071990 31.173064,-15.860944 30.338955,-15.880839 30.274256,-15.507787 30.179481,-14.796099 33.214025,-13.971860 33.789700,-14.451831 34.064825,-14.359950 34.459633,-14.613010 34.517666,-15.013709 34.307291,-15.478641 34.381292,-16.183560 35.033810,-16.801300 35.339063,-16.107440 35.771905,-15.896859 35.686845,-14.611046 35.267956,-13.887834 34.907151,-13.565425 34.559989,-13.579998 34.280006,-12.280025 34.559989,-11.520020 + + + + + 26573706 + Mozambique + 2 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 32.071665,-26.733820 31.868060,-27.177927 31.282773,-27.285879 30.685962,-26.743845 30.676609,-26.398078 30.949667,-26.022649 31.044080,-25.731452 31.333158,-25.660191 31.837778,-25.843332 31.985779,-26.291780 32.071665,-26.733820 + + + + + 1467152 + eSwatini + 3 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 28.978263,-28.955597 29.325166,-29.257387 29.018415,-29.743766 28.848400,-30.070051 28.291069,-30.226217 28.107205,-30.545732 27.749397,-30.645106 26.999262,-29.875954 27.532511,-29.242711 28.074338,-28.851469 28.541700,-28.647502 28.978263,-28.955597 + + + + + 1958042 + Lesotho + 4 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + + + 16.344977,-28.576705 16.824017,-28.082162 17.218929,-28.355943 17.387497,-28.783514 17.836152,-28.856378 18.464899,-29.045462 19.002127,-28.972443 19.894734,-28.461105 19.895768,-24.767790 20.165726,-24.917962 20.758609,-25.868136 20.666470,-26.477453 20.889609,-26.828543 21.605896,-26.726534 22.105969,-26.280256 22.579532,-25.979448 22.824271,-25.500459 23.312097,-25.268690 23.733570,-25.390129 24.211267,-25.670216 25.025171,-25.719670 25.664666,-25.486816 25.765849,-25.174845 25.941652,-24.696373 26.485753,-24.616327 26.786407,-24.240691 27.119410,-23.574323 28.017236,-22.827754 29.432188,-22.091313 29.839037,-22.102216 30.322883,-22.271612 30.659865,-22.151567 31.191409,-22.251510 31.670398,-23.658969 31.930589,-24.369417 31.752408,-25.484284 31.837778,-25.843332 31.333158,-25.660191 31.044080,-25.731452 30.949667,-26.022649 30.676609,-26.398078 30.685962,-26.743845 31.282773,-27.285879 31.868060,-27.177927 32.071665,-26.733820 32.830120,-26.742192 32.580265,-27.470158 32.462133,-28.301011 32.203389,-28.752405 31.521001,-29.257387 31.325561,-29.401978 30.901763,-29.909957 30.622813,-30.423776 30.055716,-31.140269 28.925553,-32.172041 28.219756,-32.771953 27.464608,-33.226964 26.419452,-33.614950 25.909664,-33.667040 25.780628,-33.944646 25.172862,-33.796851 24.677853,-33.987176 23.594043,-33.794474 22.988189,-33.916431 22.574157,-33.864083 21.542799,-34.258839 20.689053,-34.417175 20.071261,-34.795137 19.616405,-34.819166 19.193278,-34.462599 18.855315,-34.444306 18.424643,-33.997873 18.377411,-34.136521 18.244499,-33.867752 18.250080,-33.281431 17.925190,-32.611291 18.247910,-32.429131 18.221762,-31.661633 17.566918,-30.725721 17.064416,-29.878641 17.062918,-29.875954 16.344977,-28.576705 + + + + + 28.978263,-28.955597 28.541700,-28.647502 28.074338,-28.851469 27.532511,-29.242711 26.999262,-29.875954 27.749397,-30.645106 28.107205,-30.545732 28.291069,-30.226217 28.848400,-30.070051 29.018415,-29.743766 29.325166,-29.257387 28.978263,-28.955597 + + + + + + + 54841552 + South Africa + 5 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 29.432188,-22.091313 28.017236,-22.827754 27.119410,-23.574323 26.786407,-24.240691 26.485753,-24.616327 25.941652,-24.696373 25.765849,-25.174845 25.664666,-25.486816 25.025171,-25.719670 24.211267,-25.670216 23.733570,-25.390129 23.312097,-25.268690 22.824271,-25.500459 22.579532,-25.979448 22.105969,-26.280256 21.605896,-26.726534 20.889609,-26.828543 20.666470,-26.477453 20.758609,-25.868136 20.165726,-24.917962 19.895768,-24.767790 19.895458,-21.849157 20.881134,-21.814327 20.910641,-18.252219 21.655040,-18.219146 23.196858,-17.869038 23.579006,-18.281261 24.217365,-17.889347 24.520705,-17.887125 25.084443,-17.661816 25.264226,-17.736540 25.649163,-18.536026 25.850391,-18.714413 26.164791,-19.293086 27.296505,-20.391520 27.724747,-20.499059 27.727228,-20.851802 28.021370,-21.485975 28.794656,-21.639454 29.432188,-22.091313 + + + + + 2214858 + Botswana + 6 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 19.895768,-24.767790 19.894734,-28.461105 19.002127,-28.972443 18.464899,-29.045462 17.836152,-28.856378 17.387497,-28.783514 17.218929,-28.355943 16.824017,-28.082162 16.344977,-28.576705 15.601818,-27.821247 15.210472,-27.090956 14.989711,-26.117372 14.743214,-25.392920 14.408144,-23.853014 14.385717,-22.656653 14.257714,-22.111208 13.868642,-21.699037 13.352498,-20.872834 12.826845,-19.673166 12.608564,-19.045349 11.794919,-18.069129 11.734199,-17.301889 12.215461,-17.111668 12.814081,-16.941343 13.462362,-16.971212 14.058501,-17.423381 14.209707,-17.353101 18.263309,-17.309951 18.956187,-17.789095 21.377176,-17.930636 23.215048,-17.523116 24.033862,-17.295843 24.682349,-17.353411 25.076950,-17.578823 25.084443,-17.661816 24.520705,-17.887125 24.217365,-17.889347 23.579006,-18.281261 23.196858,-17.869038 21.655040,-18.219146 20.910641,-18.252219 20.881134,-21.814327 19.895458,-21.849157 19.895768,-24.767790 + + + + + 2484780 + Namibia + 7 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 31.191409,-22.251510 30.659865,-22.151567 30.322883,-22.271612 29.839037,-22.102216 29.432188,-22.091313 28.794656,-21.639454 28.021370,-21.485975 27.727228,-20.851802 27.724747,-20.499059 27.296505,-20.391520 26.164791,-19.293086 25.850391,-18.714413 25.649163,-18.536026 25.264226,-17.736540 26.381935,-17.846042 26.706773,-17.961229 27.044427,-17.938026 27.598243,-17.290831 28.467906,-16.468400 28.825869,-16.389749 28.947463,-16.043051 29.516834,-15.644678 30.274256,-15.507787 30.338955,-15.880839 31.173064,-15.860944 31.636498,-16.071990 31.852041,-16.319417 32.328239,-16.392074 32.847639,-16.713398 32.849861,-17.979057 32.654886,-18.672090 32.611994,-19.419383 32.772708,-19.715592 32.659743,-20.304290 32.508693,-20.395292 32.244988,-21.116489 31.191409,-22.251510 + + + + + 13805084 + Zimbabwe + 8 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.740010,-8.340006 31.157751,-8.594579 31.556348,-8.762049 32.191865,-8.930359 32.759375,-9.230599 33.231388,-9.676722 33.485688,-10.525559 33.315310,-10.796550 33.114289,-11.607198 33.306422,-12.435778 32.991764,-12.783871 32.688165,-13.712858 33.214025,-13.971860 30.179481,-14.796099 30.274256,-15.507787 29.516834,-15.644678 28.947463,-16.043051 28.825869,-16.389749 28.467906,-16.468400 27.598243,-17.290831 27.044427,-17.938026 26.706773,-17.961229 26.381935,-17.846042 25.264226,-17.736540 25.084443,-17.661816 25.076950,-17.578823 24.682349,-17.353411 24.033862,-17.295843 23.215048,-17.523116 22.562478,-16.898451 21.887843,-16.080310 21.933886,-12.898437 24.016137,-12.911046 23.930922,-12.565848 24.079905,-12.191297 23.904154,-11.722282 24.017894,-11.237298 23.912215,-10.926826 24.257155,-10.951993 24.314516,-11.262826 24.783170,-11.238694 25.418118,-11.330936 25.752310,-11.784965 26.553088,-11.924440 27.164420,-11.608748 27.388799,-12.132747 28.155109,-12.272481 28.523562,-12.698604 28.934286,-13.248958 29.699614,-13.257227 29.616001,-12.178895 29.341548,-12.360744 28.642417,-11.971569 28.372253,-11.793647 28.496070,-10.789884 28.673682,-9.605925 28.449871,-9.164918 28.734867,-8.526559 29.002912,-8.407032 30.346086,-8.238257 30.740010,-8.340006 + + + + + 15972000 + Zambia + 9 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + + + 12.995517,-4.781103 12.631612,-4.991271 12.468004,-5.248362 12.436688,-5.684304 12.182337,-5.789931 11.914963,-5.037987 12.318608,-4.606230 12.620760,-4.438023 12.995517,-4.781103 + + + + + + + + + 12.322432,-6.100092 12.735171,-5.965682 13.024869,-5.984389 13.375597,-5.864241 16.326528,-5.877470 16.573180,-6.622645 16.860191,-7.222298 17.089996,-7.545689 17.472970,-8.068551 18.134222,-7.987678 18.464176,-7.847014 19.016752,-7.988246 19.166613,-7.738184 19.417502,-7.155429 20.037723,-7.116361 20.091622,-6.943090 20.601823,-6.939318 20.514748,-7.299606 21.728111,-7.290872 21.746456,-7.920085 21.949131,-8.305901 21.801801,-8.908707 21.875182,-9.523708 22.208753,-9.894796 22.155268,-11.084801 22.402798,-10.993075 22.837345,-11.017622 23.456791,-10.867863 23.912215,-10.926826 24.017894,-11.237298 23.904154,-11.722282 24.079905,-12.191297 23.930922,-12.565848 24.016137,-12.911046 21.933886,-12.898437 21.887843,-16.080310 22.562478,-16.898451 23.215048,-17.523116 21.377176,-17.930636 18.956187,-17.789095 18.263309,-17.309951 14.209707,-17.353101 14.058501,-17.423381 13.462362,-16.971212 12.814081,-16.941343 12.215461,-17.111668 11.734199,-17.301889 11.640096,-16.673142 11.778537,-15.793816 12.123581,-14.878316 12.175619,-14.449144 12.500095,-13.547700 12.738479,-13.137906 13.312914,-12.483630 13.633721,-12.038645 13.738728,-11.297863 13.686379,-10.731076 13.387328,-10.373578 13.120988,-9.766897 12.875370,-9.166934 12.929061,-8.959091 13.236433,-8.562629 12.933040,-7.596539 12.728298,-6.927122 12.227347,-6.294448 12.322432,-6.100092 + + + + + + + 29310273 + Angola + 10 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 29.339998,-4.499983 29.519987,-5.419979 29.419993,-5.939999 29.620032,-6.520015 30.199997,-7.079981 30.740015,-8.340007 30.740010,-8.340006 30.346086,-8.238257 29.002912,-8.407032 28.734867,-8.526559 28.449871,-9.164918 28.673682,-9.605925 28.496070,-10.789884 28.372253,-11.793647 28.642417,-11.971569 29.341548,-12.360744 29.616001,-12.178895 29.699614,-13.257227 28.934286,-13.248958 28.523562,-12.698604 28.155109,-12.272481 27.388799,-12.132747 27.164420,-11.608748 26.553088,-11.924440 25.752310,-11.784965 25.418118,-11.330936 24.783170,-11.238694 24.314516,-11.262826 24.257155,-10.951993 23.912215,-10.926826 23.456791,-10.867863 22.837345,-11.017622 22.402798,-10.993075 22.155268,-11.084801 22.208753,-9.894796 21.875182,-9.523708 21.801801,-8.908707 21.949131,-8.305901 21.746456,-7.920085 21.728111,-7.290872 20.514748,-7.299606 20.601823,-6.939318 20.091622,-6.943090 20.037723,-7.116361 19.417502,-7.155429 19.166613,-7.738184 19.016752,-7.988246 18.464176,-7.847014 18.134222,-7.987678 17.472970,-8.068551 17.089996,-7.545689 16.860191,-7.222298 16.573180,-6.622645 16.326528,-5.877470 13.375597,-5.864241 13.024869,-5.984389 12.735171,-5.965682 12.322432,-6.100092 12.182337,-5.789931 12.436688,-5.684304 12.468004,-5.248362 12.631612,-4.991271 12.995517,-4.781103 13.258240,-4.882957 13.600235,-4.500138 14.144956,-4.510009 14.209035,-4.793092 14.582604,-4.970239 15.170992,-4.343507 15.753540,-3.855165 16.006290,-3.535133 15.972803,-2.712392 16.407092,-1.740927 16.865307,-1.225816 17.523716,-0.743830 17.638645,-0.424832 17.663553,-0.058084 17.826540,0.288923 17.774192,0.855659 17.898835,1.741832 18.094276,2.365722 18.393792,2.900443 18.453065,3.504386 18.542982,4.201785 18.932312,4.709506 19.467784,5.031528 20.290679,4.691678 20.927591,4.322786 21.659123,4.224342 22.405124,4.029160 22.704124,4.633051 22.841480,4.710126 23.297214,4.609693 24.410531,5.108784 24.805029,4.897247 25.128833,4.927245 25.278798,5.170408 25.650455,5.256088 26.402761,5.150875 27.044065,5.127853 27.374226,5.233944 27.979977,4.408413 28.428994,4.287155 28.696678,4.455077 29.159078,4.389267 29.715995,4.600805 29.953500,4.173699 30.833852,3.509172 30.833860,3.509166 30.773347,2.339883 31.174149,2.204465 30.852670,1.849396 30.468508,1.583805 30.086154,1.062313 29.875779,0.597380 29.819503,-0.205310 29.587838,-0.587406 29.579466,-1.341313 29.291887,-1.620056 29.254835,-2.215110 29.117479,-2.292211 29.024926,-2.839258 29.276384,-3.293907 29.339998,-4.499983 + + + + + 83301151 + Democratic Republic of the Congo + 11 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.469674,-2.413855 30.527660,-2.807620 30.743010,-3.034310 30.752240,-3.359310 30.505540,-3.568580 30.116320,-4.090120 29.753512,-4.452389 29.339998,-4.499983 29.276384,-3.293907 29.024926,-2.839258 29.632176,-2.917858 29.938359,-2.348487 30.469674,-2.413855 + + + + + 11466756 + Burundi + 12 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.419105,-1.134659 30.816135,-1.698914 30.758309,-2.287250 30.469670,-2.413830 30.469674,-2.413855 29.938359,-2.348487 29.632176,-2.917858 29.024926,-2.839258 29.117479,-2.292211 29.254835,-2.215110 29.291887,-1.620056 29.579466,-1.341313 29.821519,-1.443322 30.419105,-1.134659 + + + + + 11901484 + Rwanda + 13 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 39.202220,-4.676770 37.766900,-3.677120 37.698690,-3.096990 34.072620,-1.059820 33.903711,-0.950000 33.893569,0.109814 34.180000,0.515000 34.672100,1.176940 35.035990,1.905840 34.596070,3.053740 34.479130,3.555600 34.005000,4.249885 34.620196,4.847123 35.298007,5.506000 35.817448,5.338232 35.817448,4.776966 36.159079,4.447864 36.855093,4.447864 38.120915,3.598605 38.436970,3.588510 38.671140,3.616070 38.892510,3.500740 39.559384,3.422060 39.854940,3.838790 40.768480,4.257020 41.171800,3.919090 41.855083,3.918912 40.981050,2.784520 40.993000,-0.858290 41.585130,-1.683250 40.884770,-2.082550 40.637850,-2.499790 40.263040,-2.573090 40.121190,-3.277680 39.800060,-3.681160 39.604890,-4.346530 39.202220,-4.676770 + + + + + 47615739 + Kenya + 14 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 33.903711,-0.950000 34.072620,-1.059820 37.698690,-3.096990 37.766900,-3.677120 39.202220,-4.676770 38.740540,-5.908950 38.799770,-6.475660 39.440000,-6.840000 39.470000,-7.100000 39.194690,-7.703900 39.252030,-8.007810 39.186520,-8.485510 39.535740,-9.112370 39.949600,-10.098400 40.316586,-10.317098 40.316590,-10.317100 39.521000,-10.896880 38.427557,-11.285202 37.827640,-11.268790 37.471290,-11.568760 36.775151,-11.594537 36.514082,-11.720938 35.312398,-11.439146 34.559989,-11.520020 34.280000,-10.160000 33.940838,-9.693674 33.739720,-9.417150 32.759375,-9.230599 32.191865,-8.930359 31.556348,-8.762049 31.157751,-8.594579 30.740010,-8.340006 30.740015,-8.340007 30.199997,-7.079981 29.620032,-6.520015 29.419993,-5.939999 29.519987,-5.419979 29.339998,-4.499983 29.753512,-4.452389 30.116320,-4.090120 30.505540,-3.568580 30.752240,-3.359310 30.743010,-3.034310 30.527660,-2.807620 30.469674,-2.413855 30.469670,-2.413830 30.758309,-2.287250 30.816135,-1.698914 30.419105,-1.134659 30.769860,-1.014550 31.866170,-1.027360 33.903711,-0.950000 + + + + + 53950935 + Tanzania + 15 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 32.759375,-9.230599 33.739720,-9.417150 33.940838,-9.693674 34.280000,-10.160000 34.559989,-11.520020 34.280006,-12.280025 34.559989,-13.579998 34.907151,-13.565425 35.267956,-13.887834 35.686845,-14.611046 35.771905,-15.896859 35.339063,-16.107440 35.033810,-16.801300 34.381292,-16.183560 34.307291,-15.478641 34.517666,-15.013709 34.459633,-14.613010 34.064825,-14.359950 33.789700,-14.451831 33.214025,-13.971860 32.688165,-13.712858 32.991764,-12.783871 33.306422,-12.435778 33.114289,-11.607198 33.315310,-10.796550 33.485688,-10.525559 33.231388,-9.676722 32.759375,-9.230599 + + + + + 19196246 + Malawi + 16 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 48.948205,11.410617 48.948205,11.410617 48.942005,11.394266 48.938491,10.982327 48.938233,9.973500 48.938130,9.451749 48.486736,8.837626 47.789420,8.003000 46.948340,7.996880 43.678750,9.183580 43.296990,9.540480 42.928120,10.021940 42.558760,10.572580 42.776852,10.926879 43.145305,11.462040 43.470660,11.277710 43.666668,10.864169 44.117804,10.445538 44.614259,10.442205 45.556941,10.698029 46.645401,10.816549 47.525658,11.127228 48.021596,11.193064 48.378784,11.375482 48.948206,11.410622 48.948205,11.410617 + + + + + 3500000 + Somaliland + 17 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 41.585130,-1.683250 40.993000,-0.858290 40.981050,2.784520 41.855083,3.918912 42.128610,4.234130 42.769670,4.252590 43.660870,4.957550 44.963600,5.001620 47.789420,8.003000 48.486736,8.837626 48.938130,9.451749 48.938233,9.973500 48.938491,10.982327 48.942005,11.394266 48.948205,11.410617 48.948205,11.410617 49.267760,11.430330 49.728620,11.578900 50.258780,11.679570 50.732020,12.021900 51.111200,12.024640 51.133870,11.748150 51.041530,11.166510 51.045310,10.640900 50.834180,10.279720 50.552390,9.198740 50.070920,8.081730 49.452700,6.804660 48.594550,5.339110 47.740790,4.219400 46.564760,2.855290 45.563990,2.045760 44.068150,1.052830 43.135970,0.292200 42.041570,-0.919160 41.810950,-1.446470 41.585130,-1.683250 + + + + + 7531386 + Somalia + 18 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 47.789420,8.003000 44.963600,5.001620 43.660870,4.957550 42.769670,4.252590 42.128610,4.234130 41.855083,3.918912 41.171800,3.919090 40.768480,4.257020 39.854940,3.838790 39.559384,3.422060 38.892510,3.500740 38.671140,3.616070 38.436970,3.588510 38.120915,3.598605 36.855093,4.447864 36.159079,4.447864 35.817448,4.776966 35.817448,5.338232 35.298007,5.506000 34.707020,6.594220 34.250320,6.826070 34.075100,7.225950 33.568290,7.713340 32.954180,7.784970 33.294800,8.354580 33.825500,8.379160 33.974980,8.684560 33.961620,9.583580 34.257450,10.630090 34.731150,10.910170 34.831630,11.318960 35.260490,12.082860 35.863630,12.578280 36.270220,13.563330 36.429510,14.422110 37.593770,14.213100 37.906070,14.959430 38.512950,14.505470 39.099400,14.740640 39.340610,14.531550 40.026250,14.519590 40.896600,14.118640 41.155200,13.773330 41.598560,13.452090 42.009750,12.865820 42.351560,12.542230 42.000000,12.100000 41.661760,11.631200 41.739590,11.355110 41.755570,11.050910 42.314140,11.034200 42.554930,11.105110 42.776852,10.926879 42.558760,10.572580 42.928120,10.021940 43.296990,9.540480 43.678750,9.183580 46.948340,7.996880 47.789420,8.003000 + + + + + 105350020 + Ethiopia + 19 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 42.351560,12.542230 42.779642,12.455416 43.081226,12.699639 43.317852,12.390148 43.286381,11.974928 42.715874,11.735641 43.145305,11.462040 42.776852,10.926879 42.554930,11.105110 42.314140,11.034200 41.755570,11.050910 41.739590,11.355110 41.661760,11.631200 42.000000,12.100000 42.351560,12.542230 + + + + + 865267 + Djibouti + 20 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 36.429510,14.422110 36.323220,14.822490 36.753890,16.291860 36.852530,16.956550 37.167470,17.263140 37.904000,17.427540 38.410090,17.998307 38.990623,16.840626 39.266110,15.922723 39.814294,15.435647 41.179275,14.491080 41.734952,13.921037 42.276831,13.343992 42.589576,13.000421 43.081226,12.699639 42.779642,12.455416 42.351560,12.542230 42.009750,12.865820 41.598560,13.452090 41.155200,13.773330 40.896600,14.118640 40.026250,14.519590 39.340610,14.531550 39.099400,14.740640 38.512950,14.505470 37.906070,14.959430 37.593770,14.213100 36.429510,14.422110 + + + + + 5918919 + Eritrea + 21 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 36.866230,22.000000 32.900000,22.000000 29.020000,22.000000 25.000000,22.000000 25.000000,25.682500 25.000000,29.238655 24.700070,30.044190 24.957620,30.661600 24.802870,31.089290 25.164820,31.569150 26.495330,31.585680 27.457620,31.321260 28.450480,31.025770 28.913530,30.870050 29.683420,31.186860 30.095030,31.473400 30.976930,31.555860 31.687960,31.429600 31.960410,30.933600 32.192470,31.260340 32.993920,31.024070 33.773400,30.967460 34.265435,31.219357 34.265440,31.219360 34.823243,29.761081 34.922600,29.501330 34.641740,29.099420 34.426550,28.343990 34.154510,27.823300 33.921360,27.648700 33.588110,27.971360 33.136760,28.417650 32.423230,29.851080 32.320460,29.760430 32.734820,28.705230 33.348760,27.699890 34.104550,26.142270 34.473870,25.598560 34.795070,25.033750 35.692410,23.926710 35.493720,23.752370 35.525980,23.102440 36.690690,22.204850 36.866230,22.000000 + + + + + 97041072 + Egypt + 22 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 25.000000,22.000000 25.000000,20.003040 23.850000,20.000000 23.837660,19.580470 19.849260,21.495090 15.860850,23.409720 14.851300,22.862950 14.143871,22.491289 13.581425,23.040506 11.999506,23.471668 11.560669,24.097909 10.771364,24.562532 10.303847,24.379313 9.948261,24.936954 9.910693,25.365455 9.319411,26.094325 9.716286,26.512206 9.629056,27.140953 9.756128,27.688259 9.683885,28.144174 9.859998,28.959990 9.805634,29.424638 9.482140,30.307556 9.970017,30.539325 10.056575,30.961831 9.950225,31.376070 10.636901,31.761421 10.944790,32.081815 11.432253,32.368903 11.488787,33.136996 12.663310,32.792780 13.083260,32.878820 13.918680,32.711960 15.245630,32.265080 15.713940,31.376260 16.611620,31.182180 18.021090,30.763570 19.086410,30.266390 19.574040,30.525820 20.053350,30.985760 19.820330,31.751790 20.133970,32.238200 20.854520,32.706800 21.542980,32.843200 22.895760,32.638580 23.236800,32.191490 23.609130,32.187260 23.927500,32.016670 24.921140,31.899360 25.164820,31.569150 24.802870,31.089290 24.957620,30.661600 24.700070,30.044190 25.000000,29.238655 25.000000,25.682500 25.000000,22.000000 + + + + + 6653210 + Libya + 23 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 23.837660,19.580470 23.886890,15.610840 23.024590,15.680720 22.567950,14.944290 22.303510,14.326820 22.512020,14.093180 22.183290,13.786480 22.296580,13.372320 22.037590,12.955460 21.936810,12.588180 22.288010,12.646050 22.497620,12.260240 22.508690,11.679360 22.876220,11.384610 22.864165,11.142395 22.231129,10.971889 21.723822,10.567056 21.000868,9.475985 20.059685,9.012706 19.094008,9.074847 18.812010,8.982915 18.911022,8.630895 18.389555,8.281304 17.964930,7.890914 16.705988,7.508328 16.456185,7.734774 16.290562,7.754307 16.106232,7.497088 15.279460,7.421925 15.436092,7.692812 15.120866,8.382150 14.979996,8.796104 14.544467,8.965861 13.954218,9.549495 14.171466,10.021378 14.627201,9.920919 14.909354,9.992129 15.467873,9.982337 14.923565,10.891325 14.960152,11.555574 14.893360,12.219050 14.495787,12.859396 14.595781,13.330427 13.954477,13.353449 13.956699,13.996691 13.540394,14.367134 13.972170,15.684370 15.247731,16.627306 15.300441,17.927950 15.685741,19.957180 15.903247,20.387619 15.487148,20.730415 15.471060,21.048450 15.096888,21.308519 14.851300,22.862950 15.860850,23.409720 19.849260,21.495090 23.837660,19.580470 + + + + + 12075985 + Chad + 24 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 24.567369,8.229188 23.805813,8.666319 23.459013,8.954286 23.394779,9.265068 23.557250,9.681218 23.554304,10.089255 22.977544,10.714463 22.864165,11.142395 22.876220,11.384610 22.508690,11.679360 22.497620,12.260240 22.288010,12.646050 21.936810,12.588180 22.037590,12.955460 22.296580,13.372320 22.183290,13.786480 22.512020,14.093180 22.303510,14.326820 22.567950,14.944290 23.024590,15.680720 23.886890,15.610840 23.837660,19.580470 23.850000,20.000000 25.000000,20.003040 25.000000,22.000000 29.020000,22.000000 32.900000,22.000000 36.866230,22.000000 37.188720,21.018850 36.969410,20.837440 37.114700,19.807960 37.481790,18.614090 37.862760,18.367860 38.410090,17.998307 37.904000,17.427540 37.167470,17.263140 36.852530,16.956550 36.753890,16.291860 36.323220,14.822490 36.429510,14.422110 36.270220,13.563330 35.863630,12.578280 35.260490,12.082860 34.831630,11.318960 34.731150,10.910170 34.257450,10.630090 33.961620,9.583580 33.974980,8.684560 33.963393,9.464285 33.824963,9.484061 33.842131,9.981915 33.721959,10.325262 33.206938,10.720112 33.086766,11.441141 33.206938,12.179338 32.743419,12.248008 32.674750,12.024832 32.073892,11.973330 32.314235,11.681484 32.400072,11.080626 31.850716,10.531271 31.352862,9.810241 30.837841,9.707237 29.996639,10.290927 29.618957,10.084919 29.515953,9.793074 29.000932,9.604232 28.966597,9.398224 27.970890,9.398224 27.833551,9.604232 27.112521,9.638567 26.752006,9.466893 26.477328,9.552730 25.962307,10.136421 25.790633,10.411099 25.069604,10.273760 24.794926,9.810241 24.537415,8.917538 24.194068,8.728696 23.886980,8.619730 24.567369,8.229188 + + + + + 37345935 + Sudan + 25 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 30.833852,3.509172 29.953500,4.173699 29.715995,4.600805 29.159078,4.389267 28.696678,4.455077 28.428994,4.287155 27.979977,4.408413 27.374226,5.233944 27.213409,5.550953 26.465909,5.946717 26.213418,6.546603 25.796648,6.979316 25.124131,7.500085 25.114932,7.825104 24.567369,8.229188 23.886980,8.619730 24.194068,8.728696 24.537415,8.917538 24.794926,9.810241 25.069604,10.273760 25.790633,10.411099 25.962307,10.136421 26.477328,9.552730 26.752006,9.466893 27.112521,9.638567 27.833551,9.604232 27.970890,9.398224 28.966597,9.398224 29.000932,9.604232 29.515953,9.793074 29.618957,10.084919 29.996639,10.290927 30.837841,9.707237 31.352862,9.810241 31.850716,10.531271 32.400072,11.080626 32.314235,11.681484 32.073892,11.973330 32.674750,12.024832 32.743419,12.248008 33.206938,12.179338 33.086766,11.441141 33.206938,10.720112 33.721959,10.325262 33.842131,9.981915 33.824963,9.484061 33.963393,9.464285 33.974980,8.684560 33.825500,8.379160 33.294800,8.354580 32.954180,7.784970 33.568290,7.713340 34.075100,7.225950 34.250320,6.826070 34.707020,6.594220 35.298007,5.506000 34.620196,4.847123 34.005000,4.249885 33.390000,3.790000 32.686420,3.792320 31.881450,3.558270 31.245560,3.781900 30.833852,3.509172 + + + + + 13026129 + South Sudan + 26 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 33.903711,-0.950000 31.866170,-1.027360 30.769860,-1.014550 30.419105,-1.134659 29.821519,-1.443322 29.579466,-1.341313 29.587838,-0.587406 29.819503,-0.205310 29.875779,0.597380 30.086154,1.062313 30.468508,1.583805 30.852670,1.849396 31.174149,2.204465 30.773347,2.339883 30.833860,3.509166 30.833852,3.509172 31.245560,3.781900 31.881450,3.558270 32.686420,3.792320 33.390000,3.790000 34.005000,4.249885 34.479130,3.555600 34.596070,3.053740 35.035990,1.905840 34.672100,1.176940 34.180000,0.515000 33.893569,0.109814 33.903711,-0.950000 + + + + + 39570125 + Uganda + 27 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 27.374226,5.233944 27.044065,5.127853 26.402761,5.150875 25.650455,5.256088 25.278798,5.170408 25.128833,4.927245 24.805029,4.897247 24.410531,5.108784 23.297214,4.609693 22.841480,4.710126 22.704124,4.633051 22.405124,4.029160 21.659123,4.224342 20.927591,4.322786 20.290679,4.691678 19.467784,5.031528 18.932312,4.709506 18.542982,4.201785 18.453065,3.504386 17.809900,3.560196 17.133042,3.728197 16.537058,3.198255 16.012852,2.267640 15.907381,2.557389 15.862732,3.013537 15.405396,3.335301 15.036220,3.851367 14.950953,4.210389 14.478372,4.732605 14.558936,5.030598 14.459407,5.451761 14.536560,6.226959 14.776545,6.408498 15.279460,7.421925 16.106232,7.497088 16.290562,7.754307 16.456185,7.734774 16.705988,7.508328 17.964930,7.890914 18.389555,8.281304 18.911022,8.630895 18.812010,8.982915 19.094008,9.074847 20.059685,9.012706 21.000868,9.475985 21.723822,10.567056 22.231129,10.971889 22.864165,11.142395 22.977544,10.714463 23.554304,10.089255 23.557250,9.681218 23.394779,9.265068 23.459013,8.954286 23.805813,8.666319 24.567369,8.229188 25.114932,7.825104 25.124131,7.500085 25.796648,6.979316 26.213418,6.546603 26.465909,5.946717 27.213409,5.550953 27.374226,5.233944 + + + + + 5625118 + Central African Republic + 28 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 14.495787,12.859396 14.893360,12.219050 14.960152,11.555574 14.923565,10.891325 15.467873,9.982337 14.909354,9.992129 14.627201,9.920919 14.171466,10.021378 13.954218,9.549495 14.544467,8.965861 14.979996,8.796104 15.120866,8.382150 15.436092,7.692812 15.279460,7.421925 14.776545,6.408498 14.536560,6.226959 14.459407,5.451761 14.558936,5.030598 14.478372,4.732605 14.950953,4.210389 15.036220,3.851367 15.405396,3.335301 15.862732,3.013537 15.907381,2.557389 16.012852,2.267640 15.940919,1.727673 15.146342,1.964015 14.337813,2.227875 13.075822,2.267097 12.951334,2.321616 12.359380,2.192812 11.751665,2.326758 11.276449,2.261051 9.649158,2.283866 9.795196,3.073404 9.404367,3.734527 8.948116,3.904129 8.744924,4.352215 8.488816,4.495617 8.500288,4.771983 8.757533,5.479666 9.233163,6.444491 9.522706,6.453482 10.118277,7.038770 10.497375,7.055358 11.058788,6.644427 11.745774,6.981383 11.839309,7.397042 12.063946,7.799808 12.218872,8.305824 12.753672,8.717763 12.955468,9.417772 13.167600,9.640626 13.308676,10.160362 13.572950,10.798566 14.415379,11.572369 14.468192,11.904752 14.577178,12.085361 14.181336,12.483657 14.213531,12.802035 14.495787,12.859396 + + + + + 24994885 + Cameroon + 29 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 2.691702,6.258817 2.749063,7.870734 2.723793,8.506845 2.912308,9.137608 3.220352,9.444153 3.705438,10.063210 3.600070,10.332186 3.797112,10.734746 3.572216,11.327939 3.611180,11.660167 3.680634,12.552903 3.967283,12.956109 4.107946,13.531216 4.368344,13.747482 5.443058,13.865924 6.445426,13.492768 6.820442,13.115091 7.330747,13.098038 7.804671,13.343527 9.014933,12.826659 9.524928,12.851102 10.114814,13.277252 10.701032,13.246918 10.989593,13.387323 11.527803,13.328980 12.302071,13.037189 13.083987,13.596147 13.318702,13.556356 13.995353,12.461565 14.181336,12.483657 14.577178,12.085361 14.468192,11.904752 14.415379,11.572369 13.572950,10.798566 13.308676,10.160362 13.167600,9.640626 12.955468,9.417772 12.753672,8.717763 12.218872,8.305824 12.063946,7.799808 11.839309,7.397042 11.745774,6.981383 11.058788,6.644427 10.497375,7.055358 10.118277,7.038770 9.522706,6.453482 9.233163,6.444491 8.757533,5.479666 8.500288,4.771983 7.462108,4.412108 7.082596,4.464689 6.698072,4.240594 5.898173,4.262453 5.362805,4.887971 5.033574,5.611802 4.325607,6.270651 3.574180,6.258300 2.691702,6.258817 + + + + + 190632261 + Nigeria + 30 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 9.649158,2.283866 11.276449,2.261051 11.285079,1.057662 9.830284,1.067894 9.492889,1.010120 9.305613,1.160911 9.649158,2.283866 + + + + + 778358 + Equatorial Guinea + 31 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 0.899563,10.997339 0.772336,10.470808 1.077795,10.175607 1.425061,9.825395 1.463043,9.334624 1.664478,9.128590 1.618951,6.832038 1.865241,6.142158 1.060122,5.928837 0.836931,6.279979 0.570384,6.914359 0.490957,7.411744 0.712029,8.312465 0.461192,8.677223 0.365901,9.465004 0.367580,10.191213 -0.049785,10.706918 0.023803,11.018682 0.899563,10.997339 + + + + + 7965055 + Togo + 32 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 2.691702,6.258817 1.865241,6.142158 1.618951,6.832038 1.664478,9.128590 1.463043,9.334624 1.425061,9.825395 1.077795,10.175607 0.772336,10.470808 0.899563,10.997339 1.243470,11.110511 1.447178,11.547719 1.935986,11.641150 2.154474,11.940150 2.490164,12.233052 2.848643,12.235636 3.611180,11.660167 3.572216,11.327939 3.797112,10.734746 3.600070,10.332186 3.705438,10.063210 3.220352,9.444153 2.912308,9.137608 2.723793,8.506845 2.749063,7.870734 2.691702,6.258817 + + + + + 11038805 + Benin + 33 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 14.851300,22.862950 15.096888,21.308519 15.471060,21.048450 15.487148,20.730415 15.903247,20.387619 15.685741,19.957180 15.300441,17.927950 15.247731,16.627306 13.972170,15.684370 13.540394,14.367134 13.956699,13.996691 13.954477,13.353449 14.595781,13.330427 14.495787,12.859396 14.213531,12.802035 14.181336,12.483657 13.995353,12.461565 13.318702,13.556356 13.083987,13.596147 12.302071,13.037189 11.527803,13.328980 10.989593,13.387323 10.701032,13.246918 10.114814,13.277252 9.524928,12.851102 9.014933,12.826659 7.804671,13.343527 7.330747,13.098038 6.820442,13.115091 6.445426,13.492768 5.443058,13.865924 4.368344,13.747482 4.107946,13.531216 3.967283,12.956109 3.680634,12.552903 3.611180,11.660167 2.848643,12.235636 2.490164,12.233052 2.154474,11.940150 2.177108,12.625018 1.024103,12.851826 0.993046,13.335750 0.429928,13.988733 0.295646,14.444235 0.374892,14.928908 1.015783,14.968182 1.385528,15.323561 2.749993,15.409525 3.638259,15.568120 3.723422,16.184284 4.270210,16.852227 4.267419,19.155265 5.677566,19.601207 8.572893,21.565661 11.999506,23.471668 13.581425,23.040506 14.143871,22.491289 14.851300,22.862950 + + + + + 19245344 + Niger + 34 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 9.482140,30.307556 9.055603,32.102692 8.439103,32.506285 8.430473,32.748337 7.612642,33.344115 7.524482,34.097376 8.140981,34.655146 8.376368,35.479876 8.217824,36.433177 8.420964,36.946427 9.509994,37.349994 10.210002,37.230002 10.180650,36.724038 11.028867,37.092103 11.100026,36.899996 10.600005,36.410000 10.593287,35.947444 10.939519,35.698984 10.807847,34.833507 10.149593,34.330773 10.339659,33.785742 10.856836,33.768740 11.108501,33.293343 11.488787,33.136996 11.432253,32.368903 10.944790,32.081815 10.636901,31.761421 9.950225,31.376070 10.056575,30.961831 9.970017,30.539325 9.482140,30.307556 + + + + + 11403800 + Tunisia + 35 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.684400,27.395744 -8.665124,27.589479 -8.665590,27.656426 -8.674116,28.841289 -7.059228,29.579228 -6.060632,29.731700 -5.242129,30.000443 -4.859646,30.501188 -3.690441,30.896952 -3.647498,31.637294 -3.068980,31.724498 -2.616605,32.094346 -1.307899,32.262889 -1.124551,32.651522 -1.388049,32.864015 -1.733455,33.919713 -1.792986,34.527919 -2.169914,35.168396 -1.208603,35.714849 -0.127454,35.888662 0.503877,36.301273 1.466919,36.605647 3.161699,36.783905 4.815758,36.865037 5.320120,36.716519 6.261820,37.110655 7.330385,37.118381 7.737078,36.885708 8.420964,36.946427 8.217824,36.433177 8.376368,35.479876 8.140981,34.655146 7.524482,34.097376 7.612642,33.344115 8.430473,32.748337 8.439103,32.506285 9.055603,32.102692 9.482140,30.307556 9.805634,29.424638 9.859998,28.959990 9.683885,28.144174 9.756128,27.688259 9.629056,27.140953 9.716286,26.512206 9.319411,26.094325 9.910693,25.365455 9.948261,24.936954 10.303847,24.379313 10.771364,24.562532 11.560669,24.097909 11.999506,23.471668 8.572893,21.565661 5.677566,19.601207 4.267419,19.155265 3.158133,19.057364 3.146661,19.693579 2.683588,19.856230 2.060991,20.142233 1.823228,20.610809 -1.550055,22.792666 -4.923337,24.974574 -8.684400,27.395744 + + + + + 40969443 + Algeria + 36 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -2.169914,35.168396 -1.792986,34.527919 -1.733455,33.919713 -1.388049,32.864015 -1.124551,32.651522 -1.307899,32.262889 -2.616605,32.094346 -3.068980,31.724498 -3.647498,31.637294 -3.690441,30.896952 -4.859646,30.501188 -5.242129,30.000443 -6.060632,29.731700 -7.059228,29.579228 -8.674116,28.841289 -8.665590,27.656426 -8.817828,27.656426 -8.794884,27.120696 -9.413037,27.088476 -9.735343,26.860945 -10.189424,26.860945 -10.551263,26.990808 -11.392555,26.883424 -11.718220,26.104092 -12.030759,26.030866 -12.500963,24.770116 -13.891110,23.691009 -14.221168,22.310163 -14.630833,21.860940 -14.750955,21.500600 -17.002962,21.420734 -17.020428,21.422310 -16.973248,21.885745 -16.589137,22.158234 -16.261922,22.679340 -16.326414,23.017768 -15.982611,23.723358 -15.426004,24.359134 -15.089332,24.520261 -14.824645,25.103533 -14.800926,25.636265 -14.439940,26.254418 -13.773805,26.618892 -13.139942,27.640148 -13.121613,27.654148 -12.618837,28.038186 -11.688919,28.148644 -10.900957,28.832142 -10.399592,29.098586 -9.564811,29.933574 -9.814718,31.177736 -9.434793,32.038096 -9.300693,32.564679 -8.657476,33.240245 -7.654178,33.697065 -6.912544,34.110476 -6.244342,35.145865 -5.929994,35.759988 -5.193863,35.755182 -4.591006,35.330712 -3.640057,35.399855 -2.604306,35.179093 -2.169914,35.168396 + + + + + 33986655 + Morocco + 37 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.665590,27.656426 -8.665124,27.589479 -8.684400,27.395744 -8.687294,25.881056 -11.969419,25.933353 -11.937224,23.374594 -12.874222,23.284832 -13.118754,22.771220 -12.929102,21.327071 -16.845194,21.333323 -17.063423,20.999752 -17.020428,21.422310 -17.002962,21.420734 -14.750955,21.500600 -14.630833,21.860940 -14.221168,22.310163 -13.891110,23.691009 -12.500963,24.770116 -12.030759,26.030866 -11.718220,26.104092 -11.392555,26.883424 -10.551263,26.990808 -10.189424,26.860945 -9.735343,26.860945 -9.413037,27.088476 -8.794884,27.120696 -8.817828,27.656426 -8.665590,27.656426 + + + + + 603253 + Western Sahara + 38 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -17.063423,20.999752 -16.845194,21.333323 -12.929102,21.327071 -13.118754,22.771220 -12.874222,23.284832 -11.937224,23.374594 -11.969419,25.933353 -8.687294,25.881056 -8.684400,27.395744 -4.923337,24.974574 -6.453787,24.956591 -5.971129,20.640833 -5.488523,16.325102 -5.315277,16.201854 -5.537744,15.501690 -9.550238,15.486497 -9.700255,15.264107 -10.086846,15.330486 -10.650791,15.132746 -11.349095,15.411256 -11.666078,15.388208 -11.834208,14.799097 -12.170750,14.616834 -12.830658,15.303692 -13.435738,16.039383 -14.099521,16.304302 -14.577348,16.598264 -15.135737,16.587282 -15.623666,16.369337 -16.120690,16.455663 -16.463098,16.135036 -16.549708,16.673892 -16.270552,17.166963 -16.146347,18.108482 -16.256883,19.096716 -16.377651,19.593817 -16.277838,20.092521 -16.536324,20.567866 -17.063423,20.999752 + + + + + 3758571 + Mauritania + 39 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.677452,12.384852 -16.147717,12.547762 -15.816574,12.515567 -15.548477,12.628170 -13.700476,12.586183 -13.718744,12.247186 -13.828272,12.142644 -13.743161,11.811269 -13.900800,11.678719 -14.121406,11.677117 -14.382192,11.509272 -14.685687,11.527824 -15.130311,11.040412 -15.664180,11.458474 -16.085214,11.524594 -16.314787,11.806515 -16.308947,11.958702 -16.613838,12.170911 -16.677452,12.384852 + + + + + 1792338 + Guinea-Bissau + 40 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.713729,13.594959 -15.624596,13.623587 -15.398770,13.860369 -15.081735,13.876492 -14.687031,13.630357 -14.376714,13.625680 -14.046992,13.794068 -13.844963,13.505042 -14.277702,13.280585 -14.712197,13.298207 -15.141163,13.509512 -15.511813,13.278570 -15.691001,13.270353 -15.931296,13.130284 -16.841525,13.151394 -16.713729,13.594959 + + + + + 2051363 + The Gambia + 41 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -16.713729,13.594959 -17.126107,14.373516 -17.625043,14.729541 -17.185173,14.919477 -16.700706,15.621527 -16.463098,16.135036 -16.120690,16.455663 -15.623666,16.369337 -15.135737,16.587282 -14.577348,16.598264 -14.099521,16.304302 -13.435738,16.039383 -12.830658,15.303692 -12.170750,14.616834 -12.124887,13.994727 -11.927716,13.422075 -11.553398,13.141214 -11.467899,12.754519 -11.513943,12.442988 -11.658301,12.386583 -12.203565,12.465648 -12.278599,12.354440 -12.499051,12.332090 -13.217818,12.575874 -13.700476,12.586183 -15.548477,12.628170 -15.816574,12.515567 -16.147717,12.547762 -16.677452,12.384852 -16.841525,13.151394 -15.931296,13.130284 -15.691001,13.270353 -15.511813,13.278570 -15.141163,13.509512 -14.712197,13.298207 -14.277702,13.280585 -13.844963,13.505042 -14.046992,13.794068 -14.376714,13.625680 -14.687031,13.630357 -15.081735,13.876492 -15.398770,13.860369 -15.624596,13.623587 -16.713729,13.594959 + + + + + 14668522 + Senegal + 42 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -11.513943,12.442988 -11.467899,12.754519 -11.553398,13.141214 -11.927716,13.422075 -12.124887,13.994727 -12.170750,14.616834 -11.834208,14.799097 -11.666078,15.388208 -11.349095,15.411256 -10.650791,15.132746 -10.086846,15.330486 -9.700255,15.264107 -9.550238,15.486497 -5.537744,15.501690 -5.315277,16.201854 -5.488523,16.325102 -5.971129,20.640833 -6.453787,24.956591 -4.923337,24.974574 -1.550055,22.792666 1.823228,20.610809 2.060991,20.142233 2.683588,19.856230 3.146661,19.693579 3.158133,19.057364 4.267419,19.155265 4.270210,16.852227 3.723422,16.184284 3.638259,15.568120 2.749993,15.409525 1.385528,15.323561 1.015783,14.968182 0.374892,14.928908 -0.266257,14.924309 -0.515854,15.116158 -1.066363,14.973815 -2.001035,14.559008 -2.191825,14.246418 -2.967694,13.798150 -3.103707,13.541267 -3.522803,13.337662 -4.006391,13.472485 -4.280405,13.228444 -4.427166,12.542646 -5.220942,11.713859 -5.197843,11.375146 -5.470565,10.951270 -5.404342,10.370737 -5.816926,10.222555 -6.050452,10.096361 -6.205223,10.524061 -6.493965,10.411303 -6.666461,10.430811 -6.850507,10.138994 -7.622759,10.147236 -7.899590,10.297382 -8.029944,10.206535 -8.335377,10.494812 -8.282357,10.792597 -8.407311,10.909257 -8.620321,10.810891 -8.581305,11.136246 -8.376305,11.393646 -8.786099,11.812561 -8.905265,12.088358 -9.127474,12.308060 -9.327616,12.334286 -9.567912,12.194243 -9.890993,12.060479 -10.165214,11.844084 -10.593224,11.923975 -10.870830,12.177887 -11.036556,12.211245 -11.297574,12.077971 -11.456169,12.076834 -11.513943,12.442988 + + + + + 17885245 + Mali + 43 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -5.404342,10.370737 -5.470565,10.951270 -5.197843,11.375146 -5.220942,11.713859 -4.427166,12.542646 -4.280405,13.228444 -4.006391,13.472485 -3.522803,13.337662 -3.103707,13.541267 -2.967694,13.798150 -2.191825,14.246418 -2.001035,14.559008 -1.066363,14.973815 -0.515854,15.116158 -0.266257,14.924309 0.374892,14.928908 0.295646,14.444235 0.429928,13.988733 0.993046,13.335750 1.024103,12.851826 2.177108,12.625018 2.154474,11.940150 1.935986,11.641150 1.447178,11.547719 1.243470,11.110511 0.899563,10.997339 0.023803,11.018682 -0.438702,11.098341 -0.761576,10.936930 -1.203358,11.009819 -2.940409,10.962690 -2.963896,10.395335 -2.827496,9.642461 -3.511899,9.900326 -3.980449,9.862344 -4.330247,9.610835 -4.779884,9.821985 -4.954653,10.152714 -5.404342,10.370737 + + + + + 20107509 + Burkina Faso + 44 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.029944,10.206535 -7.899590,10.297382 -7.622759,10.147236 -6.850507,10.138994 -6.666461,10.430811 -6.493965,10.411303 -6.205223,10.524061 -6.050452,10.096361 -5.816926,10.222555 -5.404342,10.370737 -4.954653,10.152714 -4.779884,9.821985 -4.330247,9.610835 -3.980449,9.862344 -3.511899,9.900326 -2.827496,9.642461 -2.562190,8.219628 -2.983585,7.379705 -3.244370,6.250472 -2.810701,5.389051 -2.856125,4.994476 -3.311084,4.984296 -4.008820,5.179813 -4.649917,5.168264 -5.834496,4.993701 -6.528769,4.705088 -7.518941,4.338288 -7.712159,4.364566 -7.635368,5.188159 -7.539715,5.313345 -7.570153,5.707352 -7.993693,6.126190 -8.311348,6.193033 -8.602880,6.467564 -8.385452,6.911801 -8.485446,7.395208 -8.439298,7.686043 -8.280703,7.687180 -8.221792,8.123329 -8.299049,8.316444 -8.203499,8.455453 -7.832100,8.575704 -8.079114,9.376224 -8.309616,9.789532 -8.229337,10.129020 -8.029944,10.206535 + + + + + 24184810 + Ivory Coast + 45 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 0.023803,11.018682 -0.049785,10.706918 0.367580,10.191213 0.365901,9.465004 0.461192,8.677223 0.712029,8.312465 0.490957,7.411744 0.570384,6.914359 0.836931,6.279979 1.060122,5.928837 -0.507638,5.343473 -1.063625,5.000548 -1.964707,4.710462 -2.856125,4.994476 -2.810701,5.389051 -3.244370,6.250472 -2.983585,7.379705 -2.562190,8.219628 -2.827496,9.642461 -2.963896,10.395335 -2.940409,10.962690 -1.203358,11.009819 -0.761576,10.936930 -0.438702,11.098341 0.023803,11.018682 + + + + + 27499924 + Ghana + 46 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -8.439298,7.686043 -8.485446,7.395208 -8.385452,6.911801 -8.602880,6.467564 -8.311348,6.193033 -7.993693,6.126190 -7.570153,5.707352 -7.539715,5.313345 -7.635368,5.188159 -7.712159,4.364566 -7.974107,4.355755 -9.004794,4.832419 -9.913420,5.593561 -10.765384,6.140711 -11.438779,6.785917 -11.199802,7.105846 -11.146704,7.396706 -10.695595,7.939464 -10.230094,8.406206 -10.016567,8.428504 -9.755342,8.541055 -9.337280,7.928534 -9.403348,7.526905 -9.208786,7.313921 -8.926065,7.309037 -8.722124,7.711674 -8.439298,7.686043 + + + + + 4689021 + Liberia + 47 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -13.246550,8.903049 -12.711958,9.342712 -12.596719,9.620188 -12.425929,9.835834 -12.150338,9.858572 -11.917277,10.046984 -11.117481,10.045873 -10.839152,9.688246 -10.622395,9.267910 -10.654770,8.977178 -10.494315,8.715541 -10.505477,8.348896 -10.230094,8.406206 -10.695595,7.939464 -11.146704,7.396706 -11.199802,7.105846 -11.438779,6.785917 -11.708195,6.860098 -12.428099,7.262942 -12.949049,7.798646 -13.124025,8.163946 -13.246550,8.903049 + + + + + 6163195 + Sierra Leone + 48 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + -13.700476,12.586183 -13.217818,12.575874 -12.499051,12.332090 -12.278599,12.354440 -12.203565,12.465648 -11.658301,12.386583 -11.513943,12.442988 -11.456169,12.076834 -11.297574,12.077971 -11.036556,12.211245 -10.870830,12.177887 -10.593224,11.923975 -10.165214,11.844084 -9.890993,12.060479 -9.567912,12.194243 -9.327616,12.334286 -9.127474,12.308060 -8.905265,12.088358 -8.786099,11.812561 -8.376305,11.393646 -8.581305,11.136246 -8.620321,10.810891 -8.407311,10.909257 -8.282357,10.792597 -8.335377,10.494812 -8.029944,10.206535 -8.229337,10.129020 -8.309616,9.789532 -8.079114,9.376224 -7.832100,8.575704 -8.203499,8.455453 -8.299049,8.316444 -8.221792,8.123329 -8.280703,7.687180 -8.439298,7.686043 -8.722124,7.711674 -8.926065,7.309037 -9.208786,7.313921 -9.403348,7.526905 -9.337280,7.928534 -9.755342,8.541055 -10.016567,8.428504 -10.230094,8.406206 -10.505477,8.348896 -10.494315,8.715541 -10.654770,8.977178 -10.622395,9.267910 -10.839152,9.688246 -11.117481,10.045873 -11.917277,10.046984 -12.150338,9.858572 -12.425929,9.835834 -12.596719,9.620188 -12.711958,9.342712 -13.246550,8.903049 -13.685154,9.494744 -14.074045,9.886167 -14.330076,10.015720 -14.579699,10.214467 -14.693232,10.656301 -14.839554,10.876572 -15.130311,11.040412 -14.685687,11.527824 -14.382192,11.509272 -14.121406,11.677117 -13.900800,11.678719 -13.743161,11.811269 -13.828272,12.142644 -13.718744,12.247186 -13.700476,12.586183 + + + + + 12413867 + Guinea + 49 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 11.276449,2.261051 11.751665,2.326758 12.359380,2.192812 12.951334,2.321616 13.075822,2.267097 13.003114,1.830896 13.282631,1.314184 14.026669,1.395677 14.276266,1.196930 13.843321,0.038758 14.316418,-0.552627 14.425456,-1.333407 14.299210,-1.998276 13.992407,-2.470805 13.109619,-2.428740 12.575284,-1.948511 12.495703,-2.391688 11.820964,-2.514161 11.478039,-2.765619 11.855122,-3.426871 11.093773,-3.978827 10.066135,-2.969483 9.405245,-2.144313 8.797996,-1.111301 8.830087,-0.779074 9.048420,-0.459351 9.291351,0.268666 9.492889,1.010120 9.830284,1.067894 11.285079,1.057662 11.276449,2.261051 + + + + + 1772255 + Gabon + 50 + + + + + + + -1.000000,-1.000000 -1.000000,-1.000000 + + + + + + + 18.453065,3.504386 18.393792,2.900443 18.094276,2.365722 17.898835,1.741832 17.774192,0.855659 17.826540,0.288923 17.663553,-0.058084 17.638645,-0.424832 17.523716,-0.743830 16.865307,-1.225816 16.407092,-1.740927 15.972803,-2.712392 16.006290,-3.535133 15.753540,-3.855165 15.170992,-4.343507 14.582604,-4.970239 14.209035,-4.793092 14.144956,-4.510009 13.600235,-4.500138 13.258240,-4.882957 12.995517,-4.781103 12.620760,-4.438023 12.318608,-4.606230 11.914963,-5.037987 11.093773,-3.978827 11.855122,-3.426871 11.478039,-2.765619 11.820964,-2.514161 12.495703,-2.391688 12.575284,-1.948511 13.109619,-2.428740 13.992407,-2.470805 14.299210,-1.998276 14.425456,-1.333407 14.316418,-0.552627 13.843321,0.038758 14.276266,1.196930 14.026669,1.395677 13.282631,1.314184 13.003114,1.830896 13.075822,2.267097 14.337813,2.227875 15.146342,1.964015 15.940919,1.727673 16.012852,2.267640 16.537058,3.198255 17.133042,3.728197 17.809900,3.560196 18.453065,3.504386 + + + + + 4954674 + Republic of the Congo + 51 + + + + diff --git a/msautotest/misc/flatgeobuf.map b/msautotest/misc/flatgeobuf.map index 8092054f36..378f626c57 100644 --- a/msautotest/misc/flatgeobuf.map +++ b/msautotest/misc/flatgeobuf.map @@ -1,11 +1,31 @@ # # Test FlatGeobuf native access (RFC 137) # -# REQUIRES: INPUT=FLATGEOBUF +# REQUIRES: INPUT=FLATGEOBUF SUPPORTS=WFS # #RUN_PARMS: flatgeobuf-continent.png [MAP2IMG] -m [MAPFILE] -i png -o [RESULT] -l africa-continent #RUN_PARMS: flatgeobuf-classes.png [MAP2IMG] -m [MAPFILE] -i png -o [RESULT] -l africa-classes - +# +# WFS 1.0.0 +# +# Capabilities +# RUN_PARMS: flatgeobuf-wfs-cap.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetCapabilities" > [RESULT_DEVERSION] +# +# Feature types description +# RUN_PARMS: flatgeobuf-wfs-describe.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType" > [RESULT] +# +# Generate simple layer info. +# RUN_PARMS: flatgeobuf-wfs-get-feature.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=africa-continent" > [RESULT] +# +# Generate layer info using property name. +# RUN_PARMS: flatgeobuf-wfs-get-feature-propertyname.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=africa-continent&propertyname=(name_en)" > [RESULT] +# +# Generate layer info using property name and a geoemtry property. +# RUN_PARMS: flatgeobuf-wfs-get-feature-propertyname-geometry.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=africa-continent&propertyname=(name_en,msGeometry)" > [RESULT] +# +# Get Feature by id +# RUN_PARMS: flatgeobuf-wfs-get-feature-id.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=africa-continent&featureid=africa-continent.46" > [RESULT] +# MAP NAME "fgb-test" STATUS ON From d68bc824e58918fe9254429a29db2b18e3861e99 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Jul 2022 09:19:40 -0300 Subject: [PATCH 013/170] [Backport branch-8-0] flatgeobuf: fix wkt srs (#6572) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * flatgeobuf: fix wkt srs * Fix allocation of strings * Rework logic * add FlatGeobuf WKT test * Further mem alloc fixes * Memory allocation fixes * Fix conditionals * Fix mem leak * remove unnecessary extent param Co-authored-by: Björn Harrtell Co-authored-by: Jeff McKenna --- flatgeobuf/flatgeobuf_c.cpp | 43 ++++++++++++++++++++++++---------- flatgeobuf/flatgeobuf_c.h | 3 ++- mapflatgeobuf.c | 23 +++++++++++++----- msautotest/misc/flatgeobuf.map | 4 ++-- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/flatgeobuf/flatgeobuf_c.cpp b/flatgeobuf/flatgeobuf_c.cpp index 6eb4036f14..ff783244ec 100644 --- a/flatgeobuf/flatgeobuf_c.cpp +++ b/flatgeobuf/flatgeobuf_c.cpp @@ -37,12 +37,17 @@ ctx *flatgeobuf_init_ctx() void flatgeobuf_free_ctx(ctx *ctx) { - if (ctx->columns) + if (ctx->columns) { + for (uint32_t i = 0; i < ctx->columns_len; i++) + free(ctx->columns[i].name); free(ctx->columns); + } if (ctx->search_result) free(ctx->search_result); if (ctx->buf) free(ctx->buf); + if (ctx->wkt) + free(ctx->wkt); free(ctx); } @@ -74,17 +79,27 @@ void flatgeobuf_ensure_point(ctx *ctx, uint32_t len) int flatgeobuf_ensure_buf(ctx *ctx, uint32_t size) { - if (size > 100 * 1024 * 1024) + if (size > 100 * 1024 * 1024) { + msSetError(MS_FGBERR, "Invalid buffer size requested", "flatgeobuf_ensure_buf"); return -1; + } if (!ctx->buf) { - ctx->buf_size = INIT_BUFFER_SIZE; + ctx->buf_size = std::max(INIT_BUFFER_SIZE, size); ctx->buf = (uint8_t *) malloc(ctx->buf_size); + if (ctx->buf == NULL) { + msSetError(MS_FGBERR, "Failed to allocate buffer", "flatgeobuf_ensure_buf"); + return -1; + } return 0; } if (ctx->buf_size < size) { - ctx->buf_size = ctx->buf_size * 2; - ctx->buf = (uint8_t *) realloc(ctx->buf, ctx->buf_size); - flatgeobuf_ensure_buf(ctx, size); + ctx->buf_size = std::max(ctx->buf_size * 2, size); + auto buf = (uint8_t *) realloc(ctx->buf, ctx->buf_size); + if (buf == NULL) { + msSetError(MS_FGBERR, "Failed to reallocate buffer", "flatgeobuf_ensure_buf"); + return -1; + } + ctx->buf = buf; } return 0; } @@ -104,7 +119,6 @@ int flatgeobuf_decode_feature(ctx *ctx, layerObj *layer, shapeObj *shape) ctx->offset += sizeof(uoffset_t); if (flatgeobuf_ensure_buf(ctx, featureSize) != 0) { - msSetError(MS_FGBERR, "Failed to allocate buffer for feature", "flatgeobuf_decode_feature"); return -1; } @@ -238,7 +252,8 @@ int flatgeobuf_check_magicbytes(ctx *ctx) msSetError(MS_FGBERR, "Unexpected offset", "flatgeobuf_check_magicbytes"); return -1; } - flatgeobuf_ensure_buf(ctx, FLATGEOBUF_MAGICBYTES_SIZE); + if (flatgeobuf_ensure_buf(ctx, FLATGEOBUF_MAGICBYTES_SIZE) != 0) + return -1; if (VSIFReadL(ctx->buf, 8, 1, ctx->file) != 1) { msSetError(MS_FGBERR, "Failed to read magicbytes", "flatgeobuf_check_magicbytes"); return -1; @@ -270,8 +285,8 @@ int flatgeobuf_decode_header(ctx *ctx) return -1; } ctx->offset += sizeof(uoffset_t); - if (flatgeobuf_ensure_buf(ctx, headerSize) != -1) { - msSetError(MS_FGBERR, "Failed to allocate buffer for header", "flatgeobuf_decode_header"); + if (flatgeobuf_ensure_buf(ctx, headerSize) != 0) { + return -1; } if (VSIFReadL(ctx->buf, 1, headerSize, ctx->file) != headerSize) { msSetError(MS_FGBERR, "Failed to read header", "flatgeobuf_decode_header"); @@ -300,8 +315,12 @@ int flatgeobuf_decode_header(ctx *ctx) ctx->has_tm = header->has_tm(); ctx->index_node_size = header->index_node_size(); auto crs = header->crs(); - if (crs != nullptr) + if (crs != nullptr) { ctx->srid = crs->code(); + auto wkt = crs->wkt(); + if (wkt != nullptr) + ctx->wkt = msStrdup(wkt->c_str()); + } auto columns = header->columns(); if (columns != nullptr) { auto size = columns->size(); @@ -310,7 +329,7 @@ int flatgeobuf_decode_header(ctx *ctx) ctx->columns_len = size; for (uint32_t i = 0; i < size; i++) { auto column = columns->Get(i); - ctx->columns[i].name = column->name()->c_str(); + ctx->columns[i].name = msStrdup(column->name()->c_str()); ctx->columns[i].type = (uint8_t) column->type(); ctx->columns[i].itemindex = -1; } diff --git a/flatgeobuf/flatgeobuf_c.h b/flatgeobuf/flatgeobuf_c.h index a20e93064b..32d804ac12 100644 --- a/flatgeobuf/flatgeobuf_c.h +++ b/flatgeobuf/flatgeobuf_c.h @@ -33,7 +33,7 @@ extern uint8_t FLATGEOBUF_MAGICBYTES_SIZE; typedef struct flatgeobuf_column { - const char *name; + char *name; uint8_t type; const char *title; const char *description; @@ -87,6 +87,7 @@ typedef struct flatgeobuf_ctx bool has_tm; uint16_t index_node_size; int32_t srid; + char *wkt; flatgeobuf_column *columns; uint16_t columns_len; diff --git a/mapflatgeobuf.c b/mapflatgeobuf.c index ca4a12b586..e4c3cd92e0 100644 --- a/mapflatgeobuf.c +++ b/mapflatgeobuf.c @@ -163,15 +163,26 @@ int msFlatGeobufLayerOpen(layerObj *layer) } if (layer->projection.numargs > 0 && - EQUAL(layer->projection.args[0], "auto")) - { + EQUAL(layer->projection.args[0], "auto")) { OGRSpatialReferenceH hSRS = OSRNewSpatialReference( NULL ); - if (ctx->srid) - if (!(OSRImportFromEPSG(hSRS, ctx->srid) != OGRERR_NONE)) - return -1; char *pszWKT = NULL; + if (ctx->srid > 0) { + if (OSRImportFromEPSG(hSRS, ctx->srid) != OGRERR_NONE) { + OSRDestroySpatialReference(hSRS); + flatgeobuf_free_ctx(ctx); + return MS_FAILURE; + } + if (OSRExportToWkt(hSRS, &pszWKT) != OGRERR_NONE) { + OSRDestroySpatialReference(hSRS); + flatgeobuf_free_ctx(ctx); + return MS_FAILURE; + } + } else if (ctx->wkt == NULL) { + OSRDestroySpatialReference(hSRS); + return MS_SUCCESS; + } int bOK = MS_FALSE; - if (msOGCWKT2ProjectionObj(pszWKT, &(layer->projection), layer->debug) == MS_SUCCESS) + if (msOGCWKT2ProjectionObj(ctx->wkt ? ctx->wkt : pszWKT, &(layer->projection), layer->debug) == MS_SUCCESS) bOK = MS_TRUE; CPLFree(pszWKT); OSRDestroySpatialReference(hSRS); diff --git a/msautotest/misc/flatgeobuf.map b/msautotest/misc/flatgeobuf.map index 378f626c57..e125938b9d 100644 --- a/msautotest/misc/flatgeobuf.map +++ b/msautotest/misc/flatgeobuf.map @@ -121,8 +121,8 @@ MAP END #class TEMPLATE "ttt.html" PROJECTION - "init=epsg:4326" - END + AUTO + END END # layer END # map From eab78f2961ffbfbf2586072ee537d62cf2854b28 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 21 Jul 2022 13:57:36 -0300 Subject: [PATCH 014/170] [Backport branch-8-0] [msautotest] upgrade tests to use PHP 8.1.8 (#6575) * upgrade tests to PHP 8.1.8 * update PHPUnit readme * update PHPUnit readme Co-authored-by: Jeff McKenna --- .travis.yml | 2 +- msautotest/php/README | 8 -------- msautotest/php/README.md | 24 ++++++++++++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 msautotest/php/README create mode 100644 msautotest/php/README.md diff --git a/.travis.yml b/.travis.yml index 31ba2a43da..b42fbbaf9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: - BUILD_NAME=PHP_8.0 - PYTHON_VERSION=3.8 - - php: 8.1.7 + - php: 8.1.8 env: - BUILD_NAME=PHP_8.1 - PYTHON_VERSION=3.9 diff --git a/msautotest/php/README b/msautotest/php/README deleted file mode 100644 index 27c8b4a162..0000000000 --- a/msautotest/php/README +++ /dev/null @@ -1,8 +0,0 @@ -To run these tests you need PHPUnit (and PHP's Xdebug extension) installed. -You can find how to install PHPUnit at https://phpunit.readthedocs.io . -The official PHPUnit site is: https://phpunit.de - -To run the tests simply run 'phpunit --debug .' from inside the /msautotest/php/ -folder. - -You can run a single test such as: 'phpunit --debug classObjTest.php' diff --git a/msautotest/php/README.md b/msautotest/php/README.md new file mode 100644 index 0000000000..2cdd858d54 --- /dev/null +++ b/msautotest/php/README.md @@ -0,0 +1,24 @@ +# PHPNG MapScript Unit Tests + +To run these tests you need PHPUnit (and PHP's Xdebug extension) installed. +You can find how to install PHPUnit at https://phpunit.readthedocs.io . +The official PHPUnit site is: https://phpunit.de + +# Running the tests + +To run the tests simply run `phpunit --debug .` from inside the `/msautotest/php/` +folder. + +You can run a single test such as: `phpunit --debug classObjTest.php` + +# Configuring the test environment + +This folder includes a `phpunit.xml` configuration file for these tests. More +info about these settings: https://phpunit.readthedocs.io/en/9.5/configuration.html + +# PHPNG (SWIG) MapScript API documentation + +Follow: https://mapserver.org/mapscript/mapscript.html + + + From 93e353ce4e8544a7fd2f7ba8c7bcf2458f011633 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Aug 2022 18:23:49 +0200 Subject: [PATCH 015/170] [Backport branch-8-0] Increase Python max line length for linting (#6579) * Increase Python max line length and fix Flake8 version * Cover all Python versions Co-authored-by: sethg --- mapscript/python/CMakeLists.txt | 2 +- mapscript/python/requirements-dev.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mapscript/python/CMakeLists.txt b/mapscript/python/CMakeLists.txt index 4d3394d52f..c8dd96941a 100644 --- a/mapscript/python/CMakeLists.txt +++ b/mapscript/python/CMakeLists.txt @@ -74,7 +74,7 @@ add_custom_command( DEPENDS mapscriptvenv.stamp OUTPUT mapscriptlinting.stamp WORKING_DIRECTORY ${OUTPUT_FOLDER} - COMMAND ${Python_VENV_SCRIPTS}/flake8 $/mapscript/tests --max-line-length=120 + COMMAND ${Python_VENV_SCRIPTS}/flake8 $/mapscript/tests --max-line-length=140 COMMAND ${Python_VENV_SCRIPTS}/flake8 $/mapscript/examples --max-line-length=120 COMMENT "Linting test suite and examples with flake8" # note only one comment is output per custom command block ) diff --git a/mapscript/python/requirements-dev.txt b/mapscript/python/requirements-dev.txt index d3f5800bb1..8fb82c7a5c 100644 --- a/mapscript/python/requirements-dev.txt +++ b/mapscript/python/requirements-dev.txt @@ -2,4 +2,5 @@ pytest pillow wheel>=0.31.1 setuptools>=40.2.0 -flake8 \ No newline at end of file +flake8==3.9.2; python_version == '2.7' +flake8==5.0.3; python_version >= '3.0' \ No newline at end of file From 32188a2ac4c69ee74b81ccc4ef69530cfe763c08 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Aug 2022 15:36:56 -0300 Subject: [PATCH 016/170] Apply special processings of PROJ_LIB to PROJ_DATA as well (#6576) PROJ 9.1 recognizes the PROJ_DATA environment variable, as a replacement for PROJ_LIB (both are still recognized by PROJ >= 9.1. PROJ_LIB will be retired in PROJ 10, whose release is unplanned for now) Cf https://github.com/OSGeo/PROJ/pull/3253 Co-authored-by: Even Rouault --- map2img.c | 4 +-- mapobject.c | 9 +++--- mapproject.c | 77 +++++++++++++++++++++++----------------------- mapproject.h | 4 +-- mapserv-config.cpp | 5 +-- mapservutil.c | 4 +-- maputil.c | 6 ++-- 7 files changed, 56 insertions(+), 53 deletions(-) diff --git a/map2img.c b/map2img.c index c8ed3229ef..ecb4333ded 100644 --- a/map2img.c +++ b/map2img.c @@ -139,8 +139,8 @@ int main(int argc, char *argv[]) if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&requeststarttime, NULL); - /* Use PROJ_LIB env vars if set */ - msProjLibInitFromEnv(); + /* Use PROJ_DATA/PROJ_LIB env vars if set */ + msProjDataInitFromEnv(); /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */ if ( msDebugInitFromEnv() != MS_SUCCESS ) { diff --git a/mapobject.c b/mapobject.c index ffe8c53ac6..1f7db5446b 100644 --- a/mapobject.c +++ b/mapobject.c @@ -166,9 +166,9 @@ int msSetConfigOption( mapObj *map, const char *key, const char *value) { /* We have special "early" handling of this so that it will be */ /* in effect when the projection blocks are parsed and pj_init is called. */ - if( strcasecmp(key,"PROJ_LIB") == 0 ) { + if( strcasecmp(key,"PROJ_DATA") == 0 || strcasecmp(key,"PROJ_LIB") == 0 ) { /* value may be relative to map path */ - msSetPROJ_LIB( value, map->mappath ); + msSetPROJ_DATA( value, map->mappath ); } /* Same for MS_ERRORFILE, we want it to kick in as early as possible @@ -220,8 +220,9 @@ void msApplyMapConfigOptions( mapObj *map ) key != NULL; key = msNextKeyFromHashTable( &(map->configoptions), key ) ) { const char *value = msLookupHashTable( &(map->configoptions), key ); - if( strcasecmp(key,"PROJ_LIB") == 0 ) { - msSetPROJ_LIB( value, map->mappath ); + if( strcasecmp(key,"PROJ_DATA") == 0 || + strcasecmp(key,"PROJ_LIB") == 0 ) { + msSetPROJ_DATA( value, map->mappath ); } else if( strcasecmp(key,"MS_ERRORFILE") == 0 ) { msSetErrorFile( value, map->mappath ); } else { diff --git a/mapproject.c b/mapproject.c index 3faad46d4a..5594446d46 100644 --- a/mapproject.c +++ b/mapproject.c @@ -39,9 +39,9 @@ #include "cpl_conv.h" #include "ogr_srs_api.h" -static char *ms_proj_lib = NULL; +static char *ms_proj_data = NULL; #if PROJ_VERSION_MAJOR >= 6 -static unsigned ms_proj_lib_change_counter = 0; +static unsigned ms_proj_data_change_counter = 0; #endif typedef struct LinkedListOfProjContext LinkedListOfProjContext; @@ -79,7 +79,7 @@ typedef struct struct projectionContext { PJ_CONTEXT* proj_ctx; - unsigned ms_proj_lib_change_counter; + unsigned ms_proj_data_change_counter; int ref_count; pjCacheEntry pj_cache[PJ_CACHE_ENTRY_SIZE]; int pj_cache_size; @@ -865,13 +865,13 @@ int msProcessProjection(projectionObj *p) return -1; } } - if( p->proj_ctx->ms_proj_lib_change_counter != ms_proj_lib_change_counter ) + if( p->proj_ctx->ms_proj_data_change_counter != ms_proj_data_change_counter ) { msAcquireLock( TLOCK_PROJ ); - p->proj_ctx->ms_proj_lib_change_counter = ms_proj_lib_change_counter; + p->proj_ctx->ms_proj_data_change_counter = ms_proj_data_change_counter; { - const char* const paths[1] = { ms_proj_lib }; - proj_context_set_search_paths(p->proj_ctx->proj_ctx, 1, ms_proj_lib ? paths : NULL); + const char* const paths[1] = { ms_proj_data }; + proj_context_set_search_paths(p->proj_ctx->proj_ctx, 1, ms_proj_data ? paths : NULL); } msReleaseLock( TLOCK_PROJ ); } @@ -2501,45 +2501,46 @@ static const char *msProjFinder( const char *filename) if( filename == NULL ) return NULL; - if( ms_proj_lib == NULL ) + if( ms_proj_data == NULL ) return filename; - last_filename = (char *) malloc(strlen(filename)+strlen(ms_proj_lib)+2); - sprintf( last_filename, "%s/%s", ms_proj_lib, filename ); + last_filename = (char *) malloc(strlen(filename)+strlen(ms_proj_data)+2); + sprintf( last_filename, "%s/%s", ms_proj_data, filename ); return last_filename; } #endif /************************************************************************/ -/* msProjLibInitFromEnv() */ +/* msProjDataInitFromEnv() */ /************************************************************************/ -void msProjLibInitFromEnv() +void msProjDataInitFromEnv() { const char *val; - if( (val=CPLGetConfigOption( "PROJ_LIB", NULL )) != NULL ) { - msSetPROJ_LIB(val, NULL); + if( (val=CPLGetConfigOption( "PROJ_DATA", NULL )) != NULL || + (val=CPLGetConfigOption( "PROJ_LIB", NULL )) != NULL ) { + msSetPROJ_DATA(val, NULL); } } /************************************************************************/ -/* msSetPROJ_LIB() */ +/* msSetPROJ_DATA() */ /************************************************************************/ -void msSetPROJ_LIB( const char *proj_lib, const char *pszRelToPath ) +void msSetPROJ_DATA( const char *proj_data, const char *pszRelToPath ) { char *extended_path = NULL; /* Handle relative path if applicable */ - if( proj_lib && pszRelToPath - && proj_lib[0] != '/' - && proj_lib[0] != '\\' - && !(proj_lib[0] != '\0' && proj_lib[1] == ':') ) { + if( proj_data && pszRelToPath + && proj_data[0] != '/' + && proj_data[0] != '\\' + && !(proj_data[0] != '\0' && proj_data[1] == ':') ) { struct stat stat_buf; extended_path = (char*) msSmallMalloc(strlen(pszRelToPath) - + strlen(proj_lib) + 10); - sprintf( extended_path, "%s/%s", pszRelToPath, proj_lib ); + + strlen(proj_data) + 10); + sprintf( extended_path, "%s/%s", pszRelToPath, proj_data ); #ifndef S_ISDIR # define S_ISDIR(x) ((x) & S_IFDIR) @@ -2547,41 +2548,41 @@ void msSetPROJ_LIB( const char *proj_lib, const char *pszRelToPath ) if( stat( extended_path, &stat_buf ) == 0 && S_ISDIR(stat_buf.st_mode) ) - proj_lib = extended_path; + proj_data = extended_path; } msAcquireLock( TLOCK_PROJ ); #if PROJ_VERSION_MAJOR >= 6 - if( proj_lib == NULL && ms_proj_lib == NULL ) + if( proj_data == NULL && ms_proj_data == NULL ) { /* do nothing */ } - else if( proj_lib != NULL && ms_proj_lib != NULL && - strcmp(proj_lib, ms_proj_lib) == 0 ) + else if( proj_data != NULL && ms_proj_data != NULL && + strcmp(proj_data, ms_proj_data) == 0 ) { /* do nothing */ } else { - ms_proj_lib_change_counter++; - free( ms_proj_lib ); - ms_proj_lib = proj_lib ? msStrdup(proj_lib) : NULL; + ms_proj_data_change_counter++; + free( ms_proj_data ); + ms_proj_data = proj_data ? msStrdup(proj_data) : NULL; } #else { static int finder_installed = 0; - if( finder_installed == 0 && proj_lib != NULL) { + if( finder_installed == 0 && proj_data != NULL) { finder_installed = 1; pj_set_finder( msProjFinder ); } } - if (proj_lib == NULL) pj_set_finder(NULL); + if (proj_data == NULL) pj_set_finder(NULL); - if( ms_proj_lib != NULL ) { - free( ms_proj_lib ); - ms_proj_lib = NULL; + if( ms_proj_data != NULL ) { + free( ms_proj_data ); + ms_proj_data = NULL; } if( last_filename != NULL ) { @@ -2589,15 +2590,15 @@ void msSetPROJ_LIB( const char *proj_lib, const char *pszRelToPath ) last_filename = NULL; } - if( proj_lib != NULL ) - ms_proj_lib = msStrdup( proj_lib ); + if( proj_data != NULL ) + ms_proj_data = msStrdup( proj_data ); #endif msReleaseLock( TLOCK_PROJ ); #if GDAL_VERSION_MAJOR >= 3 - if( ms_proj_lib != NULL ) + if( ms_proj_data != NULL ) { - const char* const apszPaths[] = { ms_proj_lib, NULL }; + const char* const apszPaths[] = { ms_proj_data, NULL }; OSRSetPROJSearchPaths(apszPaths); } #endif diff --git a/mapproject.h b/mapproject.h index e229524979..2d54c60278 100644 --- a/mapproject.h +++ b/mapproject.h @@ -156,8 +156,8 @@ but are not directly exposed by the mapscript module MS_DLL_EXPORT void msAxisDenormalizePoints( projectionObj *proj, int count, double *x, double *y ); - MS_DLL_EXPORT void msSetPROJ_LIB( const char *, const char * ); - MS_DLL_EXPORT void msProjLibInitFromEnv(); + MS_DLL_EXPORT void msSetPROJ_DATA( const char *, const char * ); + MS_DLL_EXPORT void msProjDataInitFromEnv(); int msProjIsGeographicCRS(projectionObj* proj); #if PROJ_VERSION_MAJOR >= 6 diff --git a/mapserv-config.cpp b/mapserv-config.cpp index 9b57651388..779473b485 100644 --- a/mapserv-config.cpp +++ b/mapserv-config.cpp @@ -108,8 +108,9 @@ static int loadConfig(configObj *config) static void msConfigSetConfigOption(const char* key, const char* value) { CPLSetConfigOption(key, value); - if( strcasecmp(key,"PROJ_LIB") == 0 ) { - msSetPROJ_LIB( value, nullptr ); + if( strcasecmp(key,"PROJ_DATA") == 0 || + strcasecmp(key,"PROJ_LIB") == 0 ) { + msSetPROJ_DATA( value, nullptr ); } } diff --git a/mapservutil.c b/mapservutil.c index c23322c4b1..dae501ec6c 100644 --- a/mapservutil.c +++ b/mapservutil.c @@ -2010,8 +2010,8 @@ int msCGIHandler(const char *query_string, void **out_buffer, size_t *buffer_len msIO_installStdoutToBuffer(); - /* Use PROJ_LIB env vars if set */ - msProjLibInitFromEnv(); + /* Use PROJ_DATA/PROJ_LIB env vars if set */ + msProjDataInitFromEnv(); /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */ if( msDebugInitFromEnv() != MS_SUCCESS ) { diff --git a/maputil.c b/maputil.c index 0e488fe9c3..45e6679d20 100644 --- a/maputil.c +++ b/maputil.c @@ -2008,8 +2008,8 @@ int msSetup() msThreadInit(); #endif - /* Use PROJ_LIB env vars if set */ - msProjLibInitFromEnv(); + /* Use PROJ_DATA/PROJ_LIB env vars if set */ + msProjDataInitFromEnv(); /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */ if (msDebugInitFromEnv() != MS_SUCCESS) @@ -2069,7 +2069,7 @@ void msCleanup() # endif pj_deallocate_grids(); #endif - msSetPROJ_LIB( NULL, NULL ); + msSetPROJ_DATA( NULL, NULL ); msProjectionContextPoolCleanup(); #if defined(USE_CURL) From 29eb6fa06d13bbbbd40b6f6f491001f0cc55b63a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Aug 2022 09:26:52 -0300 Subject: [PATCH 017/170] [Backport branch-8-0] reset isreported to MS_FALSE in msResetErrorList() (#6543) (#6581) * reset isreported to MS_FALSE in msResetErrorList() (#6543) * send two queries in a row without arguments to the FastCGI process (#6543) Co-authored-by: Landry Breuil --- .github/workflows/start.sh | 8 ++++++++ maperror.c | 1 + 2 files changed, 9 insertions(+) diff --git a/.github/workflows/start.sh b/.github/workflows/start.sh index c26bb98210..060be5574e 100755 --- a/.github/workflows/start.sh +++ b/.github/workflows/start.sh @@ -106,6 +106,14 @@ echo "Running FastCGI query again" curl -s "http://localhost/cgi-bin/mapserv.fcgi?MAP=/tmp/wfs_simple.map&SERVICE=WFS&REQUEST=GetCapabilities" > /tmp/res.xml cat /tmp/res.xml | grep wfs:WFS_Capabilities >/dev/null || (cat /tmp/res.xml && /bin/false) +echo "Check that we return an error if given no arguments" +curl -s "http://localhost/cgi-bin/mapserv.fcgi" > /tmp/res.xml +cat /tmp/res.xml | grep -q 'QUERY_STRING is set, but empty' || (cat /tmp/res.xml && /bin/false) + +echo "Check again to make sure further errors are reported (#6543)" +curl -s "http://localhost/cgi-bin/mapserv.fcgi" > /tmp/res.xml +cat /tmp/res.xml | grep -q 'QUERY_STRING is set, but empty' || (cat /tmp/res.xml && /bin/false) + cd msautotest/wxs export PATH=/tmp/install-mapserver/bin:$PATH diff --git a/maperror.c b/maperror.c index b1bb1cd71f..389b1a529d 100644 --- a/maperror.c +++ b/maperror.c @@ -232,6 +232,7 @@ void msResetErrorList() ms_error->next = NULL; ms_error->code = MS_NOERR; + ms_error->isreported = MS_FALSE; ms_error->routine[0] = '\0'; ms_error->message[0] = '\0'; ms_error->errorcount = 0; From 6833dddc95575647b87504c4835186761060ddd2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 06:42:11 -0300 Subject: [PATCH 018/170] reset layer filteritem to its old value in case of no overlap (fixes #6580) (#6589) Co-authored-by: Landry Breuil --- mapquery.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mapquery.c b/mapquery.c index 9646c57ed8..62159e953b 100644 --- a/mapquery.c +++ b/mapquery.c @@ -905,6 +905,9 @@ int msQueryByFilter(mapObj *map) status = msLayerWhichShapes(lp, search_rect, MS_TRUE); if(status == MS_DONE) { /* no overlap */ + lp->filteritem = old_filteritem; /* point back to original value */ + msCopyExpression(&lp->filter, &old_filter); /* restore old filter */ + msFreeExpression(&old_filter); msLayerClose(lp); continue; } else if(status != MS_SUCCESS) goto restore_old_filter; From d4fdbe3627e77b0b6ef80eb9e21fb786fbb08421 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 06:42:21 -0300 Subject: [PATCH 019/170] [ogcapi] make sure there are features before accessing them in jinja templates (#6588) Co-authored-by: Landry Breuil --- share/ogcapi/templates/html-bootstrap4/collection-items.html | 2 ++ share/ogcapi/templates/html-plain/collection-items.html | 2 ++ 2 files changed, 4 insertions(+) diff --git a/share/ogcapi/templates/html-bootstrap4/collection-items.html b/share/ogcapi/templates/html-bootstrap4/collection-items.html index 5d824467c1..f5950c5e50 100644 --- a/share/ogcapi/templates/html-bootstrap4/collection-items.html +++ b/share/ogcapi/templates/html-bootstrap4/collection-items.html @@ -49,9 +49,11 @@

{{ template.title }} - Collection Items: {{ response.collection.title }}

ID +{% if response.features %} {% for key, value in response.features.0.properties %} {{ key }} {% endfor %} +{% endif %} {% for feature in response.features %} diff --git a/share/ogcapi/templates/html-plain/collection-items.html b/share/ogcapi/templates/html-plain/collection-items.html index 1266710be3..94f5bb3581 100644 --- a/share/ogcapi/templates/html-plain/collection-items.html +++ b/share/ogcapi/templates/html-plain/collection-items.html @@ -10,9 +10,11 @@

{{ template.title }} - Collection Items: {{ response.collection.title }}

ID +{% if response.features %} {% for key, value in response.features.0.properties %} {{ key }} {% endfor %} +{% endif %} {% for feature in response.features %} From 447f435c670a808a073f148fab028bd850cd6faa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 6 Aug 2022 06:42:30 -0300 Subject: [PATCH 020/170] Fix MSSQL query returns invalid result (#6585) (#6587) Co-authored-by: Tamas Szekeres --- mapmssql2008.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mapmssql2008.c b/mapmssql2008.c index 2d0a750099..3468bbc4da 100644 --- a/mapmssql2008.c +++ b/mapmssql2008.c @@ -1339,7 +1339,7 @@ int msMSSQL2008LayerGetNumFeatures(layerObj *layer) } /* Prepare and execute the SQL statement for this layer */ -static int prepare_database(layerObj *layer, rectObj rect, char **query_string) +static int prepare_database(layerObj *layer, rectObj rect, char **query_string, int isQuery) { msMSSQL2008LayerInfo *layerinfo; char *query = 0; @@ -1609,6 +1609,12 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string) query = msStringConcatenate(query, pszTmp); msFree(pszTmp); } + else if (isQuery && !layerinfo->sort_spec) { + /* Add orderby to make the result set order deterministic */ + query = msStringConcatenate(query, " ORDER BY ["); + query = msStringConcatenate(query, layerinfo->urid_name); + query = msStringConcatenate(query, "]"); + } } @@ -1674,7 +1680,7 @@ int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) return MS_FAILURE; } - set_up_result = prepare_database(layer, rect, &query_str); + set_up_result = prepare_database(layer, rect, &query_str, isQuery); if(set_up_result != MS_SUCCESS) { msFree(query_str); From 2a3da6c0deab5b0bb459dfd1a4ce47973aca163e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 14:08:13 -0300 Subject: [PATCH 021/170] add PHPUnit test for createLegendIcon (#6591) Co-authored-by: Jeff McKenna --- .travis.yml | 2 +- msautotest/php/classObjTest.php | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b42fbbaf9e..73dbfe57c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: - BUILD_NAME=PHP_8.0 - PYTHON_VERSION=3.8 - - php: 8.1.8 + - php: 8.1.9 env: - BUILD_NAME=PHP_8.1 - PYTHON_VERSION=3.9 diff --git a/msautotest/php/classObjTest.php b/msautotest/php/classObjTest.php index bf96d56611..fdc074734e 100644 --- a/msautotest/php/classObjTest.php +++ b/msautotest/php/classObjTest.php @@ -26,11 +26,19 @@ public function testinsertremoveStyle() } - public function testpleader() + public function testleader() { $this->assertInstanceOf('labelLeaderObj', $this->class->leader); } + public function testcreateLegendIcon() + { + $map_file = 'maps/labels-leader.map'; + $map = new mapObj($map_file); + $layer = $map->getLayer(0); + $this->assertInstanceOf('imageObj', $layer->getClass(0)->createLegendIcon( $map, $layer, 50, 50 )); + } + # destroy variables, if not can lead to segmentation fault public function tearDown(): void { unset($this->class, $map_file, $map, $layer, $classtmp, $style); From 9d39356b08d283e2d1d352e2602a8ecbc9a13de1 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Tue, 9 Aug 2022 12:38:33 -0300 Subject: [PATCH 022/170] update for 8.0.0-beta2 release --- CMakeLists.txt | 2 +- HISTORY.TXT | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d857594fcb..e70ceb7bc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) -set (MapServer_VERSION_SUFFIX "-beta1") +set (MapServer_VERSION_SUFFIX "-beta2") # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user diff --git a/HISTORY.TXT b/HISTORY.TXT index 1ce814084e..eaa9bc627a 100644 --- a/HISTORY.TXT +++ b/HISTORY.TXT @@ -12,6 +12,21 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +8.0.0-beta2 release (2022-08-09) +-------------------------------- + +- install coshp utility (#6540) + +- improve error messages about missing mandatory metadata (#6542) + +- fix reprojection of lines crossing the antimeridian (#6557) + +- config file parsing: use msSetPROJ_LIB() when ENV PROJ_LIB is set (#6565) + +- handle PROJ_DATA as well as PROJ_LIB (#6573) + +- reset layer filteritem to its old value in case of no overlap (#6550) + 8.0.0-beta1 release (2022-06-27) -------------------------------- From af5f54ace1b392b5e5187b0ff33db7afe9c1d6cf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Aug 2022 12:18:27 -0300 Subject: [PATCH 023/170] mapfile.c: add missing include to fix build issue on some compilers (fixes #6595) (#6597) Co-authored-by: Even Rouault --- mapfile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mapfile.c b/mapfile.c index 827d050b5d..8e4bee839b 100755 --- a/mapfile.c +++ b/mapfile.c @@ -32,6 +32,7 @@ #endif #include +#include #include #include #include From bf81fb76c9b94997f5d9a77dc97bd1f8d9090e49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Aug 2022 07:07:46 -0300 Subject: [PATCH 024/170] update MS_MAP_PATTERN required note (#6599) Co-authored-by: Jeff McKenna --- etc/mapserver-sample.conf | 2 +- tests/mapserver-sample.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/mapserver-sample.conf b/etc/mapserver-sample.conf index 54a0d644a7..3391e1d2fd 100644 --- a/etc/mapserver-sample.conf +++ b/etc/mapserver-sample.conf @@ -11,7 +11,7 @@ CONFIG # Limit Mapfile Access # # MS_MAP_NO_PATH "1" - MS_MAP_PATTERN "^/opt/mapserver" ## required + MS_MAP_PATTERN "^/opt/mapserver" ## required when referencing mapfiles by path # MS_MAP_BAD_PATTERN "[/\\]{2}|[/\\]?\\.+[/\\]|," # diff --git a/tests/mapserver-sample.conf b/tests/mapserver-sample.conf index 288f87dda5..74b061dbc3 100644 --- a/tests/mapserver-sample.conf +++ b/tests/mapserver-sample.conf @@ -11,7 +11,7 @@ CONFIG # Limit Mapfile Access # # MS_MAP_NO_PATH "1" - MS_MAP_PATTERN "^/opt/mapserver" ## required + MS_MAP_PATTERN "^/opt/mapserver" ## required when referencing mapfiles by path # # Global Log/Debug Setup From d8a60df84a89b13238fcec34e1c9e9b2df5eeda4 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Fri, 19 Aug 2022 14:35:40 -0300 Subject: [PATCH 025/170] update for 8.0.0-rc1 release --- CMakeLists.txt | 2 +- HISTORY.TXT | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e70ceb7bc4..26e14300f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) -set (MapServer_VERSION_SUFFIX "-beta2") +set (MapServer_VERSION_SUFFIX "-rc1") # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user diff --git a/HISTORY.TXT b/HISTORY.TXT index eaa9bc627a..80e684944d 100644 --- a/HISTORY.TXT +++ b/HISTORY.TXT @@ -12,6 +12,13 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +8.0.0-rc1 release (2022-08-19) +------------------------------ + +- add missing include to fix build issue on some compilers (#6595) + +- update the distributed mapserver-sample.conf (#6598) + 8.0.0-beta2 release (2022-08-09) -------------------------------- From af77f919d27219975acd20718f6326896821d99d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 4 Sep 2022 11:03:56 -0300 Subject: [PATCH 026/170] [Backport branch-8-0] Fix for #6601 - ensure a valid WHERE clause is created in all cases (#6608) * Fix for #6601 - ensure a valid WHERE clause is created in all cases * add debug for msPostGISReplaceBoxToken() call * add boxtoken test Co-authored-by: sethg Co-authored-by: Jeff McKenna --- mappostgis.cpp | 11 +- .../wms_get_map_polygon_postgis_boxtoken.png | Bin 0 -> 5384 bytes msautotest/wxs/wms_postgis_boxtoken.map | 110 ++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 msautotest/wxs/expected/wms_get_map_polygon_postgis_boxtoken.png create mode 100644 msautotest/wxs/wms_postgis_boxtoken.map diff --git a/mappostgis.cpp b/mappostgis.cpp index f198996eb4..e54121b8ad 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -1801,6 +1801,10 @@ static std::string msPostGISBuildSQLSRID(layerObj *layer) static std::string msPostGISReplaceBoxToken(layerObj *layer, const rectObj *rect, const char *fromsource) { std::string result(fromsource); + + if( layer->debug > 1 ) { + msDebug("msPostGISReplaceBoxToken called.\n"); + } if ( strstr(fromsource, BOXTOKEN) && rect ) { char *strBox = nullptr; @@ -1901,7 +1905,7 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, // If the SRID is known, we can safely use ST_Intersects() // otherwise if find_srid() would return 0, ST_Intersects() would not // work at all, which breaks the msautotest/query/query_postgis.map - // tests, releated to bdry_counpy2 layer that has no SRID + // tests, related to bdry_counpy2 layer that has no SRID if( layerinfo->version >= 20500 ) { strRect = "ST_Intersects(\""; @@ -2051,6 +2055,11 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, strWhere += std::to_string(layer->startindex-1); } + if (strWhere.empty()) { + // return all records + strWhere = "true"; + } + return strWhere; } diff --git a/msautotest/wxs/expected/wms_get_map_polygon_postgis_boxtoken.png b/msautotest/wxs/expected/wms_get_map_polygon_postgis_boxtoken.png new file mode 100644 index 0000000000000000000000000000000000000000..96068aeada177dcf4f49ebc282e674abdc446d53 GIT binary patch literal 5384 zcmb`LS2PIrqMNV)S*@NQs$<0RRB0hWc9r002+$KR^5k|37uW6LbOq z@B#YTMk+Wg7K=i`X=zs}DObqJZ%nau1EfRU~{yoay|2QsgM^|?RAAd_h0W&{;+1tDI z`t^Br^?{?~4iI=fF|n<#j`H>0di4rjTZ^u*KZ=P#e)w?F)^=J@upuOLnwxvk*}0{x zyk~2R{{8#1r)S^B=B&8*@bl-Z@$vQN&o@Lw&PqxyIy#ObBac&3&Pq!UBO)%lySLTU zuK)hMXl~xOv)fitIr{Pi-PE+s!-EPAKFP?q8XVk`lRK}h+y#O5Y-~>R^Rc_To6^#l z#YH$hJ!WZXM^6vCwRPa>c|9|;&drT(Y}}NQLHYO~{rr&c-(Plhot2egW@q=Ttd5eB z&LNOZDXGi;{%vLDqv+@zP0ejp)dOeeo0XMK2?^}R#=gD%&Fbp))YMsd`FT~`Y1LQ>E(4+QE?a+w(;V{%9AJ8lar``fNe#^12?xFEv?(5 zqjfH>^M;12p`mp?zCCmE%i-a5etuMF=*G*J=QTB3^71PHz>bd2MN7-|*w|@a-pTjx z*zN6Ief^u|TS@7%ukZZVud~9!^V-_e>}<^3+=j65)#&J+g~iR<+OCli zW?^BCh2`qcA2=D=aa!665z*1NZ~HDTYtNpov9lkBhaWgOo&EfYU|_gCI9PrB_&7fP zBr_9ENqMurz6%B;n3)lbjBA{nn1BCv3=KEL#CAuFmP&W+|?EC{QU0v`tIiD4vW3Jy}iTX?(gp-)qXky0F?b2ZxxOF za}V?U6sTQ_damH@S4Z$5KkV;rS!5g1%oJ%(-)>qDIkX6(SEL}|15y0yi|MI!-kT=4 z>YWyOpg26OWts+W5C5d}h5_a?80mh1tjV$LK9c?$eo=r??XwNw)GLsuGHI@{nrjNpusQ>Re0CDgR&a_le z)^z0T-KA|B^r;OuOpK!V>o(pquyUSPorbBf=y#uee#w3BeeaB>!UxP?zA-B8>BuO* z0*iYsAlhy5@1M7zup{Ls1|fzwEWdW$?M6@3L-p3I?PKt$!Oy!@<;SJWz5B;}_&V~a z7xQQsH+qynY!_;csp!|{Yt5kR@EsmT+g_#ls7>c`^~V!z6f!-FF2c$Zro&5+XxnxS z13YPv?Cl`=C{DK?^k!-*rVAujB6o;@xy8arYzNPO~txV>q#;`OyD*^h92ITin+ zrBQXY;I~sb(RP`x)A`xvJ5WF|QTI^`=X|)g?HASYtS&;?aA_6C?wclJ958Wu0 zmtQ|1XnRi{Q8WHTc7J^AbN6R17=B%yZru15CSO?0DirJ})#J0FL^o@RF{&HyV)aJ{ z7_0@+MIQ|d1YIqwVhH(B~hxoWHV(F^0nQay+M?1cRiaerV!ru58= z&gctEF5Y>uu);lZ!&zKz=#YGh^g7Ag4_jc7#rEdty0q15cQIzlgxeH}Z)Kk_?dpiz z%J6p`cn!zyZwm*05a)A?@|hJ@_6otV*S$$>n~8q7Jm;|qjT$#!%Cq~EDl~BDnepGW+i{2hHTAP&ct_bNSB62eLu{t zUAk)=C_v|x6^`!&B)-iv({9MkWMMUU+q zrwqjUfs+f%1)WslW?}NCsOx{`BV1Dk50;BMT}I+D1(O?=XU)&50P9wuEfcZaEgJST zqH&!PpnSFol8dskJsv&u#4B8p-alioaAb05q3%wqSF$~&^>HYCM`1Eou>t|@{51Yz z;h4L(U65BC5B+35Dps@CZu<@mNxSNE!*w@%%VS>)E_W-^i61#sKRS_~BbY7|lS0?A zH+T7-RLBGu_8=u2fG0WuWbO=)-;0neQEWLcv&KnZ>qpC2dmu3pFAWZoEeo~2@+&rH zCttwUt?4qF*q#a7y>{O;$&pqx=`49TO5#h=1qKi0P|PVBE7RErygLw;Gd*n|YIcnJ zt@(I!CfEwy>xhf3=zb^;E&vZ6s>0LIHPok?51C$d=y^w`DJdeeSxE;T$AzarC@*3S zGI*BG%5|n>zGa_wbtOr-R+ZEz2{C?L@4koE!|7ctY;D-xdg43wM_ zhI^~HDfu+kh0DC&RJ5hHVEX4SL9Lzm5chh!ry{Gv#4u^u(@mv?CU%s!pS9GD8q4Lc z!zFnVjm-!nQU51eec3om?gH7XinDl0x56Euul54O(N+3al$0sRt9gL0t}aeju{P_y z%4axFzs8*uMYsmxL;wR*z2md7xDd})c|RKzOgavY!i*$AKXvcRI$op)UW|Sga2l0= z%Yc1CuX`xmVnjYax?(qsU);A0(hR^9iO z#r9V;?YkV%`i0KtKcnP7h34|4B`m+L>C6u0T|f5`BTb+ode+Ca&Se;Ugobyc;);s zc{n8FuhuN53o`=`!9W^1`2-+M9 zZ&b#0;RQu48=A@OhxQc^zD3+rA14lGVxT_-h9WoH$JUISGYF6CH`w%e1r2*5&lODO zH*8uA)|*-66_b&ynX+qnDrX5J@GJStZ;9Jyu#FJ!F8{P)`Sfq@PwA;9fBXm`xjexO z43uhAhrCSl{(0(;#RxA@Uq98PTD30hM`(_$d9fI-*t>snFiuaJEp@M0q{;koKj;6h z(hJGo(A7agpasE2=2ukC1!^1EtQZNA26?=#Lg>=oPVd##7S(_seR9AJ+DKMI=1(kU zS4W5czJA`^WnBvI8txgMx5mx*h`hNIs5OqXgreBz6i7AZ-rDZ;DxNax5EC30_1FFM zh-#7)$ZX?Hki8D~P)#)Zu+`}oq~~Zj9lG1cB{p3jSNfp{>lOHk)~}jst&%h!cV~Jr zc+l;@@us&~t-~=b+5LO@LLAit6R3Y~z1mX=e)Ek8Qc~?^3!1)7I*y3aHo>yy?>BA(6q41>%_pXf=<;ima zyx%{l^J!xYqk-%#sdM!2KOQIq2WRpMy1&7L+t+gnDMpC!seFXK{A*vYUG#ZJ_iBfe z2~oj*!tGWf$praT6U%RcpkvoezgQAK_?HaheiUSUvui;Bxu_h+>*iSm776O+n+sW< zTlj9RlPwib53`RGl*jQi_@!&UE>x_gYOFo5Dh>YkC~DfCG>fPap~39+(D@o2rVPrd za$z>?fMibp;Ubg5eBPP&dZlkEtf2u7=9ksL^7w*PmLd-ETbI`-0-ipewZ2^{Srft^ z99-kz9x-eE=~P&M@)-t;^z{@?^|no9=%(*ZAf}v{+wTO1b;M(&9jHgO()kqUC%i~J zSl$v@rp!fNoeehy4hp@VEmK`LVMG%2%@JF{VF_5#3LD=l#5J z@xd9T$Tp>k1nt!`*&qF~1wtUz4$-Tv1;$UNtmx?smr9b(18-eFVzyF0nXNjC0vuoQ z5vYt-&OGiOhBb+JQe*iwmg<5pBgvZUNe>^SB<7}oLdkp&Vz-4FU_7%b@+|@|n-X!EB>jD$nAiXmAF z3^dQ(Y9|A;IVf#a$_ghx8VC$mmk3O@tI>AwbaS+af?`9qka*5q>)*8$4)StFu^wtR zG~CD=W3|FoV^qMtt>5&-%{Y1Ks>S1YV-^>AnIz9F*Xhdz16=XLCe}uJqTHthBi;^H zRD9f>v*&b3`}K;~Z67sJkoE5m*=p!tma!SBFvIVDuX(b~#;z`V^3!m-T?e;Z_aNbQ zbf=2H1wT4=*_7*5*LTP?E%0Q4f>~va`ku=NL_5L#LSL_T#nol|$;+i8?_-xZ!=aoRf-jG}0UuG|5&Au2^$^(qHA%Ivf~R}paSx2#4Z89Y6;XIVs5Jw%`7q?g z^=+l|nF`P@R_nYuStSfu{DC!*iQJy>EnNWRzd6{GB)+~294Mf>QKhB!j}~`Ws`>)} z*qqUhCA3+GA~G~vr17KG9O8={!2U;~P($_nXZJbSbV*En{wgP2x;Ps!ydhMT4T%)| zWI|zVBQVH_Dmo!{mZ@qd+BdI0%KFJtC`T+xoBMzt)Lba%34VY;@vs{Ba^3MJ_@vWMj#(i^}XDUki}PqM255q4hfUtZB@cz|2Qm1H3$Hn zwL2PB7ju4+I*5sO$tKw91-Hqbu}6=rAU{iT zq}u||W|HU)fS;C z$mGmlgkjsFLY*M1sc!Wy`Nay~452=_Of~&hN4M-GRa#Eo?8sr`ge+6Apd_L(W_d(! z@85|u9M1nL@ex22d>ls2y5?8JsXn>bR>{~|@aoT#R@FP>Lz>x;9i6Jc1ez^o!-K)= z@68`@d-A;r+{b{GXpeU*Kr=|*OpPmkbVu=zbIqJpE2~-}a~lQYlptrR-JU?RA)L$1 s*c-lUvwwKI{}aXd|Kg4RmEevIDz`{+HCgZ<>jVHaRCM3gDA`2(9|x7q00000 literal 0 HcmV?d00001 diff --git a/msautotest/wxs/wms_postgis_boxtoken.map b/msautotest/wxs/wms_postgis_boxtoken.map new file mode 100644 index 0000000000..93691ab11b --- /dev/null +++ b/msautotest/wxs/wms_postgis_boxtoken.map @@ -0,0 +1,110 @@ +# +# Test the !BOX! token trick, through WMS +# +# REQUIRES: INPUT=POSTGIS INPUT=GDAL OUTPUT=PNG SUPPORTS=WMS +# +# Draw a map with a single polygon layer. BBOX is set to keep image square +# RUN_PARMS: wms_get_map_polygon_postgis_boxtoken.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WMS&VERSION=1.1.0&REQUEST=GetMap&SRS=EPSG:4326&BBOX=-67.5725,42.3683,-58.9275,48.13&FORMAT=image/png&WIDTH=300&HEIGHT=200&STYLES=&LAYERS=road" > [RESULT_DEMIME] +# +MAP + +NAME WMS_TEST +STATUS ON +SIZE 400 300 +#EXTENT 2018000 -73300 3410396 647400 +#UNITS METERS +EXTENT -67.5725 42 -58.9275 48.5 +UNITS DD +IMAGECOLOR 255 255 255 +SHAPEPATH ./data +SYMBOLSET etc/symbols.sym +FONTSET etc/fonts.txt + + +OUTPUTFORMAT + NAME GDPNG + DRIVER "GD/PNG" + MIMETYPE "image/png" +# IMAGEMODE RGB + EXTENSION "png" +END + + +# +# Start of web interface definition +# +WEB + + IMAGEPATH "/tmp/ms_tmp/" + IMAGEURL "/ms_tmp/" + + METADATA + "ows_updatesequence" "123" + "wms_title" "Test simple wms" + "wms_onlineresource" "http://localhost/path/to/wms_simple?" + "ows_srs" "EPSG:42304 EPSG:42101 EPSG:4269 EPSG:4326" + "ows_schemas_location" "http://schemas.opengis.net" + "ows_keywordlist" "ogc,wms,mapserver" + "ows_service_onlineresource" "https://mapserver.org/" + "ows_fees" "None" + "ows_accessconstraints" "None" + "ows_addresstype" "postal" + "ows_address" "123 SomeRoad Road" + "ows_city" "Lunenburg" + "ows_stateorprovince" "Nova Scotia" + "ows_postcode" "xxx-xxx" + "ows_country" "Canada" + "ows_contactelectronicmailaddress" "jmckenna@xxxxxxx.xxx" + "ows_contactvoicetelephone" "+xx-xxx-xxx-xxxx" + "ows_contactfacsimiletelephone" "+xx-xxx-xxx-xxxx" + "ows_contactperson" "Jeff McKenna" + "ows_contactorganization" "MapServer" + "ows_contactposition" "self" + + "ows_rootlayer_title" "My Layers" + "ows_rootlayer_abstract" "These are my layers" + "ows_rootlayer_keywordlist" "layers,list" + "ows_layerlimit" "1" + "ows_enable_request" "*" + "wms_getmap_formatlist" "image/png,image/png; mode=24bit,image/jpeg,image/gif,image/png; mode=8bit,image/tiff" + END +END + +PROJECTION + "init=epsg:4326" + #"init=./data/epsg2:42304" +END + + +# +# Start of layer definitions +# + +LAYER + NAME road + INCLUDE "postgis.include" + DATA "the_geom from (select * from road WHERE ST_Intersects(the_geom, !BOX!)) as foo using unique gid using srid=3978" + TEMPLATE "ttt" + METADATA + "wms_title" "road" + "wms_description" "Roads of I.P.E." + "wms_srs" "EPSG:43204" + "gml_include_items" "all" + END + TYPE LINE + STATUS ON + PROJECTION + "init=epsg:3978" + END + + CLASSITEM "name_e" + CLASS + NAME "Roads" + STYLE + SYMBOL 0 + COLOR 220 0 0 + END + END +END # Layer + +END # Map File From a3d4f098a4e931d833c9e75b357cc8e1e57cf667 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 4 Sep 2022 11:04:08 -0300 Subject: [PATCH 027/170] Check if a LAYER has a NAME before accessing the property (#6607) Co-authored-by: sethg --- mapwms.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mapwms.cpp b/mapwms.cpp index d06f0bc514..294d8f232f 100644 --- a/mapwms.cpp +++ b/mapwms.cpp @@ -539,8 +539,10 @@ void msWMSPrepareNestedGroups(mapObj* map, int /* nVersion */, char*** nestedGro } /* Iterate through layers to find out whether they are in any of the nested groups */ for (int i = 0; i < map->numlayers; i++) { - if( uniqgroups.find(msStringToLower(std::string(GET_LAYER(map, i)->name))) != uniqgroups.end() ) { - isUsedInNestedGroup[i] = 1; + if (GET_LAYER(map, i)->name) { + if( uniqgroups.find(msStringToLower(std::string(GET_LAYER(map, i)->name))) != uniqgroups.end() ) { + isUsedInNestedGroup[i] = 1; + } } } } From 6c3e6ab499caf5a18b160cc7b3cae9b0aa587649 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Mon, 5 Sep 2022 11:22:03 -0300 Subject: [PATCH 028/170] update for 8.0.0-rc2 release --- CMakeLists.txt | 2 +- HISTORY.TXT | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 26e14300f7..0500379d43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) -set (MapServer_VERSION_SUFFIX "-rc1") +set (MapServer_VERSION_SUFFIX "-rc2") # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user diff --git a/HISTORY.TXT b/HISTORY.TXT index 80e684944d..eec42481fe 100644 --- a/HISTORY.TXT +++ b/HISTORY.TXT @@ -12,6 +12,13 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +8.0.0-rc2 release (2022-09-05) +------------------------------ + +- fix !BOX! token not working for a PostGIS connection (#6601) + +- check if a LAYER has a NAME, before including it in a GROUP (#6603) + 8.0.0-rc1 release (2022-08-19) ------------------------------ From 984d976d5ae9df35b40dedf814b93ee987401540 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Sep 2022 07:48:21 -0300 Subject: [PATCH 029/170] update tests for PHP 8.1.10 release (#6611) Co-authored-by: Jeff McKenna --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73dbfe57c2..4e26ae0b91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: - BUILD_NAME=PHP_8.0 - PYTHON_VERSION=3.8 - - php: 8.1.9 + - php: 8.1.10 env: - BUILD_NAME=PHP_8.1 - PYTHON_VERSION=3.9 From a50744748797057f2c3a7509cd82e36dde6d9eb6 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Mon, 12 Sep 2022 11:34:03 -0300 Subject: [PATCH 030/170] update for 8.0.0 release --- CMakeLists.txt | 2 +- HISTORY.TXT | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0500379d43..949900c559 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) set (MapServer_VERSION_REVISION 0) -set (MapServer_VERSION_SUFFIX "-rc2") +set (MapServer_VERSION_SUFFIX "") # Set C++ version # Make CMAKE_CXX_STANDARD available as cache option overridable by user diff --git a/HISTORY.TXT b/HISTORY.TXT index eec42481fe..12b5b1c035 100644 --- a/HISTORY.TXT +++ b/HISTORY.TXT @@ -12,6 +12,11 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +8.0.0 release (2022-09-12) +-------------------------- + +RC2 was released as the final 8.0.0 (see major changes below) + 8.0.0-rc2 release (2022-09-05) ------------------------------ From 137b4bf7489e03a11d58cfd0c3d2ec6975ec65b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 15:25:13 -0300 Subject: [PATCH 031/170] update security policy to mention 8.0 release (#6618) --- SECURITY.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 20cc093f94..ac7faa18b5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,13 +13,14 @@ submissions, when describing the vulnerability (see https://mapserver.org/develo The MapServer PSC (Project Steering Committee) will release patches for security vulnerabilities for the last release branch of the **two most recent release series** (such as 8.x, 7.x. 6.x, etc...). Patches will only be provided **for a period of three years** from the release date of the current series. -For example, once 8.0 is released, then only 8.0.x and 7.6.x will be supported/patched and 7.6.x will +For example, as 8.0 has been released, now only 8.0.x and 7.6.x will be supported/patched and 7.6.x will only be supported for three years from the date of the 8.0 series release. Currently, the following versions are supported: | Version | Supported | | ------- | ------------------ | +| 8.0.x | :white_check_mark: | | 7.6.x | :white_check_mark: | | 7.4.x | :x: | | 7.2.x | :x: | @@ -27,6 +28,7 @@ Currently, the following versions are supported: | 6.4.x | :x: | | < 6.4 | :x: | +Note: _MapServer 8.0.0 was released on 2022-09-12._ Note: _MapServer 7.0.0 was released on 2015-07-24._ ## Version Numbering: Explained @@ -37,7 +39,7 @@ version x.y.z means: - Major release series number. - Major releases indicate substantial changes to the software and backwards compatibility is not guaranteed across series. Current - release series is 7. + release series is 8. **y** - Minor release series number. From a78f782e9f05e4ec44d7a8dd9b252b90e167d6fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 14:07:00 -0300 Subject: [PATCH 032/170] Possible fix for #6613 by setting layer startindex for paging (#6619) --- mapogcapi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mapogcapi.cpp b/mapogcapi.cpp index 4c5c08cd3a..3c136037fc 100644 --- a/mapogcapi.cpp +++ b/mapogcapi.cpp @@ -1058,9 +1058,10 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co return MS_SUCCESS; } - // msExecuteQuery() use a 1-based offst convention, whereas the API + // msExecuteQuery() use a 1-based offset convention, whereas the API // uses a 0-based offset convention. map->query.startindex = 1 + offset; + layer->startindex = 1 + offset; } if(msExecuteQuery(map) != MS_SUCCESS) { From 3b9483dbb149ea2e7f1d492bca854f54129a0227 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 14:07:35 -0300 Subject: [PATCH 033/170] Redact password= content in msError() and msDebug() messages (#6620) --- mapdebug.c | 20 +++++++++----------- maperror.c | 14 ++++++++++++++ maperror.h | 1 + mappostgis.cpp | 14 +------------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/mapdebug.c b/mapdebug.c index 75261808ba..1ef0788b1f 100644 --- a/mapdebug.c +++ b/mapdebug.c @@ -326,10 +326,18 @@ void msDebug( const char * pszFormat, ... ) { va_list args; debugInfoObj *debuginfo = msGetDebugInfoObj(); + char szMessage[MESSAGELENGTH]; if (debuginfo == NULL || debuginfo->debug_mode == MS_DEBUGMODE_OFF) return; /* Don't waste time here! */ + va_start(args, pszFormat); + vsnprintf( szMessage, MESSAGELENGTH, pszFormat, args ); + va_end(args); + szMessage[MESSAGELENGTH-1] = '\0'; + + msRedactCredentials(szMessage); + if (debuginfo->fp) { /* Writing to a stdio file handle */ @@ -347,21 +355,11 @@ void msDebug( const char * pszFormat, ... ) msStringChop(ctime(&t)), (long)tv.tv_usec); } - va_start(args, pszFormat); - msIO_vfprintf(debuginfo->fp, pszFormat, args); - va_end(args); + msIO_fprintf(debuginfo->fp, "%s", szMessage); } #ifdef _WIN32 else if (debuginfo->debug_mode == MS_DEBUGMODE_WINDOWSDEBUG) { /* Writing to Windows Debug Console */ - - char szMessage[MESSAGELENGTH]; - - va_start(args, pszFormat); - vsnprintf( szMessage, MESSAGELENGTH, pszFormat, args ); - va_end(args); - - szMessage[MESSAGELENGTH-1] = '\0'; OutputDebugStringA(szMessage); } #endif diff --git a/maperror.c b/maperror.c index 389b1a529d..35683da184 100644 --- a/maperror.c +++ b/maperror.c @@ -327,6 +327,18 @@ char *msGetErrorString(const char *delimiter) return(errstr); } +void msRedactCredentials(char* str) +{ + char* password = strstr(str, "password="); + if (password != NULL) { + char* ptr = password + strlen("password="); + while (*ptr != '\0' && *ptr != ' ') { + *ptr = '*'; + ptr++; + } + } +} + void msSetError(int code, const char *message_fmt, const char *routine, ...) { errorObj *ms_error; @@ -359,6 +371,8 @@ void msSetError(int code, const char *message_fmt, const char *routine, ...) else ++ms_error->errorcount; + msRedactCredentials(ms_error->message); + /* Log a copy of errors to MS_ERRORFILE if set (handled automatically inside msDebug()) */ msDebug("%s: %s %s\n", ms_error->routine, ms_errorCodes[ms_error->code], ms_error->message); diff --git a/maperror.h b/maperror.h index 8a7c87c23a..f7de095e1c 100644 --- a/maperror.h +++ b/maperror.h @@ -150,6 +150,7 @@ Errors are managed as a chained list with the first item being the most recent e MS_DLL_EXPORT char *msGetErrorString(const char *delimiter); #ifndef SWIG + MS_DLL_EXPORT void msRedactCredentials(char* str); MS_DLL_EXPORT void msSetError(int code, const char *message, const char *routine, ...) MS_PRINT_FUNC_FORMAT(2,4) ; MS_DLL_EXPORT void msWriteError(FILE *stream); MS_DLL_EXPORT void msWriteErrorXML(FILE *stream); diff --git a/mappostgis.cpp b/mappostgis.cpp index e54121b8ad..b8cbd77879 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -2367,25 +2367,13 @@ static int msPostGISLayerOpen(layerObj *layer) ** Connection failed, return error message with passwords ***ed out. */ if (!layerinfo->pgconn || PQstatus(layerinfo->pgconn) == CONNECTION_BAD) { - char *index, *maskeddata; if (layer->debug) msDebug("msPostGISLayerOpen: Connection failure.\n"); - maskeddata = msStrdup(layer->connection); - index = strstr(maskeddata, "password="); - if (index != nullptr) { - index = (char*)(index + 9); - while (*index != '\0' && *index != ' ') { - *index = '*'; - index++; - } - } - - msDebug( "Database connection failed (%s) with connect string '%s'\nIs the database running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port? in msPostGISLayerOpen()", PQerrorMessage(layerinfo->pgconn), maskeddata); + msDebug( "Database connection failed (%s) with connect string '%s'\nIs the database running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port? in msPostGISLayerOpen()", PQerrorMessage(layerinfo->pgconn), layer->connection); msSetError(MS_QUERYERR, "Database connection failed. Check server logs for more details.Is the database running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port?", "msPostGISLayerOpen()"); if(layerinfo->pgconn) PQfinish(layerinfo->pgconn); - free(maskeddata); delete layerinfo; return MS_FAILURE; } From 7045a7e9eac51ff900a735c572e6bfd887bf9bce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 17:02:29 -0300 Subject: [PATCH 034/170] update TravisCI for Python version (#6623) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4e26ae0b91..8959b23370 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: - php: 7.4 env: - BUILD_NAME=PHP_7.4_WITH_ASAN - - PYTHON_VERSION=3.7.7 + - PYTHON_VERSION=3.7.13 - CRYPTOGRAPHY_DONT_BUILD_RUST=1 # to avoid issue when building Cryptography python module (https://travis-ci.com/github/MapServer/MapServer/jobs/482212623) - php: 8.0 From 148fa2a65e3907fc0ddafb13ae7da9bbdecb92f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:07:30 -0300 Subject: [PATCH 035/170] correct CONFIG url message (#6627) --- mapfile.c | 2 +- mapserv-config.cpp | 2 +- msautotest/config/expected/missing_conf.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mapfile.c b/mapfile.c index 8e4bee839b..f9ca45df6b 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4161,7 +4161,7 @@ int loadLayer(layerObj *layer, mapObj *map) plugin_library = msConfigGetPlugin(map->config, value); msFree(value); if(!plugin_library) { - msSetError(MS_MISCERR, "Plugin value not found in config file. See mapserver.org/config_file.html for more information." , "loadLayer()"); + msSetError(MS_MISCERR, "Plugin value not found in config file. See mapserver.org/mapfile/config.html for more information." , "loadLayer()"); return(-1); } layer->plugin_library_original = strdup(plugin_library); diff --git a/mapserv-config.cpp b/mapserv-config.cpp index 779473b485..7906c49ee1 100644 --- a/mapserv-config.cpp +++ b/mapserv-config.cpp @@ -145,7 +145,7 @@ configObj *msLoadConfig(const char* ms_config_file) if((msyyin = fopen(ms_config_file, "r")) == NULL) { msDebug("Cannot open configuration file %s.\n", ms_config_file); - msSetError(MS_IOERR, "See mapserver.org/config_file.html for more information.", "msLoadConfig()"); + msSetError(MS_IOERR, "See mapserver.org/mapfile/config.html for more information.", "msLoadConfig()"); msReleaseLock(TLOCK_PARSER); msFree(config); return NULL; diff --git a/msautotest/config/expected/missing_conf.txt b/msautotest/config/expected/missing_conf.txt index e9830ec7ac..7fb9ba8bab 100644 --- a/msautotest/config/expected/missing_conf.txt +++ b/msautotest/config/expected/missing_conf.txt @@ -2,5 +2,5 @@ Content-Type: text/html MapServer Message -msLoadConfig(): Unable to access file. See mapserver.org/config_file.html for more information. +msLoadConfig(): Unable to access file. See mapserver.org/mapfile/config.html for more information. \ No newline at end of file From 806ab4c20a7498a39fabe25cc26b3c7145fd8327 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 29 Sep 2022 20:03:39 +0200 Subject: [PATCH 036/170] shapeObjTest.php: adjust expected result to fix https://github.com/MapServer/MapServer/actions/runs/3153195615/jobs/5129376375 --- msautotest/php/shapeObjTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msautotest/php/shapeObjTest.php b/msautotest/php/shapeObjTest.php index fb489c0fca..666d10f274 100644 --- a/msautotest/php/shapeObjTest.php +++ b/msautotest/php/shapeObjTest.php @@ -37,7 +37,7 @@ public function testdistanceToShape() $line2->add(new pointObj(3,5)); $shape2->add($line2); - $this->assertEquals(1.4142135623731, $this->shape->distanceToShape($shape2)); + $this->assertEquals(1.4142135623730951, $this->shape->distanceToShape($shape2)); } public function test__setresultindex() From c97ad488303dad8a1015a5c8ead73aafa0ec783d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 29 Sep 2022 19:05:00 +0200 Subject: [PATCH 037/170] msLoadConfig(): fix memory leak if configuration file cannot be open --- mapserv-config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mapserv-config.cpp b/mapserv-config.cpp index 7906c49ee1..d7a0b20ded 100644 --- a/mapserv-config.cpp +++ b/mapserv-config.cpp @@ -137,7 +137,7 @@ configObj *msLoadConfig(const char* ms_config_file) MS_CHECK_ALLOC(config, sizeof(configObj), NULL); if(initConfig(config) != MS_SUCCESS) { - msFree(config); + msFreeConfig(config); return NULL; } @@ -147,7 +147,7 @@ configObj *msLoadConfig(const char* ms_config_file) msDebug("Cannot open configuration file %s.\n", ms_config_file); msSetError(MS_IOERR, "See mapserver.org/mapfile/config.html for more information.", "msLoadConfig()"); msReleaseLock(TLOCK_PARSER); - msFree(config); + msFreeConfig(config); return NULL; } From dd18e10881134f549cdcf05b85fac67d641115ff Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Sep 2022 16:47:28 +0200 Subject: [PATCH 038/170] msInsertErrorObj(): limit number of linked errors to 100 to avoid unbounded memory usage Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51551 --- maperror.c | 6 ++++-- maperror.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/maperror.c b/maperror.c index 35683da184..6de97c5b6e 100644 --- a/maperror.c +++ b/maperror.c @@ -132,7 +132,7 @@ errorObj *msGetErrorObj() /* We don't have one ... initialize one. */ else if( link == NULL || link->next == NULL ) { te_info_t *new_link; - errorObj error_obj = { MS_NOERR, "", "", 0, 0, NULL }; + errorObj error_obj = { MS_NOERR, "", "", 0, 0, NULL, 0 }; new_link = (te_info_t *) malloc(sizeof(te_info_t)); new_link->next = error_list; @@ -180,7 +180,7 @@ static errorObj *msInsertErrorObj(void) errorObj *ms_error; ms_error = msGetErrorObj(); - if (ms_error->code != MS_NOERR) { + if (ms_error->code != MS_NOERR && ms_error->totalerrorcount < 100) { /* Head of the list already in use, insert a new errorObj after the head * and move head contents to this new errorObj, freeing the errorObj * for reuse. @@ -207,6 +207,7 @@ static errorObj *msInsertErrorObj(void) ms_error->message[0] = '\0'; ms_error->errorcount = 0; } + ms_error->totalerrorcount ++; } return ms_error; @@ -236,6 +237,7 @@ void msResetErrorList() ms_error->routine[0] = '\0'; ms_error->message[0] = '\0'; ms_error->errorcount = 0; + ms_error->totalerrorcount = 0; /* -------------------------------------------------------------------- */ /* Cleanup our entry in the thread list. This is mainly */ diff --git a/maperror.h b/maperror.h index f7de095e1c..b8196d6325 100644 --- a/maperror.h +++ b/maperror.h @@ -119,6 +119,7 @@ Errors are managed as a chained list with the first item being the most recent e int errorcount; ///< Number of subsequent errors #ifndef SWIG struct errorObj *next; + int totalerrorcount; #endif } errorObj; From f982a03ddd352920175bb36a3331ca2c3dd764b1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Sep 2022 16:48:30 +0200 Subject: [PATCH 039/170] shape reader: fix use of uninitialized memory on corrupted file, and other sanitizations Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51539 --- mapshape.c | 111 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 36 deletions(-) diff --git a/mapshape.c b/mapshape.c index c3ff715731..69fd40b42e 100644 --- a/mapshape.c +++ b/mapshape.c @@ -38,6 +38,7 @@ #include #include +#include #include "mapserver.h" #include "mapows.h" @@ -992,7 +993,7 @@ static uchar *msSHPReadAllocateBuffer( SHPHandle psSHP, int hEntity, const char* { int nEntitySize = msSHXReadSize(psSHP, hEntity); - if( nEntitySize < 0 || nEntitySize > INT_MAX - 8 ) { + if( nEntitySize <= 0 || nEntitySize > INT_MAX - 8 ) { msSetError(MS_MEMERR, "Out of memory. Cannot allocate %d bytes. Probably broken shapefile at feature %d", pszCallingFunction, nEntitySize, hEntity); return NULL; @@ -1065,7 +1066,8 @@ int msSHPReadPoint( SHPHandle psSHP, int hEntity, pointObj *point ) /* -------------------------------------------------------------------- */ /* Read the record. */ /* -------------------------------------------------------------------- */ - if( 0 != VSIFSeekL( psSHP->fpSHP, msSHXReadOffset( psSHP, hEntity), 0 )) { + const int offset = msSHXReadOffset( psSHP, hEntity); + if( offset <= 0 || 0 != VSIFSeekL( psSHP->fpSHP, offset, 0 )) { msSetError(MS_IOERR, "failed to seek offset", "msSHPReadPoint()"); return(MS_FAILURE); } @@ -1094,7 +1096,7 @@ int msSHPReadPoint( SHPHandle psSHP, int hEntity, pointObj *point ) ** successive accesses during the reading cycle (first bounds are read, ** then entire shapes). Each time we read a page, we mark it as read. */ -static int msSHXLoadPage( SHPHandle psSHP, int shxBufferPage ) +static bool msSHXLoadPage( SHPHandle psSHP, int shxBufferPage ) { int i; @@ -1105,27 +1107,34 @@ static int msSHXLoadPage( SHPHandle psSHP, int shxBufferPage ) if( shxBufferPage < 0 ) return(MS_FAILURE); + const int nShapesToCache = + shxBufferPage < psSHP->nRecords / SHX_BUFFER_PAGE ? SHX_BUFFER_PAGE : + psSHP->nRecords - shxBufferPage * SHX_BUFFER_PAGE; + if( 0 != VSIFSeekL( psSHP->fpSHX, 100 + shxBufferPage * SHX_BUFFER_PAGE * 8, 0 )) { - /* - * msSetError(MS_IOERR, "failed to seek offset", "msSHXLoadPage()"); - * return(MS_FAILURE); - */ + memset(psSHP->panRecOffset + shxBufferPage * SHX_BUFFER_PAGE, 0, + nShapesToCache * sizeof(psSHP->panRecOffset[0])); + memset(psSHP->panRecSize + shxBufferPage * SHX_BUFFER_PAGE, 0, + nShapesToCache * sizeof(psSHP->panRecSize[0])); + msSetBit(psSHP->panRecLoaded, shxBufferPage, 1); + msSetError(MS_IOERR, "failed to seek offset", "msSHXLoadPage()"); + return false; } - if( SHX_BUFFER_PAGE != VSIFReadL( buffer, 8, SHX_BUFFER_PAGE, psSHP->fpSHX )) { - /* - * msSetError(MS_IOERR, "failed to fread SHX record", "msSHXLoadPage()"); - * return(MS_FAILURE); - */ + + if( (size_t)nShapesToCache != VSIFReadL( buffer, 8, nShapesToCache, psSHP->fpSHX )) { + memset(psSHP->panRecOffset + shxBufferPage * SHX_BUFFER_PAGE, 0, + nShapesToCache * sizeof(psSHP->panRecOffset[0])); + memset(psSHP->panRecSize + shxBufferPage * SHX_BUFFER_PAGE, 0, + nShapesToCache * sizeof(psSHP->panRecSize[0])); + msSetBit(psSHP->panRecLoaded, shxBufferPage, 1); + msSetError(MS_IOERR, "failed to fread SHX record", "msSHXLoadPage()"); + return false; } /* Copy the buffer contents out into the working arrays. */ - for( i = 0; i < SHX_BUFFER_PAGE; i++ ) { + for( i = 0; i < nShapesToCache; i++ ) { int tmpOffset, tmpSize; - /* Don't write information past the end of the arrays, please. */ - if(psSHP->nRecords <= (shxBufferPage * SHX_BUFFER_PAGE + i) ) - break; - memcpy( &tmpOffset, (buffer + (8*i)), 4); memcpy( &tmpSize, (buffer + (8*i) + 4), 4); @@ -1138,8 +1147,15 @@ static int msSHXLoadPage( SHPHandle psSHP, int shxBufferPage ) /* SHX stores the offsets in 2 byte units, so we double them to get */ /* an offset in bytes. */ - tmpOffset = tmpOffset * 2; - tmpSize = tmpSize * 2; + if( tmpOffset < INT_MAX / 2 ) + tmpOffset = tmpOffset * 2; + else + tmpOffset = 0; + + if( tmpSize < INT_MAX / 2 ) + tmpSize = tmpSize * 2; + else + tmpSize = 0; /* Write the answer into the working arrays on the SHPHandle */ psSHP->panRecOffset[shxBufferPage * SHX_BUFFER_PAGE + i] = tmpOffset; @@ -1157,7 +1173,12 @@ static int msSHXLoadAll( SHPHandle psSHP ) int i; uchar *pabyBuf; - pabyBuf = (uchar *) msSmallMalloc(8 * psSHP->nRecords ); + pabyBuf = (uchar *) malloc(8 * psSHP->nRecords ); + if( pabyBuf == NULL ) + { + msSetError(MS_IOERR, "failed to allocate memory for SHX buffer", "msSHXLoadAll()"); + return MS_FAILURE; + } if((size_t)psSHP->nRecords != VSIFReadL( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )) { msSetError(MS_IOERR, "failed to read shx records", "msSHXLoadAll()"); free(pabyBuf); @@ -1174,8 +1195,20 @@ static int msSHXLoadAll( SHPHandle psSHP ) nLength = SWAP_FOUR_BYTES( nLength ); } - psSHP->panRecOffset[i] = nOffset*2; - psSHP->panRecSize[i] = nLength*2; + /* SHX stores the offsets in 2 byte units, so we double them to get */ + /* an offset in bytes. */ + if( nOffset < INT_MAX / 2 ) + nOffset = nOffset * 2; + else + nOffset = 0; + + if( nLength < INT_MAX / 2 ) + nLength = nLength * 2; + else + nLength = 0; + + psSHP->panRecOffset[i] = nOffset; + psSHP->panRecSize[i] = nLength; } free(pabyBuf); psSHP->panRecAllLoaded = 1; @@ -1191,7 +1224,7 @@ static int msSHXReadOffset( SHPHandle psSHP, int hEntity ) /* Validate the record/entity number. */ if( hEntity < 0 || hEntity >= psSHP->nRecords ) - return(MS_FAILURE); + return 0; if( ! (psSHP->panRecAllLoaded || msGetBit(psSHP->panRecLoaded, shxBufferPage)) ) { msSHXLoadPage( psSHP, shxBufferPage ); @@ -1208,7 +1241,7 @@ static int msSHXReadSize( SHPHandle psSHP, int hEntity ) /* Validate the record/entity number. */ if( hEntity < 0 || hEntity >= psSHP->nRecords ) - return(MS_FAILURE); + return 0; if( ! (psSHP->panRecAllLoaded || msGetBit(psSHP->panRecLoaded, shxBufferPage)) ) { msSHXLoadPage( psSHP, shxBufferPage ); @@ -1249,8 +1282,16 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape ) if( hEntity < 0 || hEntity >= psSHP->nRecords ) return; - nEntitySize = msSHXReadSize(psSHP, hEntity) + 8; + nEntitySize = msSHXReadSize(psSHP, hEntity); + if( nEntitySize < 4 || nEntitySize > INT_MAX - 8 ) + { + shape->type = MS_SHAPE_NULL; + msSetError(MS_SHPERR, "Corrupted feature encountered. hEntity = %d, nEntitySize=%d", "msSHPReadShape()", + hEntity, nEntitySize); + return; + } + nEntitySize += 8; if( nEntitySize == 12 ) { shape->type = MS_SHAPE_NULL; return; @@ -1265,7 +1306,8 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape ) /* -------------------------------------------------------------------- */ /* Read the record. */ /* -------------------------------------------------------------------- */ - if( 0 != VSIFSeekL( psSHP->fpSHP, msSHXReadOffset( psSHP, hEntity), 0 )) { + const int offset = msSHXReadOffset( psSHP, hEntity); + if( offset <= 0 || 0 != VSIFSeekL( psSHP->fpSHP, offset, 0 )) { msSetError(MS_IOERR, "failed to seek offset", "msSHPReadShape()"); shape->type = MS_SHAPE_NULL; return; @@ -1626,16 +1668,18 @@ int msSHPReadBounds( SHPHandle psSHP, int hEntity, rectObj *padBounds) padBounds->maxy = psSHP->adBoundsMax[1]; } else { - if( msSHXReadSize(psSHP, hEntity) == 4 ) { /* NULL shape */ + if( msSHXReadSize(psSHP, hEntity) <= 4 ) { /* NULL shape */ padBounds->minx = padBounds->miny = padBounds->maxx = padBounds->maxy = 0.0; return MS_FAILURE; } + const int offset = msSHXReadOffset( psSHP, hEntity); + if( offset <= 0 || offset >= INT_MAX - 12 || 0 != VSIFSeekL( psSHP->fpSHP, offset + 12, 0 )) { + msSetError(MS_IOERR, "failed to seek offset", "msSHPReadBounds()"); + return(MS_FAILURE); + } + if( psSHP->nShapeType != SHP_POINT && psSHP->nShapeType != SHP_POINTZ && psSHP->nShapeType != SHP_POINTM) { - if( 0 != VSIFSeekL( psSHP->fpSHP, msSHXReadOffset( psSHP, hEntity) + 12, 0 )) { - msSetError(MS_IOERR, "failed to seek offset", "msSHPReadBounds()"); - return(MS_FAILURE); - } if( 1 != VSIFReadL( padBounds, sizeof(double)*4, 1, psSHP->fpSHP )) { msSetError(MS_IOERR, "failed to fread record", "msSHPReadBounds()"); return(MS_FAILURE); @@ -1657,11 +1701,6 @@ int msSHPReadBounds( SHPHandle psSHP, int hEntity, rectObj *padBounds) /* For points we fetch the point, and duplicate it as the */ /* minimum and maximum bound. */ /* -------------------------------------------------------------------- */ - - if( 0 != VSIFSeekL( psSHP->fpSHP, msSHXReadOffset( psSHP, hEntity) + 12, 0 )) { - msSetError(MS_IOERR, "failed to seek offset", "msSHPReadBounds()"); - return(MS_FAILURE); - } if( 1 != VSIFReadL( padBounds, sizeof(double)*2, 1, psSHP->fpSHP )) { msSetError(MS_IOERR, "failed to fread record", "msSHPReadBounds()"); return(MS_FAILURE); From 183eb8b22917fc33b0b2ac6d44cce334f00885d4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 2 Oct 2022 21:03:43 +0200 Subject: [PATCH 040/170] mapshape.c: avoid integer overflow in msSHPOpenVirtualFile() Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51532 --- mapshape.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/mapshape.c b/mapshape.c index 69fd40b42e..d24f6798c7 100644 --- a/mapshape.c +++ b/mapshape.c @@ -229,10 +229,22 @@ SHPHandle msSHPOpenVirtualFile( VSILFILE * fpSHP, VSILFILE * fpSHX ) return( NULL ); } - psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256 - + pabyBuf[25] * 256 * 256 - + pabyBuf[26] * 256 - + pabyBuf[27]) * 2; + if( !bBigEndian ) SwapWord( 4, pabyBuf+24 ); + memcpy(&psSHP->nFileSize, pabyBuf+24, 4); + if( psSHP->nFileSize < 0 || psSHP->nFileSize > INT_MAX / 2 ) { + msDebug("Invalid / unsupported nFileSize = %d value. Got it from actual file length", psSHP->nFileSize); + VSIFSeekL( psSHP->fpSHP, 0, SEEK_END ); + vsi_l_offset nSize = VSIFTellL( psSHP->fpSHP ); + if( nSize > (vsi_l_offset)INT_MAX ) { + msDebug("Actual .shp size is larger than 2 GB. Not suported. Invalidating nFileSize"); + psSHP->nFileSize = 0; + } + else + psSHP->nFileSize = (int)nSize; + } + else { + psSHP->nFileSize *= 2; + } /* -------------------------------------------------------------------- */ /* Read SHX file Header info */ @@ -247,7 +259,7 @@ SHPHandle msSHPOpenVirtualFile( VSILFILE * fpSHP, VSILFILE * fpSHX ) } if( pabyBuf[0] != 0 || pabyBuf[1] != 0 || pabyBuf[2] != 0x27 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) { - msSetError(MS_SHPERR, "Corrupted .shp file", "msSHPOpen()"); + msSetError(MS_SHPERR, "Corrupted .shx file", "msSHPOpen()"); VSIFCloseL( psSHP->fpSHP ); VSIFCloseL( psSHP->fpSHX ); free( psSHP ); @@ -256,12 +268,16 @@ SHPHandle msSHPOpenVirtualFile( VSILFILE * fpSHP, VSILFILE * fpSHX ) return( NULL ); } - psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256 + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256; - if (psSHP->nRecords != 0) - psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8; + int nSHXHalfFileSize; + if( !bBigEndian ) SwapWord( 4, pabyBuf+24 ); + memcpy(&nSHXHalfFileSize, pabyBuf+24, 4); + if (nSHXHalfFileSize != 0) + psSHP->nRecords = (nSHXHalfFileSize - 50) / 4; // (nSHXFileSize - 100) / 8 + else + psSHP->nRecords = 0; if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) { - msSetError(MS_SHPERR, "Corrupted .shp file : nRecords = %d.", "msSHPOpen()", + msSetError(MS_SHPERR, "Corrupted .shx file : nRecords = %d.", "msSHPOpen()", psSHP->nRecords); VSIFCloseL( psSHP->fpSHP ); VSIFCloseL( psSHP->fpSHX ); @@ -603,6 +619,7 @@ int msSHPWritePoint(SHPHandle psSHP, pointObj *point ) ms_int32 i32, nPoints, nParts; if( psSHP->nShapeType != SHP_POINT) return(-1); + if( psSHP->nFileSize == 0 ) return -1; psSHP->bUpdated = MS_TRUE; @@ -697,6 +714,9 @@ int msSHPWriteShape(SHPHandle psSHP, shapeObj *shape ) int nShapeType; ms_int32 i32, nPoints, nParts; + + if( psSHP->nFileSize == 0 ) return -1; + psSHP->bUpdated = MS_TRUE; /* Fill the SHX buffer if it is not already full. */ From cc44cacb5a597246d06add09651da3f100a7372b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 2 Oct 2022 21:11:25 +0200 Subject: [PATCH 041/170] loadProjection(): avoid write heap-bufer-overflow on invalid PROJECTION block Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52066 --- mapfile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mapfile.c b/mapfile.c index f9ca45df6b..47fba4903d 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1195,6 +1195,12 @@ static int loadProjection(projectionObj *p) break; case(MS_STRING): case(MS_AUTO): + if( i == MS_MAXPROJARGS ) { + msSetError(MS_MISCERR, "Parsing error near (%s):(line %d): Too many arguments in projection string", "loadProjection()", + msyystring_buffer, msyylineno); + p->numargs = i; + return -1; + } p->args[i] = msStrdup(msyystring_buffer); p->automatic = MS_TRUE; i++; From af39c2a3464e4cf21e52d13d37fd1c470468b963 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 4 Oct 2022 01:23:58 +0200 Subject: [PATCH 042/170] Fix memory leak related to styles on invalid mapfile Found locally with ossfuzz ``` Direct leak of 1304 byte(s) in 1 object(s) allocated from: #0 0x54de9e in __interceptor_calloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:77:3 #1 0x5c6ce8 in msGrowClassStyles /src/MapServer/mapfile.c:3020:48 #2 0x5c8513 in loadClass /src/MapServer/mapfile.c:3262:12 #3 0x5d0f1e in loadLayer /src/MapServer/mapfile.c:3968:12 #4 0x5ec0a0 in loadMapInternal /src/MapServer/mapfile.c:6053:12 #5 0x5ef850 in msLoadMap /src/MapServer/mapfile.c:6333:6 #6 0x58b1df in LLVMFuzzerTestOneInput /src/MapServer/build/../fuzzers/mapfuzzer.c:50:13 #7 0x45cb33 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15 #8 0x45c31a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:514:3 #9 0x45d9e9 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:757:19 #10 0x45e6b5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:895:5 #11 0x44da1f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:912:6 #12 0x477072 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 #13 0x7f8124cb8082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee) ``` --- mapfile.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mapfile.c b/mapfile.c index 47fba4903d..84824d84e7 100755 --- a/mapfile.c +++ b/mapfile.c @@ -2961,6 +2961,11 @@ int freeClass(classObj *class) } } } + if( class->numstyles == 0 && class->styles != NULL && + class->styles[0] != NULL ) { + /* msGrowClassStyles() creates class->styles[0] during the first call */ + msFree(class->styles[0]); + } msFree(class->styles); for(i=0; inumlabels; i++) { /* each label */ From 31584c29ed94d5b2d39afa0fc333cb09324412c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 07:28:14 -0300 Subject: [PATCH 043/170] loadHashTable(): fix memory leak in error code path (#6662) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52111 --- mapfile.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mapfile.c b/mapfile.c index 84824d84e7..f80309db95 100755 --- a/mapfile.c +++ b/mapfile.c @@ -2185,7 +2185,6 @@ static void writeExpression(FILE *stream, int indent, const char *name, expressi int loadHashTable(hashTableObj *ptable) { - char *key=NULL, *data=NULL; assert(ptable); for(;;) { @@ -2196,14 +2195,19 @@ int loadHashTable(hashTableObj *ptable) case(END): return(MS_SUCCESS); case(MS_STRING): - key = msStrdup(msyystring_buffer); /* the key is *always* a string */ - if(getString(&data) == MS_FAILURE) return(MS_FAILURE); + { + char* data = NULL; + char* key = msStrdup(msyystring_buffer); /* the key is *always* a string */ + if(getString(&data) == MS_FAILURE) { + free(key); + return(MS_FAILURE); + } msInsertHashTable(ptable, key, data); free(key); free(data); - data=NULL; break; + } default: msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadHashTable()", msyystring_buffer, msyylineno ); return(MS_FAILURE); From 38ddf89c1f5f50b9ed67c01e69f25d8a208c6432 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 07:29:03 -0300 Subject: [PATCH 044/170] msLoadMap(): fix double-free related to labels (#6660) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52102 --- mapfile.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mapfile.c b/mapfile.c index f80309db95..d9da3a5f64 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1623,7 +1623,6 @@ static int loadLabel(labelObj *label) break; case(EOF): msSetError(MS_EOFERR, NULL, "loadLabel()"); - freeLabel(label); /* free any structures allocated before EOF */ return(-1); case(EXPRESSION): if(loadExpression(&(label->expression)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ @@ -3235,7 +3234,9 @@ int loadClass(classObj *class, layerObj *layer) initLabel(class->labels[class->numlabels]); class->labels[class->numlabels]->size = MS_MEDIUM; /* only set a default if the LABEL section is present */ if(loadLabel(class->labels[class->numlabels]) == -1) { - msFree(class->labels[class->numlabels]); + freeLabel(class->labels[class->numlabels]); + free(class->labels[class->numlabels]); + class->labels[class->numlabels] = NULL; return(-1); } class->numlabels++; From 53ed7fe6a71813044c1b44df3b3d94e0d585b1c2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 4 Oct 2022 19:24:01 +0200 Subject: [PATCH 045/170] loadClass(): better fix for class->styles[] mem-leak Improved fix of https://github.com/MapServer/MapServer/pull/6651 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52107 --- mapfile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mapfile.c b/mapfile.c index d9da3a5f64..978ef7c4c2 100755 --- a/mapfile.c +++ b/mapfile.c @@ -2964,11 +2964,6 @@ int freeClass(classObj *class) } } } - if( class->numstyles == 0 && class->styles != NULL && - class->styles[0] != NULL ) { - /* msGrowClassStyles() creates class->styles[0] during the first call */ - msFree(class->styles[0]); - } msFree(class->styles); for(i=0; inumlabels; i++) { /* each label */ @@ -3272,7 +3267,12 @@ int loadClass(classObj *class, layerObj *layer) if(msGrowClassStyles(class) == NULL) return(-1); initStyle(class->styles[class->numstyles]); - if(loadStyle(class->styles[class->numstyles]) != MS_SUCCESS) return(-1); + if(loadStyle(class->styles[class->numstyles]) != MS_SUCCESS) { + freeStyle(class->styles[class->numstyles]); + free(class->styles[class->numstyles]); + class->styles[class->numstyles] = NULL; + return(-1); + } class->numstyles++; break; case(TEMPLATE): From e915c0238269e004d508115fe955df15a8d12d2b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 4 Oct 2022 19:29:37 +0200 Subject: [PATCH 046/170] mapfile.c: fix very likely memory leaks in error code paths after call to msGrowXXXX() functions --- mapfile.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mapfile.c b/mapfile.c index 978ef7c4c2..454123efb9 100755 --- a/mapfile.c +++ b/mapfile.c @@ -3113,6 +3113,9 @@ int msMaybeAllocateClassStyle(classObj* c, int idx) if ( initStyle(c->styles[c->numstyles]) == MS_FAILURE ) { msSetError(MS_MISCERR, "Failed to init new styleObj", "msMaybeAllocateClassStyle()"); + freeStyle(c->styles[c->numstyles]); + free(c->styles[c->numstyles]); + c->styles[c->numstyles] = NULL; return(MS_FAILURE); } c->numstyles++; @@ -3975,7 +3978,13 @@ int loadLayer(layerObj *layer, mapObj *map) if (msGrowLayerClasses(layer) == NULL) return(-1); initClass(layer->class[layer->numclasses]); - if(loadClass(layer->class[layer->numclasses], layer) == -1) return(-1); + if(loadClass(layer->class[layer->numclasses], layer) == -1) + { + freeClass(layer->class[layer->numclasses]); + free(layer->class[layer->numclasses]); + layer->class[layer->numclasses] = NULL; + return(-1); + } layer->numclasses++; break; case(CLUSTER): @@ -4215,7 +4224,10 @@ int loadLayer(layerObj *layer, mapObj *map) if (msGrowLayerScaletokens(layer) == NULL) return(-1); initScaleToken(&layer->scaletokens[layer->numscaletokens]); - if(loadScaletoken(&layer->scaletokens[layer->numscaletokens], layer) == -1) return(-1); + if(loadScaletoken(&layer->scaletokens[layer->numscaletokens], layer) == -1) { + freeScaleToken(&layer->scaletokens[layer->numscaletokens]); + return(-1); + } layer->numscaletokens++; break; case(SIZEUNITS): From 04037b969a304cd32c5142ac72680f07c842ef1e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 5 Oct 2022 22:05:28 +0200 Subject: [PATCH 047/170] msLoadMap(): fix memleak in error code path related to style loading Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52124 --- mapfile.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 454123efb9..7da18fe351 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1813,7 +1813,12 @@ static int loadLabel(labelObj *label) if(msGrowLabelStyles(label) == NULL) return(-1); initStyle(label->styles[label->numstyles]); - if(loadStyle(label->styles[label->numstyles]) != MS_SUCCESS) return(-1); + if(loadStyle(label->styles[label->numstyles]) != MS_SUCCESS) { + freeStyle(label->styles[label->numstyles]); + free(label->styles[label->numstyles]); + label->styles[label->numstyles] = NULL; + return(-1); + } if(label->styles[label->numstyles]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) label->styles[label->numstyles]->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOINT; /* set a default, a marker? */ label->numstyles++; From e2a6d22c7bce3b38eb1f7fdc46614d518c913f05 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 5 Oct 2022 22:23:58 +0200 Subject: [PATCH 048/170] msLoadFontSet(): fix null pointer dereference Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52131 --- maplabel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/maplabel.c b/maplabel.c index 418a39a589..be7fa892a3 100644 --- a/maplabel.c +++ b/maplabel.c @@ -804,6 +804,7 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) char szPath[MS_MAXPATHLEN]; int i; int bFullPath = 0; + const char* realpath; if(fontset->numfonts != 0) /* already initialized */ return(0); @@ -821,7 +822,12 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) /* return(-1); */ /* } */ - stream = VSIFOpenL( msBuildPath(szPath, fontset->map->mappath, fontset->filename), "rb"); + realpath = msBuildPath(szPath, fontset->map->mappath, fontset->filename); + if( !realpath ) { + free(path); + return -1; + } + stream = VSIFOpenL( realpath, "rb"); if(!stream) { msSetError(MS_IOERR, "Error opening fontset %s.", "msLoadFontset()", fontset->filename); From 53dff44c872c7e4d7046461030ba765579a519ef Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 5 Oct 2022 22:34:27 +0200 Subject: [PATCH 049/170] msLoadMap(): fix nullptr dereference when using LATLON keyword As far as I can see, this was broken in the nominal case since https://github.com/MapServer/MapServer/commit/f595e91f1b418db72b806162dba4470109ac8dc1 So this feature is not used in msautotest, nor documented (https://mapserver.org/search.html?q=LATLON doesn't return anything relevant) Probably that the mapObj::latlon member would be better initialized by taking the geographic CRS of the mapObj::projection. --- mapfile.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 454123efb9..37deb7b36d 100755 --- a/mapfile.c +++ b/mapfile.c @@ -6065,7 +6065,6 @@ static int loadMapInternal(mapObj *map) map->imagetype = getToken(); break; case(LATLON): - msFreeProjectionExceptContext(&map->latlon); if(loadProjection(&map->latlon) == -1) return MS_FAILURE; break; case(LAYER): From fd1fc3e27a0b4d80563811455ea4a66ea8f34661 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:25:17 -0300 Subject: [PATCH 050/170] mapshape.c: avoid 'undefined-shift' issue with SWAP_FOUR_BYTES() macro (#6673) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52130 --- mapshape.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mapshape.c b/mapshape.c index d24f6798c7..34a6b4b06e 100644 --- a/mapshape.c +++ b/mapshape.c @@ -46,9 +46,7 @@ #include /* Only use this macro on 32-bit integers! */ -#define SWAP_FOUR_BYTES(data) \ - ( ((data >> 24) & 0x000000FF) | ((data >> 8) & 0x0000FF00) | \ - ((data << 8) & 0x00FF0000) | ((data << 24) & 0xFF000000) ) +#define SWAP_FOUR_BYTES(data) CPL_SWAP32(data) #define ByteCopy( a, b, c ) memcpy( b, a, c ) From 7c4d2a63271141ddcfcbc2656aa57ca87a600c88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:25:46 -0300 Subject: [PATCH 051/170] msLoadMap(): fix memleak in error code path related to symbol loading (#6674) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52114 --- mapfile.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 454123efb9..47b0f763be 100755 --- a/mapfile.c +++ b/mapfile.c @@ -6130,7 +6130,12 @@ static int loadMapInternal(mapObj *map) case(SYMBOL): if(msGrowSymbolSet(&(map->symbolset)) == NULL) return MS_FAILURE; - if((loadSymbol(map->symbolset.symbol[map->symbolset.numsymbols], map->mappath) == -1)) return MS_FAILURE; + if((loadSymbol(map->symbolset.symbol[map->symbolset.numsymbols], map->mappath) == -1)) { + msFreeSymbol(map->symbolset.symbol[map->symbolset.numsymbols]); + free(map->symbolset.symbol[map->symbolset.numsymbols]); + map->symbolset.symbol[map->symbolset.numsymbols] = NULL; + return MS_FAILURE; + } map->symbolset.symbol[map->symbolset.numsymbols]->inmapfile = MS_TRUE; map->symbolset.numsymbols++; break; From 66b17b6b3919df419e82b730291d998d0ee1618e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:26:32 -0300 Subject: [PATCH 052/170] msLoadFontSet(): fix memleak in error code path (#6676) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52123 --- maplabel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/maplabel.c b/maplabel.c index 418a39a589..4416c56224 100644 --- a/maplabel.c +++ b/maplabel.c @@ -825,6 +825,7 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) if(!stream) { msSetError(MS_IOERR, "Error opening fontset %s.", "msLoadFontset()", fontset->filename); + free(path); return(-1); } From 5424483a07366f99f0bd3fd4fcc34acb0e68acea Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 7 Oct 2022 00:11:10 +0200 Subject: [PATCH 053/170] _msProcessAutoProjection(): fix memleak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52158 --- mapproject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mapproject.c b/mapproject.c index 5594446d46..a38794aa9f 100644 --- a/mapproject.c +++ b/mapproject.c @@ -725,6 +725,7 @@ static int _msProcessAutoProjection(projectionObj *p) "WMS/WFS AUTO/AUTO2 PROJECTION must be in the format " "'AUTO:proj_id,units_id,lon0,lat0' or 'AUTO2:crs_id,factor,lon0,lat0'(got '%s').\n", "_msProcessAutoProjection()", p->args[0]); + msFreeCharArray(args, numargs); return -1; } From 76c504a8acacde15781179c4b29e4123d0858c52 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 7 Oct 2022 13:11:43 +0200 Subject: [PATCH 054/170] maplexer.l: avoid non-null terminated msyystring_buffer that can cause read heap-buffer-overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52175 --- maplexer.c | 789 ++++++++++++++++++++++++++--------------------------- maplexer.l | 81 +++--- 2 files changed, 426 insertions(+), 444 deletions(-) diff --git a/maplexer.c b/maplexer.c index a2d9059381..b713ac90e9 100644 --- a/maplexer.c +++ b/maplexer.c @@ -1,6 +1,6 @@ -#line 2 "/home/bjorn/code/MapServer/maplexer.c" +#line 2 "/home/even/mapserver/mapserver/maplexer.c" -#line 4 "/home/bjorn/code/MapServer/maplexer.c" +#line 4 "/home/even/mapserver/mapserver/maplexer.c" #define YY_INT_ALIGNED short int @@ -2217,7 +2217,6 @@ double msyynumber; int msyystate=MS_TOKENIZE_DEFAULT; char *msyystring=NULL; char *msyybasepath=NULL; -char *msyystring_buffer_ptr; int msyystring_buffer_size = 0; int msyystring_size; char msyystring_begin; @@ -2225,25 +2224,21 @@ char *msyystring_buffer = NULL; int msyystring_icase = MS_FALSE; int msyystring_return_state; int msyystring_begin_state; -int msyystring_size_tmp; int msyyreturncomments = 0; -#define MS_LEXER_STRING_REALLOC(string, string_size, max_size, string_ptr) \ +#define MS_LEXER_STRING_REALLOC(string, string_size, max_size) \ do { \ const int string_size_macro = (int)(string_size); \ if (string_size_macro >= (int)(max_size)) { \ - msyystring_size_tmp = (max_size); \ max_size = (((int)(max_size)*2) > string_size_macro) ? ((int)(max_size))*2 : string_size_macro+1; \ string = (char *) msSmallRealloc(string, sizeof(char *) * (max_size)); \ - string_ptr = string; \ - string_ptr += msyystring_size_tmp; \ } \ } while(0) #define MS_LEXER_RETURN_TOKEN(token) \ MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), \ - msyystring_buffer_size, msyystring_buffer_ptr); \ + msyystring_buffer_size); \ strcpy(msyystring_buffer, msyytext); \ return(token); @@ -2253,9 +2248,9 @@ int include_lineno[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; char path[MS_MAXPATHLEN]; -#line 2257 "/home/bjorn/code/MapServer/maplexer.c" +#line 2252 "/home/even/mapserver/mapserver/maplexer.c" -#line 2259 "/home/bjorn/code/MapServer/maplexer.c" +#line 2254 "/home/even/mapserver/mapserver/maplexer.c" #define INITIAL 0 #define EXPRESSION_STRING 1 @@ -2469,9 +2464,9 @@ YY_DECL } { -#line 93 "maplexer.l" +#line 88 "maplexer.l" -#line 95 "maplexer.l" +#line 90 "maplexer.l" if (msyystring_buffer == NULL) { msyystring_buffer_size = 256; @@ -2535,7 +2530,7 @@ YY_DECL break; } -#line 2539 "/home/bjorn/code/MapServer/maplexer.c" +#line 2534 "/home/even/mapserver/mapserver/maplexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -2590,1611 +2585,1611 @@ YY_DECL case 1: YY_RULE_SETUP -#line 158 "maplexer.l" +#line 153 "maplexer.l" ; YY_BREAK case 2: YY_RULE_SETUP -#line 160 "maplexer.l" +#line 155 "maplexer.l" { if (msyyreturncomments) return(MS_COMMENT); } YY_BREAK case 3: YY_RULE_SETUP -#line 162 "maplexer.l" +#line 157 "maplexer.l" { BEGIN(MULTILINE_COMMENT); } YY_BREAK case 4: YY_RULE_SETUP -#line 163 "maplexer.l" +#line 158 "maplexer.l" { BEGIN(INITIAL); } YY_BREAK case 5: YY_RULE_SETUP -#line 164 "maplexer.l" +#line 159 "maplexer.l" ; YY_BREAK case 6: YY_RULE_SETUP -#line 165 "maplexer.l" +#line 160 "maplexer.l" ; YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP -#line 166 "maplexer.l" +#line 161 "maplexer.l" { msyylineno++; } YY_BREAK case 8: YY_RULE_SETUP -#line 168 "maplexer.l" +#line 163 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION); } YY_BREAK case 9: YY_RULE_SETUP -#line 169 "maplexer.l" +#line 164 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_ENV); } YY_BREAK case 10: YY_RULE_SETUP -#line 170 "maplexer.l" +#line 165 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_MAPS); } YY_BREAK case 11: YY_RULE_SETUP -#line 171 "maplexer.l" +#line 166 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_PLUGINS) } YY_BREAK case 12: YY_RULE_SETUP -#line 173 "maplexer.l" +#line 168 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_OR); } YY_BREAK case 13: YY_RULE_SETUP -#line 174 "maplexer.l" +#line 169 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_AND); } YY_BREAK case 14: YY_RULE_SETUP -#line 175 "maplexer.l" +#line 170 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_NOT); } YY_BREAK case 15: YY_RULE_SETUP -#line 176 "maplexer.l" +#line 171 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_EQ); } YY_BREAK case 16: YY_RULE_SETUP -#line 177 "maplexer.l" +#line 172 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_NE); } YY_BREAK case 17: YY_RULE_SETUP -#line 178 "maplexer.l" +#line 173 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_GT); } YY_BREAK case 18: YY_RULE_SETUP -#line 179 "maplexer.l" +#line 174 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_LT); } YY_BREAK case 19: YY_RULE_SETUP -#line 180 "maplexer.l" +#line 175 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_GE); } YY_BREAK case 20: YY_RULE_SETUP -#line 181 "maplexer.l" +#line 176 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_LE); } YY_BREAK case 21: YY_RULE_SETUP -#line 182 "maplexer.l" +#line 177 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_RE); } YY_BREAK case 22: YY_RULE_SETUP -#line 184 "maplexer.l" +#line 179 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IEQ); } YY_BREAK case 23: YY_RULE_SETUP -#line 185 "maplexer.l" +#line 180 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IRE); } YY_BREAK case 24: YY_RULE_SETUP -#line 187 "maplexer.l" +#line 182 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IN); /* was IN */ } YY_BREAK case 25: YY_RULE_SETUP -#line 189 "maplexer.l" +#line 184 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_AREA); } YY_BREAK case 26: YY_RULE_SETUP -#line 190 "maplexer.l" +#line 185 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_LENGTH); } YY_BREAK case 27: YY_RULE_SETUP -#line 191 "maplexer.l" +#line 186 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_TOSTRING); } YY_BREAK case 28: YY_RULE_SETUP -#line 192 "maplexer.l" +#line 187 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_COMMIFY); } YY_BREAK case 29: YY_RULE_SETUP -#line 193 "maplexer.l" +#line 188 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_ROUND); } YY_BREAK case 30: YY_RULE_SETUP -#line 194 "maplexer.l" +#line 189 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_UPPER); } YY_BREAK case 31: YY_RULE_SETUP -#line 195 "maplexer.l" +#line 190 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_LOWER); } YY_BREAK case 32: YY_RULE_SETUP -#line 196 "maplexer.l" +#line 191 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_INITCAP); } YY_BREAK case 33: YY_RULE_SETUP -#line 197 "maplexer.l" +#line 192 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_FIRSTCAP); } YY_BREAK case 34: YY_RULE_SETUP -#line 199 "maplexer.l" +#line 194 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_BUFFER); } YY_BREAK case 35: YY_RULE_SETUP -#line 200 "maplexer.l" +#line 195 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_DIFFERENCE); } YY_BREAK case 36: YY_RULE_SETUP -#line 201 "maplexer.l" +#line 196 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SIMPLIFY); } YY_BREAK case 37: YY_RULE_SETUP -#line 202 "maplexer.l" +#line 197 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SIMPLIFYPT); } YY_BREAK case 38: YY_RULE_SETUP -#line 203 "maplexer.l" +#line 198 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_GENERALIZE); } YY_BREAK case 39: YY_RULE_SETUP -#line 204 "maplexer.l" +#line 199 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SMOOTHSIA); } YY_BREAK case 40: YY_RULE_SETUP -#line 205 "maplexer.l" +#line 200 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_CENTERLINE); } YY_BREAK case 41: YY_RULE_SETUP -#line 206 "maplexer.l" +#line 201 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_DENSIFY); } YY_BREAK case 42: YY_RULE_SETUP -#line 207 "maplexer.l" +#line 202 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_OUTER); } YY_BREAK case 43: YY_RULE_SETUP -#line 208 "maplexer.l" +#line 203 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_INNER); } YY_BREAK case 44: YY_RULE_SETUP -#line 209 "maplexer.l" +#line 204 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_JAVASCRIPT); } YY_BREAK case 45: YY_RULE_SETUP -#line 211 "maplexer.l" +#line 206 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_INTERSECTS); } YY_BREAK case 46: YY_RULE_SETUP -#line 212 "maplexer.l" +#line 207 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_DISJOINT); } YY_BREAK case 47: YY_RULE_SETUP -#line 213 "maplexer.l" +#line 208 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_TOUCHES); } YY_BREAK case 48: YY_RULE_SETUP -#line 214 "maplexer.l" +#line 209 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_OVERLAPS); } YY_BREAK case 49: YY_RULE_SETUP -#line 215 "maplexer.l" +#line 210 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_CROSSES); } YY_BREAK case 50: YY_RULE_SETUP -#line 216 "maplexer.l" +#line 211 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_WITHIN); } YY_BREAK case 51: YY_RULE_SETUP -#line 217 "maplexer.l" +#line 212 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_CONTAINS); } YY_BREAK case 52: YY_RULE_SETUP -#line 218 "maplexer.l" +#line 213 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_EQUALS); } YY_BREAK case 53: YY_RULE_SETUP -#line 219 "maplexer.l" +#line 214 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_BEYOND); } YY_BREAK case 54: YY_RULE_SETUP -#line 220 "maplexer.l" +#line 215 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_DWITHIN); } YY_BREAK case 55: YY_RULE_SETUP -#line 222 "maplexer.l" +#line 217 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_FROMTEXT); } YY_BREAK case 56: YY_RULE_SETUP -#line 224 "maplexer.l" +#line 219 "maplexer.l" { msyynumber=MS_TRUE; return(MS_TOKEN_LITERAL_BOOLEAN); } YY_BREAK case 57: YY_RULE_SETUP -#line 225 "maplexer.l" +#line 220 "maplexer.l" { msyynumber=MS_FALSE; return(MS_TOKEN_LITERAL_BOOLEAN); } YY_BREAK case 58: YY_RULE_SETUP -#line 227 "maplexer.l" +#line 222 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COLORRANGE); } YY_BREAK case 59: YY_RULE_SETUP -#line 228 "maplexer.l" +#line 223 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DATARANGE); } YY_BREAK case 60: YY_RULE_SETUP -#line 229 "maplexer.l" +#line 224 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RANGEITEM); } YY_BREAK case 61: YY_RULE_SETUP -#line 231 "maplexer.l" +#line 226 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ALIGN); } YY_BREAK case 62: YY_RULE_SETUP -#line 232 "maplexer.l" +#line 227 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANCHORPOINT); } YY_BREAK case 63: YY_RULE_SETUP -#line 233 "maplexer.l" +#line 228 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANGLE); } YY_BREAK case 64: YY_RULE_SETUP -#line 234 "maplexer.l" +#line 229 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANTIALIAS); } YY_BREAK case 65: YY_RULE_SETUP -#line 235 "maplexer.l" +#line 230 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BACKGROUNDCOLOR); } YY_BREAK case 66: YY_RULE_SETUP -#line 236 "maplexer.l" +#line 231 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BANDSITEM); } YY_BREAK case 67: YY_RULE_SETUP -#line 237 "maplexer.l" +#line 232 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BINDVALS); } YY_BREAK case 68: YY_RULE_SETUP -#line 238 "maplexer.l" +#line 233 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BOM); } YY_BREAK case 69: YY_RULE_SETUP -#line 239 "maplexer.l" +#line 234 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BROWSEFORMAT); } YY_BREAK case 70: YY_RULE_SETUP -#line 240 "maplexer.l" +#line 235 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BUFFER); } YY_BREAK case 71: YY_RULE_SETUP -#line 241 "maplexer.l" +#line 236 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CHARACTER); } YY_BREAK case 72: YY_RULE_SETUP -#line 242 "maplexer.l" +#line 237 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASS); } YY_BREAK case 73: YY_RULE_SETUP -#line 243 "maplexer.l" +#line 238 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASSITEM); } YY_BREAK case 74: YY_RULE_SETUP -#line 244 "maplexer.l" +#line 239 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASSGROUP); } YY_BREAK case 75: YY_RULE_SETUP -#line 245 "maplexer.l" +#line 240 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLUSTER); } YY_BREAK case 76: YY_RULE_SETUP -#line 246 "maplexer.l" +#line 241 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COLOR); } YY_BREAK case 77: YY_RULE_SETUP -#line 247 "maplexer.l" +#line 242 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPFILTER); } YY_BREAK case 78: YY_RULE_SETUP -#line 248 "maplexer.l" +#line 243 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPOSITE); } YY_BREAK case 79: YY_RULE_SETUP -#line 249 "maplexer.l" +#line 244 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPOP); } YY_BREAK case 80: YY_RULE_SETUP -#line 250 "maplexer.l" +#line 245 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONFIG); } YY_BREAK case 81: YY_RULE_SETUP -#line 251 "maplexer.l" +#line 246 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTION); } YY_BREAK case 82: YY_RULE_SETUP -#line 252 "maplexer.l" +#line 247 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTIONTYPE); } YY_BREAK case 83: YY_RULE_SETUP -#line 253 "maplexer.l" +#line 248 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DATA); } YY_BREAK case 84: YY_RULE_SETUP -#line 254 "maplexer.l" +#line 249 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DEBUG); } YY_BREAK case 85: YY_RULE_SETUP -#line 255 "maplexer.l" +#line 250 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DRIVER); } YY_BREAK case 86: YY_RULE_SETUP -#line 256 "maplexer.l" +#line 251 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EMPTY); } YY_BREAK case 87: YY_RULE_SETUP -#line 257 "maplexer.l" +#line 252 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ENCODING); } YY_BREAK case 88: YY_RULE_SETUP -#line 258 "maplexer.l" +#line 253 "maplexer.l" { MS_LEXER_RETURN_TOKEN(END); } YY_BREAK case 89: YY_RULE_SETUP -#line 259 "maplexer.l" +#line 254 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ERROR); } YY_BREAK case 90: YY_RULE_SETUP -#line 260 "maplexer.l" +#line 255 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXPRESSION); } YY_BREAK case 91: YY_RULE_SETUP -#line 261 "maplexer.l" +#line 256 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXTENT); } YY_BREAK case 92: YY_RULE_SETUP -#line 262 "maplexer.l" +#line 257 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXTENSION); } YY_BREAK case 93: YY_RULE_SETUP -#line 263 "maplexer.l" +#line 258 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FEATURE); } YY_BREAK case 94: YY_RULE_SETUP -#line 264 "maplexer.l" +#line 259 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILLED); } YY_BREAK case 95: YY_RULE_SETUP -#line 265 "maplexer.l" +#line 260 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILTER); } YY_BREAK case 96: YY_RULE_SETUP -#line 266 "maplexer.l" +#line 261 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILTERITEM); } YY_BREAK case 97: YY_RULE_SETUP -#line 267 "maplexer.l" +#line 262 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FOOTER); } YY_BREAK case 98: YY_RULE_SETUP -#line 268 "maplexer.l" +#line 263 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FONT); } YY_BREAK case 99: YY_RULE_SETUP -#line 269 "maplexer.l" +#line 264 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FONTSET); } YY_BREAK case 100: YY_RULE_SETUP -#line 270 "maplexer.l" +#line 265 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FORCE); } YY_BREAK case 101: YY_RULE_SETUP -#line 271 "maplexer.l" +#line 266 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FORMATOPTION); } YY_BREAK case 102: YY_RULE_SETUP -#line 272 "maplexer.l" +#line 267 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FROM); } YY_BREAK case 103: YY_RULE_SETUP -#line 273 "maplexer.l" +#line 268 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GAP); } YY_BREAK case 104: YY_RULE_SETUP -#line 274 "maplexer.l" +#line 269 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GEOMTRANSFORM); } YY_BREAK case 105: YY_RULE_SETUP -#line 275 "maplexer.l" +#line 270 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRID); } YY_BREAK case 106: YY_RULE_SETUP -#line 276 "maplexer.l" +#line 271 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRIDSTEP); } YY_BREAK case 107: YY_RULE_SETUP -#line 277 "maplexer.l" +#line 272 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRATICULE); } YY_BREAK case 108: YY_RULE_SETUP -#line 278 "maplexer.l" +#line 273 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GROUP); } YY_BREAK case 109: YY_RULE_SETUP -#line 279 "maplexer.l" +#line 274 "maplexer.l" { MS_LEXER_RETURN_TOKEN(HEADER); } YY_BREAK case 110: YY_RULE_SETUP -#line 280 "maplexer.l" +#line 275 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGE); } YY_BREAK case 111: YY_RULE_SETUP -#line 281 "maplexer.l" +#line 276 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGECOLOR); } YY_BREAK case 112: YY_RULE_SETUP -#line 282 "maplexer.l" +#line 277 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGETYPE); } YY_BREAK case 113: YY_RULE_SETUP -#line 283 "maplexer.l" +#line 278 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEMODE); } YY_BREAK case 114: YY_RULE_SETUP -#line 284 "maplexer.l" +#line 279 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEPATH); } YY_BREAK case 115: YY_RULE_SETUP -#line 285 "maplexer.l" +#line 280 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEMPPATH); } YY_BREAK case 116: YY_RULE_SETUP -#line 286 "maplexer.l" +#line 281 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEURL); } YY_BREAK case 117: YY_RULE_SETUP -#line 287 "maplexer.l" +#line 282 "maplexer.l" { BEGIN(INCLUDE); } YY_BREAK case 118: YY_RULE_SETUP -#line 288 "maplexer.l" +#line 283 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INDEX); } YY_BREAK case 119: YY_RULE_SETUP -#line 289 "maplexer.l" +#line 284 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INITIALGAP); } YY_BREAK case 120: YY_RULE_SETUP -#line 290 "maplexer.l" +#line 285 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INTERVALS); } YY_BREAK case 121: YY_RULE_SETUP -#line 291 "maplexer.l" +#line 286 "maplexer.l" { MS_LEXER_RETURN_TOKEN(JOIN); } YY_BREAK case 122: YY_RULE_SETUP -#line 292 "maplexer.l" +#line 287 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYIMAGE); } YY_BREAK case 123: YY_RULE_SETUP -#line 293 "maplexer.l" +#line 288 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYSIZE); } YY_BREAK case 124: YY_RULE_SETUP -#line 294 "maplexer.l" +#line 289 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYSPACING); } YY_BREAK case 125: YY_RULE_SETUP -#line 295 "maplexer.l" +#line 290 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABEL); } YY_BREAK case 126: YY_RULE_SETUP -#line 296 "maplexer.l" +#line 291 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELCACHE); } YY_BREAK case 127: YY_RULE_SETUP -#line 297 "maplexer.l" +#line 292 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELFORMAT); } YY_BREAK case 128: YY_RULE_SETUP -#line 298 "maplexer.l" +#line 293 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELITEM); } YY_BREAK case 129: YY_RULE_SETUP -#line 299 "maplexer.l" +#line 294 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMAXSCALE); } YY_BREAK case 130: YY_RULE_SETUP -#line 300 "maplexer.l" +#line 295 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMAXSCALEDENOM); } YY_BREAK case 131: YY_RULE_SETUP -#line 301 "maplexer.l" +#line 296 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMINSCALE); } YY_BREAK case 132: YY_RULE_SETUP -#line 302 "maplexer.l" +#line 297 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMINSCALEDENOM); } YY_BREAK case 133: YY_RULE_SETUP -#line 303 "maplexer.l" +#line 298 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELREQUIRES); } YY_BREAK case 134: YY_RULE_SETUP -#line 304 "maplexer.l" +#line 299 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LATLON); } YY_BREAK case 135: YY_RULE_SETUP -#line 305 "maplexer.l" +#line 300 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LAYER); } YY_BREAK case 136: YY_RULE_SETUP -#line 306 "maplexer.l" +#line 301 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEADER); } YY_BREAK case 137: YY_RULE_SETUP -#line 307 "maplexer.l" +#line 302 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEGEND); } YY_BREAK case 138: YY_RULE_SETUP -#line 308 "maplexer.l" +#line 303 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEGENDFORMAT); } YY_BREAK case 139: YY_RULE_SETUP -#line 309 "maplexer.l" +#line 304 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINECAP); } YY_BREAK case 140: YY_RULE_SETUP -#line 310 "maplexer.l" +#line 305 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINEJOIN); } YY_BREAK case 141: YY_RULE_SETUP -#line 311 "maplexer.l" +#line 306 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINEJOINMAXSIZE); } YY_BREAK case 142: YY_RULE_SETUP -#line 312 "maplexer.l" +#line 307 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAP); } YY_BREAK case 143: YY_RULE_SETUP -#line 313 "maplexer.l" +#line 308 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MARKER); } YY_BREAK case 144: YY_RULE_SETUP -#line 314 "maplexer.l" +#line 309 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MARKERSIZE); } YY_BREAK case 145: YY_RULE_SETUP -#line 315 "maplexer.l" +#line 310 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MASK); } YY_BREAK case 146: YY_RULE_SETUP -#line 316 "maplexer.l" +#line 311 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXARCS); } YY_BREAK case 147: YY_RULE_SETUP -#line 317 "maplexer.l" +#line 312 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXBOXSIZE); } YY_BREAK case 148: YY_RULE_SETUP -#line 318 "maplexer.l" +#line 313 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXDISTANCE); } YY_BREAK case 149: YY_RULE_SETUP -#line 319 "maplexer.l" +#line 314 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXFEATURES); } YY_BREAK case 150: YY_RULE_SETUP -#line 320 "maplexer.l" +#line 315 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXINTERVAL); } YY_BREAK case 151: YY_RULE_SETUP -#line 321 "maplexer.l" +#line 316 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSCALE); } YY_BREAK case 152: YY_RULE_SETUP -#line 322 "maplexer.l" +#line 317 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSCALEDENOM); } YY_BREAK case 153: YY_RULE_SETUP -#line 323 "maplexer.l" +#line 318 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXGEOWIDTH); } YY_BREAK case 154: YY_RULE_SETUP -#line 324 "maplexer.l" +#line 319 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXLENGTH); } YY_BREAK case 155: YY_RULE_SETUP -#line 325 "maplexer.l" +#line 320 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSIZE); } YY_BREAK case 156: YY_RULE_SETUP -#line 326 "maplexer.l" +#line 321 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSUBDIVIDE); } YY_BREAK case 157: YY_RULE_SETUP -#line 327 "maplexer.l" +#line 322 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXTEMPLATE); } YY_BREAK case 158: YY_RULE_SETUP -#line 328 "maplexer.l" +#line 323 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXWIDTH); } YY_BREAK case 159: YY_RULE_SETUP -#line 329 "maplexer.l" +#line 324 "maplexer.l" { MS_LEXER_RETURN_TOKEN(METADATA); } YY_BREAK case 160: YY_RULE_SETUP -#line 330 "maplexer.l" +#line 325 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MIMETYPE); } YY_BREAK case 161: YY_RULE_SETUP -#line 331 "maplexer.l" +#line 326 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINARCS); } YY_BREAK case 162: YY_RULE_SETUP -#line 332 "maplexer.l" +#line 327 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINBOXSIZE); } YY_BREAK case 163: YY_RULE_SETUP -#line 333 "maplexer.l" +#line 328 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINDISTANCE); } YY_BREAK case 164: YY_RULE_SETUP -#line 334 "maplexer.l" +#line 329 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REPEATDISTANCE); } YY_BREAK case 165: YY_RULE_SETUP -#line 335 "maplexer.l" +#line 330 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXOVERLAPANGLE); } YY_BREAK case 166: YY_RULE_SETUP -#line 336 "maplexer.l" +#line 331 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINFEATURESIZE); } YY_BREAK case 167: YY_RULE_SETUP -#line 337 "maplexer.l" +#line 332 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MININTERVAL); } YY_BREAK case 168: YY_RULE_SETUP -#line 338 "maplexer.l" +#line 333 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSCALE); } YY_BREAK case 169: YY_RULE_SETUP -#line 339 "maplexer.l" +#line 334 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSCALEDENOM); } YY_BREAK case 170: YY_RULE_SETUP -#line 340 "maplexer.l" +#line 335 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINGEOWIDTH); } YY_BREAK case 171: YY_RULE_SETUP -#line 341 "maplexer.l" +#line 336 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSIZE); } YY_BREAK case 172: YY_RULE_SETUP -#line 342 "maplexer.l" +#line 337 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSUBDIVIDE); } YY_BREAK case 173: YY_RULE_SETUP -#line 343 "maplexer.l" +#line 338 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINTEMPLATE); } YY_BREAK case 174: YY_RULE_SETUP -#line 344 "maplexer.l" +#line 339 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINWIDTH); } YY_BREAK case 175: YY_RULE_SETUP -#line 345 "maplexer.l" +#line 340 "maplexer.l" { MS_LEXER_RETURN_TOKEN(NAME); } YY_BREAK case 176: YY_RULE_SETUP -#line 346 "maplexer.l" +#line 341 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OFFSET); } YY_BREAK case 177: YY_RULE_SETUP -#line 347 "maplexer.l" +#line 342 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OFFSITE); } YY_BREAK case 178: YY_RULE_SETUP -#line 348 "maplexer.l" +#line 343 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OPACITY); } YY_BREAK case 179: YY_RULE_SETUP -#line 349 "maplexer.l" +#line 344 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTIONOPTIONS); } YY_BREAK case 180: YY_RULE_SETUP -#line 350 "maplexer.l" +#line 345 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTLINECOLOR); } YY_BREAK case 181: YY_RULE_SETUP -#line 351 "maplexer.l" +#line 346 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTLINEWIDTH); } YY_BREAK case 182: YY_RULE_SETUP -#line 352 "maplexer.l" +#line 347 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTPUTFORMAT); } YY_BREAK case 183: YY_RULE_SETUP -#line 353 "maplexer.l" +#line 348 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PARTIALS); } YY_BREAK case 184: YY_RULE_SETUP -#line 354 "maplexer.l" +#line 349 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PATTERN); } YY_BREAK case 185: YY_RULE_SETUP -#line 355 "maplexer.l" +#line 350 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POINTS); } YY_BREAK case 186: YY_RULE_SETUP -#line 356 "maplexer.l" +#line 351 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ITEMS); } YY_BREAK case 187: YY_RULE_SETUP -#line 357 "maplexer.l" +#line 352 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POSITION); } YY_BREAK case 188: YY_RULE_SETUP -#line 358 "maplexer.l" +#line 353 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POSTLABELCACHE); } YY_BREAK case 189: YY_RULE_SETUP -#line 359 "maplexer.l" +#line 354 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PRIORITY); } YY_BREAK case 190: YY_RULE_SETUP -#line 360 "maplexer.l" +#line 355 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PROCESSING); } YY_BREAK case 191: YY_RULE_SETUP -#line 361 "maplexer.l" +#line 356 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PROJECTION); } YY_BREAK case 192: YY_RULE_SETUP -#line 362 "maplexer.l" +#line 357 "maplexer.l" { MS_LEXER_RETURN_TOKEN(QUERYFORMAT); } YY_BREAK case 193: YY_RULE_SETUP -#line 363 "maplexer.l" +#line 358 "maplexer.l" { MS_LEXER_RETURN_TOKEN(QUERYMAP); } YY_BREAK case 194: YY_RULE_SETUP -#line 364 "maplexer.l" +#line 359 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REFERENCE); } YY_BREAK case 195: YY_RULE_SETUP -#line 365 "maplexer.l" +#line 360 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REGION); } YY_BREAK case 196: YY_RULE_SETUP -#line 366 "maplexer.l" +#line 361 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RELATIVETO); } YY_BREAK case 197: YY_RULE_SETUP -#line 367 "maplexer.l" +#line 362 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REQUIRES); } YY_BREAK case 198: YY_RULE_SETUP -#line 368 "maplexer.l" +#line 363 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RESOLUTION); } YY_BREAK case 199: YY_RULE_SETUP -#line 369 "maplexer.l" +#line 364 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DEFRESOLUTION); } YY_BREAK case 200: YY_RULE_SETUP -#line 370 "maplexer.l" +#line 365 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALE); } YY_BREAK case 201: YY_RULE_SETUP -#line 371 "maplexer.l" +#line 366 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALEDENOM); } YY_BREAK case 202: YY_RULE_SETUP -#line 372 "maplexer.l" +#line 367 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALEBAR); } YY_BREAK case 203: YY_RULE_SETUP -#line 373 "maplexer.l" +#line 368 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALETOKEN); } YY_BREAK case 204: YY_RULE_SETUP -#line 374 "maplexer.l" +#line 369 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHADOWCOLOR); } YY_BREAK case 205: YY_RULE_SETUP -#line 375 "maplexer.l" +#line 370 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHADOWSIZE); } YY_BREAK case 206: YY_RULE_SETUP -#line 376 "maplexer.l" +#line 371 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHAPEPATH); } YY_BREAK case 207: YY_RULE_SETUP -#line 377 "maplexer.l" +#line 372 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SIZE); } YY_BREAK case 208: YY_RULE_SETUP -#line 378 "maplexer.l" +#line 373 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SIZEUNITS); } YY_BREAK case 209: YY_RULE_SETUP -#line 379 "maplexer.l" +#line 374 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STATUS); } YY_BREAK case 210: YY_RULE_SETUP -#line 380 "maplexer.l" +#line 375 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STYLE); } YY_BREAK case 211: YY_RULE_SETUP -#line 381 "maplexer.l" +#line 376 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STYLEITEM); } YY_BREAK case 212: YY_RULE_SETUP -#line 382 "maplexer.l" +#line 377 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOL); } YY_BREAK case 213: YY_RULE_SETUP -#line 383 "maplexer.l" +#line 378 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSCALE); } YY_BREAK case 214: YY_RULE_SETUP -#line 384 "maplexer.l" +#line 379 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSCALEDENOM); } YY_BREAK case 215: YY_RULE_SETUP -#line 385 "maplexer.l" +#line 380 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSET); } YY_BREAK case 216: YY_RULE_SETUP -#line 386 "maplexer.l" +#line 381 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TABLE); } YY_BREAK case 217: YY_RULE_SETUP -#line 387 "maplexer.l" +#line 382 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEMPLATE); } YY_BREAK case 218: YY_RULE_SETUP -#line 388 "maplexer.l" +#line 383 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEXT); } YY_BREAK case 219: YY_RULE_SETUP -#line 389 "maplexer.l" +#line 384 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILEINDEX); } YY_BREAK case 220: YY_RULE_SETUP -#line 390 "maplexer.l" +#line 385 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILEITEM); } YY_BREAK case 221: YY_RULE_SETUP -#line 391 "maplexer.l" +#line 386 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILESRS); } YY_BREAK case 222: YY_RULE_SETUP -#line 392 "maplexer.l" +#line 387 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TITLE); } YY_BREAK case 223: YY_RULE_SETUP -#line 393 "maplexer.l" +#line 388 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TO); } YY_BREAK case 224: YY_RULE_SETUP -#line 394 "maplexer.l" +#line 389 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TOLERANCE); } YY_BREAK case 225: YY_RULE_SETUP -#line 395 "maplexer.l" +#line 390 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TOLERANCEUNITS); } YY_BREAK case 226: YY_RULE_SETUP -#line 396 "maplexer.l" +#line 391 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TRANSPARENT); } YY_BREAK case 227: YY_RULE_SETUP -#line 397 "maplexer.l" +#line 392 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TRANSFORM); } YY_BREAK case 228: YY_RULE_SETUP -#line 398 "maplexer.l" +#line 393 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TYPE); } YY_BREAK case 229: YY_RULE_SETUP -#line 399 "maplexer.l" +#line 394 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UNITS); } YY_BREAK case 230: YY_RULE_SETUP -#line 400 "maplexer.l" +#line 395 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UTFDATA); } YY_BREAK case 231: YY_RULE_SETUP -#line 401 "maplexer.l" +#line 396 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UTFITEM); } YY_BREAK case 232: YY_RULE_SETUP -#line 402 "maplexer.l" +#line 397 "maplexer.l" { MS_LEXER_RETURN_TOKEN(VALIDATION); } YY_BREAK case 233: YY_RULE_SETUP -#line 403 "maplexer.l" +#line 398 "maplexer.l" { MS_LEXER_RETURN_TOKEN(VALUES); } YY_BREAK case 234: YY_RULE_SETUP -#line 404 "maplexer.l" +#line 399 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WEB); } YY_BREAK case 235: YY_RULE_SETUP -#line 405 "maplexer.l" +#line 400 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WIDTH); } YY_BREAK case 236: YY_RULE_SETUP -#line 406 "maplexer.l" +#line 401 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WKT); } YY_BREAK case 237: YY_RULE_SETUP -#line 407 "maplexer.l" +#line 402 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WRAP); } YY_BREAK case 238: YY_RULE_SETUP -#line 409 "maplexer.l" +#line 404 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_ANNOTATION); } YY_BREAK case 239: YY_RULE_SETUP -#line 410 "maplexer.l" +#line 405 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_AUTO); } YY_BREAK case 240: YY_RULE_SETUP -#line 411 "maplexer.l" +#line 406 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_AUTO2); } YY_BREAK case 241: YY_RULE_SETUP -#line 412 "maplexer.l" +#line 407 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_BEVEL); } YY_BREAK case 242: YY_RULE_SETUP -#line 413 "maplexer.l" +#line 408 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_BITMAP); } YY_BREAK case 243: YY_RULE_SETUP -#line 414 "maplexer.l" +#line 409 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_BUTT); } YY_BREAK case 244: YY_RULE_SETUP -#line 415 "maplexer.l" +#line 410 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CC); } YY_BREAK case 245: YY_RULE_SETUP -#line 416 "maplexer.l" +#line 411 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_CENTER); } YY_BREAK case 246: YY_RULE_SETUP -#line 417 "maplexer.l" +#line 412 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_CHART); } YY_BREAK case 247: YY_RULE_SETUP -#line 418 "maplexer.l" +#line 413 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_CIRCLE); } YY_BREAK case 248: YY_RULE_SETUP -#line 419 "maplexer.l" +#line 414 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CL); } YY_BREAK case 249: YY_RULE_SETUP -#line 420 "maplexer.l" +#line 415 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CR); } YY_BREAK case 250: YY_RULE_SETUP -#line 421 "maplexer.l" +#line 416 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_CSV); } YY_BREAK case 251: YY_RULE_SETUP -#line 422 "maplexer.l" +#line 417 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_POSTGRES); } YY_BREAK case 252: YY_RULE_SETUP -#line 423 "maplexer.l" +#line 418 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_MYSQL); } YY_BREAK case 253: YY_RULE_SETUP -#line 424 "maplexer.l" +#line 419 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DEFAULT); } YY_BREAK case 254: YY_RULE_SETUP -#line 425 "maplexer.l" +#line 420 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DD); } YY_BREAK case 255: YY_RULE_SETUP -#line 426 "maplexer.l" +#line 421 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_ELLIPSE); } YY_BREAK case 256: YY_RULE_SETUP -#line 427 "maplexer.l" +#line 422 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_EMBED); } YY_BREAK case 257: YY_RULE_SETUP -#line 428 "maplexer.l" +#line 423 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FALSE); } YY_BREAK case 258: YY_RULE_SETUP -#line 429 "maplexer.l" +#line 424 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FEET); } YY_BREAK case 259: YY_RULE_SETUP -#line 430 "maplexer.l" +#line 425 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FOLLOW); } YY_BREAK case 260: YY_RULE_SETUP -#line 431 "maplexer.l" +#line 426 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_GIANT); } YY_BREAK case 261: YY_RULE_SETUP -#line 432 "maplexer.l" +#line 427 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_HATCH); } YY_BREAK case 262: YY_RULE_SETUP -#line 433 "maplexer.l" +#line 428 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_KERNELDENSITY); } YY_BREAK case 263: YY_RULE_SETUP -#line 434 "maplexer.l" +#line 429 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_IDW); } YY_BREAK case 264: YY_RULE_SETUP -#line 435 "maplexer.l" +#line 430 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_HILITE); } YY_BREAK case 265: YY_RULE_SETUP -#line 436 "maplexer.l" +#line 431 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_INCHES); } YY_BREAK case 266: YY_RULE_SETUP -#line 437 "maplexer.l" +#line 432 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_KILOMETERS); } YY_BREAK case 267: YY_RULE_SETUP -#line 438 "maplexer.l" +#line 433 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LARGE); } YY_BREAK case 268: YY_RULE_SETUP -#line 439 "maplexer.l" +#line 434 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LC); } YY_BREAK case 269: YY_RULE_SETUP -#line 440 "maplexer.l" +#line 435 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_LEFT); } YY_BREAK case 270: YY_RULE_SETUP -#line 441 "maplexer.l" +#line 436 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_LINE); } YY_BREAK case 271: YY_RULE_SETUP -#line 442 "maplexer.l" +#line 437 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LL); } YY_BREAK case 272: YY_RULE_SETUP -#line 443 "maplexer.l" +#line 438 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LR); } YY_BREAK case 273: YY_RULE_SETUP -#line 444 "maplexer.l" +#line 439 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MEDIUM); } YY_BREAK case 274: YY_RULE_SETUP -#line 445 "maplexer.l" +#line 440 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_METERS); } YY_BREAK case 275: YY_RULE_SETUP -#line 446 "maplexer.l" +#line 441 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_NAUTICALMILES); } YY_BREAK case 276: YY_RULE_SETUP -#line 447 "maplexer.l" +#line 442 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MILES); } YY_BREAK case 277: YY_RULE_SETUP -#line 448 "maplexer.l" +#line 443 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_MITER); } YY_BREAK case 278: YY_RULE_SETUP -#line 449 "maplexer.l" +#line 444 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MULTIPLE); } YY_BREAK case 279: YY_RULE_SETUP -#line 450 "maplexer.l" +#line 445 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_NONE); } YY_BREAK case 280: YY_RULE_SETUP -#line 451 "maplexer.l" +#line 446 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_NORMAL); } YY_BREAK case 281: YY_RULE_SETUP -#line 452 "maplexer.l" +#line 447 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_OFF); } YY_BREAK case 282: YY_RULE_SETUP -#line 453 "maplexer.l" +#line 448 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_OGR); } YY_BREAK case 283: YY_RULE_SETUP -#line 454 "maplexer.l" +#line 449 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FLATGEOBUF); } YY_BREAK case 284: YY_RULE_SETUP -#line 455 "maplexer.l" +#line 450 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ON); } YY_BREAK case 285: YY_RULE_SETUP -#line 456 "maplexer.l" +#line 451 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_JOIN_ONE_TO_ONE); } YY_BREAK case 286: YY_RULE_SETUP -#line 457 "maplexer.l" +#line 452 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_JOIN_ONE_TO_MANY); } YY_BREAK case 287: YY_RULE_SETUP -#line 458 "maplexer.l" +#line 453 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ORACLESPATIAL); } YY_BREAK case 288: YY_RULE_SETUP -#line 459 "maplexer.l" +#line 454 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PERCENTAGES); } YY_BREAK case 289: YY_RULE_SETUP -#line 460 "maplexer.l" +#line 455 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_PIXMAP); } YY_BREAK case 290: YY_RULE_SETUP -#line 461 "maplexer.l" +#line 456 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PIXELS); } YY_BREAK case 291: YY_RULE_SETUP -#line 462 "maplexer.l" +#line 457 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_POINT); } YY_BREAK case 292: YY_RULE_SETUP -#line 463 "maplexer.l" +#line 458 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_POLYGON); } YY_BREAK case 293: YY_RULE_SETUP -#line 464 "maplexer.l" +#line 459 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_POSTGIS); } YY_BREAK case 294: YY_RULE_SETUP -#line 465 "maplexer.l" +#line 460 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PLUGIN); } YY_BREAK case 295: YY_RULE_SETUP -#line 466 "maplexer.l" +#line 461 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_QUERY); } YY_BREAK case 296: YY_RULE_SETUP -#line 467 "maplexer.l" +#line 462 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_RASTER); } YY_BREAK case 297: YY_RULE_SETUP -#line 468 "maplexer.l" +#line 463 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_RIGHT); } YY_BREAK case 298: YY_RULE_SETUP -#line 469 "maplexer.l" +#line 464 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_ROUND); } YY_BREAK case 299: YY_RULE_SETUP -#line 470 "maplexer.l" +#line 465 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SELECTED); } YY_BREAK case 300: YY_RULE_SETUP -#line 471 "maplexer.l" +#line 466 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_SIMPLE); } YY_BREAK case 301: YY_RULE_SETUP -#line 472 "maplexer.l" +#line 467 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SINGLE); } YY_BREAK case 302: YY_RULE_SETUP -#line 473 "maplexer.l" +#line 468 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SMALL); } YY_BREAK case 303: YY_RULE_SETUP -#line 474 "maplexer.l" +#line 469 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_SQUARE); } YY_BREAK case 304: YY_RULE_SETUP -#line 475 "maplexer.l" +#line 470 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_SVG); } YY_BREAK case 305: YY_RULE_SETUP -#line 476 "maplexer.l" +#line 471 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POLAROFFSET); } YY_BREAK case 306: YY_RULE_SETUP -#line 477 "maplexer.l" +#line 472 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TINY); } YY_BREAK case 307: YY_RULE_SETUP -#line 478 "maplexer.l" +#line 473 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_TRIANGLE); } YY_BREAK case 308: YY_RULE_SETUP -#line 479 "maplexer.l" +#line 474 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TRUE); } YY_BREAK case 309: YY_RULE_SETUP -#line 480 "maplexer.l" +#line 475 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TRUETYPE); } YY_BREAK case 310: YY_RULE_SETUP -#line 481 "maplexer.l" +#line 476 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UC); } YY_BREAK case 311: YY_RULE_SETUP -#line 482 "maplexer.l" +#line 477 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UL); } YY_BREAK case 312: YY_RULE_SETUP -#line 483 "maplexer.l" +#line 478 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UR); } YY_BREAK case 313: YY_RULE_SETUP -#line 484 "maplexer.l" +#line 479 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UNION); } YY_BREAK case 314: YY_RULE_SETUP -#line 485 "maplexer.l" +#line 480 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UVRASTER); } YY_BREAK case 315: YY_RULE_SETUP -#line 486 "maplexer.l" +#line 481 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONTOUR); } YY_BREAK case 316: YY_RULE_SETUP -#line 487 "maplexer.l" +#line 482 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_VECTOR); } YY_BREAK case 317: YY_RULE_SETUP -#line 488 "maplexer.l" +#line 483 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_WFS); } YY_BREAK case 318: YY_RULE_SETUP -#line 489 "maplexer.l" +#line 484 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_WMS); } YY_BREAK case 319: /* rule 319 can match eol */ YY_RULE_SETUP -#line 491 "maplexer.l" +#line 486 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); return(MS_BINDING); } YY_BREAK case 320: YY_RULE_SETUP -#line 500 "maplexer.l" +#line 495 "maplexer.l" { /* attribute binding - shape (fixed value) */ return(MS_TOKEN_BINDING_SHAPE); @@ -4202,7 +4197,7 @@ YY_RULE_SETUP YY_BREAK case 321: YY_RULE_SETUP -#line 504 "maplexer.l" +#line 499 "maplexer.l" { /* attribute binding - map cellsize */ return(MS_TOKEN_BINDING_MAP_CELLSIZE); @@ -4210,7 +4205,7 @@ YY_RULE_SETUP YY_BREAK case 322: YY_RULE_SETUP -#line 508 "maplexer.l" +#line 503 "maplexer.l" { /* attribute binding - data cellsize */ return(MS_TOKEN_BINDING_DATA_CELLSIZE); @@ -4219,13 +4214,13 @@ YY_RULE_SETUP case 323: /* rule 323 can match eol */ YY_RULE_SETUP -#line 512 "maplexer.l" +#line 507 "maplexer.l" { /* attribute binding - numeric (no quotes) */ msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_DOUBLE); } @@ -4233,13 +4228,13 @@ YY_RULE_SETUP case 324: /* rule 324 can match eol */ YY_RULE_SETUP -#line 521 "maplexer.l" +#line 516 "maplexer.l" { /* attribute binding - string (single or double quotes) */ msyytext+=2; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_STRING); } @@ -4247,23 +4242,23 @@ YY_RULE_SETUP case 325: /* rule 325 can match eol */ YY_RULE_SETUP -#line 530 "maplexer.l" +#line 525 "maplexer.l" { /* attribute binding - time */ msyytext+=2; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_TIME); } YY_BREAK case 326: YY_RULE_SETUP -#line 540 "maplexer.l" +#line 535 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); return(MS_NUMBER); @@ -4271,10 +4266,10 @@ YY_RULE_SETUP YY_BREAK case 327: YY_RULE_SETUP -#line 548 "maplexer.l" +#line 543 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); return(MS_TOKEN_LITERAL_NUMBER); @@ -4283,12 +4278,12 @@ YY_RULE_SETUP case 328: /* rule 328 can match eol */ YY_RULE_SETUP -#line 556 "maplexer.l" +#line 551 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_LITERAL_TIME); } @@ -4296,12 +4291,12 @@ YY_RULE_SETUP case 329: /* rule 329 can match eol */ YY_RULE_SETUP -#line 565 "maplexer.l" +#line 560 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_IREGEX); } @@ -4309,62 +4304,57 @@ YY_RULE_SETUP case 330: /* rule 330 can match eol */ YY_RULE_SETUP -#line 574 "maplexer.l" +#line 569 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_REGEX); } YY_BREAK case 331: YY_RULE_SETUP -#line 583 "maplexer.l" +#line 578 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_EXPRESSION); } YY_BREAK case 332: YY_RULE_SETUP -#line 592 "maplexer.l" +#line 587 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_LIST); } YY_BREAK case 333: YY_RULE_SETUP -#line 601 "maplexer.l" +#line 596 "maplexer.l" { msyystring_return_state = MS_STRING; msyystring_begin = msyytext[0]; msyystring_size = 0; - msyystring_buffer_ptr = msyystring_buffer; + msyystring_buffer[0] = '\0'; BEGIN(MSSTRING); } YY_BREAK case 334: YY_RULE_SETUP -#line 609 "maplexer.l" +#line 604 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); if (msyystring_begin == msyytext[0]) { BEGIN(msyystring_begin_state); - - *msyystring_buffer_ptr = '\0'; - if (msyystring_return_state == MS_STRING) { if (msyystring_icase && strlen(msyytext)==2) { msyystring_icase = MS_FALSE; // reset @@ -4376,49 +4366,50 @@ YY_RULE_SETUP } else { - ++msyystring_size; - *msyystring_buffer_ptr++ = *msyytext; + int old_size = msyystring_size; + msyystring_size += (strlen(msyytext)==2) ? 2 : 1; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + msyystring_buffer[old_size] = *msyytext; if (strlen(msyytext)==2) { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; - *msyystring_buffer_ptr++ = msyytext[1]; + msyystring_buffer[old_size+1] = msyytext[1]; } + msyystring_buffer[msyystring_size] = '\0'; } } YY_BREAK case 335: YY_RULE_SETUP -#line 639 "maplexer.l" +#line 630 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + if (strlen(msyytext) == 2) - *msyystring_buffer_ptr++ = msyytext[1]; + msyystring_buffer[msyystring_size-1] = msyytext[1]; else - *msyystring_buffer_ptr++ = msyytext[0]; + msyystring_buffer[msyystring_size-1] = msyytext[0]; + msyystring_buffer[msyystring_size] = '\0'; } YY_BREAK case 336: /* rule 336 can match eol */ YY_RULE_SETUP -#line 650 "maplexer.l" +#line 642 "maplexer.l" { - char *yptr = msyytext; - while ( *yptr ) { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; - *msyystring_buffer_ptr++ = *yptr++; - } + int old_size = msyystring_size; + int msyytext_len = (int)strlen(msyytext); + msyystring_size += msyytext_len; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1); } YY_BREAK case 337: /* rule 337 can match eol */ YY_RULE_SETUP -#line 660 "maplexer.l" +#line 651 "maplexer.l" { msyytext++; msyytext[strlen(msyytext)-1] = '\0'; @@ -4447,21 +4438,21 @@ YY_RULE_SETUP YY_BREAK case 338: YY_RULE_SETUP -#line 686 "maplexer.l" +#line 677 "maplexer.l" { msyystring_return_state = MS_TOKEN_LITERAL_STRING; msyystring_begin = msyytext[0]; msyystring_size = 0; - msyystring_buffer_ptr = msyystring_buffer; + msyystring_buffer[0] = '\0'; BEGIN(MSSTRING); } YY_BREAK case 339: YY_RULE_SETUP -#line 694 "maplexer.l" +#line 685 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_STRING); } @@ -4469,12 +4460,12 @@ YY_RULE_SETUP case 340: /* rule 340 can match eol */ YY_RULE_SETUP -#line 701 "maplexer.l" +#line 692 "maplexer.l" { msyylineno++; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CONFIG_FILE): -#line 703 "maplexer.l" +#line 694 "maplexer.l" { if( --include_stack_ptr < 0 ) return(EOF); /* end of main file */ @@ -4489,32 +4480,32 @@ case YY_STATE_EOF(CONFIG_FILE): case 341: /* rule 341 can match eol */ YY_RULE_SETUP -#line 714 "maplexer.l" +#line 705 "maplexer.l" { return(0); } YY_BREAK case 342: YY_RULE_SETUP -#line 718 "maplexer.l" +#line 709 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(0); } YY_BREAK case 343: YY_RULE_SETUP -#line 724 "maplexer.l" +#line 715 "maplexer.l" { return(msyytext[0]); } YY_BREAK case 344: YY_RULE_SETUP -#line 725 "maplexer.l" +#line 716 "maplexer.l" ECHO; YY_BREAK -#line 4518 "/home/bjorn/code/MapServer/maplexer.c" +#line 4509 "/home/even/mapserver/mapserver/maplexer.c" case YY_STATE_EOF(EXPRESSION_STRING): case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(MSSTRING): @@ -5523,7 +5514,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 725 "maplexer.l" +#line 716 "maplexer.l" /* diff --git a/maplexer.l b/maplexer.l index a3987daeba..00b3c85d15 100644 --- a/maplexer.l +++ b/maplexer.l @@ -46,7 +46,6 @@ double msyynumber; int msyystate=MS_TOKENIZE_DEFAULT; char *msyystring=NULL; char *msyybasepath=NULL; -char *msyystring_buffer_ptr; int msyystring_buffer_size = 0; int msyystring_size; char msyystring_begin; @@ -54,25 +53,21 @@ char *msyystring_buffer = NULL; int msyystring_icase = MS_FALSE; int msyystring_return_state; int msyystring_begin_state; -int msyystring_size_tmp; int msyyreturncomments = 0; -#define MS_LEXER_STRING_REALLOC(string, string_size, max_size, string_ptr) \ +#define MS_LEXER_STRING_REALLOC(string, string_size, max_size) \ do { \ const int string_size_macro = (int)(string_size); \ if (string_size_macro >= (int)(max_size)) { \ - msyystring_size_tmp = (max_size); \ max_size = (((int)(max_size)*2) > string_size_macro) ? ((int)(max_size))*2 : string_size_macro+1; \ string = (char *) msSmallRealloc(string, sizeof(char *) * (max_size)); \ - string_ptr = string; \ - string_ptr += msyystring_size_tmp; \ } \ } while(0) #define MS_LEXER_RETURN_TOKEN(token) \ MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), \ - msyystring_buffer_size, msyystring_buffer_ptr); \ + msyystring_buffer_size); \ strcpy(msyystring_buffer, msyytext); \ return(token); @@ -491,7 +486,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); return(MS_BINDING); } @@ -513,7 +508,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_DOUBLE); } @@ -522,7 +517,7 @@ char path[MS_MAXPATHLEN]; msyytext+=2; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_STRING); } @@ -531,14 +526,14 @@ char path[MS_MAXPATHLEN]; msyytext+=2; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_TIME); } -?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); return(MS_NUMBER); @@ -546,7 +541,7 @@ char path[MS_MAXPATHLEN]; -?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); return(MS_TOKEN_LITERAL_NUMBER); @@ -556,7 +551,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_LITERAL_TIME); } @@ -565,7 +560,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-2] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_IREGEX); } @@ -574,7 +569,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_REGEX); } @@ -583,7 +578,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_EXPRESSION); } @@ -592,7 +587,7 @@ char path[MS_MAXPATHLEN]; msyytext++; msyytext[strlen(msyytext)-1] = '\0'; MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_LIST); } @@ -601,18 +596,13 @@ char path[MS_MAXPATHLEN]; msyystring_return_state = MS_STRING; msyystring_begin = msyytext[0]; msyystring_size = 0; - msyystring_buffer_ptr = msyystring_buffer; + msyystring_buffer[0] = '\0'; BEGIN(MSSTRING); } \'|\"|\"i|\'i { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); if (msyystring_begin == msyytext[0]) { BEGIN(msyystring_begin_state); - - *msyystring_buffer_ptr = '\0'; - if (msyystring_return_state == MS_STRING) { if (msyystring_icase && strlen(msyytext)==2) { msyystring_icase = MS_FALSE; // reset @@ -624,36 +614,37 @@ char path[MS_MAXPATHLEN]; } else { - ++msyystring_size; - *msyystring_buffer_ptr++ = *msyytext; + int old_size = msyystring_size; + msyystring_size += (strlen(msyytext)==2) ? 2 : 1; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + msyystring_buffer[old_size] = *msyytext; if (strlen(msyytext)==2) { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; - *msyystring_buffer_ptr++ = msyytext[1]; + msyystring_buffer[old_size+1] = msyytext[1]; } + msyystring_buffer[msyystring_size] = '\0'; } } \\\'|\\\"|\\\\|\\ { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + if (strlen(msyytext) == 2) - *msyystring_buffer_ptr++ = msyytext[1]; + msyystring_buffer[msyystring_size-1] = msyytext[1]; else - *msyystring_buffer_ptr++ = msyytext[0]; + msyystring_buffer[msyystring_size-1] = msyytext[0]; + msyystring_buffer[msyystring_size] = '\0'; } [^\\\'\\\"]+ { - char *yptr = msyytext; - while ( *yptr ) { - MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, - msyystring_buffer_size, msyystring_buffer_ptr); - ++msyystring_size; - *msyystring_buffer_ptr++ = *yptr++; - } + int old_size = msyystring_size; + int msyytext_len = (int)strlen(msyytext); + msyystring_size += msyytext_len; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, + msyystring_buffer_size); + memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1); } \"[^\"]*\"|\'[^\']*\' { @@ -686,13 +677,13 @@ char path[MS_MAXPATHLEN]; msyystring_return_state = MS_TOKEN_LITERAL_STRING; msyystring_begin = msyytext[0]; msyystring_size = 0; - msyystring_buffer_ptr = msyystring_buffer; + msyystring_buffer[0] = '\0'; BEGIN(MSSTRING); } [a-z/\.][a-z0-9/\._\-\=]* { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_STRING); } @@ -716,7 +707,7 @@ char path[MS_MAXPATHLEN]; . { MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), - msyystring_buffer_size, msyystring_buffer_ptr); + msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(0); } From 22bcde33f0965c68eec72948c1514d0c65a8ddb7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Oct 2022 12:59:30 +0200 Subject: [PATCH 055/170] msSHPReadShape(): avoid integer overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52209 --- mapshape.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mapshape.c b/mapshape.c index 34a6b4b06e..e3e80e55e5 100644 --- a/mapshape.c +++ b/mapshape.c @@ -1431,11 +1431,12 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape ) const ms_int32 end = i == nParts - 1 ? nPoints : psSHP->panParts[i+1]; - shape->line[i].numpoints = end - psSHP->panParts[i]; if (psSHP->panParts[i] < 0 || end < 0 || end > nPoints || psSHP->panParts[i] >= end) { - msSetError(MS_SHPERR, "Corrupted .shp file : shape %d, shape->line[%d].numpoints=%d", "msSHPReadShape()", - hEntity, i, shape->line[i].numpoints); + msSetError(MS_SHPERR, "Corrupted .shp file : shape %d, shape->line[%d].start=%d, shape->line[%d].end=%d", "msSHPReadShape()", + hEntity, + i, psSHP->panParts[i], + i, end); while(--i >= 0) free(shape->line[i].point); free(shape->line); @@ -1445,6 +1446,7 @@ void msSHPReadShape( SHPHandle psSHP, int hEntity, shapeObj *shape ) return; } + shape->line[i].numpoints = end - psSHP->panParts[i]; if( (shape->line[i].point = (pointObj *)malloc(sizeof(pointObj)*shape->line[i].numpoints)) == NULL ) { while(--i >= 0) free(shape->line[i].point); From 6b4ac646c9bfbc4288275703b1a4693de7b6f469 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Oct 2022 13:02:22 +0200 Subject: [PATCH 056/170] msSHXLoadPage(): fix integer overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52211 --- mapshape.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mapshape.c b/mapshape.c index 34a6b4b06e..98e94080a6 100644 --- a/mapshape.c +++ b/mapshape.c @@ -1165,12 +1165,12 @@ static bool msSHXLoadPage( SHPHandle psSHP, int shxBufferPage ) /* SHX stores the offsets in 2 byte units, so we double them to get */ /* an offset in bytes. */ - if( tmpOffset < INT_MAX / 2 ) + if( tmpOffset > 0 && tmpOffset < INT_MAX / 2 ) tmpOffset = tmpOffset * 2; else tmpOffset = 0; - if( tmpSize < INT_MAX / 2 ) + if( tmpSize > 0 && tmpSize < INT_MAX / 2 ) tmpSize = tmpSize * 2; else tmpSize = 0; @@ -1215,12 +1215,12 @@ static int msSHXLoadAll( SHPHandle psSHP ) /* SHX stores the offsets in 2 byte units, so we double them to get */ /* an offset in bytes. */ - if( nOffset < INT_MAX / 2 ) + if( nOffset > 0 && nOffset < INT_MAX / 2 ) nOffset = nOffset * 2; else nOffset = 0; - if( nLength < INT_MAX / 2 ) + if( nLength > 0 && nLength < INT_MAX / 2 ) nLength = nLength * 2; else nLength = 0; From 883714e12ed1ecaa0c0664bd77a5fcf76e9cfc3e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Oct 2022 13:05:25 +0200 Subject: [PATCH 057/170] msSHPOpenVirtualFile(): fix integer overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52213 --- mapshape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mapshape.c b/mapshape.c index 34a6b4b06e..fef8c62498 100644 --- a/mapshape.c +++ b/mapshape.c @@ -269,10 +269,10 @@ SHPHandle msSHPOpenVirtualFile( VSILFILE * fpSHP, VSILFILE * fpSHX ) int nSHXHalfFileSize; if( !bBigEndian ) SwapWord( 4, pabyBuf+24 ); memcpy(&nSHXHalfFileSize, pabyBuf+24, 4); - if (nSHXHalfFileSize != 0) + if (nSHXHalfFileSize >= 50) psSHP->nRecords = (nSHXHalfFileSize - 50) / 4; // (nSHXFileSize - 100) / 8 else - psSHP->nRecords = 0; + psSHP->nRecords = -1; if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) { msSetError(MS_SHPERR, "Corrupted .shx file : nRecords = %d.", "msSHPOpen()", From 9452e33951196edaa8ac7f1737e0dfcf48664143 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Oct 2022 13:17:56 +0200 Subject: [PATCH 058/170] loadFeaturePoints(): fix memleak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52222 --- mapfile.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/mapfile.c b/mapfile.c index 34468bc720..9e88f42066 100755 --- a/mapfile.c +++ b/mapfile.c @@ -912,6 +912,7 @@ void freeFeatureList(featureListNodeObjPtr list) /* lineObj = multipointObj */ static int loadFeaturePoints(lineObj *points) { + int ret = -1; int buffer_size=0; points->point = (pointObj *)malloc(sizeof(pointObj)*MS_FEATUREINITSIZE); @@ -919,30 +920,48 @@ static int loadFeaturePoints(lineObj *points) points->numpoints = 0; buffer_size = MS_FEATUREINITSIZE; - for(;;) { + while( ret < 0 ) { switch(msyylex()) { case(EOF): msSetError(MS_EOFERR, NULL, "loadFeaturePoints()"); - return(MS_FAILURE); + ret = MS_FAILURE; + break; case(END): - return(MS_SUCCESS); + ret = MS_SUCCESS; + break; case(MS_NUMBER): if(points->numpoints == buffer_size) { /* just add it to the end */ - points->point = (pointObj *) realloc(points->point, sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT)); - MS_CHECK_ALLOC(points->point, sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT), MS_FAILURE); + pointObj* newPoints = (pointObj *) realloc(points->point, sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT)); + if( newPoints == NULL ) { + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", __FUNCTION__, + __FILE__, __LINE__, (unsigned int)(sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT))); + ret = MS_FAILURE; + break; + } + points->point = newPoints; buffer_size+=MS_FEATUREINCREMENT; } points->point[points->numpoints].x = atof(msyystring_buffer); - if(getDouble(&(points->point[points->numpoints].y), MS_NUM_CHECK_NONE, -1, -1) == -1) return(MS_FAILURE); - + if(getDouble(&(points->point[points->numpoints].y), MS_NUM_CHECK_NONE, -1, -1) == -1) { + ret = MS_FAILURE; + break; + } points->numpoints++; break; default: msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadFeaturePoints()", msyystring_buffer, msyylineno ); - return(MS_FAILURE); + ret = MS_FAILURE; + break; } } + + if( ret == MS_FAILURE ) { + msFree(points->point); /* clean up */ + points->point = NULL; + points->numpoints = 0; + } + return ret; } static int loadFeature(layerObj *player, int type) From b8d1a43ccacde9de2b187d2dc272ae2c1d69e1ca Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Oct 2022 13:43:02 +0200 Subject: [PATCH 059/170] msOGRShapeFromWKT(): fix memleak in error code path Likely fix for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52223 (couldn't reproduce the leak with the reproducer and current main, but this commit does fix a leak) --- mapogr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapogr.cpp b/mapogr.cpp index 1b66219b10..e3162de2ad 100644 --- a/mapogr.cpp +++ b/mapogr.cpp @@ -5537,7 +5537,7 @@ shapeObj *msOGRShapeFromWKT(const char *string) wkbFlatten(OGR_G_GetGeometryType(hGeom)) ) == MS_FAILURE ) { free( shape ); - return NULL; + shape = NULL; } OGR_G_DestroyGeometry( hGeom ); From 539cbefb4e03b612a73ec6582323c3eb129daf2c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 9 Oct 2022 13:29:03 +0200 Subject: [PATCH 060/170] loadProjection(): fix memleak in case of repeated PROJECTION block Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52252 --- mapfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 34468bc720..6a89b8d5f6 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1165,7 +1165,7 @@ static int loadProjection(projectionObj *p) p->gt.need_geotransform = MS_FALSE; - if ( p->proj != NULL ) { + if ( p->proj != NULL || p->numargs != 0 ) { msSetError(MS_MISCERR, "Projection is already initialized. Multiple projection definitions are not allowed in this object. (line %d)", "loadProjection()", msyylineno); return(-1); From c58ae271f5c89c7fc2a0762f567bf5b26f64a1db Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 9 Oct 2022 13:33:53 +0200 Subject: [PATCH 061/170] msIsAxisInverted(): avoid undefined-shift on invalid code Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52259 --- mapproject.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mapproject.c b/mapproject.c index a38794aa9f..7f5bb36ba9 100644 --- a/mapproject.c +++ b/mapproject.c @@ -980,6 +980,8 @@ int msProcessProjection(projectionObj *p) /************************************************************************/ int msIsAxisInverted(int epsg_code) { + if( epsg_code < 0 ) + return MS_FALSE; const unsigned int row = epsg_code / 8; const unsigned char index = epsg_code % 8; From 37eed55a728293e4f05ed13b43b719808374f81d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 9 Oct 2022 22:44:47 +0200 Subject: [PATCH 062/170] loadSymbol(): fix potential memory leak Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52272 --- mapsymbol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mapsymbol.c b/mapsymbol.c index bc294a19f1..82e578e61d 100644 --- a/mapsymbol.c +++ b/mapsymbol.c @@ -231,8 +231,10 @@ int loadSymbol(symbolObj *s, char *symbolpath) msSetError(MS_TYPEERR, "Parsing error near (%s):(line %d)", "loadSymbol()", msyystring_buffer, msyylineno); return(-1); } + msFree(s->full_pixmap_path); s->full_pixmap_path = msStrdup(msBuildPath(szPath, symbolpath, msyystring_buffer)); /* Set imagepath */ + msFree(s->imagepath); s->imagepath = msStrdup(msyystring_buffer); break; case(NAME): From 59a0cbc5175cab6efd2e956a53120f95ff958b51 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 9 Oct 2022 22:52:01 +0200 Subject: [PATCH 063/170] msDBFOpenVirtualFile(): avoid integer overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52283 --- mapxbase.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mapxbase.c b/mapxbase.c index df43653f8d..60946e710f 100644 --- a/mapxbase.c +++ b/mapxbase.c @@ -127,7 +127,7 @@ DBFHandle msDBFOpenVirtualFile( VSILFILE * fp ) { DBFHandle psDBF; uchar *pabyBuf; - int nFields, nRecords, nHeadLen, nRecLen, iField; + int nFields, nHeadLen, nRecLen, iField; /* -------------------------------------------------------------------- */ /* Open the file. */ @@ -155,8 +155,10 @@ DBFHandle msDBFOpenVirtualFile( VSILFILE * fp ) return( NULL ); } - psDBF->nRecords = nRecords = - pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; + if( pabyBuf[7] < 128 ) + psDBF->nRecords = pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; + else + psDBF->nRecords = 0; psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256; From 700ea8243c496f3d574102c432deaf1a85472271 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 11 Oct 2022 00:48:52 +0200 Subject: [PATCH 064/170] maplexer.l: fix heap-buffer-overflow issues with NUL characters Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52305 --- maplexer.c | 81 +++++++++++++++++++++++++++--------------------------- maplexer.l | 59 +++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/maplexer.c b/maplexer.c index b713ac90e9..b128d98cb2 100644 --- a/maplexer.c +++ b/maplexer.c @@ -4180,8 +4180,8 @@ YY_RULE_SETUP #line 486 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); return(MS_BINDING); @@ -4218,8 +4218,8 @@ YY_RULE_SETUP { /* attribute binding - numeric (no quotes) */ msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_DOUBLE); @@ -4232,8 +4232,8 @@ YY_RULE_SETUP { /* attribute binding - string (single or double quotes) */ msyytext+=2; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-2-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_STRING); @@ -4246,8 +4246,8 @@ YY_RULE_SETUP { /* attribute binding - time */ msyytext+=2; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-2-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_TIME); @@ -4257,7 +4257,7 @@ case 326: YY_RULE_SETUP #line 535 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); @@ -4268,7 +4268,7 @@ case 327: YY_RULE_SETUP #line 543 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); @@ -4281,8 +4281,8 @@ YY_RULE_SETUP #line 551 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_LITERAL_TIME); @@ -4294,8 +4294,8 @@ YY_RULE_SETUP #line 560 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_IREGEX); @@ -4307,8 +4307,8 @@ YY_RULE_SETUP #line 569 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_REGEX); @@ -4319,8 +4319,8 @@ YY_RULE_SETUP #line 578 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_EXPRESSION); @@ -4331,8 +4331,8 @@ YY_RULE_SETUP #line 587 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_LIST); @@ -4356,7 +4356,7 @@ YY_RULE_SETUP if (msyystring_begin == msyytext[0]) { BEGIN(msyystring_begin_state); if (msyystring_return_state == MS_STRING) { - if (msyystring_icase && strlen(msyytext)==2) { + if (msyystring_icase && msyyleng==2) { msyystring_icase = MS_FALSE; // reset return MS_ISTRING; } else @@ -4367,11 +4367,11 @@ YY_RULE_SETUP } else { int old_size = msyystring_size; - msyystring_size += (strlen(msyytext)==2) ? 2 : 1; + msyystring_size += (msyyleng==2) ? 2 : 1; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); msyystring_buffer[old_size] = *msyytext; - if (strlen(msyytext)==2) { + if (msyyleng==2) { msyystring_buffer[old_size+1] = msyytext[1]; } msyystring_buffer[msyystring_size] = '\0'; @@ -4386,7 +4386,7 @@ YY_RULE_SETUP MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); - if (strlen(msyytext) == 2) + if (msyyleng == 2) msyystring_buffer[msyystring_size-1] = msyytext[1]; else msyystring_buffer[msyystring_size-1] = msyytext[0]; @@ -4399,20 +4399,19 @@ YY_RULE_SETUP #line 642 "maplexer.l" { int old_size = msyystring_size; - int msyytext_len = (int)strlen(msyytext); - msyystring_size += msyytext_len; + msyystring_size += msyyleng; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); - memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1); + memcpy(msyystring_buffer + old_size, msyytext, msyyleng + 1); } YY_BREAK case 337: /* rule 337 can match eol */ YY_RULE_SETUP -#line 651 "maplexer.l" +#line 650 "maplexer.l" { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; + msyytext[msyyleng-1-1] = '\0'; if(include_stack_ptr >= MAX_INCLUDE_DEPTH) { msSetError(MS_IOERR, "Includes nested to deeply.", "msyylex()"); @@ -4438,7 +4437,7 @@ YY_RULE_SETUP YY_BREAK case 338: YY_RULE_SETUP -#line 677 "maplexer.l" +#line 676 "maplexer.l" { msyystring_return_state = MS_TOKEN_LITERAL_STRING; msyystring_begin = msyytext[0]; @@ -4449,9 +4448,9 @@ YY_RULE_SETUP YY_BREAK case 339: YY_RULE_SETUP -#line 685 "maplexer.l" +#line 684 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_STRING); @@ -4460,12 +4459,12 @@ YY_RULE_SETUP case 340: /* rule 340 can match eol */ YY_RULE_SETUP -#line 692 "maplexer.l" +#line 691 "maplexer.l" { msyylineno++; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CONFIG_FILE): -#line 694 "maplexer.l" +#line 693 "maplexer.l" { if( --include_stack_ptr < 0 ) return(EOF); /* end of main file */ @@ -4480,16 +4479,16 @@ case YY_STATE_EOF(CONFIG_FILE): case 341: /* rule 341 can match eol */ YY_RULE_SETUP -#line 705 "maplexer.l" +#line 704 "maplexer.l" { return(0); } YY_BREAK case 342: YY_RULE_SETUP -#line 709 "maplexer.l" +#line 708 "maplexer.l" { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(0); @@ -4497,15 +4496,15 @@ YY_RULE_SETUP YY_BREAK case 343: YY_RULE_SETUP -#line 715 "maplexer.l" +#line 714 "maplexer.l" { return(msyytext[0]); } YY_BREAK case 344: YY_RULE_SETUP -#line 716 "maplexer.l" +#line 715 "maplexer.l" ECHO; YY_BREAK -#line 4509 "/home/even/mapserver/mapserver/maplexer.c" +#line 4508 "/home/even/mapserver/mapserver/maplexer.c" case YY_STATE_EOF(EXPRESSION_STRING): case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(MSSTRING): @@ -5514,7 +5513,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 716 "maplexer.l" +#line 715 "maplexer.l" /* diff --git a/maplexer.l b/maplexer.l index 00b3c85d15..7a67479c40 100644 --- a/maplexer.l +++ b/maplexer.l @@ -484,8 +484,8 @@ char path[MS_MAXPATHLEN]; \[[^\]]*\] { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); return(MS_BINDING); @@ -506,8 +506,8 @@ char path[MS_MAXPATHLEN]; \[[^\]]*\] { /* attribute binding - numeric (no quotes) */ msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_DOUBLE); @@ -515,8 +515,8 @@ char path[MS_MAXPATHLEN]; \"\[[^\"]*\]\"|\'\[[^\']*\]\' { /* attribute binding - string (single or double quotes) */ msyytext+=2; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-2-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_STRING); @@ -524,15 +524,15 @@ char path[MS_MAXPATHLEN]; \`\[[^\`]*\]\` { /* attribute binding - time */ msyytext+=2; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-2-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_BINDING_TIME); } -?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); @@ -540,7 +540,7 @@ char path[MS_MAXPATHLEN]; } -?[0-9]+|-?[0-9]+\.[0-9]*|-?\.[0-9]*|-?[0-9]+[eE][+-]?[0-9]+|-?[0-9]+\.[0-9]*[eE][+-]?[0-9]+|-?\.[0-9]*[eE][+-]?[0-9]+ { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer,msyytext); msyynumber = atof(msyytext); @@ -549,8 +549,8 @@ char path[MS_MAXPATHLEN]; \`[^\`]*\` { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_TOKEN_LITERAL_TIME); @@ -558,8 +558,8 @@ char path[MS_MAXPATHLEN]; \/[^*]{1}[^\/]*\/i { msyytext++; - msyytext[strlen(msyytext)-2] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-2] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_IREGEX); @@ -567,8 +567,8 @@ char path[MS_MAXPATHLEN]; \/[^*]{1}[^\/]*\/ { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_REGEX); @@ -576,8 +576,8 @@ char path[MS_MAXPATHLEN]; \(.*\) { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_EXPRESSION); @@ -585,8 +585,8 @@ char path[MS_MAXPATHLEN]; \{.*\} { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + msyytext[msyyleng-1-1] = '\0'; + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_LIST); @@ -604,7 +604,7 @@ char path[MS_MAXPATHLEN]; if (msyystring_begin == msyytext[0]) { BEGIN(msyystring_begin_state); if (msyystring_return_state == MS_STRING) { - if (msyystring_icase && strlen(msyytext)==2) { + if (msyystring_icase && msyyleng==2) { msyystring_icase = MS_FALSE; // reset return MS_ISTRING; } else @@ -615,11 +615,11 @@ char path[MS_MAXPATHLEN]; } else { int old_size = msyystring_size; - msyystring_size += (strlen(msyytext)==2) ? 2 : 1; + msyystring_size += (msyyleng==2) ? 2 : 1; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); msyystring_buffer[old_size] = *msyytext; - if (strlen(msyytext)==2) { + if (msyyleng==2) { msyystring_buffer[old_size+1] = msyytext[1]; } msyystring_buffer[msyystring_size] = '\0'; @@ -631,7 +631,7 @@ char path[MS_MAXPATHLEN]; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); - if (strlen(msyytext) == 2) + if (msyyleng == 2) msyystring_buffer[msyystring_size-1] = msyytext[1]; else msyystring_buffer[msyystring_size-1] = msyytext[0]; @@ -640,16 +640,15 @@ char path[MS_MAXPATHLEN]; [^\\\'\\\"]+ { int old_size = msyystring_size; - int msyytext_len = (int)strlen(msyytext); - msyystring_size += msyytext_len; + msyystring_size += msyyleng; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, msyystring_buffer_size); - memcpy(msyystring_buffer + old_size, msyytext, msyytext_len + 1); + memcpy(msyystring_buffer + old_size, msyytext, msyyleng + 1); } \"[^\"]*\"|\'[^\']*\' { msyytext++; - msyytext[strlen(msyytext)-1] = '\0'; + msyytext[msyyleng-1-1] = '\0'; if(include_stack_ptr >= MAX_INCLUDE_DEPTH) { msSetError(MS_IOERR, "Includes nested to deeply.", "msyylex()"); @@ -682,7 +681,7 @@ char path[MS_MAXPATHLEN]; } [a-z/\.][a-z0-9/\._\-\=]* { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(MS_STRING); @@ -706,7 +705,7 @@ char path[MS_MAXPATHLEN]; } . { - MS_LEXER_STRING_REALLOC(msyystring_buffer, strlen(msyytext), + MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); strcpy(msyystring_buffer, msyytext); return(0); From 36def2d2565be0f536fd1613e49649d84c3625ef Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 13 Oct 2022 15:00:36 +0200 Subject: [PATCH 065/170] msOGRShapeFromWKT(): fix memory leak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52363 --- mapogr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mapogr.cpp b/mapogr.cpp index e3162de2ad..13a6a5d0a7 100644 --- a/mapogr.cpp +++ b/mapogr.cpp @@ -5536,6 +5536,7 @@ shapeObj *msOGRShapeFromWKT(const char *string) if( msOGRGeometryToShape( hGeom, shape, wkbFlatten(OGR_G_GetGeometryType(hGeom)) ) == MS_FAILURE ) { + msFreeShape(shape); free( shape ); shape = NULL; } From f49d430b0cfe0b4bd3fd885fb8a0f075a2020dda Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 13 Oct 2022 19:58:50 +0200 Subject: [PATCH 066/170] loadColor(): fix memory leak if LABEL.COLOR is repeated Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52371 --- mapfile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mapfile.c b/mapfile.c index e56dd8e7b2..a9e3c758f2 100755 --- a/mapfile.c +++ b/mapfile.c @@ -466,6 +466,7 @@ int loadColor(colorObj *color, attributeBindingObj *binding) } } else { assert(binding); + msFree(binding->item); binding->item = msStrdup(msyystring_buffer); binding->index = -1; } From 5059f658046835e9d282077e737497bacf3061b7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 13 Oct 2022 20:17:32 +0200 Subject: [PATCH 067/170] loadLeader(): fix memleak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52376 --- mapfile.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index e56dd8e7b2..1c1697deb9 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1573,7 +1573,13 @@ static int loadLeader(labelLeaderObj *leader) if(msGrowLeaderStyles(leader) == NULL) return(-1); initStyle(leader->styles[leader->numstyles]); - if(loadStyle(leader->styles[leader->numstyles]) != MS_SUCCESS) return(-1); + if(loadStyle(leader->styles[leader->numstyles]) != MS_SUCCESS) + { + freeStyle(leader->styles[leader->numstyles]); + free(leader->styles[leader->numstyles]); + leader->styles[leader->numstyles] = NULL; + return -1; + } leader->numstyles++; break; default: From 213f2edab37ee5c43a351a2058a7c73f60642735 Mon Sep 17 00:00:00 2001 From: Steve Lime Date: Fri, 14 Oct 2022 23:09:49 -0500 Subject: [PATCH 068/170] Make sure a POINT block doesn't contain too many points. --- mapsymbol.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mapsymbol.c b/mapsymbol.c index 82e578e61d..9a1ef74991 100644 --- a/mapsymbol.c +++ b/mapsymbol.c @@ -250,6 +250,10 @@ int loadSymbol(symbolObj *s, char *symbolpath) done = MS_TRUE; break; case(MS_NUMBER): + if(s->numpoints == MS_MAXVECTORPOINTS) { + msSetError(MS_SYMERR, "POINT block contains too many points.", "loadSymbol()"); + return(-1); + } s->points[s->numpoints].x = atof(msyystring_buffer); /* grab the x */ if(getDouble(&(s->points[s->numpoints].y), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); /* grab the y */ if(s->points[s->numpoints].x!=-99) { From adcdac83674c4e0299c5691326d7b0cd4c8d9304 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 16 Oct 2022 21:56:11 +0200 Subject: [PATCH 069/170] loadProjection(): fix memleak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52472 --- mapfile.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/mapfile.c b/mapfile.c index da30deaa3f..81ed654503 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1181,8 +1181,6 @@ static void writeGrid(FILE *stream, int indent, graticuleObj *pGraticule) static int loadProjection(projectionObj *p) { - int i=0; - p->gt.need_geotransform = MS_FALSE; if ( p->proj != NULL || p->numargs != 0 ) { @@ -1197,16 +1195,16 @@ static int loadProjection(projectionObj *p) msSetError(MS_EOFERR, NULL, "loadProjection()"); return(-1); case(END): - if( i == 1 && strstr(p->args[0],"+") != NULL ) { + if( p->numargs == 1 && strstr(p->args[0],"+") != NULL ) { char *one_line_def = p->args[0]; int result; p->args[0] = NULL; + p->numargs = 0; result = msLoadProjectionString( p, one_line_def ); free( one_line_def ); return result; } else { - p->numargs = i; if(p->numargs != 0) return msProcessProjection(p); else @@ -1215,15 +1213,14 @@ static int loadProjection(projectionObj *p) break; case(MS_STRING): case(MS_AUTO): - if( i == MS_MAXPROJARGS ) { + if( p->numargs == MS_MAXPROJARGS ) { msSetError(MS_MISCERR, "Parsing error near (%s):(line %d): Too many arguments in projection string", "loadProjection()", msyystring_buffer, msyylineno); - p->numargs = i; return -1; } - p->args[i] = msStrdup(msyystring_buffer); + p->args[p->numargs] = msStrdup(msyystring_buffer); p->automatic = MS_TRUE; - i++; + p->numargs++; break; default: msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadProjection()", From 8d522da223832c840d93560e8449a074535a5b41 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 16 Oct 2022 23:48:32 +0200 Subject: [PATCH 070/170] writeLayer(): fix wrong argument that cause invalid stack reading (perhaps fixes #6628) This was introduced per 6da3b29110 --- mapfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index da30deaa3f..36163da8aa 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4479,7 +4479,7 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeCluster(stream, indent, &(layer->cluster)); writeLayerCompositer(stream, indent, layer->compositer); writeString(stream, indent, "CONNECTION", NULL, layer->connection); - writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 13, MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, "CONTOUR", MS_KERNELDENSITY, "KERNELDENSITY", MS_IDW, "IDW", MS_FLATGEOBUF, "FLATGEOBUF"); + writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 12, MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, "CONTOUR", MS_KERNELDENSITY, "KERNELDENSITY", MS_IDW, "IDW", MS_FLATGEOBUF, "FLATGEOBUF"); writeHashTableInline(stream, indent, "CONNECTIONOPTIONS", &(layer->connectionoptions)); writeString(stream, indent, "DATA", NULL, layer->data); writeNumber(stream, indent, "DEBUG", 0, layer->debug); /* is this right? see loadLayer() */ From 34e7ce1081272ff604b473533ee04048ef9a897d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 20 Oct 2022 12:39:12 +0200 Subject: [PATCH 071/170] msBuildPluginLibraryPath(): fix potential memleak Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52556 --- mapfile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mapfile.c b/mapfile.c index c7cc3a6ae8..648166ee56 100755 --- a/mapfile.c +++ b/mapfile.c @@ -370,6 +370,7 @@ int msBuildPluginLibraryPath(char **dest, const char *lib_str, mapObj *map) if (NULL == msBuildPath(szLibPath, plugin_dir, lib_str)) { return MS_FAILURE; } + msFree(*dest); *dest = msStrdup(szLibPath); return MS_SUCCESS; @@ -4217,6 +4218,7 @@ int loadLayer(layerObj *layer, mapObj *map) msSetError(MS_MISCERR, "Plugin value not found in config file. See mapserver.org/mapfile/config.html for more information." , "loadLayer()"); return(-1); } + msFree(layer->plugin_library_original); layer->plugin_library_original = strdup(plugin_library); } else { if(getString(&layer->plugin_library_original) == MS_FAILURE) return(-1); From ba2b036c04baabec4f440501ab7a5082455100eb Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 19 Oct 2022 22:09:21 +0200 Subject: [PATCH 072/170] msMapComputeGeotransform(): avoid (harmless) potential floating-point division by zero Also add msMapComputeGeotransformEx() that can be used to properly generate rasters of width or height 1 (refs #3857) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52480 --- mapobject.c | 30 +++++++++++------ mapserver.h | 1 + mapwcs.cpp | 5 ++- mapwcs20.cpp | 31 +++++++++++++++--- msautotest/renderers/expected/labelrot.png | Bin 13582 -> 13584 bytes .../wcs_20_getcov_trim_x_y_both_1px.tif | Bin 413 -> 413 bytes .../wcs_20_multi_getcov_trim_x_to_1px.tif | Bin 1031 -> 1031 bytes .../wcs_20_multi_getcov_trim_y_to_1px.tif | Bin 1471 -> 1427 bytes .../wcs_20_post_getcov_trim_x_y_both_1px.tif | Bin 413 -> 413 bytes .../expected/wcs_mask_20_getcov_reproj.dat | Bin 4626 -> 4626 bytes .../wcs_mask_20_getcov_trim_x_y_both_1px.tif | Bin 413 -> 413 bytes 11 files changed, 51 insertions(+), 16 deletions(-) diff --git a/mapobject.c b/mapobject.c index 1f7db5446b..21fb1115e8 100644 --- a/mapobject.c +++ b/mapobject.c @@ -382,7 +382,7 @@ int msMapSetSize( mapObj *map, int width, int height ) extern int InvGeoTransform( double *gt_in, double *gt_out ); -int msMapComputeGeotransform( mapObj * map ) +int msMapComputeGeotransformEx( mapObj * map, double resolutionX, double resolutionY ) { double rot_angle; @@ -390,11 +390,6 @@ int msMapComputeGeotransform( mapObj * map ) map->saved_extent = map->extent; - /* Do we have all required parameters? */ - if( map->extent.minx == map->extent.maxx - || map->width == 0 || map->height == 0 ) - return MS_FAILURE; - rot_angle = map->gt.rotation_angle * MS_PI / 180.0; geo_width = map->extent.maxx - map->extent.minx; @@ -409,17 +404,17 @@ int msMapComputeGeotransform( mapObj * map ) ** edges as is expected in a geotransform. */ map->gt.geotransform[1] = - cos(rot_angle) * geo_width / (map->width-1); + cos(rot_angle) * resolutionX; map->gt.geotransform[2] = - sin(rot_angle) * geo_height / (map->height-1); + sin(rot_angle) * resolutionY; map->gt.geotransform[0] = center_x - (map->width * 0.5) * map->gt.geotransform[1] - (map->height * 0.5) * map->gt.geotransform[2]; map->gt.geotransform[4] = - sin(rot_angle) * geo_width / (map->width-1); + sin(rot_angle) * resolutionX; map->gt.geotransform[5] = - - cos(rot_angle) * geo_height / (map->height-1); + - cos(rot_angle) * resolutionY; map->gt.geotransform[3] = center_y - (map->width * 0.5) * map->gt.geotransform[4] - (map->height * 0.5) * map->gt.geotransform[5]; @@ -431,6 +426,21 @@ int msMapComputeGeotransform( mapObj * map ) return MS_FAILURE; } +int msMapComputeGeotransform( mapObj * map ) + +{ + /* Do we have all required parameters? */ + if( map->extent.minx == map->extent.maxx + || map->width <= 1 || map->height <= 1 ) + return MS_FAILURE; + + const double geo_width = map->extent.maxx - map->extent.minx; + const double geo_height = map->extent.maxy - map->extent.miny; + return msMapComputeGeotransformEx(map, + geo_width / (map->width-1), + geo_height / (map->height-1)); +} + /************************************************************************/ /* msMapPixelToGeoref() */ /************************************************************************/ diff --git a/mapserver.h b/mapserver.h index e8117351b8..3a81db4431 100755 --- a/mapserver.h +++ b/mapserver.h @@ -2183,6 +2183,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char int default_result ); MS_DLL_EXPORT void msApplyMapConfigOptions( mapObj *map ); MS_DLL_EXPORT int msMapComputeGeotransform( mapObj *map ); + int msMapComputeGeotransformEx( mapObj * map, double resolutionX, double resolutionY ); MS_DLL_EXPORT void msMapPixelToGeoref( mapObj *map, double *x, double *y ); MS_DLL_EXPORT void msMapGeorefToPixel( mapObj *map, double *x, double *y ); diff --git a/mapwcs.cpp b/mapwcs.cpp index ac0a9ad2ce..70e63b8185 100644 --- a/mapwcs.cpp +++ b/mapwcs.cpp @@ -2479,7 +2479,10 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage()", par map->cellsize = params->resx; /* pick one, MapServer only supports square cells (what about msAdjustExtent here!) */ - msMapComputeGeotransform(map); + if( params->width == 1 || params->height == 1 ) + msMapComputeGeotransformEx(map, params->resx, params->resy); + else + msMapComputeGeotransform(map); /* Do we need to fake out stuff for rotated support? */ if( map->gt.need_geotransform ) diff --git a/mapwcs20.cpp b/mapwcs20.cpp index d6ee9a325f..815390f6d3 100644 --- a/mapwcs20.cpp +++ b/mapwcs20.cpp @@ -4423,6 +4423,10 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage20()", p x_1 = cm.geotransform[0] + orig_bbox.minx * cm.geotransform[1] + orig_bbox.miny * cm.geotransform[2]; + // below +1 look suspicious to me (E. Rouault) and probably mean that + // there are still issues with pixel-center vs pixel-corner convention + // The resolution computed on wcs_20_post_getcov_trim_x_y_both_1px + // with that is 11, whereas it should be 10 x_2 = cm.geotransform[0] + (orig_bbox.maxx+1) * cm.geotransform[1] + (orig_bbox.maxy+1) * cm.geotransform[2]; @@ -4431,6 +4435,7 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage20()", p subsets.maxx = MS_MAX(x_1, x_2); } if(subsets.miny != -DBL_MAX || subsets.maxy != DBL_MAX) { + // below +1 are suspicious. See bove comment in the minx/maxx cases y_1 = cm.geotransform[3] + (orig_bbox.maxx+1) * cm.geotransform[4] + (orig_bbox.maxy+1) * cm.geotransform[5]; @@ -4589,6 +4594,7 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage20()", p } /* WCS 2.0 is center of pixel oriented */ + rectObj bboxOriginIsCorner = bbox; bbox.minx += params->resolutionX * 0.5; bbox.maxx -= params->resolutionX * 0.5; bbox.miny += params->resolutionY * 0.5; @@ -4611,12 +4617,24 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage20()", p msDebug("msWCSGetCoverage20(): projecting to outputcrs %s\n", params->outputcrs); msProjectRect(&(map->projection), &outputProj, &bbox); - msFreeProjection(&(map->projection)); - map->projection = outputProj; /* recalculate resolutions, needed if UOM changes (e.g: deg -> m) */ - params->resolutionX = (bbox.maxx - bbox.minx) / params->width; - params->resolutionY = (bbox.maxy - bbox.miny) / params->height; + if( params->width == 1 || params->height == 1 ) + { + // if one of the dimension is 1, we cannot use the center-of-pixel bbox, + // but must use the origin-is-corner one. + msProjectRect(&(map->projection), &outputProj, &bboxOriginIsCorner); + params->resolutionX = (bboxOriginIsCorner.maxx - bboxOriginIsCorner.minx) / params->width; + params->resolutionY = (bboxOriginIsCorner.maxy - bboxOriginIsCorner.miny) / params->height; + } + else + { + params->resolutionX = (bbox.maxx - bbox.minx) / (params->width - 1); + params->resolutionY = (bbox.maxy - bbox.miny) / (params->height - 1); + } + + msFreeProjection(&(map->projection)); + map->projection = outputProj; } else { msFreeProjection(&outputProj); @@ -4676,7 +4694,10 @@ this request. Check wcs/ows_enable_request settings.", "msWCSGetCoverage20()", p /* make sure layer is on */ layer->status = MS_ON; - msMapComputeGeotransform(map); + if( params->width == 1 || params->height == 1 ) + msMapComputeGeotransformEx(map, params->resolutionX, params->resolutionY); + else + msMapComputeGeotransform(map); /* fill in bands rangeset info, if required. */ /* msWCSSetDefaultBandsRangeSetInfo(params, &cm, layer); */ diff --git a/msautotest/renderers/expected/labelrot.png b/msautotest/renderers/expected/labelrot.png index f2e2ef6beb2a2a74eae1933c478733cf9f0b0496..a585b36ad2c7d797c5bc62165e8321168df0f48d 100644 GIT binary patch delta 313 zcmV-90mlB0YLIHMFdzZTvoRn90e`fsOR0c$T%qTO6fl9hpgu&1AJqskFs1UWTFmfr zqY#CKh*xC>mJ|8ZsZ*)=uypBCH#av+2xCoPU4v`nZN#?JUkdTobCtUlQ-W1_zq)*` zU0mNR#EVAvJtV1%P#+tu__Gi%3o%dK^t?`pD=CZB7h;ksx8LD**b2psYC_4W7nkB^V{@$s2Db!vkK4RD0`%P+rJ0vT%ps~nUgZzi@y#*E2L zi0&%QdHn2K`&6zpS6zU=s%p*&F;s{yLd+H-GG(!ER03sK3zvLf@o2mdp9qm%-Pr)@ zo5zWYO=HyvQ9~Z4X5CaOce61fy8{ArYqRbp{sIFNY_7BKC<_b}*<@K7oiQ~100000 LNkvXXu0mjf-20I) delta 313 zcmV-90mlB2YL05KFdzZRvoRn90e|MHaw=dQSLpd61x%nWs1Fh1M>RqWOsPDp7Bjru zC`4f);#HY}QpK|EM2SK;lbaCT zRhsko*|+uyF;s}T>H_>#RdY_&bP-~<5Roa1eWMa6!&=05LmfBvd$avMFOaV=(~eg9w2D delta 51 zcmbQsJePUGH-RM#6PaANKG>JvFZ{TP_k;apK}PAx3XJT$AmIo5KkTTu$#$Y>vMFOa GV>SQ|gA@(` diff --git a/msautotest/wxs/expected/wcs_20_multi_getcov_trim_x_to_1px.tif b/msautotest/wxs/expected/wcs_20_multi_getcov_trim_x_to_1px.tif index 48b466c6b84a23a95a5870e101a865a2cec23ff1..1bbc6df8c8fdac9aa3549c2b541776d145fec977 100644 GIT binary patch delta 187 zcmV;s07U6uW@WRp+M0cesnA=A5vw#7V I0h90n^9EcMAOHXW diff --git a/msautotest/wxs/expected/wcs_20_multi_getcov_trim_y_to_1px.tif b/msautotest/wxs/expected/wcs_20_multi_getcov_trim_y_to_1px.tif index 8af67d3ffffd113b7e239193aa2986108c19573c..461702e5fbe6d94f683ae0bf93491e286eb5405a 100644 GIT binary patch delta 819 zcmXxi%Wv8S90zbaQL9FcqE3pkZcBieH|1dn5HMhy*cfa^cqC3jnsimu1|fo4MAx*6 zUo;_rfq+M{G*SB64wJe{TeWG2T_#P_ChbqyvF9FotF*&3tJ8j$??+$hr{CrG%f-RP z5t_CE7XSblS4O76G3APW=ryQhoMZo}-6!BV095llsB|Dkr*Z)t21e8dRz0>m3Jj~B zQ~hvn6gaPXRrPm`VL+!^R{ecr6c|$dr|MUYq4$^m0+lz+rCMom@B#T8119eoC!nvf zK@HShUXg%}Ki=B$zw7Y3!`~CQy7_*7_z4^a#TI#&@`X9$)Z^{)X8EvDEO*It6bTDv zZ68ksygmu~NG6sMIL1M`KA8{taLEFlWh*OmX`hNbN-i(pnL6w|*(%(sepBz%W%A@2 zy1|=Wa`aBZ>*p<#Ev%gO&vQmYXKp*`5Az0XpZYQ%OiE^bOGMKlFU(J0R#MePx+oz? zi`a@IG0qA#QLoWu*n!3$EtPU?r=DADQPmu}&bhrxlqK9LNo$eGy|n<%8%;{4yi9D@ z5Ud-ch#(@GbiH^bhvX%vr->yE?(mLL^W%CdzI1e0+;2zo0e?uaXxee{Yz?`}n{2%( z9`>=K)p-!RlMXJ5Hsb-sEn=+bw0u?h>_+uB`RGMAA;@xG*?El4G)eqtHiu>IA8%YgCM%x?m|d&+*LgRL*3O8}kExqDvatuxbQvLw z-4gwQQ|bm2D%S0xcF1jZI0gM=Pd(;~i$>_%QkE`u`@+3Gk+OS&l0p9k(Pw>$nhEMe zgEOvK!JuhHAEZUcEU%q>l4T$i#_M%Tyu$d2 znoZwjPD*T4pmnb{ljzd5!79~73yjkxYQ`0`NWe1^^zkW!+K}7(p8QM#2zI(5g;>| zk(q%LD53&n-)QAw5CF2xfb8|{%nS-Z_BJ4ULpu)x6OjE4$lln_1U8+GY2ptrhlcEs o$$~Bm?SYa&@Z&#(hLME%lOHnLF@3P#+{MVuIQawPTr@lh0K_^hHUIzs diff --git a/msautotest/wxs/expected/wcs_20_post_getcov_trim_x_y_both_1px.tif b/msautotest/wxs/expected/wcs_20_post_getcov_trim_x_y_both_1px.tif index f3e09ea9996e3754a7fb19267d48f602bf65122a..4c0b3d6f26ff3cbcec4c33eccade51581086abd2 100644 GIT binary patch delta 51 qcmbQsJePUGHvtAPP;-FMlLZ;YCo3>=05LmfBvd$avMFOaV=(~f3kZb( delta 51 zcmbQsJePUGH-RM#6PaANKG>JvFZ{TP_k;apK}PAx3XJT$AmIo5KkTTu$#$Y>vMFOa GV>SQ|gA@(` diff --git a/msautotest/wxs/expected/wcs_mask_20_getcov_reproj.dat b/msautotest/wxs/expected/wcs_mask_20_getcov_reproj.dat index 578ea3654f6c85f9a2d53a88f8b2c8b7f93f4b4b..c0c7bec9b0439b587db8005a158c58dbd45ef876 100644 GIT binary patch delta 386 zcmYk0Ay33W5QP`gkV`M^6-#n(7fLWxAV?569PT7_mrXDuM5*%?=Dqi2X6NnVUHs{Vk79gM$-!efl7q1d2q_z33QD3#%~QB~kU*RO zB+A3?IHVOI;V~+ZBqgQ_0a2Kb@FE~yc~O`$0W?30<$N#_2{eJ(221lB`mC28a4+)} z+?)`{=Tk(M*c&dgSTD1qKC0&ME~{CS31C>CAVuzAvh- zX_}(flYye?tG=B8wz;dzqHa1nwDWDIUDlR$JG8r+DM!|pU2V4K>ocqEKC75tdpgT= Rvst{(13yXLB_>JW{{hSqbmag5 delta 412 zcmYk1ze@u#6vtCqXszTpJ6g~y7G1o-L2&Rd@DC8VO&+)eM9ARq);DIc$(Z%V13Ne# zPPcZv@xY~P|AhFW^hcI_-sim}-z?^f`R5?HL$O;3e^}_9iQrI?CjZ}yLLu;ky-%`R zp@=J`Km!!9w_OI6ru{t%2tXI8mDXfGlG8-+kq6WT8+P_tP9;SIP0BFYpX9O!?9YaP zKuC^x)+e4_o;=z&IqCD8(Tzw5T>vO9&g~$*>Ir+DzSvhenJT2pA*y}&7%)@~=l@P; zPhz#{x~>k!Z-Wa_cVQLQzTF=3< iku&bguR{DrHYDTA(wEE^eS^sR&9NNk`8()5m*ZdgD13eZ diff --git a/msautotest/wxs/expected/wcs_mask_20_getcov_trim_x_y_both_1px.tif b/msautotest/wxs/expected/wcs_mask_20_getcov_trim_x_y_both_1px.tif index a6dfa99049140527859a3ea934939d24d013e812..b51bda75a537cd6b9c6b8e27f5b3a2e4277ebaf7 100644 GIT binary patch delta 49 ocmbQsJePUGHvtAPP;r3KlLZ;YCo3>=05LmfBvd$avMFN*0N3>h4gdfE delta 49 zcmbQsJePUGH-RM#6PaANKG>JvFZ{TP_k;apK}PAx3XJT$AmIo5KkTTu$#$Y>vMFN* E0OrIKqW}N^ From 970ab95b93d7ba6f38f9cfc4619d6cd6e4aa819a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 20 Oct 2022 17:57:24 +0200 Subject: [PATCH 073/170] Remove call to deprecated xmlSchemaCleanupTypes() xmlSchemaCleanupTypes() is deprecated since libxml 2.10, and will be removed in a future version (as a public callable function) This function is called by xmlCleanupParser() since https://github.com/GNOME/libxml2/commit/36e5cd5064d3477a0500f6183d68b18b7493568a#diff-65f1a082f56ebd52b4eaabdbe54d6e516736c8d9186b8c82c8ca55ad3cac105eR12119 14 years ago, so no need to call it explicitly. Fixes #6614 --- mapowscommon.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mapowscommon.c b/mapowscommon.c index 2a9f059cd1..a407eca5ff 100644 --- a/mapowscommon.c +++ b/mapowscommon.c @@ -718,7 +718,6 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) /* If XML Schema hasn't been rightly loaded */ if (schema == NULL) { - xmlSchemaCleanupTypes(); xmlMemoryDump(); xmlCleanupParser(); return ret; From 857696f7bad7a50d4efeb71b2759b4eb52aa9cec Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 23 Oct 2022 21:01:38 +0200 Subject: [PATCH 074/170] msConnectLayer(): fix potential double-free introduced by recent ossfuzz fix (Coverity Scan 1526531) --- maplayer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maplayer.c b/maplayer.c index 0927a77711..9904b0fb1b 100644 --- a/maplayer.c +++ b/maplayer.c @@ -2110,10 +2110,10 @@ int msConnectLayer(layerObj *layer, /* For internal types, library_str is ignored */ if (connectiontype == MS_PLUGIN) { int rv; - msFree(layer->plugin_library); - msFree(layer->plugin_library_original); + msFree(layer->plugin_library_original); layer->plugin_library_original = msStrdup(library_str); + rv = msBuildPluginLibraryPath(&layer->plugin_library, layer->plugin_library_original, layer->map); From 9292072951eb7b07e1218734b9ea9dd6b83a77ef Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 23 Oct 2022 21:38:18 +0200 Subject: [PATCH 075/170] loadGrid(): fix memleak on LABELFORMAT DD Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52670 --- mapfile.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 648166ee56..ff7f060a60 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1127,8 +1127,10 @@ static int loadGrid( layerObj *pLayer ) break; /* for string loads */ case( LABELFORMAT ): if(getString(&(pLayer->grid->labelformat)) == MS_FAILURE) { - if(strcasecmp(msyystring_buffer, "DD") == 0) /* DD triggers a symbol to be returned instead of a string so check for this special case */ + if(strcasecmp(msyystring_buffer, "DD") == 0) /* DD triggers a symbol to be returned instead of a string so check for this special case */ { + msFree(pLayer->grid->labelformat); pLayer->grid->labelformat = msStrdup("DD"); + } else return(-1); } From 083cf8743a5610dc23ac477a4aab9a6951b4d564 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 25 Oct 2022 20:28:17 +0200 Subject: [PATCH 076/170] loadLayer(): fix memory leak in error code path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52702 --- mapfile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index ff7f060a60..68b716f1db 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4149,7 +4149,10 @@ int loadLayer(layerObj *layer, mapObj *map) return(-1); } - if(loadJoin(&(layer->joins[layer->numjoins])) == -1) return(-1); + if(loadJoin(&(layer->joins[layer->numjoins])) == -1) { + freeJoin(&(layer->joins[layer->numjoins])); + return(-1); + } layer->numjoins++; break; case(LABELCACHE): From 42cf85185fc636fb069e06ec356743ff10115f1e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 2 Nov 2022 10:29:38 +0100 Subject: [PATCH 077/170] freeLabelLeader(): fix memleak (including in nominal code path) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52947 --- mapfile.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 68b716f1db..63bcc759bd 100755 --- a/mapfile.c +++ b/mapfile.c @@ -1511,7 +1511,9 @@ int freeLabelLeader(labelLeaderObj *leader) { int i; for(i=0; inumstyles; i++) { - msFree(leader->styles[i]); + if(freeStyle(leader->styles[i]) == MS_SUCCESS) { + msFree(leader->styles[i]); + } } msFree(leader->styles); From ae232416c9b61fd88c7cc989d2add0b312d195aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 12 Nov 2022 12:05:47 +0100 Subject: [PATCH 078/170] Bit manipulation: avoid undefined-shift behavior when left-shifting of 31 bits Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53339 --- mapbits.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mapbits.c b/mapbits.c index 18a6c5617a..50469ddf9d 100644 --- a/mapbits.c +++ b/mapbits.c @@ -58,7 +58,7 @@ ms_bitarray msAllocBitArray(int numbits) int msGetBit(ms_const_bitarray array, int index) { array += index / MS_ARRAY_BIT; - return (*array & (1 << (index % MS_ARRAY_BIT))) != 0; /* 0 or 1 */ + return (*array & (1U << (index % MS_ARRAY_BIT))) != 0; /* 0 or 1 */ } /* @@ -78,7 +78,7 @@ int msGetNextBit(ms_const_bitarray array, int i, int size) if( b && (b >> (i % MS_ARRAY_BIT)) ) { /* There is something in this byte */ /* And it is not to the right of us */ - if( b & ( 1 << (i % MS_ARRAY_BIT)) ) { + if( b & ( 1U << (i % MS_ARRAY_BIT)) ) { /* There is something at this bit! */ return i; } else { @@ -98,9 +98,9 @@ void msSetBit(ms_bitarray array, int index, int value) { array += index / MS_ARRAY_BIT; if (value) - *array |= 1 << (index % MS_ARRAY_BIT); /* set bit */ + *array |= 1U << (index % MS_ARRAY_BIT); /* set bit */ else - *array &= ~(1 << (index % MS_ARRAY_BIT)); /* clear bit */ + *array &= ~(1U << (index % MS_ARRAY_BIT)); /* clear bit */ } void msSetAllBits(ms_bitarray array, int numbits, int value) @@ -114,5 +114,5 @@ void msSetAllBits(ms_bitarray array, int numbits, int value) void msFlipBit(ms_bitarray array, int index) { array += index / MS_ARRAY_BIT; - *array ^= 1 << (index % MS_ARRAY_BIT); /* flip bit */ + *array ^= 1U << (index % MS_ARRAY_BIT); /* flip bit */ } From aa45522847418edb1bdf10636cea989a6cce38bf Mon Sep 17 00:00:00 2001 From: sethg Date: Sat, 12 Nov 2022 17:05:34 +0100 Subject: [PATCH 079/170] Ignore Python 3.11 for now --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 078e59e17b..1da11fe05b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -49,6 +49,7 @@ init: build_script: - ps: Write-Host "Build tags - $env:APPVEYOR_REPO_TAG $env:APPVEYOR_REPO_TAG_NAME" - rename C:\Python310 Python310_Ignore + - rename C:\Python311 Python311_Ignore - set "BUILD_FOLDER=%APPVEYOR_BUILD_FOLDER:\=/%" - if "%platform%" == "x64" SET VS_FULL=%VS_VERSION% - if "%platform%" == "x64" SET VS_ARCH=x64 From af8e25df0e0566d62ee661bd595125e5b9a2e279 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Mon, 7 Nov 2022 13:19:16 -0400 Subject: [PATCH 080/170] upgrade PHP MapScript test to 8.1.12 release --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8959b23370..385cf26e6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ matrix: - BUILD_NAME=PHP_8.0 - PYTHON_VERSION=3.8 - - php: 8.1.10 + - php: 8.1.12 env: - BUILD_NAME=PHP_8.1 - PYTHON_VERSION=3.9 From fd9c5b822c09e2f7174709453597b7af558556ff Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 14 Nov 2022 22:32:37 +0100 Subject: [PATCH 081/170] [OGR / WFS] Fix PropertyIsLike filter with special characters like parenthesis, backslash and single quote (fixes #6751) --- mapogr.cpp | 17 +++++++-- msautotest/wxs/data/db.sqlite | Bin 157696 -> 167936 bytes ...ve_sql_like_backslash_and_single_quote.xml | 34 ++++++++++++++++++ .../wfs_ogr_native_sql_like_parenthesis.xml | 34 ++++++++++++++++++ msautotest/wxs/wfs_ogr_native_sql.map | 26 ++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 msautotest/wxs/expected/wfs_ogr_native_sql_like_backslash_and_single_quote.xml create mode 100644 msautotest/wxs/expected/wfs_ogr_native_sql_like_parenthesis.xml diff --git a/mapogr.cpp b/mapogr.cpp index 13a6a5d0a7..b242e87109 100644 --- a/mapogr.cpp +++ b/mapogr.cpp @@ -1941,10 +1941,11 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) { op = "~*"; } - char *re = (char *) msSmallMalloc(strlen(regex)+3); + const size_t regex_len = strlen(regex); + char *re = (char *) msSmallMalloc(2 * regex_len+3); size_t i = 0, j = 0; re[j++] = '\''; - while (i < strlen(regex)) { + while (i < regex_len) { char c = regex[i]; char c_next = regex[i+1]; @@ -1961,6 +1962,18 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) { else if( c == '$' && c_next == 0 ) { break; } + else if( c == '\'' ) + { + re[j++] = '\''; + } + else if( c == '\\' ) + { + if( c_next == 0 ) { + break; + } + i++; + c = c_next; + } re[j++] = c; i++; diff --git a/msautotest/wxs/data/db.sqlite b/msautotest/wxs/data/db.sqlite index cf763a153e4042d62928686aee08b47e3d7e9a69..3fde2b09ba44cf82469182d702bc9c85aff9b91f 100644 GIT binary patch delta 4778 zcmcgvZA?>F7(O3`eh7ii0!rz)6r_}oLMdo)5-s%FFO>B{%pz2blIlx!(>}b=8|P|i!NqvWZ9Omb1$?q)?M1DJK>&k z?>Xl=&w1|izW1Dc6Y_l{ioXWRR)F;?NQXgeiq#k0Gu{G!llp$~*fcvm4 zs?7bap>jH2q#zHj$S$_oZS-_!z~kNF4|qLP4b|!jhP@%bE0A~?E6cczWC-5@_zr#$ zQ?}p2ixd)=2d9O>u?LHk5(UO%eDfq8iz#zQaA^s~R@m#>>kT@0`@`MN(16$NclA2m z-L9a^9rgx8C_1^=kfX{bTrnO7_y>Fi50k;K;yMGCS~W5V<)Q#SZ-1Y2cTX5iN3RsD zAq>s~d>;RdCke=#xT;cO)rd2Q1K`-C+9V?Y_W-_!{}9&r4bIHK5KiOR1D$f1w9x=h z;4w@S@Dg#Ka#u{UTqu#jE*tD{~$BO8e?6YFwPMQ5 z9BvvknN0KVqhlX-k=f4ye2#FNAhUDnEG;8CsV<7${dma<1x8l^K8shOs|4hIWC`I+ zvV`X5N8sPc-Ec!Ax5^E#J&OF}lRjut5ri`U-^JJQ8A5OvS6AW;;sRMp{J858xct#L z3_{aKSON}lQVTjbevv^PaQqgHDinDbegLoy4U?Zd;#R)EbA;n*7-73um9)TWMf>$( z*Y;koC|S`)aJ-eF%?_G!m|NOuN+;S`M^#YTexEzTxx??#a<>;DRrC{>W1@6^kB(}y zIcO`*R8zXJcTZSHb(xvgXU*hZ8+W{xveNeFX$P}OKW=#e^}@>zB+1Q^AS1v-I13#? zMzX#Vq}ZmCfs)1*%}WcS4Bgm~#Kb1kW|P5WG#DEVbq3?!#WG;kI7xp|{&61B-z`;v zB%t-ixu7h5iboBlifSc^!5a?lrMARZS-o*n^?Ihw(p+PV-lmsSB$?9KFn7vcr3_SQ zoY4VGA>nA?zV)HvEIw5syc*!Q@oFNE37dQ<6TnVZg7_RqZFjkQLcOj~H?@@#9)$b> zU$2+aQ9F0_hrIyuxtGf^qvhHzmpBS| z2Rd1`px*1*3H5e88TFFEGIPFu3H7v83%%CP&{SuKg%5xG+PPtBw^3R#E&gw1kJTXw z*-=~u#Fv+&%G`G%gC(p+(DdN4Sxv)zPsEYQVOx`HYF_IgE^f1}rx^#8iir7K@f0lQ zd?v)CV7^G)d^-Iz3fg8NA{5ORA(;b`krjKrq4{AM?h{~{|K3*3G1iO-abKn2q*)QR z*Q6wZdY%YEdIUFlYuqH(_%t$z*kVDI1HO2;`Jae2d`V#+pEWMlA*FcwN~q4gt3b68 z(RZ5YtE;AL^acZC-_T~6`S;-mI^nCQ=ljaDaKb7P_Qhf(xEsI0yi}KTT8`5VZij&y}wg9pVX#pYdGO^B!3OWC=r@4LRI7p6esRMA;a#VGU9OyVn x5o#_aXBHuol09)-@#vT2`ue$H_H%N5G5Z{iA1X&-7^8A4&`^gYCTaf*{|$K>i1Yve delta 394 zcmZ9Iy-Nc@5XEZ+_~_JA*RC9qOn$e_W5JiBD=V#5UMeB zu||6*Xx1**h`0=2&?VwfKy*yDZ$^&@CmEh%l5U$rE4c-Cgy@uBg6(BMA12md*v1BJ zU!&F7hK2vKUC^(PL(>Wvd{0iOX|S71d@3}cfWdHspTidzlrj%?Wrb(K-Zyv}ss*l` hDXUziA1N~|lc0cstO&B{*ru5?BIbvYupTpf{2TIBbe{kK diff --git a/msautotest/wxs/expected/wfs_ogr_native_sql_like_backslash_and_single_quote.xml b/msautotest/wxs/expected/wfs_ogr_native_sql_like_backslash_and_single_quote.xml new file mode 100644 index 0000000000..98e30b0022 --- /dev/null +++ b/msautotest/wxs/expected/wfs_ogr_native_sql_like_backslash_and_single_quote.xml @@ -0,0 +1,34 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + 653901.530000,4866278.050000 653901.530000,4866278.050000 + + + + + + + 653901.530000,4866278.050000 653901.530000,4866278.050000 + + + + + 653901.530000,4866278.050000 + + + 2 + with backslash \ with single ' quote + + + + diff --git a/msautotest/wxs/expected/wfs_ogr_native_sql_like_parenthesis.xml b/msautotest/wxs/expected/wfs_ogr_native_sql_like_parenthesis.xml new file mode 100644 index 0000000000..f522e91f66 --- /dev/null +++ b/msautotest/wxs/expected/wfs_ogr_native_sql_like_parenthesis.xml @@ -0,0 +1,34 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + 653901.530000,4866278.050000 653901.530000,4866278.050000 + + + + + + + 653901.530000,4866278.050000 653901.530000,4866278.050000 + + + + + 653901.530000,4866278.050000 + + + 1 + with parenthesis ( ) + + + + diff --git a/msautotest/wxs/wfs_ogr_native_sql.map b/msautotest/wxs/wfs_ogr_native_sql.map index 306019fb11..2245e23ec7 100644 --- a/msautotest/wxs/wfs_ogr_native_sql.map +++ b/msautotest/wxs/wfs_ogr_native_sql.map @@ -49,6 +49,8 @@ # # RUN_PARMS: wfs_ogr_native_sql_20.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=towns&OUTPUTFORMAT=GML2&FILTER=nameV*o" > [RESULT] # RUN_PARMS: wfs_ogr_native_sql_21.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=towns&OUTPUTFORMAT=GML2&FILTER=namev*o" > [RESULT] +# RUN_PARMS: wfs_ogr_native_sql_like_parenthesis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=layer_with_special_characters&OUTPUTFORMAT=GML2&FILTER=text*( )" > [RESULT] +# RUN_PARMS: wfs_ogr_native_sql_like_backslash_and_single_quote.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=layer_with_special_characters&OUTPUTFORMAT=GML2&FILTER=text*\ with single ' quote" > [RESULT] # # bug in MS: ? is treated as * in this case: # @@ -331,5 +333,29 @@ LAYER TEMPLATE "wfs_ogr_native_sql.map" END # Layer +# Layer + +LAYER + + NAME layer_with_special_characters + DATA "layer_with_special_characters" + CONNECTIONTYPE OGR + CONNECTION "./data/db.sqlite" + PROCESSING "NATIVE_SQL=YES" + METADATA + "ows_title" "layer_with_special_characters" + "wfs_featureid" "ID" + "gml_include_items" "all" + "gml_types" "auto" + "wfs_getfeature_formatlist" "ogrgml" + END + TYPE POINT + STATUS ON + PROJECTION + "init=epsg:32632" + END + + TEMPLATE "wfs_ogr_native_sql.map" +END # Layer END # Map File From e68d8dc29c13404e211ab296c0cdcc61711efa29 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 18 Nov 2022 00:49:00 +0100 Subject: [PATCH 082/170] loadLayer(): fix memory leak in case of repeated CLUSTER Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53471 --- mapfile.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 63bcc759bd..113dd9e603 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4021,7 +4021,6 @@ int loadLayer(layerObj *layer, mapObj *map) layer->numclasses++; break; case(CLUSTER): - initCluster(&layer->cluster); if(loadCluster(&layer->cluster) == -1) return(-1); break; case(CLASSGROUP): From 2774b278a111cee352b4ba7a3f3f9c002b7b001f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 15 Dec 2022 18:18:58 +0100 Subject: [PATCH 083/170] Fix usage of FILE* and VSILFILE* In GDAL 3.7dev, VSILFILE* is no longer an alias for FILE* (see https://github.com/OSGeo/gdal/pull/6883), so we have to adjust our usage to be correct. This MapServer change is backward compatible with GDAL < 3.7 too --- mapcontext.c | 2 +- mapgdal.cpp | 2 +- mapogroutput.cpp | 6 +++--- mapwcs11.cpp | 2 +- mapwcs20.cpp | 2 +- mapwmslayer.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mapcontext.c b/mapcontext.c index 1562eeb5f9..43ff5cdbb6 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -1274,7 +1274,7 @@ int msLoadMapContext(mapObj *map, char *filename, int unique_layer_names) int msSaveMapContext(mapObj *map, char *filename) { #if defined(USE_WMS_LYR) - VSILFILE *stream; + FILE *stream; char szPath[MS_MAXPATHLEN]; int nStatus; diff --git a/mapgdal.cpp b/mapgdal.cpp index 7ca5c94c65..66932fa7d5 100644 --- a/mapgdal.cpp +++ b/mapgdal.cpp @@ -524,7 +524,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* stdout and delete the file. */ /* -------------------------------------------------------------------- */ if( bFileIsTemporary ) { - FILE *fp; + VSILFILE *fp; unsigned char block[4000]; int bytes_read; diff --git a/mapogroutput.cpp b/mapogroutput.cpp index 64da41fd3b..1f42625308 100644 --- a/mapogroutput.cpp +++ b/mapogroutput.cpp @@ -1209,7 +1209,7 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders ) else if( EQUAL(form,"simple") ) { char buffer[1024]; int bytes_read; - FILE *fp; + VSILFILE *fp; const char *jsonp; jsonp = msGetOutputFormatOption( format, "JSONP", NULL ); @@ -1257,7 +1257,7 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders ) CSLDestroy(papszAdditionalFiles); for( i = 0; file_list != NULL && file_list[i] != NULL; i++ ) { - FILE *fp; + VSILFILE *fp; int bytes_read; char buffer[1024]; @@ -1294,7 +1294,7 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders ) /* Handle the case of a zip file result. */ /* -------------------------------------------------------------------- */ else if( EQUAL(form,"zip") ) { - FILE *fp; + VSILFILE *fp; char *zip_filename = msTmpFile(map, NULL, "/vsimem/ogrzip/", "zip" ); void *hZip; int bytes_read; diff --git a/mapwcs11.cpp b/mapwcs11.cpp index f07c809b79..2cecfe95c4 100644 --- a/mapwcs11.cpp +++ b/mapwcs11.cpp @@ -1340,7 +1340,7 @@ int msWCSReturnCoverage11( wcsParamsObj *params, mapObj *map, for( i = 0; i < count; i++ ) { const char *mimetype = NULL; - FILE *fp; + VSILFILE *fp; unsigned char block[4000]; int bytes_read; diff --git a/mapwcs20.cpp b/mapwcs20.cpp index 815390f6d3..b35e803b53 100644 --- a/mapwcs20.cpp +++ b/mapwcs20.cpp @@ -2438,7 +2438,7 @@ static int msWCSWriteFile20(mapObj* map, imageObj* image, wcs20ParamsObjPtr para for( i = 0; i < count; i++ ) { const char *mimetype = NULL; - FILE *fp; + VSILFILE *fp; unsigned char block[4000]; int bytes_read; diff --git a/mapwmslayer.c b/mapwmslayer.c index b57a208805..d863b98d83 100755 --- a/mapwmslayer.c +++ b/mapwmslayer.c @@ -1480,7 +1480,7 @@ int msDrawWMSLayerLow(int nLayerId, httpRequestObj *pasReqInfo, if (msDrawLayer(map, lp, img) != 0) status = MS_FAILURE; } else { - FILE *fp; + VSILFILE *fp; char *wldfile; /* OK, we have to resample the raster to map projection... */ lp->transform = MS_TRUE; From dcc7749cd55b605b49365552620a98daaa0ca9bc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 15:48:54 +0100 Subject: [PATCH 084/170] msCGILoadMap(): do not load file pointed by CONTEXT= unless it validates new MS_CONTEXT_PATTERN configuration option (and doesn't validate MS_CONTEXT_BAD_PATTERN) (fixes #6779) --- mapcontext.c | 6 +++--- mapows.h | 2 +- mapservutil.c | 26 ++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/mapcontext.c b/mapcontext.c index 43ff5cdbb6..b1f8b29191 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -664,7 +664,7 @@ int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) */ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, CPLXMLNode *psMapContext, int nVersion, - char *filename) + const char *filename) { char *pszProj=NULL; @@ -809,7 +809,7 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, ** Load a Layer block from a MapContext document */ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, - char *filename, int unique_layer_names) + const char *filename, int unique_layer_names) { char *pszValue; const char *pszHash; @@ -1106,7 +1106,7 @@ int msLoadMapContextURL(mapObj *map, char *urlfilename, int unique_layer_names) ** (eg l:1:park. l:2:road ...). If It is set to MS_FALSE, the layer name ** would be the same name as the layer name in the context */ -int msLoadMapContext(mapObj *map, char *filename, int unique_layer_names) +int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) { #if defined(USE_WMS_LYR) char *pszWholeText, *pszValue; diff --git a/mapows.h b/mapows.h index f651b41682..537354b25c 100644 --- a/mapows.h +++ b/mapows.h @@ -553,7 +553,7 @@ MS_DLL_EXPORT char *msWFSExecuteGetFeature(layerObj *lp); MS_DLL_EXPORT int msWriteMapContext(mapObj *map, FILE *stream); MS_DLL_EXPORT int msSaveMapContext(mapObj *map, char *filename); -MS_DLL_EXPORT int msLoadMapContext(mapObj *map, char *filename, int unique_layer_names); +MS_DLL_EXPORT int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names); MS_DLL_EXPORT int msLoadMapContextURL(mapObj *map, char *urlfilename, int unique_layer_names); diff --git a/mapservutil.c b/mapservutil.c index dae501ec6c..203f411d78 100644 --- a/mapservutil.c +++ b/mapservutil.c @@ -243,8 +243,30 @@ mapObj *msCGILoadMap(mapservObj *mapserv, configObj *config) if(strncasecmp(mapserv->request->ParamValues[i],"http",4) == 0) { if(msGetConfigOption(map, "CGI_CONTEXT_URL")) msLoadMapContextURL(map, mapserv->request->ParamValues[i], MS_FALSE); - } else - msLoadMapContext(map, mapserv->request->ParamValues[i], MS_FALSE); + } else { + const char *map_context_filename = mapserv->request->ParamValues[i]; + const char *ms_context_pattern = CPLGetConfigOption("MS_CONTEXT_PATTERN", NULL); + const char *ms_context_bad_pattern = CPLGetConfigOption("MS_CONTEXT_BAD_PATTERN", NULL); + if(ms_context_bad_pattern == NULL) ms_context_bad_pattern = ms_map_bad_pattern_default; + + if(ms_context_pattern == NULL) { // can't go any further, bail + msSetError(MS_WEBERR, "Required configuration value MS_CONTEXT_PATTERN not set.", "msCGILoadMap()"); + msFreeMap(map); + return NULL; + } + if(msIsValidRegex(ms_context_bad_pattern) == MS_FALSE || + msEvalRegex(ms_context_bad_pattern, map_context_filename) == MS_TRUE) { + msSetError(MS_WEBERR, "CGI variable \"context\" fails to validate.", "msCGILoadMap()"); + msFreeMap(map); + return NULL; + } + if(msEvalRegex(ms_context_pattern, map_context_filename) != MS_TRUE) { + msSetError(MS_WEBERR, "CGI variable \"context\" fails to validate.", "msCGILoadMap()"); + msFreeMap(map); + return NULL; + } + msLoadMapContext(map, map_context_filename, MS_FALSE); + } } } } From a755ae811b9a26df042be247e9695c48462e07f7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 15:49:24 +0100 Subject: [PATCH 085/170] msautotest: add a test for CONTEXT= loading (refs #6779) --- msautotest/etc/mapserv.conf | 1 + msautotest/wxs/expected/ows_context_caps.xml | 128 +++++++++++++++++++ msautotest/wxs/ows_context.map | 72 +++++++++++ msautotest/wxs/ows_context.xml | 13 ++ 4 files changed, 214 insertions(+) create mode 100644 msautotest/wxs/expected/ows_context_caps.xml create mode 100644 msautotest/wxs/ows_context.map create mode 100644 msautotest/wxs/ows_context.xml diff --git a/msautotest/etc/mapserv.conf b/msautotest/etc/mapserv.conf index e494ba0ec8..6ff5298ed8 100644 --- a/msautotest/etc/mapserv.conf +++ b/msautotest/etc/mapserv.conf @@ -1,6 +1,7 @@ CONFIG ENV MS_MAP_PATTERN "." + MS_MAP_CONTEXT_PATTERN "ows_context\.xml" END # following used by the mssql tests on Appveyor PLUGINS diff --git a/msautotest/wxs/expected/ows_context_caps.xml b/msautotest/wxs/expected/ows_context_caps.xml new file mode 100644 index 0000000000..ae7f9df53e --- /dev/null +++ b/msautotest/wxs/expected/ows_context_caps.xml @@ -0,0 +1,128 @@ +Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 + + + + ]> + + + + + OGC:WMS + Map Context demo + Demo for map context document + + + + + + + + + application/vnd.ogc.wms_xml + + + + + + + + + image/png + image/jpeg + image/png; mode=8bit + image/vnd.jpeg-png + image/vnd.jpeg-png8 + application/x-pdf + image/svg+xml + image/tiff + application/vnd.google-earth.kml+xml + application/vnd.google-earth.kmz + application/vnd.mapbox-vector-tile + application/x-protobuf + application/json + + + + + + + + + text/plain + application/vnd.ogc.gml + + + + + + + + + text/xml + + + + + + + + + image/png + image/jpeg + image/png; mode=8bit + image/vnd.jpeg-png + image/vnd.jpeg-png8 + + + + + + + + + text/xml + + + + + + + + + + application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage + application/vnd.ogc.se_blank + + + + + mapcontext + Map Context demo + Demo for map context document + EPSG:4326 + + + + province + province + + + text/xml + + + + + + + diff --git a/msautotest/wxs/ows_context.map b/msautotest/wxs/ows_context.map new file mode 100644 index 0000000000..1dbbc78832 --- /dev/null +++ b/msautotest/wxs/ows_context.map @@ -0,0 +1,72 @@ +# +# Test OWS Context loading +# +# REQUIRES: INPUT=GDAL OUTPUT=PNG SUPPORTS=WMS + +# Capabilities updatesequence (less than) +# RUN_PARMS: ows_context_caps.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&CONTEXT=ows_context.xml&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities" > [RESULT_DEVERSION] + +MAP + +NAME OWS_CONTEXT_TEST +STATUS ON +SIZE 400 300 +#EXTENT 2018000 -73300 3410396 647400 +EXTENT -67.5725 42 -58.9275 48.5 +UNITS METERS +IMAGECOLOR 255 255 255 +SHAPEPATH ./data +SYMBOLSET etc/symbols.sym +FONTSET etc/fonts.txt + +# +# Start of web interface definition +# +WEB + + IMAGEPATH "/tmp/ms_tmp/" + IMAGEURL "/ms_tmp/" + + METADATA + "wms_onlineresource" "http://localhost/path/to/wfs_simple?myparam=something&" + "ows_enable_request" "*" + END +END + +PROJECTION + "init=epsg:4326" +# "init=./data/epsg2:42304" +# "init=epsg:42304" +END + + +# +# Start of layer definitions +# + +LAYER + NAME province + DATA province + METADATA + "wms_title" "province" + END + TYPE POINT + STATUS ON + PROJECTION + "init=./data/epsg2:42304" +# "init=epsg:42304" + END + + CLASSITEM "Name_e" + + CLASS + NAME "Province" + STYLE + COLOR 200 255 0 + OUTLINECOLOR 120 120 120 + END + END +END # Layer + + +END # Map File diff --git a/msautotest/wxs/ows_context.xml b/msautotest/wxs/ows_context.xml new file mode 100644 index 0000000000..8d3a4719f2 --- /dev/null +++ b/msautotest/wxs/ows_context.xml @@ -0,0 +1,13 @@ + + + + + + + + Map Context demo + Demo for map context document + + + + From b65b1dbec4603e55877fa5aff8c243956903afa2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 15:51:51 +0100 Subject: [PATCH 086/170] msGetMapContextFileText(): add sanity check on file size (refs #6779) --- mapcontext.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mapcontext.c b/mapcontext.c index b1f8b29191..81ff5812b7 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -46,11 +46,11 @@ ** Take the filename in argument ** Return value must be freed by caller */ -char * msGetMapContextFileText(char *filename) +static char * msGetMapContextFileText(const char *filename) { char *pszBuffer; VSILFILE *stream; - int nLength; + vsi_l_offset nLength; /* open file */ if(filename != NULL && strlen(filename) > 0) { @@ -65,10 +65,16 @@ char * msGetMapContextFileText(char *filename) } VSIFSeekL( stream, 0, SEEK_END ); - nLength = (int) VSIFTellL( stream ); + nLength = VSIFTellL( stream ); VSIFSeekL( stream, 0, SEEK_SET ); + if( nLength > 100 * 1024 * 1024U ) + { + msSetError(MS_MEMERR, "(%s): too big file", "msGetMapContextFileText()", filename); + VSIFCloseL( stream ); + return NULL; + } - pszBuffer = (char *) malloc(nLength+1); + pszBuffer = (char *) malloc((size_t)nLength+1); if( pszBuffer == NULL ) { msSetError(MS_MEMERR, "(%s)", "msGetMapContextFileText()", filename); VSIFCloseL( stream ); From 036e8dd7cd5f9eaeda1242358d682ab04a16498a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 15:55:12 +0100 Subject: [PATCH 087/170] CI: check that we can't load a OWS context file if MS_CONTEXT_PATTERN is not defined (refs #6779) --- .github/workflows/start.sh | 1 + msautotest/etc/mapserv.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/start.sh b/.github/workflows/start.sh index 060be5574e..9e96eee15f 100755 --- a/.github/workflows/start.sh +++ b/.github/workflows/start.sh @@ -121,6 +121,7 @@ export PATH=/tmp/install-mapserver/bin:$PATH # Demonstrate that mapserv will error out if cannot find config file mapserv 2>&1 | grep "msLoadConfig(): Unable to access file" >/dev/null && echo yes mapserv QUERY_STRING="MAP=wfs_simple.map&REQUEST=GetCapabilities" 2>&1 | grep "msLoadConfig(): Unable to access file" >/dev/null && echo yes +mapserv QUERY_STRING="map=ows_context.map&CONTEXT=ows_context.xml&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities" 2>&1 | grep "msLoadConfig(): Unable to access file" >/dev/null && echo "Check that we can't load a OWS context file if MS_CONTEXT_PATTERN is not defined: yes" echo "Check that MS_MAP_NO_PATH works" cat </tmp/mapserver.conf diff --git a/msautotest/etc/mapserv.conf b/msautotest/etc/mapserv.conf index 6ff5298ed8..4366acbda4 100644 --- a/msautotest/etc/mapserv.conf +++ b/msautotest/etc/mapserv.conf @@ -1,7 +1,7 @@ CONFIG ENV MS_MAP_PATTERN "." - MS_MAP_CONTEXT_PATTERN "ows_context\.xml" + MS_CONTEXT_PATTERN "ows_context\.xml" END # following used by the mssql tests on Appveyor PLUGINS From 98aa59e00a9008ced7089b5b5b9381fd6edcfb8b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 16:58:12 +0100 Subject: [PATCH 088/170] msLoadMapContextGeneral(): fix memory leaks --- mapcontext.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mapcontext.c b/mapcontext.c index 81ff5812b7..f0f5f6c66e 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -688,6 +688,7 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, sprintf(pszProj, "init=epsg:%s", pszValue+5); } + msFreeProjection(&map->projection); msInitProjection(&map->projection); map->projection.args[map->projection.numargs] = msStrdup(pszProj); map->projection.numargs++; @@ -752,12 +753,20 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, pszValue = (char*)CPLGetXMLValue(psMapContext, "id", NULL); if (pszValue) + { + msFree(map->name); map->name = msStrdup(pszValue); + } } else { + char* pszMapName = NULL; if(msGetMapContextXMLStringValue(psGeneral, "Name", - &(map->name)) == MS_FAILURE) { + &pszMapName) == MS_FAILURE) { msGetMapContextXMLStringValue(psGeneral, "gml:name", - &(map->name)); + &pszMapName); + } + if( pszMapName ) { + msFree(map->name); + map->name = pszMapName; } } /* Keyword */ From 9bac6407b5a83002a8cc4ca92bc7ee32e1fed90b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Dec 2022 20:18:03 +0100 Subject: [PATCH 089/170] msLoadMapContext(): add validation of filename against MS_CONTEXTFILE_PATTERN, which defaults to .xml extension --- mapcontext.c | 7 +++++++ mapserver.h | 1 + 2 files changed, 8 insertions(+) diff --git a/mapcontext.c b/mapcontext.c index f0f5f6c66e..435fe79692 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -30,6 +30,7 @@ #include "mapows.h" #include "cpl_vsi.h" +#include "cpl_conv.h" #if defined(USE_WMS_LYR) @@ -1130,6 +1131,12 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) int nVersion=-1; char szVersionBuf[OWS_VERSION_MAXLEN]; + const char *ms_contextfile_pattern = CPLGetConfigOption("MS_CONTEXTFILE_PATTERN", MS_DEFAULT_CONTEXTFILE_PATTERN); + if(msEvalRegex(ms_contextfile_pattern, filename) != MS_TRUE) { + msSetError(MS_REGEXERR, "Filename validation failed." , "msLoadMapContext()"); + return MS_FAILURE; + } + /* */ /* Load the raw XML file */ /* */ diff --git a/mapserver.h b/mapserver.h index 3a81db4431..e6cb6dd39d 100755 --- a/mapserver.h +++ b/mapserver.h @@ -234,6 +234,7 @@ extern "C" { #else #define MS_DEFAULT_MAPFILE_PATTERN "\\.map$" #endif +#define MS_DEFAULT_CONTEXTFILE_PATTERN "\\.[Xx][Mm][Ll]$" #define MS_TEMPLATE_MAGIC_STRING "MapServer Template" #define MS_TEMPLATE_EXPR "\\.(xml|wml|html|htm|svg|kml|gml|js|tmpl)$" From 7be93358fc08cff8e4ea7c88a833f7def33dc1c6 Mon Sep 17 00:00:00 2001 From: akrherz Date: Thu, 5 Jan 2023 09:52:51 -0600 Subject: [PATCH 090/170] doc: correct MS_SHP to MS_SHAPEFILE --- mapscript/swiginc/shapefile.i | 4 ++-- mapscript/tcl/mapscript_wrap.html | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mapscript/swiginc/shapefile.i b/mapscript/swiginc/shapefile.i index c64950fec5..045b0fad5e 100644 --- a/mapscript/swiginc/shapefile.i +++ b/mapscript/swiginc/shapefile.i @@ -33,8 +33,8 @@ * Create a new instance. Omit the type argument or use a value of -1 to open * an existing shapefile. * - * Type should be one of :data:`MS_SHP_POINT`, :data:`MS_SHP_ARC`, - * :data:`MS_SHP_POLYGON` or :data:`MS_SHP_MULTIPOINT` + * Type should be one of :data:`MS_SHAPEFILE_POINT`, :data:`MS_SHAPEFILE_ARC`, + * :data:`MS_SHAPEFILE_POLYGON` or :data:`MS_SHAPEFILE_MULTIPOINT` */ shapefileObj(char *filename, int type=-1) { diff --git a/mapscript/tcl/mapscript_wrap.html b/mapscript/tcl/mapscript_wrap.html index ed8c57de39..d3d6631295 100644 --- a/mapscript/tcl/mapscript_wrap.html +++ b/mapscript/tcl/mapscript_wrap.html @@ -1898,19 +1898,19 @@

mapscript_wrap.c

[ Member : returns int ]
-

mapscript::MS_SHP_POINT = 1 +

mapscript::MS_SHAPEFILE_POINT = 1

[ Constant : int ]
-

mapscript::MS_SHP_ARC = 3 +

mapscript::MS_SHAPEFILE_ARC = 3

[ Constant : int ]
-

mapscript::MS_SHP_POLYGON = 5 +

mapscript::MS_SHAPEFILE_POLYGON = 5

[ Constant : int ]
-

mapscript::MS_SHP_MULTIPOINT = 8 +

mapscript::MS_SHAPEFILE_MULTIPOINT = 8

[ Constant : int ]
From d6dc1c6776e2bab99e6c6afeee7a3e33514cb6c4 Mon Sep 17 00:00:00 2001 From: sethg Date: Wed, 11 Jan 2023 17:55:13 +0100 Subject: [PATCH 091/170] Set GML Boolean type in PostGIS with tests --- mappostgis.cpp | 2 +- msautotest/create_postgis_test_data.sh | 10 +++ .../wxs/expected/wfs_autotypes100_postgis.xml | 46 +++++++++++++ .../wxs/expected/wfs_autotypes110_postgis.xml | 46 +++++++++++++ .../wxs/expected/wfs_autotypes200_postgis.xml | 45 +++++++++++++ .../wfs_getfeaturetypes100_postgis.xml | 48 ++++++++++++++ .../wfs_getfeaturetypes110_postgis.xml | 49 ++++++++++++++ .../wfs_getfeaturetypes200_postgis.xml | 49 ++++++++++++++ msautotest/wxs/wfs_autotypes_postgis.map | 66 +++++++++++++++++++ 9 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 msautotest/wxs/expected/wfs_autotypes100_postgis.xml create mode 100644 msautotest/wxs/expected/wfs_autotypes110_postgis.xml create mode 100644 msautotest/wxs/expected/wfs_autotypes200_postgis.xml create mode 100644 msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml create mode 100644 msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml create mode 100644 msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml create mode 100644 msautotest/wxs/wfs_autotypes_postgis.map diff --git a/mappostgis.cpp b/mappostgis.cpp index b8cbd77879..7c8f51ac12 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -2975,7 +2975,7 @@ msPostGISPassThroughFieldDefinitions( layerObj *layer, gml_width = std::to_string( fmod-4 ); } else if( oid == BOOLOID ) { - gml_type = "Integer"; + gml_type = "Boolean"; gml_width = '1'; } else if( oid == INT2OID ) { diff --git a/msautotest/create_postgis_test_data.sh b/msautotest/create_postgis_test_data.sh index e1b6b1cff9..8edf0a6ac7 100755 --- a/msautotest/create_postgis_test_data.sh +++ b/msautotest/create_postgis_test_data.sh @@ -143,3 +143,13 @@ CREATE TABLE text_datatypes (id SERIAL PRIMARY KEY, mychar5 CHAR(5), myvarchar5 SELECT AddGeometryColumn('public', 'text_datatypes', 'the_geom', 27700, 'POINT', 2); INSERT INTO text_datatypes (the_geom, mychar5, myvarchar5, mytext) VALUES (GeomFromEWKT('SRID=27700;POINT(1 2)'), 'abc ', 'def ', 'ghi '); " + +psql -U postgres -d msautotest -c " +CREATE TABLE autotypes (id SERIAL PRIMARY KEY, mychar CHAR(5), myvarchar VARCHAR(5), mytext TEXT, mybool BOOL, myint2 INT2, myint4 INT4, myint8 INT8, +myfloat4 FLOAT4, myfloat8 FLOAT8, mynumeric NUMERIC(4,2), mydate DATE, mytime TIME, mytimez TIMETZ, mytimestamp TIMESTAMP, mytimestampz TIMESTAMPTZ); +SELECT AddGeometryColumn('public', 'autotypes', 'the_geom', 4326, 'POINT', 2); +INSERT INTO autotypes (the_geom, mychar, myvarchar, mytext, mybool, myint2, myint4, myint8, +myfloat4, myfloat8, mynumeric, mydate, mytime, mytimez, mytimestamp, mytimestampz) +VALUES (GeomFromEWKT('SRID=4326;POINT(1 2)'), 'abc', 'def', 'ghi', True, 10, 100, 1000, +1.5, 2.5, 3.33, '2023-01-01', '00:00:00', '00:00:00', '2023-01-01 00:00:00', '2023-01-01 00:00:00'); +" diff --git a/msautotest/wxs/expected/wfs_autotypes100_postgis.xml b/msautotest/wxs/expected/wfs_autotypes100_postgis.xml new file mode 100644 index 0000000000..a796fecef5 --- /dev/null +++ b/msautotest/wxs/expected/wfs_autotypes100_postgis.xml @@ -0,0 +1,46 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msautotest/wxs/expected/wfs_autotypes110_postgis.xml b/msautotest/wxs/expected/wfs_autotypes110_postgis.xml new file mode 100644 index 0000000000..d2c75e180b --- /dev/null +++ b/msautotest/wxs/expected/wfs_autotypes110_postgis.xml @@ -0,0 +1,46 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msautotest/wxs/expected/wfs_autotypes200_postgis.xml b/msautotest/wxs/expected/wfs_autotypes200_postgis.xml new file mode 100644 index 0000000000..bb68d0e3c9 --- /dev/null +++ b/msautotest/wxs/expected/wfs_autotypes200_postgis.xml @@ -0,0 +1,45 @@ +Content-Type: application/gml+xml; version=3.2; charset=UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml new file mode 100644 index 0000000000..4a198db637 --- /dev/null +++ b/msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml @@ -0,0 +1,48 @@ +Content-Type: text/xml; charset=UTF-8 + + + + + + 1.000000,2.000000 1.000000,2.000000 + + + + + + + 1.000000,2.000000 1.000000,2.000000 + + + + + 1.000000,2.000000 + + + 1 + abc + def + ghi + true + 10 + 100 + 1000 + 1.5 + 2.5 + 3.33 + 2023-01-01 + 00:00:00Z + 00:00:00Z + 2023-01-01T00:00:00Z + 2023-01-01T00:00:00Z + + + + diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml new file mode 100644 index 0000000000..35461c715c --- /dev/null +++ b/msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml @@ -0,0 +1,49 @@ +Content-Type: text/xml; subtype=gml/3.1.1; charset=UTF-8 + + + + + + 2.000000 1.000000 + 2.000000 1.000000 + + + + + + + 2.000000 1.000000 + 2.000000 1.000000 + + + + + 2.000000 1.000000 + + + 1 + abc + def + ghi + true + 10 + 100 + 1000 + 1.5 + 2.5 + 3.33 + 2023-01-01 + 00:00:00Z + 00:00:00Z + 2023-01-01T00:00:00Z + 2023-01-01T00:00:00Z + + + + diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml new file mode 100644 index 0000000000..470f30fd36 --- /dev/null +++ b/msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml @@ -0,0 +1,49 @@ +Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8 + + + + + + 2.000000 1.000000 + 2.000000 1.000000 + + + + + + + 2.000000 1.000000 + 2.000000 1.000000 + + + + + 2.000000 1.000000 + + + 1 + abc + def + ghi + true + 10 + 100 + 1000 + 1.5 + 2.5 + 3.33 + 2023-01-01 + 00:00:00Z + 00:00:00Z + 2023-01-01T00:00:00Z + 2023-01-01T00:00:00Z + + + + diff --git a/msautotest/wxs/wfs_autotypes_postgis.map b/msautotest/wxs/wfs_autotypes_postgis.map new file mode 100644 index 0000000000..51b422a281 --- /dev/null +++ b/msautotest/wxs/wfs_autotypes_postgis.map @@ -0,0 +1,66 @@ +# +# Test WFS +# +# REQUIRES: INPUT=OGR SUPPORTS=WFS +# +# RUN_PARMS: wfs_autotypes100_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_autotypes110_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_autotypes200_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_getfeaturetypes100_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_getfeaturetypes110_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_getfeaturetypes200_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] + +MAP + +NAME WFS_TEST +STATUS ON +SIZE 400 300 +EXTENT -180 -90 180 90 + +# +# Start of web interface definition +# +WEB + + IMAGEPATH "/tmp/ms_tmp/" + IMAGEURL "/ms_tmp/" + + METADATA + "ows_updatesequence" "123" + "wfs_title" "Test simple wfs" + "wfs_onlineresource" "http://localhost/path/to/wfs_simple?myparam=something&" + "wfs_srs" "EPSG:4326" + "ows_enable_request" "*" + END +END + +PROJECTION + "init=epsg:4326" +END + + +# +# Start of layer definitions +# + +LAYER + + NAME autotypes + INCLUDE "postgis.include" + DATA "the_geom from (select * from autotypes) as foo using unique id using srid=4326" + + METADATA + "wfs_title" "autotypes" + "wfs_featureid" "id" + "gml_include_items" "all" + "gml_types" "auto" + END + + PROJECTION + "init=epsg:4326" + END + TYPE POINT + STATUS ON +END + +END # Map File From 0530bac357aa75678fcd4420c88f6df8efb65584 Mon Sep 17 00:00:00 2001 From: sethg Date: Wed, 11 Jan 2023 18:25:08 +0100 Subject: [PATCH 092/170] Naming conventions and deversion results --- ...es100_postgis.xml => wfs_autotypes10_postgis.xml} | 0 ...es110_postgis.xml => wfs_autotypes11_postgis.xml} | 0 ...es200_postgis.xml => wfs_autotypes20_postgis.xml} | 0 ...postgis.xml => wfs_getfeaturetypes10_postgis.xml} | 0 ...postgis.xml => wfs_getfeaturetypes11_postgis.xml} | 0 ...postgis.xml => wfs_getfeaturetypes20_postgis.xml} | 2 +- msautotest/wxs/wfs_autotypes_postgis.map | 12 ++++++------ 7 files changed, 7 insertions(+), 7 deletions(-) rename msautotest/wxs/expected/{wfs_autotypes100_postgis.xml => wfs_autotypes10_postgis.xml} (100%) rename msautotest/wxs/expected/{wfs_autotypes110_postgis.xml => wfs_autotypes11_postgis.xml} (100%) rename msautotest/wxs/expected/{wfs_autotypes200_postgis.xml => wfs_autotypes20_postgis.xml} (100%) rename msautotest/wxs/expected/{wfs_getfeaturetypes100_postgis.xml => wfs_getfeaturetypes10_postgis.xml} (100%) rename msautotest/wxs/expected/{wfs_getfeaturetypes110_postgis.xml => wfs_getfeaturetypes11_postgis.xml} (100%) rename msautotest/wxs/expected/{wfs_getfeaturetypes200_postgis.xml => wfs_getfeaturetypes20_postgis.xml} (97%) diff --git a/msautotest/wxs/expected/wfs_autotypes100_postgis.xml b/msautotest/wxs/expected/wfs_autotypes10_postgis.xml similarity index 100% rename from msautotest/wxs/expected/wfs_autotypes100_postgis.xml rename to msautotest/wxs/expected/wfs_autotypes10_postgis.xml diff --git a/msautotest/wxs/expected/wfs_autotypes110_postgis.xml b/msautotest/wxs/expected/wfs_autotypes11_postgis.xml similarity index 100% rename from msautotest/wxs/expected/wfs_autotypes110_postgis.xml rename to msautotest/wxs/expected/wfs_autotypes11_postgis.xml diff --git a/msautotest/wxs/expected/wfs_autotypes200_postgis.xml b/msautotest/wxs/expected/wfs_autotypes20_postgis.xml similarity index 100% rename from msautotest/wxs/expected/wfs_autotypes200_postgis.xml rename to msautotest/wxs/expected/wfs_autotypes20_postgis.xml diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes10_postgis.xml similarity index 100% rename from msautotest/wxs/expected/wfs_getfeaturetypes100_postgis.xml rename to msautotest/wxs/expected/wfs_getfeaturetypes10_postgis.xml diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes11_postgis.xml similarity index 100% rename from msautotest/wxs/expected/wfs_getfeaturetypes110_postgis.xml rename to msautotest/wxs/expected/wfs_getfeaturetypes11_postgis.xml diff --git a/msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml b/msautotest/wxs/expected/wfs_getfeaturetypes20_postgis.xml similarity index 97% rename from msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml rename to msautotest/wxs/expected/wfs_getfeaturetypes20_postgis.xml index 470f30fd36..09f0600371 100644 --- a/msautotest/wxs/expected/wfs_getfeaturetypes200_postgis.xml +++ b/msautotest/wxs/expected/wfs_getfeaturetypes20_postgis.xml @@ -7,7 +7,7 @@ Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8 xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&SERVICE=WFS&VERSION=2.0.0&REQUEST=DescribeFeatureType&TYPENAME=autotypes&OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd" - timeStamp="2023-01-11T17:53:48" numberMatched="1" numberReturned="1"> + timeStamp="" numberMatched="1" numberReturned="1"> 2.000000 1.000000 diff --git a/msautotest/wxs/wfs_autotypes_postgis.map b/msautotest/wxs/wfs_autotypes_postgis.map index 51b422a281..909d81c3cc 100644 --- a/msautotest/wxs/wfs_autotypes_postgis.map +++ b/msautotest/wxs/wfs_autotypes_postgis.map @@ -3,12 +3,12 @@ # # REQUIRES: INPUT=OGR SUPPORTS=WFS # -# RUN_PARMS: wfs_autotypes100_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] -# RUN_PARMS: wfs_autotypes110_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] -# RUN_PARMS: wfs_autotypes200_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT] -# RUN_PARMS: wfs_getfeaturetypes100_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] -# RUN_PARMS: wfs_getfeaturetypes110_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] -# RUN_PARMS: wfs_getfeaturetypes200_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT] +# RUN_PARMS: wfs_autotypes10_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT_DEVERSION] +# RUN_PARMS: wfs_autotypes11_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT_DEVERSION] +# RUN_PARMS: wfs_autotypes20_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=DescribeFeatureType&TYPENAMES=autotypes" > [RESULT_DEVERSION] +# RUN_PARMS: wfs_getfeaturetypes10_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT_DEVERSION] +# RUN_PARMS: wfs_getfeaturetypes11_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT_DEVERSION] +# RUN_PARMS: wfs_getfeaturetypes20_postgis.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=autotypes" > [RESULT_DEVERSION] MAP From 72e5484617bb7147c31a16d258b6122e2a8c80d2 Mon Sep 17 00:00:00 2001 From: sethg Date: Thu, 12 Jan 2023 09:11:24 +0100 Subject: [PATCH 093/170] Don't set width for Boolean type --- mappostgis.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mappostgis.cpp b/mappostgis.cpp index 7c8f51ac12..b21fafce0d 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -2976,7 +2976,6 @@ msPostGISPassThroughFieldDefinitions( layerObj *layer, } else if( oid == BOOLOID ) { gml_type = "Boolean"; - gml_width = '1'; } else if( oid == INT2OID ) { gml_type = "Integer"; From 4776efa029571e6dccee48d415d6df490de1a537 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 13:39:39 -0400 Subject: [PATCH 094/170] [Backport branch-8-0] update copyright year in README (#6797) --- INSTALL | 6 +++--- README.rst => README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename README.rst => README.md (98%) diff --git a/INSTALL b/INSTALL index 77d45994d5..fc27754e6d 100644 --- a/INSTALL +++ b/INSTALL @@ -1,14 +1,14 @@ -Visit http://www.mapserver.org/ for full documentation and installation +Visit https://mapserver.org/ for full documentation and installation instructions. Unix compilation instructions ----------------------------- See INSTALL.CMAKE or the document on the MapServer website at - + Win32 compilation instructions ------------------------------ See README.WIN32 or the document on the MapServer website at - + diff --git a/README.rst b/README.md similarity index 98% rename from README.rst rename to README.md index fd49758a01..55e08f021a 100644 --- a/README.rst +++ b/README.md @@ -69,7 +69,7 @@ License :: - Copyright (c) 2008-2022 Open Source Geospatial Foundation. + Copyright (c) 2008-2023 Open Source Geospatial Foundation. Copyright (c) 1996-2008 Regents of the University of Minnesota. Permission is hereby granted, free of charge, to any person obtaining a copy From 9802d85235327107b2e9fa05dd7911af8cedd156 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 07:58:55 -0400 Subject: [PATCH 095/170] [Backport branch-8-0] update markdown for README and LICENSE (#6800) --- LICENSE.md | 36 +++++++++++++++++++++++++++ README.md | 71 ++++++++++++++++-------------------------------------- 2 files changed, 57 insertions(+), 50 deletions(-) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..cbc666116f --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,36 @@ +MapServer Licensing +=================== + +MapServer General +----------------- + +Copyright (c) 2008-2023 Open Source Geospatial Foundation. +Copyright (c) 1996-2008 Regents of the University of Minnesota. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies of this Software or works derived from this Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +FlatGeobuf +---------- + +Refer to the FlatGeobuf license found at [/flatgeobuf/LICENSE](flatgeobuf/LICENSE) + +FlatBuffers +----------- + +Refer to the FlatBuffers license found at [/flatgeobuf/include/flatbuffers/LICENSE](flatgeobuf/include/flatbuffers/LICENSE) \ No newline at end of file diff --git a/README.md b/README.md index 55e08f021a..06c8348a3a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ MapServer ========= -| |Build Status| |Appveyor Build Status| |Coveralls Status| |DOI| +[![Build Status](https://travis-ci.com/MapServer/MapServer.svg?branch=main)](https://travis-ci.com/MapServer/MapServer) +[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/vw1n07095a8bg23u?svg=true)](https://ci.appveyor.com/project/mapserver/mapserver) +[![Coveralls Status](https://coveralls.io/repos/github/MapServer/MapServer/badge.svg?branch=main)](https://coveralls.io/github/MapServer/MapServer?branch=main) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5842012.svg)](https://doi.org/10.5281/zenodo.5842012) ------- Summary @@ -30,8 +33,6 @@ Join the MapServer user mailing list online at: https://mapserver.org/community/lists.html - - Credits ------- @@ -67,50 +68,20 @@ Supporting packages are covered by their own copyrights. License ------- -:: - - Copyright (c) 2008-2023 Open Source Geospatial Foundation. - Copyright (c) 1996-2008 Regents of the University of Minnesota. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is furnished - to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies of this Software or works derived from this Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - FlatGeobuf - ---------- - - Refer to the FlatGeobuf license found at /flatgeobuf/LICENSE - - FlatBuffers - ----------- - - Refer to the FlatBuffers license found at /flatgeobuf/include/flatbuffers/LICENSE - - - -.. |Build Status| image:: https://travis-ci.com/MapServer/MapServer.svg?branch=main - :target: https://travis-ci.com/MapServer/MapServer - -.. |Appveyor Build Status| image:: https://ci.appveyor.com/api/projects/status/vw1n07095a8bg23u?svg=true - :target: https://ci.appveyor.com/project/mapserver/mapserver - -.. |Coveralls Status| image:: https://coveralls.io/repos/github/MapServer/MapServer/badge.svg?branch=main - :target: https://coveralls.io/github/MapServer/MapServer?branch=main - -.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.5842012.svg - :target: https://doi.org/10.5281/zenodo.5842012 - :alt: Digital Object Identifier (DOI) for MapServer \ No newline at end of file +See [LICENSE.md](LICENSE.md) + +Security policy +--------------- + +See [SECURITY.md](SECURITY.md) + +How to Contribute +----------------- + +See [CONTRIBUTING.md](CONTRIBUTING.md) + +Documentation Repository +------------------------ + +Use the separate [MapServer-documentation](https://github.com/MapServer/MapServer-documentation) +repository for filing documentation tickets and changes. \ No newline at end of file From deb5baf814f6a827fa07095cca7a1fddbdc9839f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:55:25 -0400 Subject: [PATCH 096/170] [Backport branch-8-0] Add Proj and GDAL versions to MapServer version output (#6802) --- maperror.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/maperror.c b/maperror.c index 6de97c5b6e..6d21f46697 100644 --- a/maperror.c +++ b/maperror.c @@ -532,12 +532,21 @@ void msWriteErrorImage(mapObj *map, char *filename, int blank) char *msGetVersion() { - static char version[1024]; + static char version[2048]; if(CPLGetConfigOption("MS_NO_VERSION", NULL) != NULL) return ""; // supressing version information sprintf(version, "MapServer version %s", MS_VERSION); + // add versions of required dependencies + static char PROJVersion[20]; + sprintf(PROJVersion, " PROJ version %d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR); + strcat(version, PROJVersion); + + static char GDALVersion[20]; + sprintf(GDALVersion, " GDAL version %d.%d", GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR); + strcat(version, GDALVersion); + #if (defined USE_PNG) strcat(version, " OUTPUT=PNG"); #endif From 717929762686c4b923c05f7409ed2cd21b89ea24 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 19:45:03 -0600 Subject: [PATCH 097/170] [Backport branch-8-0] Small changes missed in the initial 8.0 release. (#6805) * Support map.size and map_size CGI params for backwards compability reasons. * Allow runsub on the web template string (an oversight in the initial 8.0 release). Co-authored-by: Steve Lime --- mapfile.c | 2 ++ mapservutil.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 113dd9e603..5f073981cf 100755 --- a/mapfile.c +++ b/mapfile.c @@ -6468,7 +6468,9 @@ static void mapSubstituteString(mapObj *map, const char *from, const char *to) { map->outputformatlist[l]->formatoptions[o] = msCaseReplaceSubstring(map->outputformatlist[l]->formatoptions[o], from, to); } } + hashTableSubstituteString(&map->web.metadata, from, to); + if(map->web.template) map->web.template = msCaseReplaceSubstring(map->web.template, from, to); } static void applyOutputFormatDefaultSubstitutions(outputFormatObj *format, const char *option, hashTableObj *table) diff --git a/mapservutil.c b/mapservutil.c index 203f411d78..53a1a8341a 100644 --- a/mapservutil.c +++ b/mapservutil.c @@ -1038,7 +1038,9 @@ int msCGILoadForm(mapservObj *mapserv) continue; } - if(strcasecmp(mapserv->request->ParamNames[i],"mapsize") == 0) { /* size of new map (pixels) */ + /* size of new map (pixels), map.size/map_size are included for backwards compatibility and may be removed in future release */ + if(strcasecmp(mapserv->request->ParamNames[i],"mapsize") == 0 || + strcasecmp(mapserv->request->ParamNames[i],"map.size") == 0 || strcasecmp(mapserv->request->ParamNames[i],"map_size") == 0) { tokens = msStringSplit(mapserv->request->ParamValues[i], ' ', &n); if(!tokens) { From e3bbde990bfa91e54e8f686e7a79d0afcde6de38 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Jan 2023 16:15:21 -0400 Subject: [PATCH 098/170] Check for debug level before writing to log (#6807) Co-authored-by: sethg --- mapquery.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mapquery.c b/mapquery.c index 62159e953b..e5f83e92f2 100644 --- a/mapquery.c +++ b/mapquery.c @@ -177,9 +177,11 @@ static int canCacheShape(mapObj* map, queryCacheObj *queryCache, int shape_ram_s if( !queryCache->cachedShapeCountWarningEmitted ) { queryCache->cachedShapeCountWarningEmitted = MS_TRUE; - msDebug("map->query.max_cached_shape_count = %d reached. " + if (map->debug >= MS_DEBUGLEVEL_V) { + msDebug("map->query.max_cached_shape_count = %d reached. " "Next features will not be cached.\n", map->query.max_cached_shape_count); + } } return MS_FALSE; } @@ -190,10 +192,12 @@ static int canCacheShape(mapObj* map, queryCacheObj *queryCache, int shape_ram_s if( !queryCache->cachedShapeRAMWarningEmitted ) { queryCache->cachedShapeRAMWarningEmitted = MS_TRUE; - msDebug("map->query.max_cached_shape_ram_amount = %d reached after %d cached features. " + if (map->debug >= MS_DEBUGLEVEL_V) { + msDebug("map->query.max_cached_shape_ram_amount = %d reached after %d cached features. " "Next features will not be cached.\n", map->query.max_cached_shape_ram_amount, queryCache->cachedShapeCount); + } } return MS_FALSE; } From ec4e39c99014343176c9bab55120358d38e4af54 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 17:21:51 +0100 Subject: [PATCH 099/170] [Backport branch-8-0] Allow a CONFIG to be used when loading a Mapfile from a string (#6652) * Allow config to be set in msLoadMapFromString # Conflicts: # mapscript/python/pyextend.i * Add param for C# * Update C function * Fix syntax error * Update c# signature Co-authored-by: sethg --- mapfile.c | 4 +++- mapscript/python/pyextend.i | 11 ++++++++--- mapscript/swiginc/map.i | 8 +++++++- mapserver.h | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/mapfile.c b/mapfile.c index 5f073981cf..b70ae99d96 100755 --- a/mapfile.c +++ b/mapfile.c @@ -6216,7 +6216,7 @@ static bool msGetCWD(char* szBuffer, size_t nBufferSize, const char* pszFunction /* ** Sets up string-based mapfile loading and calls loadMapInternal to do the work. */ -mapObj *msLoadMapFromString(char *buffer, char *new_mappath) +mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *config) { mapObj *map; struct mstimeval starttime = {0}, endtime = {0}; @@ -6247,6 +6247,8 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath) return(NULL); } + map->config = config; // create a read-only reference + msAcquireLock( TLOCK_PARSER ); /* might need to move this lock a bit higher, yup (bug 2108) */ msyystate = MS_TOKENIZE_STRING; diff --git a/mapscript/python/pyextend.i b/mapscript/python/pyextend.i index aba9843ce6..aef9cc044a 100644 --- a/mapscript/python/pyextend.i +++ b/mapscript/python/pyextend.i @@ -21,7 +21,7 @@ /* fromstring: Factory for mapfile objects */ %pythoncode %{ -def fromstring(data, mappath=None): +def fromstring(data, mappath=None, configpath=None): """Creates map objects from mapfile strings. Parameters @@ -38,8 +38,13 @@ def fromstring(data, mappath=None): 'test' """ import re - if re.search(r"^\s*MAP", data, re.I): - return msLoadMapFromString(data, mappath) + if re.search(r"^\s*MAP", data, re.I): + # create a config object if a path is supplied + if configpath: + config = configObj(configpath) + else: + config = None + return msLoadMapFromString(data, mappath, config) elif re.search(r"^\s*LAYER", data, re.I): ob = layerObj() ob.updateFromString(data) diff --git a/mapscript/swiginc/map.i b/mapscript/swiginc/map.i index 07d5a05d0a..973b51e9e7 100644 --- a/mapscript/swiginc/map.i +++ b/mapscript/swiginc/map.i @@ -53,8 +53,14 @@ mapObj(char *mapText, int isMapText /*used as signature only to differentiate this constructor from default constructor*/ ) { - return msLoadMapFromString(mapText, NULL); + return msLoadMapFromString(mapText, NULL, NULL); } + + mapObj(char *mapText, int isMapText, configObj *config) + { + return msLoadMapFromString(mapText, NULL, config); + } + #endif ~mapObj() diff --git a/mapserver.h b/mapserver.h index e6cb6dd39d..9359a2fcac 100755 --- a/mapserver.h +++ b/mapserver.h @@ -2092,7 +2092,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char /** Sets up string-based mapfile loading and calls loadMapInternal to do the work */ - MS_DLL_EXPORT mapObj *msLoadMapFromString(char *buffer, char *new_mappath); + MS_DLL_EXPORT mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj* config); /* Function prototypes, not wrapable */ From 390d8fd9df15f6c1be4c9a6507c85b827bfe7325 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 20:04:58 -0600 Subject: [PATCH 100/170] [Backport branch-8-0] No longer output MS version numbers in client responses (#6809) * No longer output MS version numbers in client responses * Update tests to match responses with no version * Update tests to match responses with no version * Update tests to match responses with no version * Remove MS_NO_VERSION test Co-authored-by: sethg --- maperror.c | 2 -- mapogcsos.c | 3 --- mapservutil.c | 6 ------ mapwfs.cpp | 4 ---- mapwms.cpp | 6 ------ .../api/expected/ogcapi_invalid_api_signature1.txt | 3 ++- .../api/expected/ogcapi_invalid_api_signature2.txt | 3 ++- msautotest/api/expected/ogcapi_invalid_mapfile.txt | 3 ++- .../api/expected/ogcapi_missing_api_signature1.txt | 3 ++- .../api/expected/ogcapi_missing_api_signature2.txt | 3 ++- msautotest/config/expected/empty1_conf.txt | 3 ++- msautotest/config/expected/empty2_conf.txt | 3 ++- msautotest/config/expected/invalid1_conf.txt | 3 ++- msautotest/config/expected/invalid2_conf.txt | 3 ++- msautotest/config/expected/missing_conf.txt | 3 ++- msautotest/config/expected/ms_map_no_path1_conf.txt | 3 ++- .../config/expected/ms_map_no_path2_conf_failure1.txt | 3 ++- .../config/expected/ms_map_no_path2_conf_failure2.txt | 3 ++- msautotest/config/expected/ms_map_pattern_conf.txt | 3 ++- .../config/expected/ms_map_pattern_conf_bad_regex.txt | 3 ++- msautotest/config/expected/ms_no_post_conf_failure.txt | 3 ++- msautotest/config/expected/ms_no_version_conf.txt | 7 ------- msautotest/config/hello_world.map | 1 - msautotest/config/ms_no_version.conf | 9 --------- msautotest/misc/expected/centerline3_exception.txt | 3 ++- msautotest/misc/expected/centerline4_exception.txt | 3 ++- msautotest/misc/expected/centerline5_exception.txt | 3 ++- msautotest/misc/expected/flatgeobuf-wfs-cap.xml | 1 - msautotest/misc/expected/runtime_sub_test001.txt | 3 ++- msautotest/misc/expected/runtime_sub_test003.txt | 3 ++- msautotest/misc/expected/runtime_sub_test005.txt | 3 ++- msautotest/misc/expected/runtime_sub_test_caps.xml | 1 - msautotest/renderers/expected/font-fail-file.txt | 3 ++- msautotest/renderers/expected/font-fail-key.txt | 3 ++- msautotest/renderers/expected/legend_bad_imagetype.txt | 3 ++- msautotest/wxs/expected/ows_all_wms_capabilities.xml | 1 - .../wxs/expected/ows_all_wms_capabilities_post.xml | 1 - msautotest/wxs/expected/ows_context_caps.xml | 1 - .../wxs/expected/ows_metadata_wfs_capabilities100.xml | 1 - .../wxs/expected/ows_metadata_wms_capabilities111.xml | 1 - .../wxs/expected/ows_metadata_wms_capabilities130.xml | 1 - msautotest/wxs/expected/ows_wms_capabilities.xml | 1 - .../wxs/expected/ows_wms_rootlayer_name_capabilities.xml | 1 - .../ows_wms_rootlayer_name_empty_capabilities.xml | 1 - msautotest/wxs/expected/sos_cap.xml | 2 +- msautotest/wxs/expected/sos_cap0.xml | 2 +- msautotest/wxs/expected/sos_cap1.xml | 2 +- msautotest/wxs/expected/sos_caps_updatesequence.xml | 2 +- msautotest/wxs/expected/wfs10_test_xml_escaping.xml | 1 - msautotest/wxs/expected/wfs_cap.xml | 1 - msautotest/wxs/expected/wfs_cap_ogr.xml | 1 - msautotest/wxs/expected/wfs_caps_updatesequence.xml | 1 - msautotest/wxs/expected/wfs_caps_updatesequence_ogr.xml | 1 - msautotest/wxs/expected/wfs_get_caps.xml | 1 - .../wxs/expected/wfs_multiple_metadataurl_100_cap.xml | 1 - .../wxs/expected/wfs_ogr_drv_nocreatedatasource_caps.xml | 3 ++- msautotest/wxs/expected/wfs_ogr_nonexistingdrv_caps.xml | 3 ++- msautotest/wxs/expected/wfsogr10_caps.xml | 1 - msautotest/wxs/expected/wms111_test_xml_escaping.xml | 1 - msautotest/wxs/expected/wms130_test_xml_escaping.xml | 1 - msautotest/wxs/expected/wms_cap.xml | 1 - msautotest/wxs/expected/wms_cap130.xml | 1 - msautotest/wxs/expected/wms_cap130_postgis.xml | 1 - msautotest/wxs/expected/wms_cap_latestversion.xml | 1 - .../wxs/expected/wms_cap_latestversion_postgis.xml | 1 - msautotest/wxs/expected/wms_cap_postgis.xml | 1 - msautotest/wxs/expected/wms_caps_updatesequence.xml | 1 - .../wxs/expected/wms_caps_updatesequence_postgis.xml | 1 - msautotest/wxs/expected/wms_dimension_cap.xml | 1 - msautotest/wxs/expected/wms_dimension_cap130.xml | 1 - msautotest/wxs/expected/wms_empty_cap100.xml | 1 - msautotest/wxs/expected/wms_empty_cap111.xml | 1 - msautotest/wxs/expected/wms_empty_cap130.xml | 1 - msautotest/wxs/expected/wms_empty_cap_latestversion.xml | 1 - .../expected/wms_get_capabilities_tileindexmixedsrs.xml | 1 - msautotest/wxs/expected/wms_get_caps.xml | 1 - msautotest/wxs/expected/wms_inspire_cap.xml | 1 - msautotest/wxs/expected/wms_inspire_cap_111.xml | 1 - msautotest/wxs/expected/wms_inspire_cap_111_eng.xml | 1 - msautotest/wxs/expected/wms_inspire_cap_111_ger.xml | 1 - msautotest/wxs/expected/wms_inspire_cap_eng.xml | 1 - msautotest/wxs/expected/wms_inspire_cap_ger.xml | 1 - msautotest/wxs/expected/wms_inspire_scenario1_cap130.xml | 1 - .../wxs/expected/wms_inspire_scenario1_cap130_eng.xml | 1 - .../wxs/expected/wms_inspire_scenario1_cap130_ger.xml | 1 - msautotest/wxs/expected/wms_inspire_scenario2_cap111.xml | 1 - .../wxs/expected/wms_inspire_scenario2_cap111_eng.xml | 1 - .../wxs/expected/wms_inspire_scenario2_cap111_ger.xml | 1 - msautotest/wxs/expected/wms_inspire_scenario2_cap130.xml | 1 - .../wxs/expected/wms_inspire_scenario2_cap130_eng.xml | 1 - .../wxs/expected/wms_inspire_scenario2_cap130_ger.xml | 1 - msautotest/wxs/expected/wms_layer_groups_caps111.xml | 1 - msautotest/wxs/expected/wms_multiple_metadataurl_cap.xml | 1 - .../wxs/expected/wms_north_polar_stereo_extent.xml | 1 - msautotest/wxs/expected/wms_nosld_cap.xml | 1 - msautotest/wxs/expected/wms_nosld_cap_postgis.xml | 1 - msautotest/wxs/expected/wms_rast_cap.xml | 1 - msautotest/wxs/expected/wms_time_cap.xml | 1 - msautotest/wxs/expected/wms_time_cap130.xml | 1 - .../wxs/expected/wms_time_cap130_postgis_postgis.xml | 1 - msautotest/wxs/expected/wms_time_cap_postgis_postgis.xml | 1 - 101 files changed, 58 insertions(+), 131 deletions(-) delete mode 100644 msautotest/config/expected/ms_no_version_conf.txt delete mode 100644 msautotest/config/ms_no_version.conf diff --git a/maperror.c b/maperror.c index 6d21f46697..fc5d867920 100644 --- a/maperror.c +++ b/maperror.c @@ -534,8 +534,6 @@ char *msGetVersion() { static char version[2048]; - if(CPLGetConfigOption("MS_NO_VERSION", NULL) != NULL) return ""; // supressing version information - sprintf(version, "MapServer version %s", MS_VERSION); // add versions of required dependencies diff --git a/mapogcsos.c b/mapogcsos.c index 2d9b8a0301..eda0393dd5 100644 --- a/mapogcsos.c +++ b/mapogcsos.c @@ -1258,9 +1258,6 @@ int msSOSGetCapabilities(mapObj *map, sosParamsObj *sosparams, cgiRequestObj *re xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, "/sosGetCapabilities.xsd"); xmlNewNsProp(psRootNode, NULL, BAD_CAST "xsi:schemaLocation", BAD_CAST xsi_schemaLocation); - const char *version = msGetVersion(); - if(version[0] != '\0') xmlAddChild(psRootNode, xmlNewComment(BAD_CAST version)); - /*service identification*/ xmlAddChild(psRootNode, msOWSCommonServiceIdentification(psNsOws, map, "SOS", pszSOSVersion, "SO", NULL)); diff --git a/mapservutil.c b/mapservutil.c index 53a1a8341a..fe9d1e82a9 100644 --- a/mapservutil.c +++ b/mapservutil.c @@ -60,14 +60,11 @@ void msCGIWriteError(mapservObj *mapserv) return; } - const char *version = msGetVersion(); - if(!mapserv || !mapserv->map) { msIO_setHeader("Content-Type","text/html"); msIO_sendHeaders(); msIO_printf("\n"); msIO_printf("MapServer Message\n"); - if(version[0] != '\0') msIO_printf("\n", version); msIO_printf("\n"); msWriteErrorXML(stdout); msIO_printf(""); @@ -81,7 +78,6 @@ void msCGIWriteError(mapservObj *mapserv) msIO_sendHeaders(); msIO_printf("\n"); msIO_printf("MapServer Message\n"); - if(version[0] != '\0') msIO_printf("\n", version); msIO_printf("\n"); msWriteErrorXML(stdout); msIO_printf(""); @@ -94,7 +90,6 @@ void msCGIWriteError(mapservObj *mapserv) msIO_sendHeaders(); msIO_printf("\n"); msIO_printf("MapServer Message\n"); - if(version[0] != '\0') msIO_printf("\n", version); msIO_printf("\n"); msWriteErrorXML(stdout); msIO_printf(""); @@ -104,7 +99,6 @@ void msCGIWriteError(mapservObj *mapserv) msIO_sendHeaders(); msIO_printf("\n"); msIO_printf("MapServer Message\n"); - if(version[0] != '\0') msIO_printf("\n", version); msIO_printf("\n"); msWriteErrorXML(stdout); msIO_printf(""); diff --git a/mapwfs.cpp b/mapwfs.cpp index 6beedb0594..8700f4d49e 100644 --- a/mapwfs.cpp +++ b/mapwfs.cpp @@ -820,10 +820,6 @@ int msWFSGetCapabilities(mapObj *map, wfsParamsObj *wfsparams, cgiRequestObj *re wmtver, updatesequence ? updatesequence : "0", msOWSGetSchemasLocation(map), wmtver); - /* Report MapServer Version Information */ - const char *version = msGetVersion(); - if(version[0] != '\0') msIO_printf("\n\n\n", version); - /* ** SERVICE definition */ diff --git a/mapwms.cpp b/mapwms.cpp index 294d8f232f..bfb5499f1f 100644 --- a/mapwms.cpp +++ b/mapwms.cpp @@ -2900,12 +2900,6 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msIO_printf(">\n"); - - - /* Report MapServer Version Information */ - const char *version = msGetVersion(); - if(version[0] != '\0') msIO_printf("\n\n\n", version); - /* WMS definition */ msIO_printf("\n"); diff --git a/msautotest/api/expected/ogcapi_invalid_api_signature1.txt b/msautotest/api/expected/ogcapi_invalid_api_signature1.txt index dfe8e5dc74..522b9a1add 100644 --- a/msautotest/api/expected/ogcapi_invalid_api_signature1.txt +++ b/msautotest/api/expected/ogcapi_invalid_api_signature1.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGIDispatchAPIRequest(): Web application error. Invalid API signature. \ No newline at end of file diff --git a/msautotest/api/expected/ogcapi_invalid_api_signature2.txt b/msautotest/api/expected/ogcapi_invalid_api_signature2.txt index dfe8e5dc74..522b9a1add 100644 --- a/msautotest/api/expected/ogcapi_invalid_api_signature2.txt +++ b/msautotest/api/expected/ogcapi_invalid_api_signature2.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGIDispatchAPIRequest(): Web application error. Invalid API signature. \ No newline at end of file diff --git a/msautotest/api/expected/ogcapi_invalid_mapfile.txt b/msautotest/api/expected/ogcapi_invalid_mapfile.txt index 4485f0c275..b7bdadc017 100644 --- a/msautotest/api/expected/ogcapi_invalid_mapfile.txt +++ b/msautotest/api/expected/ogcapi_invalid_mapfile.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msLoadMap(): Unable to access file. (invalid.map) \ No newline at end of file diff --git a/msautotest/api/expected/ogcapi_missing_api_signature1.txt b/msautotest/api/expected/ogcapi_missing_api_signature1.txt index 7b3479b247..4fd0e6db37 100644 --- a/msautotest/api/expected/ogcapi_missing_api_signature1.txt +++ b/msautotest/api/expected/ogcapi_missing_api_signature1.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" is not set. \ No newline at end of file diff --git a/msautotest/api/expected/ogcapi_missing_api_signature2.txt b/msautotest/api/expected/ogcapi_missing_api_signature2.txt index 7b3479b247..4fd0e6db37 100644 --- a/msautotest/api/expected/ogcapi_missing_api_signature2.txt +++ b/msautotest/api/expected/ogcapi_missing_api_signature2.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" is not set. \ No newline at end of file diff --git a/msautotest/config/expected/empty1_conf.txt b/msautotest/config/expected/empty1_conf.txt index 75b0155f73..30f8a4d206 100644 --- a/msautotest/config/expected/empty1_conf.txt +++ b/msautotest/config/expected/empty1_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msLoadConfig(): Unknown identifier. First token must be CONFIG, this doesn't look like a mapserver config file. \ No newline at end of file diff --git a/msautotest/config/expected/empty2_conf.txt b/msautotest/config/expected/empty2_conf.txt index 0455cb60ee..58c7039c1d 100644 --- a/msautotest/config/expected/empty2_conf.txt +++ b/msautotest/config/expected/empty2_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. Required configuration value MS_MAP_PATTERN not set. \ No newline at end of file diff --git a/msautotest/config/expected/invalid1_conf.txt b/msautotest/config/expected/invalid1_conf.txt index ddd012ffa8..4e4990e767 100644 --- a/msautotest/config/expected/invalid1_conf.txt +++ b/msautotest/config/expected/invalid1_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msLoadConfig(): Unknown identifier. Parsing error near (INVALID):(line 2) \ No newline at end of file diff --git a/msautotest/config/expected/invalid2_conf.txt b/msautotest/config/expected/invalid2_conf.txt index 263c1f7f95..9dadb8b3c7 100644 --- a/msautotest/config/expected/invalid2_conf.txt +++ b/msautotest/config/expected/invalid2_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msLoadConfig(): Premature End-of-File. \ No newline at end of file diff --git a/msautotest/config/expected/missing_conf.txt b/msautotest/config/expected/missing_conf.txt index 7fb9ba8bab..6035f2ea26 100644 --- a/msautotest/config/expected/missing_conf.txt +++ b/msautotest/config/expected/missing_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msLoadConfig(): Unable to access file. See mapserver.org/mapfile/config.html for more information. \ No newline at end of file diff --git a/msautotest/config/expected/ms_map_no_path1_conf.txt b/msautotest/config/expected/ms_map_no_path1_conf.txt index faf65c1813..e663685aea 100644 --- a/msautotest/config/expected/ms_map_no_path1_conf.txt +++ b/msautotest/config/expected/ms_map_no_path1_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" not found in configuration and this server is not configured for full paths. \ No newline at end of file diff --git a/msautotest/config/expected/ms_map_no_path2_conf_failure1.txt b/msautotest/config/expected/ms_map_no_path2_conf_failure1.txt index faf65c1813..e663685aea 100644 --- a/msautotest/config/expected/ms_map_no_path2_conf_failure1.txt +++ b/msautotest/config/expected/ms_map_no_path2_conf_failure1.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" not found in configuration and this server is not configured for full paths. \ No newline at end of file diff --git a/msautotest/config/expected/ms_map_no_path2_conf_failure2.txt b/msautotest/config/expected/ms_map_no_path2_conf_failure2.txt index faf65c1813..e663685aea 100644 --- a/msautotest/config/expected/ms_map_no_path2_conf_failure2.txt +++ b/msautotest/config/expected/ms_map_no_path2_conf_failure2.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" not found in configuration and this server is not configured for full paths. \ No newline at end of file diff --git a/msautotest/config/expected/ms_map_pattern_conf.txt b/msautotest/config/expected/ms_map_pattern_conf.txt index c18927d493..155cbf945f 100644 --- a/msautotest/config/expected/ms_map_pattern_conf.txt +++ b/msautotest/config/expected/ms_map_pattern_conf.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" fails to validate. \ No newline at end of file diff --git a/msautotest/config/expected/ms_map_pattern_conf_bad_regex.txt b/msautotest/config/expected/ms_map_pattern_conf_bad_regex.txt index d2ed8c0645..df565db5ba 100644 --- a/msautotest/config/expected/ms_map_pattern_conf_bad_regex.txt +++ b/msautotest/config/expected/ms_map_pattern_conf_bad_regex.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadMap(): Web application error. CGI variable "map" fails to validate. msEvalRegex(): Regular expression error. Failed to compile expression ([A-Z*). \ No newline at end of file diff --git a/msautotest/config/expected/ms_no_post_conf_failure.txt b/msautotest/config/expected/ms_no_post_conf_failure.txt index 18307bf520..4f378e9900 100644 --- a/msautotest/config/expected/ms_no_post_conf_failure.txt +++ b/msautotest/config/expected/ms_no_post_conf_failure.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + loadParams(): Web application error. This script should be referenced with a METHOD of GET or METHOD of POST. \ No newline at end of file diff --git a/msautotest/config/expected/ms_no_version_conf.txt b/msautotest/config/expected/ms_no_version_conf.txt deleted file mode 100644 index e663685aea..0000000000 --- a/msautotest/config/expected/ms_no_version_conf.txt +++ /dev/null @@ -1,7 +0,0 @@ -Content-Type: text/html - - -MapServer Message - -msCGILoadMap(): Web application error. CGI variable "map" not found in configuration and this server is not configured for full paths. - \ No newline at end of file diff --git a/msautotest/config/hello_world.map b/msautotest/config/hello_world.map index 5fc89227bf..c039d62c3f 100644 --- a/msautotest/config/hello_world.map +++ b/msautotest/config/hello_world.map @@ -13,7 +13,6 @@ # RUN_PARMS: ms_map_pattern_conf_bad_regex.txt [MAPSERV] -conf ms_map_pattern_bad_regex.conf QUERY_STRING="map=[MAPFILE]&mode=map" > [RESULT_DEVERSION] # RUN_PARMS: ms_no_post_conf_success.png [MAPSERV] -conf ms_no_post.conf QUERY_STRING="map=HELLO_WORLD&mode=map" > [RESULT_DEMIME] # RUN_PARMS: ms_no_post_conf_failure.txt [MAPSERV] -conf ms_no_post.conf [POST]map=HELLO_WORLD&mode=map[/POST] > [RESULT_DEVERSION] -# RUN_PARMS: ms_no_version_conf.txt [MAPSERV] -conf ms_no_version.conf QUERY_STRING="map=TRIGGER_ERROR&mode=map" > [RESULT] MAP NAME 'hello_world' diff --git a/msautotest/config/ms_no_version.conf b/msautotest/config/ms_no_version.conf deleted file mode 100644 index dcb8e3b243..0000000000 --- a/msautotest/config/ms_no_version.conf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG - ENV - MS_NO_VERSION "1" - MS_MAP_NO_PATH "1" - END - MAPS - HELLO_WORLD "hello_world.map" - END -END diff --git a/msautotest/misc/expected/centerline3_exception.txt b/msautotest/misc/expected/centerline3_exception.txt index 9e4125733b..a06ec1f353 100644 --- a/msautotest/misc/expected/centerline3_exception.txt +++ b/msautotest/misc/expected/centerline3_exception.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'centerline3'. msGeomTransformShape(): Expression parser error. Failed to process shape expression: centerline([shape]) yyparse(): Expression parser error. Executing centerline failed. diff --git a/msautotest/misc/expected/centerline4_exception.txt b/msautotest/misc/expected/centerline4_exception.txt index be33b4f23f..50d6997c22 100644 --- a/msautotest/misc/expected/centerline4_exception.txt +++ b/msautotest/misc/expected/centerline4_exception.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'centerline4'. msGeomTransformShape(): Expression parser error. Failed to process shape expression: centerline([shape]) yyparse(): Expression parser error. Executing centerline failed. diff --git a/msautotest/misc/expected/centerline5_exception.txt b/msautotest/misc/expected/centerline5_exception.txt index 752ed9f053..a8e8a1fcca 100644 --- a/msautotest/misc/expected/centerline5_exception.txt +++ b/msautotest/misc/expected/centerline5_exception.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'centerline5'. msGeomTransformShape(): Expression parser error. Failed to process shape expression: centerline(densify([shape],-5)) yyparse(): Expression parser error. Executing densify failed. diff --git a/msautotest/misc/expected/flatgeobuf-wfs-cap.xml b/msautotest/misc/expected/flatgeobuf-wfs-cap.xml index bc04a427a6..283a6b4f92 100644 --- a/msautotest/misc/expected/flatgeobuf-wfs-cap.xml +++ b/msautotest/misc/expected/flatgeobuf-wfs-cap.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test FlatGeobuf WFS output diff --git a/msautotest/misc/expected/runtime_sub_test001.txt b/msautotest/misc/expected/runtime_sub_test001.txt index 0b62d5b3ac..2f8a698ee5 100644 --- a/msautotest/misc/expected/runtime_sub_test001.txt +++ b/msautotest/misc/expected/runtime_sub_test001.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'layer1'. [stripped line matching "ShapefileOpen"] [stripped line matching "ShapefileOpen"] diff --git a/msautotest/misc/expected/runtime_sub_test003.txt b/msautotest/misc/expected/runtime_sub_test003.txt index 223849a53c..7733e5bc26 100644 --- a/msautotest/misc/expected/runtime_sub_test003.txt +++ b/msautotest/misc/expected/runtime_sub_test003.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'layer2'. [stripped line matching "ShapefileOpen"] [stripped line matching "ShapefileOpen"] diff --git a/msautotest/misc/expected/runtime_sub_test005.txt b/msautotest/misc/expected/runtime_sub_test005.txt index 3e473cc41b..1938752748 100644 --- a/msautotest/misc/expected/runtime_sub_test005.txt +++ b/msautotest/misc/expected/runtime_sub_test005.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msDrawMap(): Image handling error. Failed to draw layer named 'layer3'. [stripped line matching "ShapefileOpen"] [stripped line matching "ShapefileOpen"] diff --git a/msautotest/misc/expected/runtime_sub_test_caps.xml b/msautotest/misc/expected/runtime_sub_test_caps.xml index f5fd47e50d..9b92aa090b 100644 --- a/msautotest/misc/expected/runtime_sub_test_caps.xml +++ b/msautotest/misc/expected/runtime_sub_test_caps.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/renderers/expected/font-fail-file.txt b/msautotest/renderers/expected/font-fail-file.txt index 278509ad80..16980e2728 100644 --- a/msautotest/renderers/expected/font-fail-file.txt +++ b/msautotest/renderers/expected/font-fail-file.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msGetFontFace(): General error message. Freetype was unable to load font file "/path/to/inexistant/file.ttf" for key "bogus" \ No newline at end of file diff --git a/msautotest/renderers/expected/font-fail-key.txt b/msautotest/renderers/expected/font-fail-key.txt index 335e4ad607..a2feb26f77 100644 --- a/msautotest/renderers/expected/font-fail-key.txt +++ b/msautotest/renderers/expected/font-fail-key.txt @@ -1,6 +1,7 @@ Content-Type: text/html -MapServer Message +MapServer Message + msGetFontFace(): General error message. Could not find font with key "foobar" in fontset \ No newline at end of file diff --git a/msautotest/renderers/expected/legend_bad_imagetype.txt b/msautotest/renderers/expected/legend_bad_imagetype.txt index 9c8a741b29..ffca27d8b8 100644 --- a/msautotest/renderers/expected/legend_bad_imagetype.txt +++ b/msautotest/renderers/expected/legend_bad_imagetype.txt @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + msCGILoadForm(): Web application error. Invalid imagetype value. \ No newline at end of file diff --git a/msautotest/wxs/expected/ows_all_wms_capabilities.xml b/msautotest/wxs/expected/ows_all_wms_capabilities.xml index 39361b3baa..ae521a9d1b 100644 --- a/msautotest/wxs/expected/ows_all_wms_capabilities.xml +++ b/msautotest/wxs/expected/ows_all_wms_capabilities.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml b/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml index 39361b3baa..ae521a9d1b 100644 --- a/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml +++ b/msautotest/wxs/expected/ows_all_wms_capabilities_post.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/ows_context_caps.xml b/msautotest/wxs/expected/ows_context_caps.xml index ae7f9df53e..fbe4e1d371 100644 --- a/msautotest/wxs/expected/ows_context_caps.xml +++ b/msautotest/wxs/expected/ows_context_caps.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Map Context demo diff --git a/msautotest/wxs/expected/ows_metadata_wfs_capabilities100.xml b/msautotest/wxs/expected/ows_metadata_wfs_capabilities100.xml index 8d998a4c48..0f828b0396 100644 --- a/msautotest/wxs/expected/ows_metadata_wfs_capabilities100.xml +++ b/msautotest/wxs/expected/ows_metadata_wfs_capabilities100.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple OWS diff --git a/msautotest/wxs/expected/ows_metadata_wms_capabilities111.xml b/msautotest/wxs/expected/ows_metadata_wms_capabilities111.xml index 9fb9e05f19..779dad3dbb 100644 --- a/msautotest/wxs/expected/ows_metadata_wms_capabilities111.xml +++ b/msautotest/wxs/expected/ows_metadata_wms_capabilities111.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple OWS diff --git a/msautotest/wxs/expected/ows_metadata_wms_capabilities130.xml b/msautotest/wxs/expected/ows_metadata_wms_capabilities130.xml index e8f861b64c..8205eb73a6 100644 --- a/msautotest/wxs/expected/ows_metadata_wms_capabilities130.xml +++ b/msautotest/wxs/expected/ows_metadata_wms_capabilities130.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple OWS diff --git a/msautotest/wxs/expected/ows_wms_capabilities.xml b/msautotest/wxs/expected/ows_wms_capabilities.xml index c8391db66c..9bd623b657 100644 --- a/msautotest/wxs/expected/ows_wms_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_capabilities.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml b/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml index a4f90b9529..bb8d250149 100644 --- a/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_rootlayer_name_capabilities.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml b/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml index 2fc51170a9..f9679c44cd 100644 --- a/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml +++ b/msautotest/wxs/expected/ows_wms_rootlayer_name_empty_capabilities.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/sos_cap.xml b/msautotest/wxs/expected/sos_cap.xml index 94312cf0c7..1a29defc90 100644 --- a/msautotest/wxs/expected/sos_cap.xml +++ b/msautotest/wxs/expected/sos_cap.xml @@ -2,7 +2,7 @@ Content-Type: text/xml; charset=UTF-8 - + Test SOS Title Test SOS Abstract diff --git a/msautotest/wxs/expected/sos_cap0.xml b/msautotest/wxs/expected/sos_cap0.xml index 94312cf0c7..1a29defc90 100644 --- a/msautotest/wxs/expected/sos_cap0.xml +++ b/msautotest/wxs/expected/sos_cap0.xml @@ -2,7 +2,7 @@ Content-Type: text/xml; charset=UTF-8 - + Test SOS Title Test SOS Abstract diff --git a/msautotest/wxs/expected/sos_cap1.xml b/msautotest/wxs/expected/sos_cap1.xml index 94312cf0c7..1a29defc90 100644 --- a/msautotest/wxs/expected/sos_cap1.xml +++ b/msautotest/wxs/expected/sos_cap1.xml @@ -2,7 +2,7 @@ Content-Type: text/xml; charset=UTF-8 - + Test SOS Title Test SOS Abstract diff --git a/msautotest/wxs/expected/sos_caps_updatesequence.xml b/msautotest/wxs/expected/sos_caps_updatesequence.xml index 94312cf0c7..1a29defc90 100644 --- a/msautotest/wxs/expected/sos_caps_updatesequence.xml +++ b/msautotest/wxs/expected/sos_caps_updatesequence.xml @@ -2,7 +2,7 @@ Content-Type: text/xml; charset=UTF-8 - + Test SOS Title Test SOS Abstract diff --git a/msautotest/wxs/expected/wfs10_test_xml_escaping.xml b/msautotest/wxs/expected/wfs10_test_xml_escaping.xml index c31c58c307..8b35169f06 100644 --- a/msautotest/wxs/expected/wfs10_test_xml_escaping.xml +++ b/msautotest/wxs/expected/wfs10_test_xml_escaping.xml @@ -6,7 +6,6 @@ xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS title & title diff --git a/msautotest/wxs/expected/wfs_cap.xml b/msautotest/wxs/expected/wfs_cap.xml index bda4925d37..60c5ad1b6b 100644 --- a/msautotest/wxs/expected/wfs_cap.xml +++ b/msautotest/wxs/expected/wfs_cap.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wfs_cap_ogr.xml b/msautotest/wxs/expected/wfs_cap_ogr.xml index da393337ee..e0689a91b6 100644 --- a/msautotest/wxs/expected/wfs_cap_ogr.xml +++ b/msautotest/wxs/expected/wfs_cap_ogr.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wfs_caps_updatesequence.xml b/msautotest/wxs/expected/wfs_caps_updatesequence.xml index bda4925d37..60c5ad1b6b 100644 --- a/msautotest/wxs/expected/wfs_caps_updatesequence.xml +++ b/msautotest/wxs/expected/wfs_caps_updatesequence.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wfs_caps_updatesequence_ogr.xml b/msautotest/wxs/expected/wfs_caps_updatesequence_ogr.xml index da393337ee..e0689a91b6 100644 --- a/msautotest/wxs/expected/wfs_caps_updatesequence_ogr.xml +++ b/msautotest/wxs/expected/wfs_caps_updatesequence_ogr.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wfs_get_caps.xml b/msautotest/wxs/expected/wfs_get_caps.xml index 01d5edf6ee..f08e155d2a 100644 --- a/msautotest/wxs/expected/wfs_get_caps.xml +++ b/msautotest/wxs/expected/wfs_get_caps.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Sample OWS for MapServer OGC Web Services Workshop diff --git a/msautotest/wxs/expected/wfs_multiple_metadataurl_100_cap.xml b/msautotest/wxs/expected/wfs_multiple_metadataurl_100_cap.xml index adccd2c004..f077eea59c 100644 --- a/msautotest/wxs/expected/wfs_multiple_metadataurl_100_cap.xml +++ b/msautotest/wxs/expected/wfs_multiple_metadataurl_100_cap.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wfs_ogr_drv_nocreatedatasource_caps.xml b/msautotest/wxs/expected/wfs_ogr_drv_nocreatedatasource_caps.xml index bfa5c8efa4..23f115a9cf 100644 --- a/msautotest/wxs/expected/wfs_ogr_drv_nocreatedatasource_caps.xml +++ b/msautotest/wxs/expected/wfs_ogr_drv_nocreatedatasource_caps.xml @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + loadOutputFormat(): General error message. OUTPUTFORMAT (nocreatedatasource) clause references driver (OGR/SDTS), but this driver isn't configured. msInitDefaultOGROutputFormat(): General error message. OGR `SDTS' driver does not support output. \ No newline at end of file diff --git a/msautotest/wxs/expected/wfs_ogr_nonexistingdrv_caps.xml b/msautotest/wxs/expected/wfs_ogr_nonexistingdrv_caps.xml index 11b586564c..6d4fb3f907 100644 --- a/msautotest/wxs/expected/wfs_ogr_nonexistingdrv_caps.xml +++ b/msautotest/wxs/expected/wfs_ogr_nonexistingdrv_caps.xml @@ -1,7 +1,8 @@ Content-Type: text/html -MapServer Message +MapServer Message + loadOutputFormat(): General error message. OUTPUTFORMAT (nonexistingdrv) clause references driver (OGR/nonexistingdrv), but this driver isn't configured. msInitDefaultOGROutputFormat(): General error message. No OGR driver named `nonexistingdrv' available. \ No newline at end of file diff --git a/msautotest/wxs/expected/wfsogr10_caps.xml b/msautotest/wxs/expected/wfsogr10_caps.xml index c95cc630f1..0de3471c7e 100644 --- a/msautotest/wxs/expected/wfsogr10_caps.xml +++ b/msautotest/wxs/expected/wfsogr10_caps.xml @@ -8,7 +8,6 @@ Content-Type: text/xml; charset=UTF-8 xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd"> - MapServer WFS Test simple wfs diff --git a/msautotest/wxs/expected/wms111_test_xml_escaping.xml b/msautotest/wxs/expected/wms111_test_xml_escaping.xml index 2b5fe8aae7..30d62518e6 100644 --- a/msautotest/wxs/expected/wms111_test_xml_escaping.xml +++ b/msautotest/wxs/expected/wms111_test_xml_escaping.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS title & title diff --git a/msautotest/wxs/expected/wms130_test_xml_escaping.xml b/msautotest/wxs/expected/wms130_test_xml_escaping.xml index 0cf895042f..f2c0a1604a 100644 --- a/msautotest/wxs/expected/wms130_test_xml_escaping.xml +++ b/msautotest/wxs/expected/wms130_test_xml_escaping.xml @@ -1,6 +1,5 @@ - WMS title & title diff --git a/msautotest/wxs/expected/wms_cap.xml b/msautotest/wxs/expected/wms_cap.xml index cf697d2c55..62fb4bc30f 100644 --- a/msautotest/wxs/expected/wms_cap.xml +++ b/msautotest/wxs/expected/wms_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_cap130.xml b/msautotest/wxs/expected/wms_cap130.xml index 882ed8d46b..f9a702eae0 100644 --- a/msautotest/wxs/expected/wms_cap130.xml +++ b/msautotest/wxs/expected/wms_cap130.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_cap130_postgis.xml b/msautotest/wxs/expected/wms_cap130_postgis.xml index 882ed8d46b..f9a702eae0 100644 --- a/msautotest/wxs/expected/wms_cap130_postgis.xml +++ b/msautotest/wxs/expected/wms_cap130_postgis.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_cap_latestversion.xml b/msautotest/wxs/expected/wms_cap_latestversion.xml index 882ed8d46b..f9a702eae0 100644 --- a/msautotest/wxs/expected/wms_cap_latestversion.xml +++ b/msautotest/wxs/expected/wms_cap_latestversion.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_cap_latestversion_postgis.xml b/msautotest/wxs/expected/wms_cap_latestversion_postgis.xml index 882ed8d46b..f9a702eae0 100644 --- a/msautotest/wxs/expected/wms_cap_latestversion_postgis.xml +++ b/msautotest/wxs/expected/wms_cap_latestversion_postgis.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_cap_postgis.xml b/msautotest/wxs/expected/wms_cap_postgis.xml index cf697d2c55..62fb4bc30f 100644 --- a/msautotest/wxs/expected/wms_cap_postgis.xml +++ b/msautotest/wxs/expected/wms_cap_postgis.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_caps_updatesequence.xml b/msautotest/wxs/expected/wms_caps_updatesequence.xml index cf697d2c55..62fb4bc30f 100644 --- a/msautotest/wxs/expected/wms_caps_updatesequence.xml +++ b/msautotest/wxs/expected/wms_caps_updatesequence.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_caps_updatesequence_postgis.xml b/msautotest/wxs/expected/wms_caps_updatesequence_postgis.xml index cf697d2c55..62fb4bc30f 100644 --- a/msautotest/wxs/expected/wms_caps_updatesequence_postgis.xml +++ b/msautotest/wxs/expected/wms_caps_updatesequence_postgis.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_dimension_cap.xml b/msautotest/wxs/expected/wms_dimension_cap.xml index d43a7f9129..7dccad721e 100644 --- a/msautotest/wxs/expected/wms_dimension_cap.xml +++ b/msautotest/wxs/expected/wms_dimension_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS diff --git a/msautotest/wxs/expected/wms_dimension_cap130.xml b/msautotest/wxs/expected/wms_dimension_cap130.xml index 51848fecb9..7e2625f192 100644 --- a/msautotest/wxs/expected/wms_dimension_cap130.xml +++ b/msautotest/wxs/expected/wms_dimension_cap130.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS diff --git a/msautotest/wxs/expected/wms_empty_cap100.xml b/msautotest/wxs/expected/wms_empty_cap100.xml index 2fd4cafc96..fb93d6003c 100644 --- a/msautotest/wxs/expected/wms_empty_cap100.xml +++ b/msautotest/wxs/expected/wms_empty_cap100.xml @@ -5,7 +5,6 @@ ]> - GetMap Test simple wms diff --git a/msautotest/wxs/expected/wms_empty_cap111.xml b/msautotest/wxs/expected/wms_empty_cap111.xml index e23f2f608b..0fc7e6832e 100644 --- a/msautotest/wxs/expected/wms_empty_cap111.xml +++ b/msautotest/wxs/expected/wms_empty_cap111.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_empty_cap130.xml b/msautotest/wxs/expected/wms_empty_cap130.xml index 3d2daea0a9..215ebffa86 100644 --- a/msautotest/wxs/expected/wms_empty_cap130.xml +++ b/msautotest/wxs/expected/wms_empty_cap130.xml @@ -1,6 +1,5 @@ - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_empty_cap_latestversion.xml b/msautotest/wxs/expected/wms_empty_cap_latestversion.xml index 3d2daea0a9..215ebffa86 100644 --- a/msautotest/wxs/expected/wms_empty_cap_latestversion.xml +++ b/msautotest/wxs/expected/wms_empty_cap_latestversion.xml @@ -1,6 +1,5 @@ - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_get_capabilities_tileindexmixedsrs.xml b/msautotest/wxs/expected/wms_get_capabilities_tileindexmixedsrs.xml index 8d83f4d063..558a365903 100644 --- a/msautotest/wxs/expected/wms_get_capabilities_tileindexmixedsrs.xml +++ b/msautotest/wxs/expected/wms_get_capabilities_tileindexmixedsrs.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS title diff --git a/msautotest/wxs/expected/wms_get_caps.xml b/msautotest/wxs/expected/wms_get_caps.xml index a6fefc6fe3..160a8b90ff 100644 --- a/msautotest/wxs/expected/wms_get_caps.xml +++ b/msautotest/wxs/expected/wms_get_caps.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Sample OWS for MapServer OGC Web Services Workshop diff --git a/msautotest/wxs/expected/wms_inspire_cap.xml b/msautotest/wxs/expected/wms_inspire_cap.xml index 4544b4c672..078eeb2545 100644 --- a/msautotest/wxs/expected/wms_inspire_cap.xml +++ b/msautotest/wxs/expected/wms_inspire_cap.xml @@ -1,6 +1,5 @@ - WMS INSPIRE Testdienst diff --git a/msautotest/wxs/expected/wms_inspire_cap_111.xml b/msautotest/wxs/expected/wms_inspire_cap_111.xml index 3e0dc9c801..cb7ebd2c7f 100644 --- a/msautotest/wxs/expected/wms_inspire_cap_111.xml +++ b/msautotest/wxs/expected/wms_inspire_cap_111.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS INSPIRE Testdienst diff --git a/msautotest/wxs/expected/wms_inspire_cap_111_eng.xml b/msautotest/wxs/expected/wms_inspire_cap_111_eng.xml index b79a639ef4..2fb75c10ff 100644 --- a/msautotest/wxs/expected/wms_inspire_cap_111_eng.xml +++ b/msautotest/wxs/expected/wms_inspire_cap_111_eng.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS INSPIRE test service diff --git a/msautotest/wxs/expected/wms_inspire_cap_111_ger.xml b/msautotest/wxs/expected/wms_inspire_cap_111_ger.xml index 3e0dc9c801..cb7ebd2c7f 100644 --- a/msautotest/wxs/expected/wms_inspire_cap_111_ger.xml +++ b/msautotest/wxs/expected/wms_inspire_cap_111_ger.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS INSPIRE Testdienst diff --git a/msautotest/wxs/expected/wms_inspire_cap_eng.xml b/msautotest/wxs/expected/wms_inspire_cap_eng.xml index f23cf490d5..d445c22dd0 100644 --- a/msautotest/wxs/expected/wms_inspire_cap_eng.xml +++ b/msautotest/wxs/expected/wms_inspire_cap_eng.xml @@ -1,6 +1,5 @@ - WMS INSPIRE test service diff --git a/msautotest/wxs/expected/wms_inspire_cap_ger.xml b/msautotest/wxs/expected/wms_inspire_cap_ger.xml index 4544b4c672..078eeb2545 100644 --- a/msautotest/wxs/expected/wms_inspire_cap_ger.xml +++ b/msautotest/wxs/expected/wms_inspire_cap_ger.xml @@ -1,6 +1,5 @@ - WMS INSPIRE Testdienst diff --git a/msautotest/wxs/expected/wms_inspire_scenario1_cap130.xml b/msautotest/wxs/expected/wms_inspire_scenario1_cap130.xml index 0b36514720..f5405991ec 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario1_cap130.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario1_cap130.xml @@ -1,6 +1,5 @@ - WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario1_cap130_eng.xml b/msautotest/wxs/expected/wms_inspire_scenario1_cap130_eng.xml index 0b36514720..f5405991ec 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario1_cap130_eng.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario1_cap130_eng.xml @@ -1,6 +1,5 @@ - WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario1_cap130_ger.xml b/msautotest/wxs/expected/wms_inspire_scenario1_cap130_ger.xml index e47f4f0fc5..60fc69fe78 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario1_cap130_ger.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario1_cap130_ger.xml @@ -1,6 +1,5 @@ - WMS myservicetitleger diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap111.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap111.xml index 54a35dfb1e..238b2959fb 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap111.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap111.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap111_eng.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap111_eng.xml index 54a35dfb1e..238b2959fb 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap111_eng.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap111_eng.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap111_ger.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap111_ger.xml index c39767924b..55f02013d3 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap111_ger.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap111_ger.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS myservicetitleger diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap130.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap130.xml index a9c69ab29c..a8201e6b00 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap130.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap130.xml @@ -1,6 +1,5 @@ - WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap130_eng.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap130_eng.xml index a9c69ab29c..a8201e6b00 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap130_eng.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap130_eng.xml @@ -1,6 +1,5 @@ - WMS myservicetitle diff --git a/msautotest/wxs/expected/wms_inspire_scenario2_cap130_ger.xml b/msautotest/wxs/expected/wms_inspire_scenario2_cap130_ger.xml index 8d7add0256..3159b54d4b 100644 --- a/msautotest/wxs/expected/wms_inspire_scenario2_cap130_ger.xml +++ b/msautotest/wxs/expected/wms_inspire_scenario2_cap130_ger.xml @@ -1,6 +1,5 @@ - WMS myservicetitleger diff --git a/msautotest/wxs/expected/wms_layer_groups_caps111.xml b/msautotest/wxs/expected/wms_layer_groups_caps111.xml index 4d77273453..626c584605 100644 --- a/msautotest/wxs/expected/wms_layer_groups_caps111.xml +++ b/msautotest/wxs/expected/wms_layer_groups_caps111.xml @@ -5,7 +5,6 @@ ]> - OGC:WMS diff --git a/msautotest/wxs/expected/wms_multiple_metadataurl_cap.xml b/msautotest/wxs/expected/wms_multiple_metadataurl_cap.xml index 6c3c79fde2..688d0438ec 100644 --- a/msautotest/wxs/expected/wms_multiple_metadataurl_cap.xml +++ b/msautotest/wxs/expected/wms_multiple_metadataurl_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_north_polar_stereo_extent.xml b/msautotest/wxs/expected/wms_north_polar_stereo_extent.xml index a09cfa430a..83ce3507b2 100644 --- a/msautotest/wxs/expected/wms_north_polar_stereo_extent.xml +++ b/msautotest/wxs/expected/wms_north_polar_stereo_extent.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_nosld_cap.xml b/msautotest/wxs/expected/wms_nosld_cap.xml index 6ae0439d39..b984f52193 100644 --- a/msautotest/wxs/expected/wms_nosld_cap.xml +++ b/msautotest/wxs/expected/wms_nosld_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_nosld_cap_postgis.xml b/msautotest/wxs/expected/wms_nosld_cap_postgis.xml index 0c6102b956..6de9b6eaa7 100644 --- a/msautotest/wxs/expected/wms_nosld_cap_postgis.xml +++ b/msautotest/wxs/expected/wms_nosld_cap_postgis.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_rast_cap.xml b/msautotest/wxs/expected/wms_rast_cap.xml index 803d4370d2..c13eebd48f 100644 --- a/msautotest/wxs/expected/wms_rast_cap.xml +++ b/msautotest/wxs/expected/wms_rast_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test simple wms diff --git a/msautotest/wxs/expected/wms_time_cap.xml b/msautotest/wxs/expected/wms_time_cap.xml index 6d1609e37d..2dca5366b2 100644 --- a/msautotest/wxs/expected/wms_time_cap.xml +++ b/msautotest/wxs/expected/wms_time_cap.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test WMS time support diff --git a/msautotest/wxs/expected/wms_time_cap130.xml b/msautotest/wxs/expected/wms_time_cap130.xml index e4e92122d4..1b5d0eebb7 100644 --- a/msautotest/wxs/expected/wms_time_cap130.xml +++ b/msautotest/wxs/expected/wms_time_cap130.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test WMS time support diff --git a/msautotest/wxs/expected/wms_time_cap130_postgis_postgis.xml b/msautotest/wxs/expected/wms_time_cap130_postgis_postgis.xml index e4e92122d4..1b5d0eebb7 100644 --- a/msautotest/wxs/expected/wms_time_cap130_postgis_postgis.xml +++ b/msautotest/wxs/expected/wms_time_cap130_postgis_postgis.xml @@ -2,7 +2,6 @@ Content-Type: text/xml; charset=UTF-8 - WMS Test WMS time support diff --git a/msautotest/wxs/expected/wms_time_cap_postgis_postgis.xml b/msautotest/wxs/expected/wms_time_cap_postgis_postgis.xml index 6d1609e37d..2dca5366b2 100644 --- a/msautotest/wxs/expected/wms_time_cap_postgis_postgis.xml +++ b/msautotest/wxs/expected/wms_time_cap_postgis_postgis.xml @@ -7,7 +7,6 @@ Content-Type: application/vnd.ogc.wms_xml; charset=UTF-8 ]> - OGC:WMS Test WMS time support From 66c441671b34c04790f4ad408c6f848665a9446d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 20:05:28 -0600 Subject: [PATCH 101/170] [Backport branch-8-0] Update MS SQL Server connection error logging (#6810) * Redact pwd from logs * Avoid reporting sensitive data to client applications * Fix parameter order * Remove unused variables * Improve redaction for different database connection strings * Remove unused variable Co-authored-by: sethg --- maperror.c | 28 ++++++++++++++++++++-------- mapmssql2008.c | 39 +++++++++++++-------------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/maperror.c b/maperror.c index fc5d867920..acb9a6e3a4 100644 --- a/maperror.c +++ b/maperror.c @@ -329,16 +329,28 @@ char *msGetErrorString(const char *delimiter) return(errstr); } -void msRedactCredentials(char* str) +void msRedactString(char* str, const char* keyword, const char delimeter) { - char* password = strstr(str, "password="); - if (password != NULL) { - char* ptr = password + strlen("password="); - while (*ptr != '\0' && *ptr != ' ') { - *ptr = '*'; - ptr++; + + char* password = strstr(str, keyword); + if (password != NULL) { + char* ptr = password + strlen(keyword); + while (*ptr != '\0' && *ptr != delimeter) { + *ptr = '*'; + ptr++; + } } - } +} + +void msRedactCredentials(char* str) +{ + + // postgres formats + msRedactString(str, "password=", ' '); + // mssql use semi-colons as delimeters for parameters + msRedactString(str, "password=", ';'); + // ODBC connections can use pwd rather than password + msRedactString(str, "pwd=", ';'); } void msSetError(int code, const char *message_fmt, const char *routine, ...) diff --git a/mapmssql2008.c b/mapmssql2008.c index 3468bbc4da..95744a51d2 100644 --- a/mapmssql2008.c +++ b/mapmssql2008.c @@ -926,8 +926,6 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt int msMSSQL2008LayerOpen(layerObj *layer) { msMSSQL2008LayerInfo *layerinfo; - char *index, *maskeddata; - int i, count; char *conn_decrypted = NULL; if(layer->debug) { @@ -991,35 +989,24 @@ int msMSSQL2008LayerOpen(layerObj *layer) if(!layerinfo->conn || layerinfo->conn->errorMessage[0]) { char *errMess = "Out of memory"; - msDebug("FAILURE!!!"); - maskeddata = (char *)msSmallMalloc(strlen(layer->connection) + 1); - strcpy(maskeddata, layer->connection); - index = strstr(maskeddata, "password="); - if(index != NULL) { - index = (char *)(index + 9); - count = (int)(strstr(index, " ") - index); - for(i = 0; i < count; i++) { - strlcpy(index, "*", (int)1); - index++; - } - } + if (layer->debug) + msDebug("MSMSSQL2008LayerOpen: Connection failure.\n"); if (layerinfo->conn) { errMess = layerinfo->conn->errorMessage; } - msSetError(MS_QUERYERR, - "Couldnt make connection to MS SQL Server 2008 with connect string '%s'.\n
\n" - "Error reported was '%s'.\n
\n\n" - "This error occured when trying to make a connection to the specified SQL server. \n" - "
\nMost commonly this is caused by
\n" - "(1) incorrect connection string
\n" - "(2) you didn't specify a 'user id=...' in your connection string
\n" - "(3) SQL server isnt running
\n" - "(4) TCPIP not enabled for SQL Client or server
\n\n", - "msMSSQL2008LayerOpen()", maskeddata, errMess); - - msFree(maskeddata); + msDebug("Couldn't make connection to MS SQL Server with connect string '%s'.\n" + "Error reported was '%s'.\n\n" + "This error occured when trying to make a connection to the specified SQL server.\n" + "Most commonly this is caused by: \n" + "(1) incorrect connection string \n" + "(2) you didn't specify a 'user id=...' in your connection string \n" + "(3) SQL server isnt running \n" + "(4) TCPIP not enabled for SQL Client or server \n\n", + layer->connection, errMess); + msSetError(MS_QUERYERR, "Database connection failed. Check server logs for more details. Is SQL Server running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port?", "MSMSSQL2008LayerOpen()"); + msMSSQL2008CloseConnection(layerinfo->conn); msFree(layerinfo); return MS_FAILURE; From 454a663b18a5d9758716b78fb09b990921f1e22f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 20:05:49 -0600 Subject: [PATCH 102/170] Add WIN32 flag to SWIG csharp command line, prevent classObj_drawLegendIcon to cause crash (#6758) (#6811) Co-authored-by: Tamas Szekeres --- mapscript/csharp/CMakeLists.txt | 6 +++++- mapscript/swiginc/class.i | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mapscript/csharp/CMakeLists.txt b/mapscript/csharp/CMakeLists.txt index 465b92940e..af395a505f 100644 --- a/mapscript/csharp/CMakeLists.txt +++ b/mapscript/csharp/CMakeLists.txt @@ -35,7 +35,11 @@ include_directories(${PROJECT_SOURCE_DIR}/mapscript/swiginc) include_directories(${PROJECT_SOURCE_DIR}/mapscript/) include_directories(${PROJECT_SOURCE_DIR}/mapscript/csharp) SET (CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}") -SET( CMAKE_SWIG_FLAGS -namespace OSGeo.MapServer ${MAPSERVER_COMPILE_DEFINITIONS}) +if (WIN32) + SET( CMAKE_SWIG_FLAGS -namespace OSGeo.MapServer -DWIN32 ${MAPSERVER_COMPILE_DEFINITIONS}) +else() + SET( CMAKE_SWIG_FLAGS -namespace OSGeo.MapServer ${MAPSERVER_COMPILE_DEFINITIONS}) +endif() if (${CMAKE_VERSION} VERSION_LESS "3.8.0") SWIG_ADD_MODULE(mapscript csharp ../mapscript.i) else() diff --git a/mapscript/swiginc/class.i b/mapscript/swiginc/class.i index b319daff51..310497cf78 100644 --- a/mapscript/swiginc/class.i +++ b/mapscript/swiginc/class.i @@ -169,8 +169,17 @@ } else layer->scalefactor = map->resolution/map->defresolution; - + + #if defined(WIN32) && defined(SWIGCSHARP) + __try { + return msDrawLegendIcon(map, layer, self, width, height, dstImage, dstX, dstY, MS_TRUE, NULL); + } + __except(1 /*EXCEPTION_EXECUTE_HANDLER, catch every exception so it doesn't crash IIS*/) { + msSetError(MS_IMGERR, "Unhandled exception in drawing legend image 0x%08x", "msDrawMap()", GetExceptionCode()); + } + #else return msDrawLegendIcon(map, layer, self, width, height, dstImage, dstX, dstY, MS_TRUE, NULL); + #endif } %newobject createLegendIcon; From c41244cab8a175e3f30c25684601c12b35d48910 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 09:52:54 -0400 Subject: [PATCH 103/170] [Backport branch-8-0] Allow NULL shapes to be returned in WFS GetFeature requests (#6814) --- mapogroutput.cpp | 2 +- mapproject.c | 33 ++++++++++++------- mapquery.c | 8 ++++- msautotest/mssql/expected/null_and_point.json | 10 ++++++ .../expected/null_and_point_reprojected.json | 9 +++++ msautotest/mssql/wfs_ogr_export.map | 19 +++++++++++ 6 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 msautotest/mssql/expected/null_and_point.json create mode 100644 msautotest/mssql/expected/null_and_point_reprojected.json diff --git a/mapogroutput.cpp b/mapogroutput.cpp index 1f42625308..93f88f633b 100644 --- a/mapogroutput.cpp +++ b/mapogroutput.cpp @@ -1135,7 +1135,7 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders ) } } - if( layer->project ) { + if( layer->project && resultshape.type != MS_SHAPE_NULL) { if( layer->reprojectorLayerToMap == NULL ) { layer->reprojectorLayerToMap = msProjectCreateReprojector( diff --git a/mapproject.c b/mapproject.c index 7f5bb36ba9..ed24dc397c 100644 --- a/mapproject.c +++ b/mapproject.c @@ -1702,21 +1702,30 @@ int msProjectShapeEx(reprojectionObj* reprojector, shapeObj *shape) #undef p_y #endif - for( i = shape->numlines-1; i >= 0; i-- ) { - if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) { - if( msProjectShapeLine( reprojector, shape, i ) == MS_FAILURE ) + if (shape->numlines == 0) { + // don't attempt to project any NULL geometries + // but if we want to return the record's attributes we won't free the shape + // and throw an error + shape->type = MS_SHAPE_NULL; + return MS_SUCCESS; + } else { + for( i = shape->numlines-1; i >= 0; i-- ) { + if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) { + if( msProjectShapeLine( reprojector, shape, i ) == MS_FAILURE ) + msShapeDeleteLine( shape, i ); + } else if( msProjectLineEx(reprojector, shape->line+i ) == MS_FAILURE ) { msShapeDeleteLine( shape, i ); - } else if( msProjectLineEx(reprojector, shape->line+i ) == MS_FAILURE ) { - msShapeDeleteLine( shape, i ); + } } - } - if( shape->numlines == 0 ) { - msFreeShape( shape ); - return MS_FAILURE; - } else { - msComputeBounds( shape ); /* fixes bug 1586 */ - return(MS_SUCCESS); + if ( shape->numlines == 0 ) { + msFreeShape(shape); + return MS_FAILURE; + } + else { + msComputeBounds(shape); /* fixes bug 1586 */ + return(MS_SUCCESS); + } } } diff --git a/mapquery.c b/mapquery.c index e5f83e92f2..ae08cbb837 100644 --- a/mapquery.c +++ b/mapquery.c @@ -1248,7 +1248,10 @@ int msQueryByRect(mapObj *map) break; } } - msProjectShapeEx(reprojector, &shape); + if( msProjectShapeEx(reprojector, &shape) != MS_SUCCESS ) { + // msProjectShapeEx() calls msFreeShape() on error + continue; + } } if(msRectContained(&shape.bounds, &searchrectInMapProj) == MS_TRUE) { /* if the whole shape is in, don't intersect */ @@ -1264,6 +1267,9 @@ int msQueryByRect(mapObj *map) case MS_SHAPE_POLYGON: status = msIntersectPolygons(&shape, &searchshape); break; + case MS_SHAPE_NULL: + status = MS_TRUE; + break; default: break; } diff --git a/msautotest/mssql/expected/null_and_point.json b/msautotest/mssql/expected/null_and_point.json new file mode 100644 index 0000000000..11278fd9f5 --- /dev/null +++ b/msautotest/mssql/expected/null_and_point.json @@ -0,0 +1,10 @@ +{ +"type": "FeatureCollection", +"numberMatched": 2, +"name": "null_and_point", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3857" } }, +"features": [ +{ "type": "Feature", "properties": { "fid": 1 }, "geometry": null }, +{ "type": "Feature", "properties": { "fid": 2 }, "geometry": { "type": "Point", "coordinates": [ 10.0, 10.0 ] } } +] +} diff --git a/msautotest/mssql/expected/null_and_point_reprojected.json b/msautotest/mssql/expected/null_and_point_reprojected.json new file mode 100644 index 0000000000..5a5000ee1b --- /dev/null +++ b/msautotest/mssql/expected/null_and_point_reprojected.json @@ -0,0 +1,9 @@ +{ +"type": "FeatureCollection", +"numberMatched": 2, +"name": "null_and_point", +"features": [ +{ "type": "Feature", "properties": { "fid": 1 }, "geometry": null }, +{ "type": "Feature", "properties": { "fid": 2 }, "geometry": { "type": "Point", "coordinates": [ 0.000089831528412, 0.000089831528412 ] } } +] +} diff --git a/msautotest/mssql/wfs_ogr_export.map b/msautotest/mssql/wfs_ogr_export.map index a081998d45..6cf4e7c0ed 100644 --- a/msautotest/mssql/wfs_ogr_export.map +++ b/msautotest/mssql/wfs_ogr_export.map @@ -10,6 +10,9 @@ # RUN_PARMS: null_multiline.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=null_multiline&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] # RUN_PARMS: null_multipolygon.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=null_multipolygon&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] +# RUN_PARMS: null_and_point.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=null_and_point&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] +# RUN_PARMS: null_and_point_reprojected.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=null_and_point&OUTPUTFORMAT=geojson&srsName=EPSG:4326" > [RESULT_DEMIME] + # RUN_PARMS: point.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=point&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] # RUN_PARMS: line.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=line&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] # RUN_PARMS: polygon.json [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&TYPENAMES=polygon&OUTPUTFORMAT=geojson" > [RESULT_DEMIME] @@ -23,6 +26,11 @@ MAP NAME 'wfs_export_mssql' UNITS METERS + EXTENT 0 0 100 100 + SIZE 100 100 + PROJECTION + "init=epsg:3857" + END WEB METADATA @@ -160,4 +168,15 @@ MAP ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))', 3857) geom) as foo USING UNIQUE fid USING SRID=3857" END + LAYER + NAME 'null_and_point' + TYPE POINT + PROJECTION + "init=epsg:3857" + END + INCLUDE 'include/mssql_connection.map' + INCLUDE 'include/wfs_ogr_export_metadata.map' + DATA "geom from (SELECT 1 fid, geometry::STGeomFromText('POINT EMPTY', 3857) geom UNION ALL SELECT 2 fid, geometry::STGeomFromText('POINT (10 10)', 3857) geom) as foo USING UNIQUE fid USING SRID=3857" + END + END From 05a618e01ff0188b9d8c6a385be69f7a222f4fde Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 12:09:08 -0400 Subject: [PATCH 104/170] Fix wfs paging on oracle (#6815) --- maporaclespatial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/maporaclespatial.c b/maporaclespatial.c index 6e35b92581..2595262961 100644 --- a/maporaclespatial.c +++ b/maporaclespatial.c @@ -2086,6 +2086,7 @@ int msOracleSpatialLayerWhichShapes( layerObj *layer, rectObj rect, int isQuery) msFree(tmp1_str); tmp_str = msStringConcatenate(tmp_str, query_str2); + memset(query_str,0,strlen(query_str)); query_str = msStringConcatenate(query_str, tmp_str); msFree(tmp_str); } From 704e68dce67436c2543297e26a093608e02181b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 10:50:32 -0400 Subject: [PATCH 105/170] [Backport branch-8-0] Issue 6631 (#6819) --- mapogcapi.cpp | 20 ++++- msautotest/api/6631.map | 69 ++++++++++++++++++ msautotest/api/data/countries-tanzania.dbf | Bin 0 -> 309 bytes msautotest/api/data/countries-tanzania.prj | 1 + msautotest/api/data/countries-tanzania.shp | Bin 0 -> 988 bytes msautotest/api/data/countries-tanzania.shx | Bin 0 -> 108 bytes ...gcapi_collections_tanzania1_items.html.txt | 1 + ...gcapi_collections_tanzania1_items.json.txt | 1 + .../ogcapi_collections_tanzania2_items.html | 47 ++++++++++++ .../ogcapi_collections_tanzania2_items.json | 1 + 10 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 msautotest/api/6631.map create mode 100755 msautotest/api/data/countries-tanzania.dbf create mode 100755 msautotest/api/data/countries-tanzania.prj create mode 100755 msautotest/api/data/countries-tanzania.shp create mode 100755 msautotest/api/data/countries-tanzania.shx create mode 100644 msautotest/api/expected/ogcapi_collections_tanzania1_items.html.txt create mode 100644 msautotest/api/expected/ogcapi_collections_tanzania1_items.json.txt create mode 100644 msautotest/api/expected/ogcapi_collections_tanzania2_items.html create mode 100644 msautotest/api/expected/ogcapi_collections_tanzania2_items.json diff --git a/mapogcapi.cpp b/mapogcapi.cpp index 3c136037fc..28178f2812 100644 --- a/mapogcapi.cpp +++ b/mapogcapi.cpp @@ -709,9 +709,18 @@ static json getCollection(mapObj *map, layerObj *layer, OGCAPIFormat format) static void outputJson(const json& j, const char *mimetype) { + std::string js; + + try { + js = j.dump(); + } catch (...) { + outputError(OGCAPI_CONFIG_ERROR, "Invalid UTF-8 data, check encoding."); + return; + } + msIO_setHeader("Content-Type", "%s", mimetype); msIO_sendHeaders(); - msIO_printf("%s\n", j.dump().c_str()); + msIO_printf("%s\n", js.c_str()); } static void outputTemplate(const char *directory, const char *filename, const json& j, const char *mimetype) @@ -720,8 +729,6 @@ static void outputTemplate(const char *directory, const char *filename, const js std::string _filename(filename); Environment env {_directory}; // catch - // somehow need to limit include processing to the directory - // ERB-style instead of Mustache (we'll see) // env.set_expression("<%=", "%>"); // env.set_statement("<%", "%>"); @@ -731,6 +738,13 @@ static void outputTemplate(const char *directory, const char *filename, const js // - contains (substring) // - URL encode + try { + std::string js = j.dump(); + } catch (...) { + outputError(OGCAPI_CONFIG_ERROR, "Invalid UTF-8 data, check encoding."); + return; + } + try { Template t = env.parse_template(_filename); // catch std::string result = env.render(t, j); diff --git a/msautotest/api/6631.map b/msautotest/api/6631.map new file mode 100644 index 0000000000..cd1252ba41 --- /dev/null +++ b/msautotest/api/6631.map @@ -0,0 +1,69 @@ +# RUN_PARMS: ogcapi_collections_tanzania1_items.json.txt [MAPSERV] "PATH_INFO=/[MAPFILE]/ogcapi/collections/tanzania1/items" "QUERY_STRING=f=json" > [RESULT_DEMIME] +# RUN_PARMS: ogcapi_collections_tanzania2_items.json [MAPSERV] "PATH_INFO=/[MAPFILE]/ogcapi/collections/tanzania2/items" "QUERY_STRING=f=json" > [RESULT_DEMIME] +# RUN_PARMS: ogcapi_collections_tanzania1_items.html.txt [MAPSERV] "PATH_INFO=/[MAPFILE]/ogcapi/collections/tanzania1/items" "QUERY_STRING=f=html" > [RESULT_DEMIME] +# RUN_PARMS: ogcapi_collections_tanzania2_items.html [MAPSERV] "PATH_INFO=/[MAPFILE]/ogcapi/collections/tanzania2/items" "QUERY_STRING=f=html" > [RESULT_DEMIME] + +MAP + EXTENT 29.339998 -11.720938 40.316590 -0.950000 + SIZE 800 800 + + PROJECTION "+init=epsg:4326" END + UNITS METERS + + WEB + METADATA + "oga_html_template_directory" "../../share/ogcapi/templates/html-plain/" + "oga_title" "Issue #6631" ## REQUIRED + "oga_description" "This is a test OGC API server description for issue #6631." + "oga_contactperson" "Contact person" + "oga_contacturl" "http://example.com/contact" + "oga_contactelectronicmailaddress" "email@example.com" + "oga_termsofservice" "Terms of Service" + "oga_onlineresource" "http://localhost/cgi-bin/mapserv/6631/ogcapi" ## REQUIRED + "oga_server_description" "Server description" + "oga_enable_request" "OGCAPI" ## REQUIRED + "oga_geometry_precision" "4" + "oga_compliance_mode" "true" + END + END + + LAYER + NAME "tanzania1" + DATA "data/countries-tanzania" + TYPE POLYGON + STATUS OFF + METADATA + "oga_keywords" "boundary,Tanzania" # falls back to wfs_keywordlist + "oga_description" "Tanzania Boundary" + "oga_title" "Tanzania Boundary" + "gml_include_items" "name,nr_id,name_hu" # also works with oga prefix + "oga_featureid" "ne_id" + END + VALIDATION + "ne_id" "^1159321337$" # only one acceptable value + END + PROJECTION "+init=epsg:4326" END + TEMPLATE VOID + END + + LAYER + NAME "tanzania2" + DATA "data/countries-tanzania" + TYPE POLYGON + STATUS OFF + ENCODING "ISO-8859-1" + METADATA + "oga_keywords" "boundary,Tanzania" # falls back to wfs_keywordlist + "oga_description" "Tanzania Boundary" + "oga_title" "Tanzania Boundary" + "gml_include_items" "name,nr_id,name_hu" # also works with oga prefix + "oga_featureid" "ne_id" + END + VALIDATION + "ne_id" "^1159321337$" # only one acceptable value + END + PROJECTION "+init=epsg:4326" END + TEMPLATE VOID + END + +END diff --git a/msautotest/api/data/countries-tanzania.dbf b/msautotest/api/data/countries-tanzania.dbf new file mode 100755 index 0000000000000000000000000000000000000000..4765712328b8a7b412569ca198369cb75d3603df GIT binary patch literal 309 zcmZQp;FM%!U|?uu*bF4mKsW)f`+8|qOw7&>wYy#vKxPR{!E^k_dSz& zXNDleY~q{6aKB^{1dCpKkg$-)-Yx^@k*MyFePVQkKdhr1+W zDkwI4#?1u_uxL|i=Gb`>UNn!dV&41#>#p0FJ=r8+ue-amF#tir8qVHL^CBo%Jjq8> zNcmK{iRM$*>BuYrYAfmS9trUIoIyCC3Aiv-M*>lwE$MZHVEp6JGL@0mOM+WIF@>o0 zT{b>?js%xA$yPff#Qa*Pu*OD$Fi>Avkr0NQh{zJdI}+4`g5sR$2&|5_|5Z-s_-MtoqD^?+N`h{5W-z8#ggzNpm*0&efkUy_zSTb>6zK)jD-{?$_Wt_g zH2=a`mvK)8c(S83He8Hv+n$Nyb5&p{|2ZyCD#jt}G0h{TYW5xnYECqNXjVe)<}(lb zU9|tVi>B5jB^aum9AJylsFkt%!qx7NJ!&mOw z8L5C_g~+&98j2rR2$J@h<)CR8QS#b^C`{;U_Oi|I`F<~R43dx0F>+AL_!SfBL3mpI zNOQMd23JfzgC+ifxFomW_p(A64BTkoR9XYjboO$8aJdW!amMt*HXeR`$1ii9HhDgA z5zJZA36z13Pem!7aFH766m#3bvcvKF$_1)L@8~iY>JFOo6k8M5&%?C*-aG!k(%e~mm~qe-_iT%;`00=w+IPhBYEqe4^=f{K zmx(@gpq}RBNx^ZURSs1BKSLWf&A~l8rEA;{IVk?@*5gW#Md#CSU}GVzzqLHAO8nY_ jM@mof?$ca4)>XHTvN-H3)6K&QAW9aqxmwEd|NrtY*F&93 literal 0 HcmV?d00001 diff --git a/msautotest/api/data/countries-tanzania.shx b/msautotest/api/data/countries-tanzania.shx new file mode 100755 index 0000000000000000000000000000000000000000..64df1f02c821f945e42f753ab0f06d9727fa1560 GIT binary patch literal 108 zcmZQzQ0HR64$NLKGcd3M + + + Issue #6631 + + + + + +

Issue #6631 - Collection Items: Tanzania Boundary

+ +

+ Number of matching items: 1
+ Number of returned items: 1
+

+ + + + + + + + + + + + + + + + + + + + + + + + +
IDnamename_hu
1159321337TanzaniaTanzánia
+ + + + + + + diff --git a/msautotest/api/expected/ogcapi_collections_tanzania2_items.json b/msautotest/api/expected/ogcapi_collections_tanzania2_items.json new file mode 100644 index 0000000000..8564c39a71 --- /dev/null +++ b/msautotest/api/expected/ogcapi_collections_tanzania2_items.json @@ -0,0 +1 @@ +{"features":[{"geometry":{"coordinates":[[[33.9038,-0.95],[34.0727,-1.0598],[37.6987,-3.0969],[37.7669,-3.6771],[39.2023,-4.6767],[38.7406,-5.9089],[38.7998,-6.4756],[39.44,-6.8399],[39.4701,-7.0999],[39.1947,-7.7038],[39.2521,-8.0078],[39.1866,-8.4855],[39.5358,-9.1123],[39.9497,-10.0984],[40.3166,-10.317],[40.3166,-10.317],[39.521,-10.8968],[38.4276,-11.2852],[37.8277,-11.2687],[37.4713,-11.5687],[36.7752,-11.5945],[36.5141,-11.7209],[35.3124,-11.4391],[34.56,-11.52],[34.28,-10.16],[33.9409,-9.6936],[33.7398,-9.4171],[32.7594,-9.2305],[32.1919,-8.9303],[31.5564,-8.762],[31.1578,-8.5945],[30.7401,-8.34],[30.7401,-8.34],[30.2,-7.0799],[29.6201,-6.52],[29.42,-5.9399],[29.52,-5.4199],[29.34,-4.4999],[29.7536,-4.4523],[30.1164,-4.0901],[30.5056,-3.5685],[30.7523,-3.3593],[30.7431,-3.0343],[30.5277,-2.8076],[30.4697,-2.4138],[30.4697,-2.4138],[30.7584,-2.2872],[30.8162,-1.6989],[30.4192,-1.1346],[30.7699,-1.0145],[31.8662,-1.0273],[33.9038,-0.95]]],"type":"Polygon"},"id":"1159321337","properties":{"name":"Tanzania","name_hu":"Tanzánia"},"type":"Feature"}],"links":[{"href":"http://localhost/cgi-bin/mapserv/6631/ogcapi/collections/tanzania2/items?f=json&limit=10&offset=0","rel":"self","title":"Items for this collection as GeoJSON","type":"application/geo+json"},{"href":"http://localhost/cgi-bin/mapserv/6631/ogcapi/collections/tanzania2/items?f=html&limit=10&offset=0","rel":"alternate","title":"Items for this collection as HTML","type":"text/html"}],"numberMatched":1,"numberReturned":1,"type":"FeatureCollection"} From 0f7e724e4a2e750329e00cdb0782ae4cd71a4d98 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 13:16:42 -0400 Subject: [PATCH 106/170] change migration guide to markdown (#6821) Co-authored-by: Jeff McKenna --- MIGRATION_GUIDE.txt => MIGRATION_GUIDE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename MIGRATION_GUIDE.txt => MIGRATION_GUIDE.md (100%) diff --git a/MIGRATION_GUIDE.txt b/MIGRATION_GUIDE.md similarity index 100% rename from MIGRATION_GUIDE.txt rename to MIGRATION_GUIDE.md From afc7692893a623104c89c95e2632c78b12852130 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 09:58:05 +0100 Subject: [PATCH 107/170] [Backport branch-8-0] Fix GetMetadata possible buffer overrun (#6828) * Fix GetMetadata request * Switch to xmlDocDumpFormatMemoryEnc * Add UTF-8 tag * Add encoding="UTF-8" to expected outputs * Add charset=UTF-8 * Update search for vsnprintf * Update CMakeLists.txt Co-authored-by: Even Rouault * Fix variable name --------- Co-authored-by: sethg Co-authored-by: Seth G Co-authored-by: Even Rouault --- CMakeLists.txt | 8 +++++++- mapmetadata.c | 10 +++++++--- .../mssql/expected/cluster_mssql_getmetadata.xml | 2 +- .../wxs/expected/ows_metadata_empty_layer_param.xml | 4 ++-- .../wxs/expected/ows_metadata_invalid_layer_param.xml | 4 ++-- msautotest/wxs/expected/ows_metadata_layer_raster.xml | 4 ++-- msautotest/wxs/expected/ows_metadata_layer_vector.xml | 4 ++-- .../wxs/expected/ows_metadata_missing_layer_param.xml | 4 ++-- 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 949900c559..02a953a672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}") include(CheckLibraryExists) include(CheckFunctionExists) +include(CheckSymbolExists) include(CheckIncludeFile) include(CheckCSourceCompiles) @@ -119,7 +120,12 @@ check_function_exists("strlcat" HAVE_STRLCAT) check_function_exists("strlcpy" HAVE_STRLCPY) check_function_exists("strlen" HAVE_STRLEN) check_function_exists("strncasecmp" HAVE_STRNCASECMP) -check_function_exists("vsnprintf" HAVE_VSNPRINTF) + +check_symbol_exists(vsnprintf stdio.h HAVE_VSNPRINTF) +IF(NOT HAVE_VSNPRINTF) + check_function_exists("vsnprintf" HAVE_VSNPRINTF) +ENDIF() + check_function_exists("lrintf" HAVE_LRINTF) check_function_exists("lrint" HAVE_LRINT) diff --git a/mapmetadata.c b/mapmetadata.c index 01956e9a02..1bf015f9bd 100644 --- a/mapmetadata.c +++ b/mapmetadata.c @@ -821,11 +821,15 @@ int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) int buffersize = 0; xmlDocSetRootElement(xml_document, psRootNode); - msIO_setHeader("Content-type", "text/xml"); + msIO_setHeader("Content-type", "text/xml; charset=UTF-8"); msIO_sendHeaders(); - xmlDocDumpFormatMemory(xml_document, &xml_buffer, &buffersize, 1); - msIO_printf("%s", (char *) xml_buffer); + msIOContext* context = NULL; + + context = msIO_getHandler(stdout); + + xmlDocDumpFormatMemoryEnc(xml_document, &xml_buffer, &buffersize, "UTF-8", 1); + msIO_contextWrite(context, xml_buffer, buffersize); xmlFree(xml_buffer); } diff --git a/msautotest/mssql/expected/cluster_mssql_getmetadata.xml b/msautotest/mssql/expected/cluster_mssql_getmetadata.xml index ad346c9e40..14bab00ef6 100644 --- a/msautotest/mssql/expected/cluster_mssql_getmetadata.xml +++ b/msautotest/mssql/expected/cluster_mssql_getmetadata.xml @@ -1,4 +1,4 @@ - + cities diff --git a/msautotest/wxs/expected/ows_metadata_empty_layer_param.xml b/msautotest/wxs/expected/ows_metadata_empty_layer_param.xml index 3ffdb516d5..94bd75cda5 100644 --- a/msautotest/wxs/expected/ows_metadata_empty_layer_param.xml +++ b/msautotest/wxs/expected/ows_metadata_empty_layer_param.xml @@ -1,6 +1,6 @@ -Content-type: text/xml +Content-type: text/xml; charset=UTF-8 - + Missing layer parameter diff --git a/msautotest/wxs/expected/ows_metadata_invalid_layer_param.xml b/msautotest/wxs/expected/ows_metadata_invalid_layer_param.xml index a59108e65b..37322cb373 100644 --- a/msautotest/wxs/expected/ows_metadata_invalid_layer_param.xml +++ b/msautotest/wxs/expected/ows_metadata_invalid_layer_param.xml @@ -1,6 +1,6 @@ -Content-type: text/xml +Content-type: text/xml; charset=UTF-8 - + Layer not found diff --git a/msautotest/wxs/expected/ows_metadata_layer_raster.xml b/msautotest/wxs/expected/ows_metadata_layer_raster.xml index f4a63b1da6..a59f055202 100644 --- a/msautotest/wxs/expected/ows_metadata_layer_raster.xml +++ b/msautotest/wxs/expected/ows_metadata_layer_raster.xml @@ -1,6 +1,6 @@ -Content-type: text/xml +Content-type: text/xml; charset=UTF-8 - + toronto diff --git a/msautotest/wxs/expected/ows_metadata_layer_vector.xml b/msautotest/wxs/expected/ows_metadata_layer_vector.xml index 1bb03a2054..2ea7d03630 100644 --- a/msautotest/wxs/expected/ows_metadata_layer_vector.xml +++ b/msautotest/wxs/expected/ows_metadata_layer_vector.xml @@ -1,6 +1,6 @@ -Content-type: text/xml +Content-type: text/xml; charset=UTF-8 - + province diff --git a/msautotest/wxs/expected/ows_metadata_missing_layer_param.xml b/msautotest/wxs/expected/ows_metadata_missing_layer_param.xml index 3ffdb516d5..94bd75cda5 100644 --- a/msautotest/wxs/expected/ows_metadata_missing_layer_param.xml +++ b/msautotest/wxs/expected/ows_metadata_missing_layer_param.xml @@ -1,6 +1,6 @@ -Content-type: text/xml +Content-type: text/xml; charset=UTF-8 - + Missing layer parameter From 86a8540416f55e230fa0fbfdf12baaf39971a8b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 09:59:43 +0100 Subject: [PATCH 108/170] [Backport branch-8-0] Appveyor SDK Update and Fixes (#6829) * Add GDAL_DRIVER_PATH to ensure MSSQL GDAL plugin is available and use new connection string params * Skip failing tests * Add back GetMetadata test * Set proj9.lib * No need to set GDAL_DRIVER_PATH * Update linefeed action to use latest ubuntu --------- Co-authored-by: sethg --- .github/workflows/check-crlf.yml | 2 +- appveyor.yml | 12 ++++++------ msautotest/mssql/cluster_mssql.map | 5 ++++- msautotest/mssql/create_mssql_db.bat | 5 +++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/check-crlf.yml b/.github/workflows/check-crlf.yml index e6ec0e623c..d5b6a81ec8 100644 --- a/.github/workflows/check-crlf.yml +++ b/.github/workflows/check-crlf.yml @@ -8,7 +8,7 @@ on: [push, pull_request] jobs: Check-CRLF: name: verify that only LF linefeeds are used - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - name: Checkout repository contents diff --git a/appveyor.yml b/appveyor.yml index 1da11fe05b..5aac3fc0dc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -80,29 +80,29 @@ build_script: - cd build - set PATH=%BUILD_FOLDER%/build/Release;%SDK_BIN%;%PATH% - set "PROJECT_BINARY_DIR=%BUILD_FOLDER%/build" - - cmake -G "%VS_FULL%" -A %VS_ARCH% .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=%SDK_PREFIX% -DPNG_LIBRARY=%SDK_LIB%/libpng16_static.lib -DHARFBUZZ_INCLUDE_DIR=%SDK_INC%/harfbuzz -DICONV_DLL=%SDK_BIN%/iconv.dll -DFRIBIDI_INCLUDE_DIR=%SDK_INC%/fribidi -DMS_EXTERNAL_LIBS=%SDK_LIB%/harfbuzz.lib;%SDK_LIB%/uriparser.lib -DSVG_LIBRARY=%SDK_LIB%/libsvg.lib -DSVGCAIRO_LIBRARY=%SDK_LIB%/libsvg-cairo.lib -DREGEX_DIR=%REGEX_DIR% -DSWIG_EXECUTABLE=%SWIG_EXECUTABLE% -DPROTOBUFC_COMPILER=%SDK_BIN%/protoc.exe -DPROTOBUFC_LIBRARY=%SDK_LIB%/protobuf-c.lib -DPROTOBUFC_INCLUDE_DIR=%SDK_INC%/protobuf-c -DWITH_CURL=1 -DWITH_KML=1 -DWITH_SVGCAIRO=1 -DWITH_THREAD_SAFETY=1 -DWITH_SOS=1 -DWITH_CLIENT_WFS=1 -DWITH_CLIENT_WMS=1-DWITH_CSHARP=1 -DWITH_PROTOBUFC=1 -DWITH_POSTGIS=0 -DWITH_PERL=0 -DWITH_MSSQL2008=1 -DWITH_PYTHON=1 -DWITH_PHPNG=0 -DWITH_HARFBUZZ=1 -DWITH_PYMAPSCRIPT_ANNOTATIONS=1 -DPROJ_INCLUDE_DIR=%SDK_INC%/proj7 + - cmake -G "%VS_FULL%" -A %VS_ARCH% .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=%SDK_PREFIX% -DPNG_LIBRARY=%SDK_LIB%/libpng16_static.lib -DHARFBUZZ_INCLUDE_DIR=%SDK_INC%/harfbuzz -DICONV_DLL=%SDK_BIN%/iconv.dll -DFRIBIDI_INCLUDE_DIR=%SDK_INC%/fribidi -DMS_EXTERNAL_LIBS=%SDK_LIB%/harfbuzz.lib;%SDK_LIB%/uriparser.lib -DSVG_LIBRARY=%SDK_LIB%/libsvg.lib -DSVGCAIRO_LIBRARY=%SDK_LIB%/libsvg-cairo.lib -DREGEX_DIR=%REGEX_DIR% -DSWIG_EXECUTABLE=%SWIG_EXECUTABLE% -DPROTOBUFC_COMPILER=%SDK_BIN%/protoc.exe -DPROTOBUFC_LIBRARY=%SDK_LIB%/protobuf-c.lib -DPROTOBUFC_INCLUDE_DIR=%SDK_INC%/protobuf-c -DWITH_CURL=1 -DWITH_KML=1 -DWITH_SVGCAIRO=1 -DWITH_THREAD_SAFETY=1 -DWITH_SOS=1 -DWITH_CLIENT_WFS=1 -DWITH_CLIENT_WMS=1-DWITH_CSHARP=1 -DWITH_PROTOBUFC=1 -DWITH_POSTGIS=0 -DWITH_PERL=0 -DWITH_MSSQL2008=1 -DWITH_PYTHON=1 -DWITH_PHPNG=0 -DWITH_HARFBUZZ=1 -DWITH_PYMAPSCRIPT_ANNOTATIONS=1 -DPROJ_INCLUDE_DIR=%SDK_INC%/proj9 -DPROJ_LIBRARY=%SDK_LIB%/proj9.lib - cmake --build . --config Release - cd %BUILD_FOLDER%/build - # set the MapScript custom environment variable for py 3.8 + # set the MapScript custom environment variable for python 3.8+ - set MAPSERVER_DLL_PATH=%BUILD_FOLDER%/build/Release;%SDK_BIN% - - set PROJ_LIB=%SDK_BIN%/proj7/SHARE + - set PROJ_LIB=%SDK_BIN%/proj9/SHARE # check the mapserver exe can run - mapserv -v - cmake --build . --target pythonmapscript-wheel --config Release before_test: - - set PATH=%PATH%;%SDK_BIN%/gdal/apps + - set PATH=%SDK_BIN%/gdal/apps;%PATH%; - cd %BUILD_FOLDER%/msautotest - "./mssql/create_mssql_db.bat" - "%Python_ROOT_DIR%/python -m pip install -U -r requirements.txt" - "%Python_ROOT_DIR%/python -m pip install --no-index --find-links=file://%BUILD_FOLDER%/build/mapscript/python/Release/dist mapscript" test_script: - - set PROJ_LIB=%SDK_BIN%/proj7/SHARE - cd %BUILD_FOLDER%/msautotest/mssql - "%Python_ROOT_DIR%/python run_test.py" - cd %BUILD_FOLDER%/msautotest/mspython - - "%Python_ROOT_DIR%/python run_all_tests.py" + # skip the datum shift test - see #6824 and PROJ9 issue + - "%Python_ROOT_DIR%/python run_all_tests.py -k \"not test_reprojection_rect_and_datum_shift\"" after_test: - cd %BUILD_FOLDER% diff --git a/msautotest/mssql/cluster_mssql.map b/msautotest/mssql/cluster_mssql.map index 006430b0b3..33acda6e84 100644 --- a/msautotest/mssql/cluster_mssql.map +++ b/msautotest/mssql/cluster_mssql.map @@ -9,6 +9,10 @@ MAP NAME 'cluster_mssql' + PROJECTION + "init=epsg:3857" + END + SYMBOL NAME "circle" TYPE ellipse @@ -27,7 +31,6 @@ MAP PROCESSING "CLUSTER_ALGORITHM=SIMPLE" PROCESSING "CLUSTER_GET_ALL_SHAPES=OFF" PROCESSING "CLUSTER_KEEP_LOCATIONS=OFF" - INCLUDE 'include/mssql_connection.map' STATUS ON DATA "ogr_geometry from (select * from cities) as foo USING UNIQUE ogr_fid USING SRID=3857" CLUSTER diff --git a/msautotest/mssql/create_mssql_db.bat b/msautotest/mssql/create_mssql_db.bat index 1e60e5a36d..448d9febe6 100644 --- a/msautotest/mssql/create_mssql_db.bat +++ b/msautotest/mssql/create_mssql_db.bat @@ -1,7 +1,8 @@ set SQLPASSWORD=Password12! set SERVER=(local)\SQL2019 +set MSSQLSPATIAL_USE_BCP=FALSE sqlcmd -S "%SERVER%" -Q "USE [master]; CREATE DATABASE msautotest;" -ogr2ogr -s_srs epsg:26915 -t_srs epsg:26915 -f MSSQLSpatial "MSSQL:server=%SERVER%;database=msautotest;User Id=sa;Password=%SQLPASSWORD%;" "query/data/bdry_counpy2.shp" -nln "bdry_counpy2" -ogr2ogr -s_srs epsg:3857 -t_srs epsg:3857 -f MSSQLSpatial "MSSQL:server=%SERVER%;database=msautotest;User Id=sa;Password=%SQLPASSWORD%;" "renderers/data/cities.shp" -nln "cities" +ogr2ogr -a_srs epsg:26915 -f MSSQLSpatial "MSSQL:server=%SERVER%;database=msautotest;UID=sa;PWD=%SQLPASSWORD%;" "query/data/bdry_counpy2.shp" -nln "bdry_counpy2" +ogr2ogr -a_srs epsg:3857 -f MSSQLSpatial "MSSQL:server=%SERVER%;database=msautotest;UID=sa;PWD=%SQLPASSWORD%;" "renderers/data/cities.shp" -nln "cities" From 61cd4a317e432bbacf11cb6d1ed34d878663d782 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 13:55:14 -0400 Subject: [PATCH 109/170] _msProcessAutoProjection(): fix memleak in error code path (#6832) --- mapproject.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mapproject.c b/mapproject.c index ed24dc397c..3504fe371e 100644 --- a/mapproject.c +++ b/mapproject.c @@ -819,6 +819,7 @@ static int _msProcessAutoProjection(projectionObj *p) int l_pj_errno = proj_context_errno (p->proj_ctx->proj_ctx); msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", "msProcessProjection()", proj_errno_string(l_pj_errno), szProjBuf) ; + msFreeCharArray(args, numargs); return(-1); } #else @@ -828,6 +829,7 @@ static int _msProcessAutoProjection(projectionObj *p) msReleaseLock( TLOCK_PROJ ); msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", "msProcessProjection()", pj_strerrno(*pj_errno_ref), szProjBuf) ; + msFreeCharArray(args, numargs); return(-1); } msReleaseLock( TLOCK_PROJ ); From 2c1afd18dbc6389bc8df596b64083314896037d2 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Tue, 10 Jan 2023 11:44:03 -0400 Subject: [PATCH 110/170] upgrade Travis to test PHP 8.2.x --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 385cf26e6c..5704e801f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,14 +14,14 @@ matrix: - PYTHON_VERSION=3.7.13 - CRYPTOGRAPHY_DONT_BUILD_RUST=1 # to avoid issue when building Cryptography python module (https://travis-ci.com/github/MapServer/MapServer/jobs/482212623) - - php: 8.0 + - php: 8.1 env: - - BUILD_NAME=PHP_8.0 + - BUILD_NAME=PHP_8.1 - PYTHON_VERSION=3.8 - - php: 8.1.12 + - php: 8.2.0 env: - - BUILD_NAME=PHP_8.1 + - BUILD_NAME=PHP_8.2 - PYTHON_VERSION=3.9 cache: From 150bcd13dccacf2d4d152476354809080cc56d82 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Tue, 10 Jan 2023 15:18:58 -0400 Subject: [PATCH 111/170] handle PHP 8.2 error --- ci/travis/before_install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/travis/before_install.sh b/ci/travis/before_install.sh index 4c27cc123b..a9a15c32ca 100755 --- a/ci/travis/before_install.sh +++ b/ci/travis/before_install.sh @@ -15,6 +15,7 @@ sudo apt-get install -y --allow-unauthenticated build-essential protobuf-c-compi sudo apt-get install -y --allow-unauthenticated libmono-system-drawing4.0-cil mono-mcs sudo apt-get install -y --allow-unauthenticated libperl-dev sudo apt-get install -y --allow-unauthenticated openjdk-8-jdk +sudo apt-get install -y --allow-unauthenticated libonig5 #install recent cmake on GH build action if [ -z ${TRAVIS+x} ]; then From a0c117d5ccdfa2cc9111a02f633906c86c42a4a9 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Tue, 10 Jan 2023 16:25:25 -0400 Subject: [PATCH 112/170] correct deprecated warning for PHP 8.2 test --- msautotest/php/reprojectionObjTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msautotest/php/reprojectionObjTest.php b/msautotest/php/reprojectionObjTest.php index b802c34143..54f4ebe00b 100644 --- a/msautotest/php/reprojectionObjTest.php +++ b/msautotest/php/reprojectionObjTest.php @@ -27,7 +27,7 @@ public function setUp(): void public function testReprojectionInstance() { - $this->assertInstanceOf("reprojectionObj", $this->reprojection = new reprojectionObj( $this->sourceProjection, $this->outputProjection )); + $this->assertInstanceOf("reprojectionObj", new reprojectionObj( $this->sourceProjection, $this->outputProjection )); } public function testProjectMethodSpeed() From 3a8e25a494cca3230ead1afd787c7ac4e3d2baae Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Tue, 10 Jan 2023 16:41:35 -0400 Subject: [PATCH 113/170] correct deprecated warning for PHP 8.2 test --- msautotest/php/reprojectionObjTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msautotest/php/reprojectionObjTest.php b/msautotest/php/reprojectionObjTest.php index 54f4ebe00b..c2f3765008 100644 --- a/msautotest/php/reprojectionObjTest.php +++ b/msautotest/php/reprojectionObjTest.php @@ -55,7 +55,7 @@ public function testProjectMethodSpeed() # destroy variables, if not can lead to segmentation fault public function tearDown(): void { - unset($reprojector, $this->reprojection, $this->map, $this->layer, $this->sourceProjection, $this->outputProjection, $point); + unset($reprojector, $this->map, $this->layer, $this->sourceProjection, $this->outputProjection, $point); } } From 747b5d005ca02ce4e95d5c5d368a18a9b7ddd03a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 11:17:00 -0400 Subject: [PATCH 114/170] Fix build issue when abseil-cpp is present (fixes #6822) (#6834) Port of upstream fix in https://github.com/google/flatbuffers/pull/7824 Co-authored-by: Even Rouault --- flatgeobuf/include/flatbuffers/base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatgeobuf/include/flatbuffers/base.h b/flatgeobuf/include/flatbuffers/base.h index 4c9ed9b342..c276236a82 100644 --- a/flatgeobuf/include/flatbuffers/base.h +++ b/flatgeobuf/include/flatbuffers/base.h @@ -236,7 +236,7 @@ namespace flatbuffers { } } #define FLATBUFFERS_HAS_STRING_VIEW 1 // Check for absl::string_view - #elif __has_include("absl/strings/string_view.h") + #elif __has_include("absl/strings/string_view.h") && (__cplusplus >= 201411) #include "absl/strings/string_view.h" namespace mapserver { namespace flatbuffers { From 49cb764a5cd138c1d60a40e3d28d6c048852bab2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 17 Feb 2023 10:07:04 -0400 Subject: [PATCH 115/170] change HISTORY.TXT to markdown (#6836) Co-authored-by: Jeff McKenna --- HISTORY.TXT => HISTORY.md | 9 +++++---- release.sh | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) rename HISTORY.TXT => HISTORY.md (99%) diff --git a/HISTORY.TXT b/HISTORY.md similarity index 99% rename from HISTORY.TXT rename to HISTORY.md index 12b5b1c035..d104673937 100644 --- a/HISTORY.TXT +++ b/HISTORY.md @@ -1,4 +1,3 @@ - MapServer Revision History ========================== @@ -12,6 +11,8 @@ For a complete change history, please see the Git log comments. For more details about recent point releases, please see the online changelog at: https://mapserver.org/development/changelog/ +The online Migration Guide can be found at https://mapserver.org/MIGRATION_GUIDE.html + 8.0.0 release (2022-09-12) -------------------------- @@ -231,7 +232,7 @@ see detailed changelog for other fixes - No other major changes, see detailed changelog for bug fixes 7.2.0-beta1 release (2018-5-9) --------------------- +------------------------------ - Support for Enhanced Layer Metadata Management (RFC82) @@ -331,7 +332,7 @@ see detailed changelog for other fixes - Implementation of offsets on follow labels (#4399) 6.2.0 release (git branch-6-2) 2012/11/14: --------------------------------------------------- +------------------------------------------ - Fix WFS GetFeature result bounds are not written in requested projection (#4494) @@ -361,7 +362,7 @@ see detailed changelog for other fixes - implement OFFSET x -99 on ANGLE FOLLOW labels (#4399) Version 6.2 (beta1: 20120629): -------------------------------------------------- +------------------------------ - Fix WFS filter is produced as non-standard XML (#4171) diff --git a/release.sh b/release.sh index 2a7a0f90a9..5892fc68a7 100755 --- a/release.sh +++ b/release.sh @@ -25,7 +25,7 @@ fi echo "#" echo "# make sure:" echo "# - you are on branch-$ms_version_major-$ms_version_minor" -echo "# - you have edited HISTORY.TXT with changes related to this release" +echo "# - you have edited HISTORY.md with changes related to this release" echo "#" echo "" @@ -38,7 +38,7 @@ else echo "sed -i '/set (MapServer_VERSION_SUFFIX/c\set (MapServer_VERSION_SUFFIX \"\")' CMakeLists.txt" fi -echo "git add HISTORY.TXT CMakeLists.txt" +echo "git add HISTORY.md CMakeLists.txt" echo "git commit -m \"update for $ms_version release\"" echo "git tag -a $tagname -m \"Create $ms_version tag\"" echo "git push origin branch-$ms_version_major-$ms_version_minor --tags" From 3c50207421c9345b5f4f6c60f33d21ba746e886c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:26:57 -0400 Subject: [PATCH 116/170] Don't use deprecated distutils module. (#6840) Co-authored-by: Bas Couwenberg --- mapscript/python/tests/timing/testing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mapscript/python/tests/timing/testing.py b/mapscript/python/tests/timing/testing.py index c10155f436..233716b427 100644 --- a/mapscript/python/tests/timing/testing.py +++ b/mapscript/python/tests/timing/testing.py @@ -39,7 +39,7 @@ import os import sys -import distutils.util +import sysconfig import unittest # define the path to mapserver test data @@ -50,7 +50,7 @@ TEST_IMAGE = os.path.join(TESTS_PATH, 'test.png') # Put local build directory on head of python path -platformdir = '-'.join((distutils.util.get_platform(), +platformdir = '-'.join((sysconfig.get_platform(), '.'.join(map(str, sys.version_info[0:2])))) sys.path.insert(0, os.path.join('build', 'lib.' + platformdir)) From 0ec505ae7fa345f7b0728dd5b08bd00e1cfcd017 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 09:39:51 -0400 Subject: [PATCH 117/170] Improve round-trip of mapfiles through mapscript (#6841) --- mapfile.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mapfile.c b/mapfile.c index b70ae99d96..ece1ddd8fa 100755 --- a/mapfile.c +++ b/mapfile.c @@ -2896,8 +2896,9 @@ void writeStyle(FILE *stream, int indent, styleObj *style) writeAttributeBinding(stream, indent, "WIDTH", &(style->bindings[MS_STYLE_BINDING_WIDTH])); else writeNumber(stream, indent, "WIDTH", 1, style->width); - if(style->rangeitem) { - writeString(stream, indent, "RANGEITEM", NULL, style->rangeitem); + writeString(stream, indent, "RANGEITEM", NULL, style->rangeitem); + /* If COLORRANGE is valid, assume DATARANGE also needs to be written */ + if(MS_VALID_COLOR(style->mincolor) && MS_VALID_COLOR(style->maxcolor)) { writeColorRange(stream, indent, "COLORRANGE", &(style->mincolor), &(style->maxcolor)); writeDoubleRange(stream, indent, "DATARANGE", style->minvalue, style->maxvalue); } @@ -4477,7 +4478,7 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) indent++; writeBlockBegin(stream, indent, "LAYER"); - /* bindvals */ + writeHashTable(stream, indent, "BINDVALS", &(layer->bindvals)); /* class - see below */ writeString(stream, indent, "CLASSGROUP", NULL, layer->classgroup); writeString(stream, indent, "CLASSITEM", NULL, layer->classitem); @@ -4536,6 +4537,8 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeKeyword(stream, indent, "TRANSFORM", layer->transform, 10, MS_FALSE, "FALSE", MS_UL, "UL", MS_UC, "UC", MS_UR, "UR", MS_CL, "CL", MS_CC, "CC", MS_CR, "CR", MS_LL, "LL", MS_LC, "LC", MS_LR, "LR"); writeKeyword(stream, indent, "TYPE", layer->type, 9, MS_LAYER_POINT, "POINT", MS_LAYER_LINE, "LINE", MS_LAYER_POLYGON, "POLYGON", MS_LAYER_RASTER, "RASTER", MS_LAYER_ANNOTATION, "ANNOTATION", MS_LAYER_QUERY, "QUERY", MS_LAYER_CIRCLE, "CIRCLE", MS_LAYER_TILEINDEX, "TILEINDEX", MS_LAYER_CHART, "CHART"); writeKeyword(stream, indent, "UNITS", layer->units, 9, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD", MS_PIXELS, "PIXELS", MS_PERCENTAGES, "PERCENTATGES"); + writeExpression(stream, indent, "UTFDATA", &(layer->utfdata)); + writeString(stream, indent, "UTFITEM", NULL, layer->utfitem); writeHashTable(stream, indent, "VALIDATION", &(layer->validation)); /* write potentially multiply occuring objects last */ From d42a49a5260cb2a608f8832a9dd91d36eecc02f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 11:29:28 -0300 Subject: [PATCH 118/170] appveyor.yml: remove support for testing python 2.7 builds (#6846) Python 2.7 is out-of-life for more than 3 years now... Co-authored-by: Even Rouault --- appveyor.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5aac3fc0dc..328f67939d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,10 +19,6 @@ environment: # VS 2019 VS_VERSION: Visual Studio 16 2019 matrix: - - platform: x86 - Python_ROOT_DIR: c:/python27 - - platform: x64 - Python_ROOT_DIR: c:/python27-x64 - platform: x64 Python_ROOT_DIR: c:/python36-x64 - platform: x64 From ac3107c3592c847696191a317314af0ef7ae12e9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 15 Mar 2023 21:55:34 +0100 Subject: [PATCH 119/170] loadLayer(): fix memory leak in case of error in loadLayerCompositer() Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57056 --- mapfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index ece1ddd8fa..f919d7c1a7 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4034,7 +4034,7 @@ int loadLayer(layerObj *layer, mapObj *map) LayerCompositer *compositer = msSmallMalloc(sizeof(LayerCompositer)); initLayerCompositer(compositer); if(MS_FAILURE == loadLayerCompositer(compositer)) { - msFree(compositer); + freeLayerCompositer(compositer); return -1; } if(!layer->compositer) { From 9c5e0cb3a38c1fe6501d823c40350ca9170ca7be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 13:44:14 -0300 Subject: [PATCH 120/170] loadLayerCompositer(): fix memleak in error code paths (#6851) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57261 The manual cleanup that was done was incomplete (it should have called freeCompositingFilter()), and it is actually useless as the caller loadLayer() takes care of cleaning. Co-authored-by: Even Rouault --- mapfile.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/mapfile.c b/mapfile.c index f919d7c1a7..f3d63a3eb8 100755 --- a/mapfile.c +++ b/mapfile.c @@ -3963,11 +3963,6 @@ int loadLayerCompositer(LayerCompositer *compositer) { else { msSetError(MS_PARSEERR,"Unknown COMPOP \"%s\"", "loadLayerCompositer()", compop); free(compop); - if (compositer->filter) { - msFree(compositer->filter->filter); - msFree(compositer->filter); - compositer->filter=NULL; - } return MS_FAILURE; } free(compop); @@ -3977,21 +3972,11 @@ int loadLayerCompositer(LayerCompositer *compositer) { return MS_SUCCESS; case OPACITY: if (getInteger(&(compositer->opacity), MS_NUM_CHECK_RANGE, 0, 100) == -1) { - if (compositer->filter) { - msFree(compositer->filter->filter); - msFree(compositer->filter); - compositer->filter=NULL; - } msSetError(MS_PARSEERR,"OPACITY must be between 0 and 100 (line %d)","loadLayerCompositer()",msyylineno); return MS_FAILURE; } break; default: - if (compositer->filter) { - msFree(compositer->filter->filter); - msFree(compositer->filter); - compositer->filter=NULL; - } msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", "loadLayerCompositer()", msyystring_buffer, msyylineno ); return(MS_FAILURE); } From 8a9aebdf7912f02cbb2108064e357264997b3b2a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 9 Apr 2023 11:06:12 -0300 Subject: [PATCH 121/170] Force HTTP/1.1 for tests that query demo.mapserver.org to workaround current issue with it (#6858) Co-authored-by: Even Rouault --- maphttp.c | 9 +++++++++ msautotest/etc/mapserv.conf | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/maphttp.c b/maphttp.c index 8e6f9bc59a..50a9bd5314 100644 --- a/maphttp.c +++ b/maphttp.c @@ -484,6 +484,8 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, msDebug("Using CURL_CA_BUNDLE=%s\n", pszCurlCABundle); } + const char* pszHttpVersion = CPLGetConfigOption("CURL_HTTP_VERSION", NULL); + /* Alloc a curl-multi handle, and add a curl-easy handle to it for each * file to download. */ @@ -545,6 +547,13 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, unchecked_curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS ); + if (pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0) + unchecked_curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_1_0); + else if (pszHttpVersion && strcmp(pszHttpVersion, "1.1") == 0) + unchecked_curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_1_1); + /* Set User-Agent (auto-generate if not set by caller */ if (pasReqInfo[i].pszUserAgent == NULL) { curl_version_info_data *psCurlVInfo; diff --git a/msautotest/etc/mapserv.conf b/msautotest/etc/mapserv.conf index 4366acbda4..4923f4c8a9 100644 --- a/msautotest/etc/mapserv.conf +++ b/msautotest/etc/mapserv.conf @@ -2,6 +2,10 @@ CONFIG ENV MS_MAP_PATTERN "." MS_CONTEXT_PATTERN "ows_context\.xml" + + # Workaround current issues with demo.mapserver.org with HTTP/2 + CURL_HTTP_VERSION "1.1" + END # following used by the mssql tests on Appveyor PLUGINS From b046ab510bdb270cb7553bd0fe1902e4349e9a75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 9 Apr 2023 11:06:48 -0300 Subject: [PATCH 122/170] [Backport branch-8-0] fix write of CONNECTIONOPTIONS (fixes #6852) (#6856) * fix write of CONNECTIONOPTIONS --- mapcopy.c | 1 + mapfile.c | 2 +- mapscript/swiginc/class.i | 8 +++++++- mapscript/swiginc/layer.i | 4 ++++ mapscript/swiginc/map.i | 4 ++-- mapscript/swiginc/shape.i | 8 +++++++- mapscript/swiginc/style.i | 8 +++++++- 7 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mapcopy.c b/mapcopy.c index 18a8bb2703..8a31fe6206 100755 --- a/mapcopy.c +++ b/mapcopy.c @@ -1121,6 +1121,7 @@ int msCopyLayer(layerObj *dst, const layerObj *src) msCopyHashTable(&(dst->metadata), &(src->metadata)); } msCopyHashTable(&dst->validation,&src->validation); + msCopyHashTable(&dst->connectionoptions,&src->connectionoptions); MS_COPYSTELEM(debug); diff --git a/mapfile.c b/mapfile.c index f3d63a3eb8..7ebba00b06 100755 --- a/mapfile.c +++ b/mapfile.c @@ -4471,7 +4471,7 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeLayerCompositer(stream, indent, layer->compositer); writeString(stream, indent, "CONNECTION", NULL, layer->connection); writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 12, MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, "CONTOUR", MS_KERNELDENSITY, "KERNELDENSITY", MS_IDW, "IDW", MS_FLATGEOBUF, "FLATGEOBUF"); - writeHashTableInline(stream, indent, "CONNECTIONOPTIONS", &(layer->connectionoptions)); + writeHashTable(stream, indent, "CONNECTIONOPTIONS", &(layer->connectionoptions)); writeString(stream, indent, "DATA", NULL, layer->data); writeNumber(stream, indent, "DEBUG", 0, layer->debug); /* is this right? see loadLayer() */ writeString(stream, indent, "ENCODING", NULL, layer->encoding); diff --git a/mapscript/swiginc/class.i b/mapscript/swiginc/class.i index 310497cf78..b3d9362c4f 100644 --- a/mapscript/swiginc/class.i +++ b/mapscript/swiginc/class.i @@ -96,7 +96,13 @@ classObj *cloneClass() #else %newobject clone; - /// Return an independent copy of the class without a parent layer + /** + Return an independent copy of the class without a parent layer + + .. note:: + + In the Java & PHP modules this method is named ``cloneClass``. + */ classObj *clone() #endif { diff --git a/mapscript/swiginc/layer.i b/mapscript/swiginc/layer.i index ab1c591088..eb563082ec 100644 --- a/mapscript/swiginc/layer.i +++ b/mapscript/swiginc/layer.i @@ -103,6 +103,10 @@ %newobject clone; /** Return an independent copy of the layer with no parent map. + + .. note:: + + In the Java & PHP modules this method is named ``cloneLayer``. */ layerObj *clone() #endif diff --git a/mapscript/swiginc/map.i b/mapscript/swiginc/map.i index 973b51e9e7..4b794a1bb2 100644 --- a/mapscript/swiginc/map.i +++ b/mapscript/swiginc/map.i @@ -74,11 +74,11 @@ #else %newobject clone; /** - Returns a independent copy of the map, less any caches. + Return an independent copy of the map, less any caches. .. note:: - In the Java module this method is named ``cloneMap``. + In the Java & PHP modules this method is named ``cloneMap``. */ mapObj *clone() #endif diff --git a/mapscript/swiginc/shape.i b/mapscript/swiginc/shape.i index 443a1c4b7e..421483023e 100644 --- a/mapscript/swiginc/shape.i +++ b/mapscript/swiginc/shape.i @@ -119,7 +119,13 @@ shapeObj *cloneShape() #else %newobject clone; - /// Return an independent copy of the shape. + /** + Return an independent copy of the shape. + + .. note:: + + In the Java & PHP modules this method is named ``cloneShape``. + */ shapeObj *clone() #endif { diff --git a/mapscript/swiginc/style.i b/mapscript/swiginc/style.i index 174f5b8f21..933e2a0192 100644 --- a/mapscript/swiginc/style.i +++ b/mapscript/swiginc/style.i @@ -95,7 +95,13 @@ styleObj *cloneStyle() #else %newobject clone; - /// Returns an independent copy of the style with no parent class. + /** + Return an independent copy of the style with no parent class. + + .. note:: + + In the Java & PHP modules this method is named ``cloneStyle``. + */ styleObj *clone() #endif { From e3ca3cb2007c494d7dec8aec0e6443abd5ce62a2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 8 Apr 2023 13:18:50 +0200 Subject: [PATCH 123/170] mapfile parser: fix double-free when included file doesn't exist Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57788 --- maplexer.c | 8 ++++---- maplexer.l | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/maplexer.c b/maplexer.c index b128d98cb2..5148de7ced 100644 --- a/maplexer.c +++ b/maplexer.c @@ -4418,10 +4418,6 @@ YY_RULE_SETUP return(-1); } - include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */ - include_lineno[include_stack_ptr] = msyylineno; - include_stack_ptr++; - msyyin = fopen(msBuildPath(path, msyybasepath, msyytext), "r"); if(!msyyin) { msSetError(MS_IOERR, "Error opening included file \"%s\".", "msyylex()", msyytext); @@ -4429,6 +4425,10 @@ YY_RULE_SETUP return(-1); } + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */ + include_lineno[include_stack_ptr] = msyylineno; + include_stack_ptr++; + msyy_switch_to_buffer( msyy_create_buffer(msyyin, YY_BUF_SIZE) ); msyylineno = 1; diff --git a/maplexer.l b/maplexer.l index 7a67479c40..bc37858571 100644 --- a/maplexer.l +++ b/maplexer.l @@ -655,10 +655,6 @@ char path[MS_MAXPATHLEN]; return(-1); } - include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */ - include_lineno[include_stack_ptr] = msyylineno; - include_stack_ptr++; - msyyin = fopen(msBuildPath(path, msyybasepath, msyytext), "r"); if(!msyyin) { msSetError(MS_IOERR, "Error opening included file \"%s\".", "msyylex()", msyytext); @@ -666,6 +662,10 @@ char path[MS_MAXPATHLEN]; return(-1); } + include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; /* save state */ + include_lineno[include_stack_ptr] = msyylineno; + include_stack_ptr++; + msyy_switch_to_buffer( msyy_create_buffer(msyyin, YY_BUF_SIZE) ); msyylineno = 1; From c83dc1574e4998fad3cc779a3ab3e0f7fa08fffe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 13:19:02 -0300 Subject: [PATCH 124/170] maplexer: avoid call to exit(1) when read error in parser file (#6861) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52125 Co-authored-by: Even Rouault --- maplexer.c | 739 +++++++++++++++++++++++++++------------------------- maplexer.l | 35 +++ mapsymbol.c | 3 +- 3 files changed, 424 insertions(+), 353 deletions(-) diff --git a/maplexer.c b/maplexer.c index 5148de7ced..b27c9dd370 100644 --- a/maplexer.c +++ b/maplexer.c @@ -2212,6 +2212,41 @@ int msyylineno = 1; #define YY_NO_INPUT +/* Below is a redefinition of the default YY_INPUT() macro but replacing the + * YY_FATAL_ERROR() macro with a call to msSetError(). + */ +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + msSetError(MS_PARSEERR, "%s", "msyyparse()", "input in flex scanner failed"); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + msSetError(MS_PARSEERR, "%s", "msyyparse()", "input in flex scanner failed"); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + } + int msyysource=MS_STRING_TOKENS; double msyynumber; int msyystate=MS_TOKENIZE_DEFAULT; @@ -2248,9 +2283,9 @@ int include_lineno[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; char path[MS_MAXPATHLEN]; -#line 2252 "/home/even/mapserver/mapserver/maplexer.c" +#line 2287 "/home/even/mapserver/mapserver/maplexer.c" -#line 2254 "/home/even/mapserver/mapserver/maplexer.c" +#line 2289 "/home/even/mapserver/mapserver/maplexer.c" #define INITIAL 0 #define EXPRESSION_STRING 1 @@ -2464,9 +2499,9 @@ YY_DECL } { -#line 88 "maplexer.l" +#line 123 "maplexer.l" -#line 90 "maplexer.l" +#line 125 "maplexer.l" if (msyystring_buffer == NULL) { msyystring_buffer_size = 256; @@ -2530,7 +2565,7 @@ YY_DECL break; } -#line 2534 "/home/even/mapserver/mapserver/maplexer.c" +#line 2569 "/home/even/mapserver/mapserver/maplexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -2585,1599 +2620,1599 @@ YY_DECL case 1: YY_RULE_SETUP -#line 153 "maplexer.l" +#line 188 "maplexer.l" ; YY_BREAK case 2: YY_RULE_SETUP -#line 155 "maplexer.l" +#line 190 "maplexer.l" { if (msyyreturncomments) return(MS_COMMENT); } YY_BREAK case 3: YY_RULE_SETUP -#line 157 "maplexer.l" +#line 192 "maplexer.l" { BEGIN(MULTILINE_COMMENT); } YY_BREAK case 4: YY_RULE_SETUP -#line 158 "maplexer.l" +#line 193 "maplexer.l" { BEGIN(INITIAL); } YY_BREAK case 5: YY_RULE_SETUP -#line 159 "maplexer.l" +#line 194 "maplexer.l" ; YY_BREAK case 6: YY_RULE_SETUP -#line 160 "maplexer.l" +#line 195 "maplexer.l" ; YY_BREAK case 7: /* rule 7 can match eol */ YY_RULE_SETUP -#line 161 "maplexer.l" +#line 196 "maplexer.l" { msyylineno++; } YY_BREAK case 8: YY_RULE_SETUP -#line 163 "maplexer.l" +#line 198 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION); } YY_BREAK case 9: YY_RULE_SETUP -#line 164 "maplexer.l" +#line 199 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_ENV); } YY_BREAK case 10: YY_RULE_SETUP -#line 165 "maplexer.l" +#line 200 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_MAPS); } YY_BREAK case 11: YY_RULE_SETUP -#line 166 "maplexer.l" +#line 201 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONFIG_SECTION_PLUGINS) } YY_BREAK case 12: YY_RULE_SETUP -#line 168 "maplexer.l" +#line 203 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_OR); } YY_BREAK case 13: YY_RULE_SETUP -#line 169 "maplexer.l" +#line 204 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_AND); } YY_BREAK case 14: YY_RULE_SETUP -#line 170 "maplexer.l" +#line 205 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_LOGICAL_NOT); } YY_BREAK case 15: YY_RULE_SETUP -#line 171 "maplexer.l" +#line 206 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_EQ); } YY_BREAK case 16: YY_RULE_SETUP -#line 172 "maplexer.l" +#line 207 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_NE); } YY_BREAK case 17: YY_RULE_SETUP -#line 173 "maplexer.l" +#line 208 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_GT); } YY_BREAK case 18: YY_RULE_SETUP -#line 174 "maplexer.l" +#line 209 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_LT); } YY_BREAK case 19: YY_RULE_SETUP -#line 175 "maplexer.l" +#line 210 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_GE); } YY_BREAK case 20: YY_RULE_SETUP -#line 176 "maplexer.l" +#line 211 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_LE); } YY_BREAK case 21: YY_RULE_SETUP -#line 177 "maplexer.l" +#line 212 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_RE); } YY_BREAK case 22: YY_RULE_SETUP -#line 179 "maplexer.l" +#line 214 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IEQ); } YY_BREAK case 23: YY_RULE_SETUP -#line 180 "maplexer.l" +#line 215 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IRE); } YY_BREAK case 24: YY_RULE_SETUP -#line 182 "maplexer.l" +#line 217 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_IN); /* was IN */ } YY_BREAK case 25: YY_RULE_SETUP -#line 184 "maplexer.l" +#line 219 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_AREA); } YY_BREAK case 26: YY_RULE_SETUP -#line 185 "maplexer.l" +#line 220 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_LENGTH); } YY_BREAK case 27: YY_RULE_SETUP -#line 186 "maplexer.l" +#line 221 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_TOSTRING); } YY_BREAK case 28: YY_RULE_SETUP -#line 187 "maplexer.l" +#line 222 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_COMMIFY); } YY_BREAK case 29: YY_RULE_SETUP -#line 188 "maplexer.l" +#line 223 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_ROUND); } YY_BREAK case 30: YY_RULE_SETUP -#line 189 "maplexer.l" +#line 224 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_UPPER); } YY_BREAK case 31: YY_RULE_SETUP -#line 190 "maplexer.l" +#line 225 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_LOWER); } YY_BREAK case 32: YY_RULE_SETUP -#line 191 "maplexer.l" +#line 226 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_INITCAP); } YY_BREAK case 33: YY_RULE_SETUP -#line 192 "maplexer.l" +#line 227 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_FIRSTCAP); } YY_BREAK case 34: YY_RULE_SETUP -#line 194 "maplexer.l" +#line 229 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_BUFFER); } YY_BREAK case 35: YY_RULE_SETUP -#line 195 "maplexer.l" +#line 230 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_DIFFERENCE); } YY_BREAK case 36: YY_RULE_SETUP -#line 196 "maplexer.l" +#line 231 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SIMPLIFY); } YY_BREAK case 37: YY_RULE_SETUP -#line 197 "maplexer.l" +#line 232 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SIMPLIFYPT); } YY_BREAK case 38: YY_RULE_SETUP -#line 198 "maplexer.l" +#line 233 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_GENERALIZE); } YY_BREAK case 39: YY_RULE_SETUP -#line 199 "maplexer.l" +#line 234 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_SMOOTHSIA); } YY_BREAK case 40: YY_RULE_SETUP -#line 200 "maplexer.l" +#line 235 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_CENTERLINE); } YY_BREAK case 41: YY_RULE_SETUP -#line 201 "maplexer.l" +#line 236 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_DENSIFY); } YY_BREAK case 42: YY_RULE_SETUP -#line 202 "maplexer.l" +#line 237 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_OUTER); } YY_BREAK case 43: YY_RULE_SETUP -#line 203 "maplexer.l" +#line 238 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_INNER); } YY_BREAK case 44: YY_RULE_SETUP -#line 204 "maplexer.l" +#line 239 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_JAVASCRIPT); } YY_BREAK case 45: YY_RULE_SETUP -#line 206 "maplexer.l" +#line 241 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_INTERSECTS); } YY_BREAK case 46: YY_RULE_SETUP -#line 207 "maplexer.l" +#line 242 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_DISJOINT); } YY_BREAK case 47: YY_RULE_SETUP -#line 208 "maplexer.l" +#line 243 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_TOUCHES); } YY_BREAK case 48: YY_RULE_SETUP -#line 209 "maplexer.l" +#line 244 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_OVERLAPS); } YY_BREAK case 49: YY_RULE_SETUP -#line 210 "maplexer.l" +#line 245 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_CROSSES); } YY_BREAK case 50: YY_RULE_SETUP -#line 211 "maplexer.l" +#line 246 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_WITHIN); } YY_BREAK case 51: YY_RULE_SETUP -#line 212 "maplexer.l" +#line 247 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_CONTAINS); } YY_BREAK case 52: YY_RULE_SETUP -#line 213 "maplexer.l" +#line 248 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_EQUALS); } YY_BREAK case 53: YY_RULE_SETUP -#line 214 "maplexer.l" +#line 249 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_BEYOND); } YY_BREAK case 54: YY_RULE_SETUP -#line 215 "maplexer.l" +#line 250 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_DWITHIN); } YY_BREAK case 55: YY_RULE_SETUP -#line 217 "maplexer.l" +#line 252 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_FROMTEXT); } YY_BREAK case 56: YY_RULE_SETUP -#line 219 "maplexer.l" +#line 254 "maplexer.l" { msyynumber=MS_TRUE; return(MS_TOKEN_LITERAL_BOOLEAN); } YY_BREAK case 57: YY_RULE_SETUP -#line 220 "maplexer.l" +#line 255 "maplexer.l" { msyynumber=MS_FALSE; return(MS_TOKEN_LITERAL_BOOLEAN); } YY_BREAK case 58: YY_RULE_SETUP -#line 222 "maplexer.l" +#line 257 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COLORRANGE); } YY_BREAK case 59: YY_RULE_SETUP -#line 223 "maplexer.l" +#line 258 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DATARANGE); } YY_BREAK case 60: YY_RULE_SETUP -#line 224 "maplexer.l" +#line 259 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RANGEITEM); } YY_BREAK case 61: YY_RULE_SETUP -#line 226 "maplexer.l" +#line 261 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ALIGN); } YY_BREAK case 62: YY_RULE_SETUP -#line 227 "maplexer.l" +#line 262 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANCHORPOINT); } YY_BREAK case 63: YY_RULE_SETUP -#line 228 "maplexer.l" +#line 263 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANGLE); } YY_BREAK case 64: YY_RULE_SETUP -#line 229 "maplexer.l" +#line 264 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ANTIALIAS); } YY_BREAK case 65: YY_RULE_SETUP -#line 230 "maplexer.l" +#line 265 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BACKGROUNDCOLOR); } YY_BREAK case 66: YY_RULE_SETUP -#line 231 "maplexer.l" +#line 266 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BANDSITEM); } YY_BREAK case 67: YY_RULE_SETUP -#line 232 "maplexer.l" +#line 267 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BINDVALS); } YY_BREAK case 68: YY_RULE_SETUP -#line 233 "maplexer.l" +#line 268 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BOM); } YY_BREAK case 69: YY_RULE_SETUP -#line 234 "maplexer.l" +#line 269 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BROWSEFORMAT); } YY_BREAK case 70: YY_RULE_SETUP -#line 235 "maplexer.l" +#line 270 "maplexer.l" { MS_LEXER_RETURN_TOKEN(BUFFER); } YY_BREAK case 71: YY_RULE_SETUP -#line 236 "maplexer.l" +#line 271 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CHARACTER); } YY_BREAK case 72: YY_RULE_SETUP -#line 237 "maplexer.l" +#line 272 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASS); } YY_BREAK case 73: YY_RULE_SETUP -#line 238 "maplexer.l" +#line 273 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASSITEM); } YY_BREAK case 74: YY_RULE_SETUP -#line 239 "maplexer.l" +#line 274 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLASSGROUP); } YY_BREAK case 75: YY_RULE_SETUP -#line 240 "maplexer.l" +#line 275 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CLUSTER); } YY_BREAK case 76: YY_RULE_SETUP -#line 241 "maplexer.l" +#line 276 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COLOR); } YY_BREAK case 77: YY_RULE_SETUP -#line 242 "maplexer.l" +#line 277 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPFILTER); } YY_BREAK case 78: YY_RULE_SETUP -#line 243 "maplexer.l" +#line 278 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPOSITE); } YY_BREAK case 79: YY_RULE_SETUP -#line 244 "maplexer.l" +#line 279 "maplexer.l" { MS_LEXER_RETURN_TOKEN(COMPOP); } YY_BREAK case 80: YY_RULE_SETUP -#line 245 "maplexer.l" +#line 280 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONFIG); } YY_BREAK case 81: YY_RULE_SETUP -#line 246 "maplexer.l" +#line 281 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTION); } YY_BREAK case 82: YY_RULE_SETUP -#line 247 "maplexer.l" +#line 282 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTIONTYPE); } YY_BREAK case 83: YY_RULE_SETUP -#line 248 "maplexer.l" +#line 283 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DATA); } YY_BREAK case 84: YY_RULE_SETUP -#line 249 "maplexer.l" +#line 284 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DEBUG); } YY_BREAK case 85: YY_RULE_SETUP -#line 250 "maplexer.l" +#line 285 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DRIVER); } YY_BREAK case 86: YY_RULE_SETUP -#line 251 "maplexer.l" +#line 286 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EMPTY); } YY_BREAK case 87: YY_RULE_SETUP -#line 252 "maplexer.l" +#line 287 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ENCODING); } YY_BREAK case 88: YY_RULE_SETUP -#line 253 "maplexer.l" +#line 288 "maplexer.l" { MS_LEXER_RETURN_TOKEN(END); } YY_BREAK case 89: YY_RULE_SETUP -#line 254 "maplexer.l" +#line 289 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ERROR); } YY_BREAK case 90: YY_RULE_SETUP -#line 255 "maplexer.l" +#line 290 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXPRESSION); } YY_BREAK case 91: YY_RULE_SETUP -#line 256 "maplexer.l" +#line 291 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXTENT); } YY_BREAK case 92: YY_RULE_SETUP -#line 257 "maplexer.l" +#line 292 "maplexer.l" { MS_LEXER_RETURN_TOKEN(EXTENSION); } YY_BREAK case 93: YY_RULE_SETUP -#line 258 "maplexer.l" +#line 293 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FEATURE); } YY_BREAK case 94: YY_RULE_SETUP -#line 259 "maplexer.l" +#line 294 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILLED); } YY_BREAK case 95: YY_RULE_SETUP -#line 260 "maplexer.l" +#line 295 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILTER); } YY_BREAK case 96: YY_RULE_SETUP -#line 261 "maplexer.l" +#line 296 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FILTERITEM); } YY_BREAK case 97: YY_RULE_SETUP -#line 262 "maplexer.l" +#line 297 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FOOTER); } YY_BREAK case 98: YY_RULE_SETUP -#line 263 "maplexer.l" +#line 298 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FONT); } YY_BREAK case 99: YY_RULE_SETUP -#line 264 "maplexer.l" +#line 299 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FONTSET); } YY_BREAK case 100: YY_RULE_SETUP -#line 265 "maplexer.l" +#line 300 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FORCE); } YY_BREAK case 101: YY_RULE_SETUP -#line 266 "maplexer.l" +#line 301 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FORMATOPTION); } YY_BREAK case 102: YY_RULE_SETUP -#line 267 "maplexer.l" +#line 302 "maplexer.l" { MS_LEXER_RETURN_TOKEN(FROM); } YY_BREAK case 103: YY_RULE_SETUP -#line 268 "maplexer.l" +#line 303 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GAP); } YY_BREAK case 104: YY_RULE_SETUP -#line 269 "maplexer.l" +#line 304 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GEOMTRANSFORM); } YY_BREAK case 105: YY_RULE_SETUP -#line 270 "maplexer.l" +#line 305 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRID); } YY_BREAK case 106: YY_RULE_SETUP -#line 271 "maplexer.l" +#line 306 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRIDSTEP); } YY_BREAK case 107: YY_RULE_SETUP -#line 272 "maplexer.l" +#line 307 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GRATICULE); } YY_BREAK case 108: YY_RULE_SETUP -#line 273 "maplexer.l" +#line 308 "maplexer.l" { MS_LEXER_RETURN_TOKEN(GROUP); } YY_BREAK case 109: YY_RULE_SETUP -#line 274 "maplexer.l" +#line 309 "maplexer.l" { MS_LEXER_RETURN_TOKEN(HEADER); } YY_BREAK case 110: YY_RULE_SETUP -#line 275 "maplexer.l" +#line 310 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGE); } YY_BREAK case 111: YY_RULE_SETUP -#line 276 "maplexer.l" +#line 311 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGECOLOR); } YY_BREAK case 112: YY_RULE_SETUP -#line 277 "maplexer.l" +#line 312 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGETYPE); } YY_BREAK case 113: YY_RULE_SETUP -#line 278 "maplexer.l" +#line 313 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEMODE); } YY_BREAK case 114: YY_RULE_SETUP -#line 279 "maplexer.l" +#line 314 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEPATH); } YY_BREAK case 115: YY_RULE_SETUP -#line 280 "maplexer.l" +#line 315 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEMPPATH); } YY_BREAK case 116: YY_RULE_SETUP -#line 281 "maplexer.l" +#line 316 "maplexer.l" { MS_LEXER_RETURN_TOKEN(IMAGEURL); } YY_BREAK case 117: YY_RULE_SETUP -#line 282 "maplexer.l" +#line 317 "maplexer.l" { BEGIN(INCLUDE); } YY_BREAK case 118: YY_RULE_SETUP -#line 283 "maplexer.l" +#line 318 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INDEX); } YY_BREAK case 119: YY_RULE_SETUP -#line 284 "maplexer.l" +#line 319 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INITIALGAP); } YY_BREAK case 120: YY_RULE_SETUP -#line 285 "maplexer.l" +#line 320 "maplexer.l" { MS_LEXER_RETURN_TOKEN(INTERVALS); } YY_BREAK case 121: YY_RULE_SETUP -#line 286 "maplexer.l" +#line 321 "maplexer.l" { MS_LEXER_RETURN_TOKEN(JOIN); } YY_BREAK case 122: YY_RULE_SETUP -#line 287 "maplexer.l" +#line 322 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYIMAGE); } YY_BREAK case 123: YY_RULE_SETUP -#line 288 "maplexer.l" +#line 323 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYSIZE); } YY_BREAK case 124: YY_RULE_SETUP -#line 289 "maplexer.l" +#line 324 "maplexer.l" { MS_LEXER_RETURN_TOKEN(KEYSPACING); } YY_BREAK case 125: YY_RULE_SETUP -#line 290 "maplexer.l" +#line 325 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABEL); } YY_BREAK case 126: YY_RULE_SETUP -#line 291 "maplexer.l" +#line 326 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELCACHE); } YY_BREAK case 127: YY_RULE_SETUP -#line 292 "maplexer.l" +#line 327 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELFORMAT); } YY_BREAK case 128: YY_RULE_SETUP -#line 293 "maplexer.l" +#line 328 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELITEM); } YY_BREAK case 129: YY_RULE_SETUP -#line 294 "maplexer.l" +#line 329 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMAXSCALE); } YY_BREAK case 130: YY_RULE_SETUP -#line 295 "maplexer.l" +#line 330 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMAXSCALEDENOM); } YY_BREAK case 131: YY_RULE_SETUP -#line 296 "maplexer.l" +#line 331 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMINSCALE); } YY_BREAK case 132: YY_RULE_SETUP -#line 297 "maplexer.l" +#line 332 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELMINSCALEDENOM); } YY_BREAK case 133: YY_RULE_SETUP -#line 298 "maplexer.l" +#line 333 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LABELREQUIRES); } YY_BREAK case 134: YY_RULE_SETUP -#line 299 "maplexer.l" +#line 334 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LATLON); } YY_BREAK case 135: YY_RULE_SETUP -#line 300 "maplexer.l" +#line 335 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LAYER); } YY_BREAK case 136: YY_RULE_SETUP -#line 301 "maplexer.l" +#line 336 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEADER); } YY_BREAK case 137: YY_RULE_SETUP -#line 302 "maplexer.l" +#line 337 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEGEND); } YY_BREAK case 138: YY_RULE_SETUP -#line 303 "maplexer.l" +#line 338 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LEGENDFORMAT); } YY_BREAK case 139: YY_RULE_SETUP -#line 304 "maplexer.l" +#line 339 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINECAP); } YY_BREAK case 140: YY_RULE_SETUP -#line 305 "maplexer.l" +#line 340 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINEJOIN); } YY_BREAK case 141: YY_RULE_SETUP -#line 306 "maplexer.l" +#line 341 "maplexer.l" { MS_LEXER_RETURN_TOKEN(LINEJOINMAXSIZE); } YY_BREAK case 142: YY_RULE_SETUP -#line 307 "maplexer.l" +#line 342 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAP); } YY_BREAK case 143: YY_RULE_SETUP -#line 308 "maplexer.l" +#line 343 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MARKER); } YY_BREAK case 144: YY_RULE_SETUP -#line 309 "maplexer.l" +#line 344 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MARKERSIZE); } YY_BREAK case 145: YY_RULE_SETUP -#line 310 "maplexer.l" +#line 345 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MASK); } YY_BREAK case 146: YY_RULE_SETUP -#line 311 "maplexer.l" +#line 346 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXARCS); } YY_BREAK case 147: YY_RULE_SETUP -#line 312 "maplexer.l" +#line 347 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXBOXSIZE); } YY_BREAK case 148: YY_RULE_SETUP -#line 313 "maplexer.l" +#line 348 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXDISTANCE); } YY_BREAK case 149: YY_RULE_SETUP -#line 314 "maplexer.l" +#line 349 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXFEATURES); } YY_BREAK case 150: YY_RULE_SETUP -#line 315 "maplexer.l" +#line 350 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXINTERVAL); } YY_BREAK case 151: YY_RULE_SETUP -#line 316 "maplexer.l" +#line 351 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSCALE); } YY_BREAK case 152: YY_RULE_SETUP -#line 317 "maplexer.l" +#line 352 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSCALEDENOM); } YY_BREAK case 153: YY_RULE_SETUP -#line 318 "maplexer.l" +#line 353 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXGEOWIDTH); } YY_BREAK case 154: YY_RULE_SETUP -#line 319 "maplexer.l" +#line 354 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXLENGTH); } YY_BREAK case 155: YY_RULE_SETUP -#line 320 "maplexer.l" +#line 355 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSIZE); } YY_BREAK case 156: YY_RULE_SETUP -#line 321 "maplexer.l" +#line 356 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXSUBDIVIDE); } YY_BREAK case 157: YY_RULE_SETUP -#line 322 "maplexer.l" +#line 357 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXTEMPLATE); } YY_BREAK case 158: YY_RULE_SETUP -#line 323 "maplexer.l" +#line 358 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXWIDTH); } YY_BREAK case 159: YY_RULE_SETUP -#line 324 "maplexer.l" +#line 359 "maplexer.l" { MS_LEXER_RETURN_TOKEN(METADATA); } YY_BREAK case 160: YY_RULE_SETUP -#line 325 "maplexer.l" +#line 360 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MIMETYPE); } YY_BREAK case 161: YY_RULE_SETUP -#line 326 "maplexer.l" +#line 361 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINARCS); } YY_BREAK case 162: YY_RULE_SETUP -#line 327 "maplexer.l" +#line 362 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINBOXSIZE); } YY_BREAK case 163: YY_RULE_SETUP -#line 328 "maplexer.l" +#line 363 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINDISTANCE); } YY_BREAK case 164: YY_RULE_SETUP -#line 329 "maplexer.l" +#line 364 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REPEATDISTANCE); } YY_BREAK case 165: YY_RULE_SETUP -#line 330 "maplexer.l" +#line 365 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MAXOVERLAPANGLE); } YY_BREAK case 166: YY_RULE_SETUP -#line 331 "maplexer.l" +#line 366 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINFEATURESIZE); } YY_BREAK case 167: YY_RULE_SETUP -#line 332 "maplexer.l" +#line 367 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MININTERVAL); } YY_BREAK case 168: YY_RULE_SETUP -#line 333 "maplexer.l" +#line 368 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSCALE); } YY_BREAK case 169: YY_RULE_SETUP -#line 334 "maplexer.l" +#line 369 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSCALEDENOM); } YY_BREAK case 170: YY_RULE_SETUP -#line 335 "maplexer.l" +#line 370 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINGEOWIDTH); } YY_BREAK case 171: YY_RULE_SETUP -#line 336 "maplexer.l" +#line 371 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSIZE); } YY_BREAK case 172: YY_RULE_SETUP -#line 337 "maplexer.l" +#line 372 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINSUBDIVIDE); } YY_BREAK case 173: YY_RULE_SETUP -#line 338 "maplexer.l" +#line 373 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINTEMPLATE); } YY_BREAK case 174: YY_RULE_SETUP -#line 339 "maplexer.l" +#line 374 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MINWIDTH); } YY_BREAK case 175: YY_RULE_SETUP -#line 340 "maplexer.l" +#line 375 "maplexer.l" { MS_LEXER_RETURN_TOKEN(NAME); } YY_BREAK case 176: YY_RULE_SETUP -#line 341 "maplexer.l" +#line 376 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OFFSET); } YY_BREAK case 177: YY_RULE_SETUP -#line 342 "maplexer.l" +#line 377 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OFFSITE); } YY_BREAK case 178: YY_RULE_SETUP -#line 343 "maplexer.l" +#line 378 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OPACITY); } YY_BREAK case 179: YY_RULE_SETUP -#line 344 "maplexer.l" +#line 379 "maplexer.l" { MS_LEXER_RETURN_TOKEN(CONNECTIONOPTIONS); } YY_BREAK case 180: YY_RULE_SETUP -#line 345 "maplexer.l" +#line 380 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTLINECOLOR); } YY_BREAK case 181: YY_RULE_SETUP -#line 346 "maplexer.l" +#line 381 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTLINEWIDTH); } YY_BREAK case 182: YY_RULE_SETUP -#line 347 "maplexer.l" +#line 382 "maplexer.l" { MS_LEXER_RETURN_TOKEN(OUTPUTFORMAT); } YY_BREAK case 183: YY_RULE_SETUP -#line 348 "maplexer.l" +#line 383 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PARTIALS); } YY_BREAK case 184: YY_RULE_SETUP -#line 349 "maplexer.l" +#line 384 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PATTERN); } YY_BREAK case 185: YY_RULE_SETUP -#line 350 "maplexer.l" +#line 385 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POINTS); } YY_BREAK case 186: YY_RULE_SETUP -#line 351 "maplexer.l" +#line 386 "maplexer.l" { MS_LEXER_RETURN_TOKEN(ITEMS); } YY_BREAK case 187: YY_RULE_SETUP -#line 352 "maplexer.l" +#line 387 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POSITION); } YY_BREAK case 188: YY_RULE_SETUP -#line 353 "maplexer.l" +#line 388 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POSTLABELCACHE); } YY_BREAK case 189: YY_RULE_SETUP -#line 354 "maplexer.l" +#line 389 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PRIORITY); } YY_BREAK case 190: YY_RULE_SETUP -#line 355 "maplexer.l" +#line 390 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PROCESSING); } YY_BREAK case 191: YY_RULE_SETUP -#line 356 "maplexer.l" +#line 391 "maplexer.l" { MS_LEXER_RETURN_TOKEN(PROJECTION); } YY_BREAK case 192: YY_RULE_SETUP -#line 357 "maplexer.l" +#line 392 "maplexer.l" { MS_LEXER_RETURN_TOKEN(QUERYFORMAT); } YY_BREAK case 193: YY_RULE_SETUP -#line 358 "maplexer.l" +#line 393 "maplexer.l" { MS_LEXER_RETURN_TOKEN(QUERYMAP); } YY_BREAK case 194: YY_RULE_SETUP -#line 359 "maplexer.l" +#line 394 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REFERENCE); } YY_BREAK case 195: YY_RULE_SETUP -#line 360 "maplexer.l" +#line 395 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REGION); } YY_BREAK case 196: YY_RULE_SETUP -#line 361 "maplexer.l" +#line 396 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RELATIVETO); } YY_BREAK case 197: YY_RULE_SETUP -#line 362 "maplexer.l" +#line 397 "maplexer.l" { MS_LEXER_RETURN_TOKEN(REQUIRES); } YY_BREAK case 198: YY_RULE_SETUP -#line 363 "maplexer.l" +#line 398 "maplexer.l" { MS_LEXER_RETURN_TOKEN(RESOLUTION); } YY_BREAK case 199: YY_RULE_SETUP -#line 364 "maplexer.l" +#line 399 "maplexer.l" { MS_LEXER_RETURN_TOKEN(DEFRESOLUTION); } YY_BREAK case 200: YY_RULE_SETUP -#line 365 "maplexer.l" +#line 400 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALE); } YY_BREAK case 201: YY_RULE_SETUP -#line 366 "maplexer.l" +#line 401 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALEDENOM); } YY_BREAK case 202: YY_RULE_SETUP -#line 367 "maplexer.l" +#line 402 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALEBAR); } YY_BREAK case 203: YY_RULE_SETUP -#line 368 "maplexer.l" +#line 403 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SCALETOKEN); } YY_BREAK case 204: YY_RULE_SETUP -#line 369 "maplexer.l" +#line 404 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHADOWCOLOR); } YY_BREAK case 205: YY_RULE_SETUP -#line 370 "maplexer.l" +#line 405 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHADOWSIZE); } YY_BREAK case 206: YY_RULE_SETUP -#line 371 "maplexer.l" +#line 406 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SHAPEPATH); } YY_BREAK case 207: YY_RULE_SETUP -#line 372 "maplexer.l" +#line 407 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SIZE); } YY_BREAK case 208: YY_RULE_SETUP -#line 373 "maplexer.l" +#line 408 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SIZEUNITS); } YY_BREAK case 209: YY_RULE_SETUP -#line 374 "maplexer.l" +#line 409 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STATUS); } YY_BREAK case 210: YY_RULE_SETUP -#line 375 "maplexer.l" +#line 410 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STYLE); } YY_BREAK case 211: YY_RULE_SETUP -#line 376 "maplexer.l" +#line 411 "maplexer.l" { MS_LEXER_RETURN_TOKEN(STYLEITEM); } YY_BREAK case 212: YY_RULE_SETUP -#line 377 "maplexer.l" +#line 412 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOL); } YY_BREAK case 213: YY_RULE_SETUP -#line 378 "maplexer.l" +#line 413 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSCALE); } YY_BREAK case 214: YY_RULE_SETUP -#line 379 "maplexer.l" +#line 414 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSCALEDENOM); } YY_BREAK case 215: YY_RULE_SETUP -#line 380 "maplexer.l" +#line 415 "maplexer.l" { MS_LEXER_RETURN_TOKEN(SYMBOLSET); } YY_BREAK case 216: YY_RULE_SETUP -#line 381 "maplexer.l" +#line 416 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TABLE); } YY_BREAK case 217: YY_RULE_SETUP -#line 382 "maplexer.l" +#line 417 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEMPLATE); } YY_BREAK case 218: YY_RULE_SETUP -#line 383 "maplexer.l" +#line 418 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TEXT); } YY_BREAK case 219: YY_RULE_SETUP -#line 384 "maplexer.l" +#line 419 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILEINDEX); } YY_BREAK case 220: YY_RULE_SETUP -#line 385 "maplexer.l" +#line 420 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILEITEM); } YY_BREAK case 221: YY_RULE_SETUP -#line 386 "maplexer.l" +#line 421 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TILESRS); } YY_BREAK case 222: YY_RULE_SETUP -#line 387 "maplexer.l" +#line 422 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TITLE); } YY_BREAK case 223: YY_RULE_SETUP -#line 388 "maplexer.l" +#line 423 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TO); } YY_BREAK case 224: YY_RULE_SETUP -#line 389 "maplexer.l" +#line 424 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TOLERANCE); } YY_BREAK case 225: YY_RULE_SETUP -#line 390 "maplexer.l" +#line 425 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TOLERANCEUNITS); } YY_BREAK case 226: YY_RULE_SETUP -#line 391 "maplexer.l" +#line 426 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TRANSPARENT); } YY_BREAK case 227: YY_RULE_SETUP -#line 392 "maplexer.l" +#line 427 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TRANSFORM); } YY_BREAK case 228: YY_RULE_SETUP -#line 393 "maplexer.l" +#line 428 "maplexer.l" { MS_LEXER_RETURN_TOKEN(TYPE); } YY_BREAK case 229: YY_RULE_SETUP -#line 394 "maplexer.l" +#line 429 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UNITS); } YY_BREAK case 230: YY_RULE_SETUP -#line 395 "maplexer.l" +#line 430 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UTFDATA); } YY_BREAK case 231: YY_RULE_SETUP -#line 396 "maplexer.l" +#line 431 "maplexer.l" { MS_LEXER_RETURN_TOKEN(UTFITEM); } YY_BREAK case 232: YY_RULE_SETUP -#line 397 "maplexer.l" +#line 432 "maplexer.l" { MS_LEXER_RETURN_TOKEN(VALIDATION); } YY_BREAK case 233: YY_RULE_SETUP -#line 398 "maplexer.l" +#line 433 "maplexer.l" { MS_LEXER_RETURN_TOKEN(VALUES); } YY_BREAK case 234: YY_RULE_SETUP -#line 399 "maplexer.l" +#line 434 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WEB); } YY_BREAK case 235: YY_RULE_SETUP -#line 400 "maplexer.l" +#line 435 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WIDTH); } YY_BREAK case 236: YY_RULE_SETUP -#line 401 "maplexer.l" +#line 436 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WKT); } YY_BREAK case 237: YY_RULE_SETUP -#line 402 "maplexer.l" +#line 437 "maplexer.l" { MS_LEXER_RETURN_TOKEN(WRAP); } YY_BREAK case 238: YY_RULE_SETUP -#line 404 "maplexer.l" +#line 439 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_ANNOTATION); } YY_BREAK case 239: YY_RULE_SETUP -#line 405 "maplexer.l" +#line 440 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_AUTO); } YY_BREAK case 240: YY_RULE_SETUP -#line 406 "maplexer.l" +#line 441 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_AUTO2); } YY_BREAK case 241: YY_RULE_SETUP -#line 407 "maplexer.l" +#line 442 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_BEVEL); } YY_BREAK case 242: YY_RULE_SETUP -#line 408 "maplexer.l" +#line 443 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_BITMAP); } YY_BREAK case 243: YY_RULE_SETUP -#line 409 "maplexer.l" +#line 444 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_BUTT); } YY_BREAK case 244: YY_RULE_SETUP -#line 410 "maplexer.l" +#line 445 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CC); } YY_BREAK case 245: YY_RULE_SETUP -#line 411 "maplexer.l" +#line 446 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_CENTER); } YY_BREAK case 246: YY_RULE_SETUP -#line 412 "maplexer.l" +#line 447 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_CHART); } YY_BREAK case 247: YY_RULE_SETUP -#line 413 "maplexer.l" +#line 448 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_CIRCLE); } YY_BREAK case 248: YY_RULE_SETUP -#line 414 "maplexer.l" +#line 449 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CL); } YY_BREAK case 249: YY_RULE_SETUP -#line 415 "maplexer.l" +#line 450 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CR); } YY_BREAK case 250: YY_RULE_SETUP -#line 416 "maplexer.l" +#line 451 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_CSV); } YY_BREAK case 251: YY_RULE_SETUP -#line 417 "maplexer.l" +#line 452 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_POSTGRES); } YY_BREAK case 252: YY_RULE_SETUP -#line 418 "maplexer.l" +#line 453 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DB_MYSQL); } YY_BREAK case 253: YY_RULE_SETUP -#line 419 "maplexer.l" +#line 454 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DEFAULT); } YY_BREAK case 254: YY_RULE_SETUP -#line 420 "maplexer.l" +#line 455 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_DD); } YY_BREAK case 255: YY_RULE_SETUP -#line 421 "maplexer.l" +#line 456 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_ELLIPSE); } YY_BREAK case 256: YY_RULE_SETUP -#line 422 "maplexer.l" +#line 457 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_EMBED); } YY_BREAK case 257: YY_RULE_SETUP -#line 423 "maplexer.l" +#line 458 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FALSE); } YY_BREAK case 258: YY_RULE_SETUP -#line 424 "maplexer.l" +#line 459 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FEET); } YY_BREAK case 259: YY_RULE_SETUP -#line 425 "maplexer.l" +#line 460 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FOLLOW); } YY_BREAK case 260: YY_RULE_SETUP -#line 426 "maplexer.l" +#line 461 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_GIANT); } YY_BREAK case 261: YY_RULE_SETUP -#line 427 "maplexer.l" +#line 462 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_HATCH); } YY_BREAK case 262: YY_RULE_SETUP -#line 428 "maplexer.l" +#line 463 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_KERNELDENSITY); } YY_BREAK case 263: YY_RULE_SETUP -#line 429 "maplexer.l" +#line 464 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_IDW); } YY_BREAK case 264: YY_RULE_SETUP -#line 430 "maplexer.l" +#line 465 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_HILITE); } YY_BREAK case 265: YY_RULE_SETUP -#line 431 "maplexer.l" +#line 466 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_INCHES); } YY_BREAK case 266: YY_RULE_SETUP -#line 432 "maplexer.l" +#line 467 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_KILOMETERS); } YY_BREAK case 267: YY_RULE_SETUP -#line 433 "maplexer.l" +#line 468 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LARGE); } YY_BREAK case 268: YY_RULE_SETUP -#line 434 "maplexer.l" +#line 469 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LC); } YY_BREAK case 269: YY_RULE_SETUP -#line 435 "maplexer.l" +#line 470 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_LEFT); } YY_BREAK case 270: YY_RULE_SETUP -#line 436 "maplexer.l" +#line 471 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_LINE); } YY_BREAK case 271: YY_RULE_SETUP -#line 437 "maplexer.l" +#line 472 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LL); } YY_BREAK case 272: YY_RULE_SETUP -#line 438 "maplexer.l" +#line 473 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LR); } YY_BREAK case 273: YY_RULE_SETUP -#line 439 "maplexer.l" +#line 474 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MEDIUM); } YY_BREAK case 274: YY_RULE_SETUP -#line 440 "maplexer.l" +#line 475 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_METERS); } YY_BREAK case 275: YY_RULE_SETUP -#line 441 "maplexer.l" +#line 476 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_NAUTICALMILES); } YY_BREAK case 276: YY_RULE_SETUP -#line 442 "maplexer.l" +#line 477 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MILES); } YY_BREAK case 277: YY_RULE_SETUP -#line 443 "maplexer.l" +#line 478 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_MITER); } YY_BREAK case 278: YY_RULE_SETUP -#line 444 "maplexer.l" +#line 479 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_MULTIPLE); } YY_BREAK case 279: YY_RULE_SETUP -#line 445 "maplexer.l" +#line 480 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_NONE); } YY_BREAK case 280: YY_RULE_SETUP -#line 446 "maplexer.l" +#line 481 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_NORMAL); } YY_BREAK case 281: YY_RULE_SETUP -#line 447 "maplexer.l" +#line 482 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_OFF); } YY_BREAK case 282: YY_RULE_SETUP -#line 448 "maplexer.l" +#line 483 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_OGR); } YY_BREAK case 283: YY_RULE_SETUP -#line 449 "maplexer.l" +#line 484 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_FLATGEOBUF); } YY_BREAK case 284: YY_RULE_SETUP -#line 450 "maplexer.l" +#line 485 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ON); } YY_BREAK case 285: YY_RULE_SETUP -#line 451 "maplexer.l" +#line 486 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_JOIN_ONE_TO_ONE); } YY_BREAK case 286: YY_RULE_SETUP -#line 452 "maplexer.l" +#line 487 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_JOIN_ONE_TO_MANY); } YY_BREAK case 287: YY_RULE_SETUP -#line 453 "maplexer.l" +#line 488 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ORACLESPATIAL); } YY_BREAK case 288: YY_RULE_SETUP -#line 454 "maplexer.l" +#line 489 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PERCENTAGES); } YY_BREAK case 289: YY_RULE_SETUP -#line 455 "maplexer.l" +#line 490 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_PIXMAP); } YY_BREAK case 290: YY_RULE_SETUP -#line 456 "maplexer.l" +#line 491 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PIXELS); } YY_BREAK case 291: YY_RULE_SETUP -#line 457 "maplexer.l" +#line 492 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_POINT); } YY_BREAK case 292: YY_RULE_SETUP -#line 458 "maplexer.l" +#line 493 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_POLYGON); } YY_BREAK case 293: YY_RULE_SETUP -#line 459 "maplexer.l" +#line 494 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_POSTGIS); } YY_BREAK case 294: YY_RULE_SETUP -#line 460 "maplexer.l" +#line 495 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_PLUGIN); } YY_BREAK case 295: YY_RULE_SETUP -#line 461 "maplexer.l" +#line 496 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_QUERY); } YY_BREAK case 296: YY_RULE_SETUP -#line 462 "maplexer.l" +#line 497 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_LAYER_RASTER); } YY_BREAK case 297: YY_RULE_SETUP -#line 463 "maplexer.l" +#line 498 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_ALIGN_RIGHT); } YY_BREAK case 298: YY_RULE_SETUP -#line 464 "maplexer.l" +#line 499 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_ROUND); } YY_BREAK case 299: YY_RULE_SETUP -#line 465 "maplexer.l" +#line 500 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SELECTED); } YY_BREAK case 300: YY_RULE_SETUP -#line 466 "maplexer.l" +#line 501 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_SIMPLE); } YY_BREAK case 301: YY_RULE_SETUP -#line 467 "maplexer.l" +#line 502 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SINGLE); } YY_BREAK case 302: YY_RULE_SETUP -#line 468 "maplexer.l" +#line 503 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SMALL); } YY_BREAK case 303: YY_RULE_SETUP -#line 469 "maplexer.l" +#line 504 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_SQUARE); } YY_BREAK case 304: YY_RULE_SETUP -#line 470 "maplexer.l" +#line 505 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_SVG); } YY_BREAK case 305: YY_RULE_SETUP -#line 471 "maplexer.l" +#line 506 "maplexer.l" { MS_LEXER_RETURN_TOKEN(POLAROFFSET); } YY_BREAK case 306: YY_RULE_SETUP -#line 472 "maplexer.l" +#line 507 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TINY); } YY_BREAK case 307: YY_RULE_SETUP -#line 473 "maplexer.l" +#line 508 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CJC_TRIANGLE); } YY_BREAK case 308: YY_RULE_SETUP -#line 474 "maplexer.l" +#line 509 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TRUE); } YY_BREAK case 309: YY_RULE_SETUP -#line 475 "maplexer.l" +#line 510 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_TRUETYPE); } YY_BREAK case 310: YY_RULE_SETUP -#line 476 "maplexer.l" +#line 511 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UC); } YY_BREAK case 311: YY_RULE_SETUP -#line 477 "maplexer.l" +#line 512 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UL); } YY_BREAK case 312: YY_RULE_SETUP -#line 478 "maplexer.l" +#line 513 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UR); } YY_BREAK case 313: YY_RULE_SETUP -#line 479 "maplexer.l" +#line 514 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UNION); } YY_BREAK case 314: YY_RULE_SETUP -#line 480 "maplexer.l" +#line 515 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_UVRASTER); } YY_BREAK case 315: YY_RULE_SETUP -#line 481 "maplexer.l" +#line 516 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_CONTOUR); } YY_BREAK case 316: YY_RULE_SETUP -#line 482 "maplexer.l" +#line 517 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_SYMBOL_VECTOR); } YY_BREAK case 317: YY_RULE_SETUP -#line 483 "maplexer.l" +#line 518 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_WFS); } YY_BREAK case 318: YY_RULE_SETUP -#line 484 "maplexer.l" +#line 519 "maplexer.l" { MS_LEXER_RETURN_TOKEN(MS_WMS); } YY_BREAK case 319: /* rule 319 can match eol */ YY_RULE_SETUP -#line 486 "maplexer.l" +#line 521 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4189,7 +4224,7 @@ YY_RULE_SETUP YY_BREAK case 320: YY_RULE_SETUP -#line 495 "maplexer.l" +#line 530 "maplexer.l" { /* attribute binding - shape (fixed value) */ return(MS_TOKEN_BINDING_SHAPE); @@ -4197,7 +4232,7 @@ YY_RULE_SETUP YY_BREAK case 321: YY_RULE_SETUP -#line 499 "maplexer.l" +#line 534 "maplexer.l" { /* attribute binding - map cellsize */ return(MS_TOKEN_BINDING_MAP_CELLSIZE); @@ -4205,7 +4240,7 @@ YY_RULE_SETUP YY_BREAK case 322: YY_RULE_SETUP -#line 503 "maplexer.l" +#line 538 "maplexer.l" { /* attribute binding - data cellsize */ return(MS_TOKEN_BINDING_DATA_CELLSIZE); @@ -4214,7 +4249,7 @@ YY_RULE_SETUP case 323: /* rule 323 can match eol */ YY_RULE_SETUP -#line 507 "maplexer.l" +#line 542 "maplexer.l" { /* attribute binding - numeric (no quotes) */ msyytext++; @@ -4228,7 +4263,7 @@ YY_RULE_SETUP case 324: /* rule 324 can match eol */ YY_RULE_SETUP -#line 516 "maplexer.l" +#line 551 "maplexer.l" { /* attribute binding - string (single or double quotes) */ msyytext+=2; @@ -4242,7 +4277,7 @@ YY_RULE_SETUP case 325: /* rule 325 can match eol */ YY_RULE_SETUP -#line 525 "maplexer.l" +#line 560 "maplexer.l" { /* attribute binding - time */ msyytext+=2; @@ -4255,7 +4290,7 @@ YY_RULE_SETUP YY_BREAK case 326: YY_RULE_SETUP -#line 535 "maplexer.l" +#line 570 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); @@ -4266,7 +4301,7 @@ YY_RULE_SETUP YY_BREAK case 327: YY_RULE_SETUP -#line 543 "maplexer.l" +#line 578 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); @@ -4278,7 +4313,7 @@ YY_RULE_SETUP case 328: /* rule 328 can match eol */ YY_RULE_SETUP -#line 551 "maplexer.l" +#line 586 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4291,7 +4326,7 @@ YY_RULE_SETUP case 329: /* rule 329 can match eol */ YY_RULE_SETUP -#line 560 "maplexer.l" +#line 595 "maplexer.l" { msyytext++; msyytext[msyyleng-1-2] = '\0'; @@ -4304,7 +4339,7 @@ YY_RULE_SETUP case 330: /* rule 330 can match eol */ YY_RULE_SETUP -#line 569 "maplexer.l" +#line 604 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4316,7 +4351,7 @@ YY_RULE_SETUP YY_BREAK case 331: YY_RULE_SETUP -#line 578 "maplexer.l" +#line 613 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4328,7 +4363,7 @@ YY_RULE_SETUP YY_BREAK case 332: YY_RULE_SETUP -#line 587 "maplexer.l" +#line 622 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4340,7 +4375,7 @@ YY_RULE_SETUP YY_BREAK case 333: YY_RULE_SETUP -#line 596 "maplexer.l" +#line 631 "maplexer.l" { msyystring_return_state = MS_STRING; msyystring_begin = msyytext[0]; @@ -4351,7 +4386,7 @@ YY_RULE_SETUP YY_BREAK case 334: YY_RULE_SETUP -#line 604 "maplexer.l" +#line 639 "maplexer.l" { if (msyystring_begin == msyytext[0]) { BEGIN(msyystring_begin_state); @@ -4380,7 +4415,7 @@ YY_RULE_SETUP YY_BREAK case 335: YY_RULE_SETUP -#line 630 "maplexer.l" +#line 665 "maplexer.l" { ++msyystring_size; MS_LEXER_STRING_REALLOC(msyystring_buffer, msyystring_size, @@ -4396,7 +4431,7 @@ YY_RULE_SETUP case 336: /* rule 336 can match eol */ YY_RULE_SETUP -#line 642 "maplexer.l" +#line 677 "maplexer.l" { int old_size = msyystring_size; msyystring_size += msyyleng; @@ -4408,7 +4443,7 @@ YY_RULE_SETUP case 337: /* rule 337 can match eol */ YY_RULE_SETUP -#line 650 "maplexer.l" +#line 685 "maplexer.l" { msyytext++; msyytext[msyyleng-1-1] = '\0'; @@ -4437,7 +4472,7 @@ YY_RULE_SETUP YY_BREAK case 338: YY_RULE_SETUP -#line 676 "maplexer.l" +#line 711 "maplexer.l" { msyystring_return_state = MS_TOKEN_LITERAL_STRING; msyystring_begin = msyytext[0]; @@ -4448,7 +4483,7 @@ YY_RULE_SETUP YY_BREAK case 339: YY_RULE_SETUP -#line 684 "maplexer.l" +#line 719 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); @@ -4459,12 +4494,12 @@ YY_RULE_SETUP case 340: /* rule 340 can match eol */ YY_RULE_SETUP -#line 691 "maplexer.l" +#line 726 "maplexer.l" { msyylineno++; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CONFIG_FILE): -#line 693 "maplexer.l" +#line 728 "maplexer.l" { if( --include_stack_ptr < 0 ) return(EOF); /* end of main file */ @@ -4479,14 +4514,14 @@ case YY_STATE_EOF(CONFIG_FILE): case 341: /* rule 341 can match eol */ YY_RULE_SETUP -#line 704 "maplexer.l" +#line 739 "maplexer.l" { return(0); } YY_BREAK case 342: YY_RULE_SETUP -#line 708 "maplexer.l" +#line 743 "maplexer.l" { MS_LEXER_STRING_REALLOC(msyystring_buffer, msyyleng, msyystring_buffer_size); @@ -4496,15 +4531,15 @@ YY_RULE_SETUP YY_BREAK case 343: YY_RULE_SETUP -#line 714 "maplexer.l" +#line 749 "maplexer.l" { return(msyytext[0]); } YY_BREAK case 344: YY_RULE_SETUP -#line 715 "maplexer.l" +#line 750 "maplexer.l" ECHO; YY_BREAK -#line 4508 "/home/even/mapserver/mapserver/maplexer.c" +#line 4543 "/home/even/mapserver/mapserver/maplexer.c" case YY_STATE_EOF(EXPRESSION_STRING): case YY_STATE_EOF(INCLUDE): case YY_STATE_EOF(MSSTRING): @@ -5513,7 +5548,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 715 "maplexer.l" +#line 750 "maplexer.l" /* diff --git a/maplexer.l b/maplexer.l index bc37858571..e3033d369a 100644 --- a/maplexer.l +++ b/maplexer.l @@ -41,6 +41,41 @@ int msyylineno = 1; #define YY_NO_INPUT +/* Below is a redefinition of the default YY_INPUT() macro but replacing the + * YY_FATAL_ERROR() macro with a call to msSetError(). + */ +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + msSetError(MS_PARSEERR, "%s", "msyyparse()", "input in flex scanner failed"); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + msSetError(MS_PARSEERR, "%s", "msyyparse()", "input in flex scanner failed"); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + } + int msyysource=MS_STRING_TOKENS; double msyynumber; int msyystate=MS_TOKENIZE_DEFAULT; diff --git a/mapsymbol.c b/mapsymbol.c index 9a1ef74991..4feed675c1 100644 --- a/mapsymbol.c +++ b/mapsymbol.c @@ -598,7 +598,8 @@ int loadSymbolSet(symbolSetObj *symbolset, mapObj *map) if(!foundSymbolSetToken && token != SYMBOLSET) { msSetError(MS_IDENTERR, "First token must be SYMBOLSET, this doesn't look like a symbol file.", "msLoadSymbolSet()"); - return(-1); + status = -1; + break; } switch(token) { From fa12568c7bc7c2200803dfb8e57688b56240ed62 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 16 Apr 2023 15:48:05 -0300 Subject: [PATCH 125/170] [Backport branch-8-0] update CI builds (#6865) --- .github/workflows/start.sh | 11 +++++++---- .travis.yml | 8 +------- ci/travis/after_success.sh | 2 +- ci/travis/before_install.sh | 8 ++++---- ci/travis/script.sh | 6 +++--- msautotest/php/README.md | 8 ++++---- msautotest/php/phpunit.xml | 18 ++++++++---------- msautotest/php/run_test.sh | 4 ++-- 8 files changed, 30 insertions(+), 35 deletions(-) diff --git a/.github/workflows/start.sh b/.github/workflows/start.sh index 9e96eee15f..cf7aaca310 100755 --- a/.github/workflows/start.sh +++ b/.github/workflows/start.sh @@ -4,7 +4,7 @@ set -e apt-get update -y -export BUILD_NAME=PHP_7.4_WITH_PROJ8 +export BUILD_NAME=PHP_8.1_WITH_PROJ8 #export PYTHON_VERSION=3.6 export PYTHON_VERSION=system @@ -12,11 +12,14 @@ LANG=en_US.UTF-8 export LANG DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ sudo locales tzdata software-properties-common python3-dev python3-pip python3-setuptools git curl \ - apt-transport-https ca-certificates gnupg software-properties-common wget \ - php-dev php-xml php-mbstring && \ + apt-transport-https ca-certificates gnupg software-properties-common wget +#install PHP 8.1 +DEBIAN_FRONTEND=noninteractive add-apt-repository ppa:ondrej/php -y +DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + sudo php8.1-dev php8.1-xml php8.1-mbstring && \ echo "$LANG UTF-8" > /etc/locale.gen && \ dpkg-reconfigure --frontend=noninteractive locales && \ - update-locale LANG=$LANG + update-locale LANG=$LANG USER=root export USER diff --git a/.travis.yml b/.travis.yml index 5704e801f3..29a0d4cc60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,15 +8,9 @@ language: php matrix: include: - - php: 7.4 - env: - - BUILD_NAME=PHP_7.4_WITH_ASAN - - PYTHON_VERSION=3.7.13 - - CRYPTOGRAPHY_DONT_BUILD_RUST=1 # to avoid issue when building Cryptography python module (https://travis-ci.com/github/MapServer/MapServer/jobs/482212623) - - php: 8.1 env: - - BUILD_NAME=PHP_8.1 + - BUILD_NAME=PHP_8.1_WITH_ASAN - PYTHON_VERSION=3.8 - php: 8.2.0 diff --git a/ci/travis/after_success.sh b/ci/travis/after_success.sh index 61e514f1f2..66768e38d0 100755 --- a/ci/travis/after_success.sh +++ b/ci/travis/after_success.sh @@ -1,7 +1,7 @@ #!/bin/sh set -eu -if [ "$BUILD_NAME" != "PHP_7.4_WITH_ASAN" ]; then +if [ "$BUILD_NAME" != "PHP_8.1_WITH_ASAN" ]; then # Only run coverage when it is safe to do so (not on pull requests), and only on master branch echo "$TRAVIS_SECURE_ENV_VARS" echo "$TRAVIS_BRANCH" diff --git a/ci/travis/before_install.sh b/ci/travis/before_install.sh index a9a15c32ca..7e677f1c90 100755 --- a/ci/travis/before_install.sh +++ b/ci/travis/before_install.sh @@ -26,9 +26,9 @@ else # install recent CMake on Travis DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" mkdir ${DEPS_DIR} && cd ${DEPS_DIR} - wget --no-check-certificate https://cmake.org/files/v3.23/cmake-3.23.1-linux-x86_64.tar.gz - tar -xvf cmake-3.23.1-linux-x86_64.tar.gz > /dev/null - mv cmake-3.23.1-linux-x86_64 cmake-install + wget --no-check-certificate https://github.com/Kitware/CMake/releases/download/v3.26.3/cmake-3.26.3-linux-x86_64.tar.gz + tar -xvf cmake-3.26.3-linux-x86_64.tar.gz > /dev/null + mv cmake-3.26.3-linux-x86_64 cmake-install export PATH=${DEPS_DIR}/cmake-install:${DEPS_DIR}/cmake-install/bin:${PATH} cd ${TRAVIS_BUILD_DIR} export MSBUILD_ENV="TRAVIS" @@ -79,7 +79,7 @@ sudo service postgresql restart 12 cd msautotest #upgrade to recent PHPUnit -cd php && curl -LO https://phar.phpunit.de/phpunit-9.5.phar +cd php && curl -LO https://phar.phpunit.de/phpunit-10.phar cd .. python -m pyflakes . ./create_postgis_test_data.sh diff --git a/ci/travis/script.sh b/ci/travis/script.sh index 0ba8e2c69f..3e67ac6ae0 100755 --- a/ci/travis/script.sh +++ b/ci/travis/script.sh @@ -28,16 +28,16 @@ pyenv which pip pyenv which python #pyenv which python-config # check for phpunit & xdebug -php msautotest/php/phpunit-9.5.phar --version +php msautotest/php/phpunit-10.phar --version php -v -if [ "$BUILD_NAME" = "PHP_7.4_WITH_ASAN" ]; then +if [ "$BUILD_NAME" = "PHP_8.1_WITH_ASAN" ]; then # -DNDEBUG to avoid issues with cairo cleanup make cmakebuild MFLAGS="-j2" CMAKE_C_FLAGS="-g -fsanitize=address -DNDEBUG" CMAKE_CXX_FLAGS="-g -fsanitize=address -DNDEBUG" EXTRA_CMAKEFLAGS="-DCMAKE_BUILD_TYPE=None -DCMAKE_EXE_LINKER_FLAGS=-fsanitize=address" export AUTOTEST_OPTS="--strict --run_under_asan" # Only run tests that only involve mapserv/map2img binaries. mspython, etc would require LD_PREOLOAD'ing the asan shared object make -j4 asan_compatible_tests -elif [ "$BUILD_NAME" = "PHP_7.4_WITH_PROJ8" ]; then +elif [ "$BUILD_NAME" = "PHP_8.1_WITH_PROJ8" ]; then #runs through GitHub action make cmakebuild MFLAGS="-j2" CMAKE_C_FLAGS="-O2" CMAKE_CXX_FLAGS="-O2" LIBMAPSERVER_EXTRA_FLAGS="-Wall -Werror -Wextra" make mspython-wheel diff --git a/msautotest/php/README.md b/msautotest/php/README.md index 2cdd858d54..24fb6f535f 100644 --- a/msautotest/php/README.md +++ b/msautotest/php/README.md @@ -1,20 +1,20 @@ # PHPNG MapScript Unit Tests To run these tests you need PHPUnit (and PHP's Xdebug extension) installed. -You can find how to install PHPUnit at https://phpunit.readthedocs.io . +You can find how to install PHPUnit at https://docs.phpunit.de . The official PHPUnit site is: https://phpunit.de # Running the tests -To run the tests simply run `phpunit --debug .` from inside the `/msautotest/php/` +To run the tests simply run `phpunit .` from inside the `/msautotest/php/` folder. -You can run a single test such as: `phpunit --debug classObjTest.php` +You can run a single test such as: `phpunit classObjTest.php` # Configuring the test environment This folder includes a `phpunit.xml` configuration file for these tests. More -info about these settings: https://phpunit.readthedocs.io/en/9.5/configuration.html +info about these settings: https://docs.phpunit.de/en/10.1/configuration.html # PHPNG (SWIG) MapScript API documentation diff --git a/msautotest/php/phpunit.xml b/msautotest/php/phpunit.xml index bda3d15706..6ed33fe539 100644 --- a/msautotest/php/phpunit.xml +++ b/msautotest/php/phpunit.xml @@ -1,18 +1,16 @@ + beStrictAboutTestsThatDoNotTestAnything="false" + cacheDirectory=".phpunit.cache" + testdox ="true"> - - ./ + + ./ diff --git a/msautotest/php/run_test.sh b/msautotest/php/run_test.sh index 0b64a75920..2dd3fc3117 100755 --- a/msautotest/php/run_test.sh +++ b/msautotest/php/run_test.sh @@ -1,9 +1,9 @@ #!/bin/bash if test -z $PHP_MAPSCRIPT_SO; then - php phpunit-9.5.phar --debug . + php phpunit-10.phar . exit $? else - php -d "extension=$PHP_MAPSCRIPT_SO" phpunit-9.5.phar --debug . + php -d "extension=$PHP_MAPSCRIPT_SO" phpunit-10.phar . exit $? fi From bdfb664011e932fea0d46c414d7d4d6c377c561e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:36:48 -0300 Subject: [PATCH 126/170] PROJ_DATA set through config option: take into account possibility of multiple paths separated by ; on Windows or : on Unix (#6867) Co-authored-by: Even Rouault --- mapproject.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/mapproject.c b/mapproject.c index 3504fe371e..f6dde810c3 100644 --- a/mapproject.c +++ b/mapproject.c @@ -37,6 +37,7 @@ #include "mapaxisorder.h" #include "cpl_conv.h" +#include "cpl_string.h" #include "ogr_srs_api.h" static char *ms_proj_data = NULL; @@ -873,8 +874,23 @@ int msProcessProjection(projectionObj *p) msAcquireLock( TLOCK_PROJ ); p->proj_ctx->ms_proj_data_change_counter = ms_proj_data_change_counter; { - const char* const paths[1] = { ms_proj_data }; - proj_context_set_search_paths(p->proj_ctx->proj_ctx, 1, ms_proj_data ? paths : NULL); + if( ms_proj_data ) + { + int num_tokens = 0; +#ifdef _WIN32 + char sep = ';'; +#else + char sep = ':'; +#endif + char** paths = msStringSplit(ms_proj_data, sep, &num_tokens); + proj_context_set_search_paths(p->proj_ctx->proj_ctx, num_tokens, + (const char* const*)paths); + msFreeCharArray(paths, num_tokens); + } + else + { + proj_context_set_search_paths(p->proj_ctx->proj_ctx, 0, NULL); + } } msReleaseLock( TLOCK_PROJ ); } @@ -2612,8 +2628,14 @@ void msSetPROJ_DATA( const char *proj_data, const char *pszRelToPath ) #if GDAL_VERSION_MAJOR >= 3 if( ms_proj_data != NULL ) { - const char* const apszPaths[] = { ms_proj_data, NULL }; - OSRSetPROJSearchPaths(apszPaths); +#ifdef _WIN32 + const char* sep = ";"; +#else + const char* sep = ":"; +#endif + char** papszPaths = CSLTokenizeString2(ms_proj_data, sep, 0); + OSRSetPROJSearchPaths((const char* const *)papszPaths); + CSLDestroy(papszPaths); } #endif From e0368d20c3b009a0074ae76a16a65b62adca0d75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 10:35:20 -0300 Subject: [PATCH 127/170] update clone tests (#6868) --- msautotest/php/classObjTest.php | 7 ++++++- msautotest/php/phpunit.xml | 12 ++++++------ msautotest/php/shapeObjTest.php | 7 ++++++- msautotest/php/styleObjTest.php | 4 ++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/msautotest/php/classObjTest.php b/msautotest/php/classObjTest.php index fdc074734e..dc7a0aa1b4 100644 --- a/msautotest/php/classObjTest.php +++ b/msautotest/php/classObjTest.php @@ -37,11 +37,16 @@ public function testcreateLegendIcon() $map = new mapObj($map_file); $layer = $map->getLayer(0); $this->assertInstanceOf('imageObj', $layer->getClass(0)->createLegendIcon( $map, $layer, 50, 50 )); + } + + public function testClone() + { + $this->assertInstanceOf('classObj', $newClass = $this->class->cloneClass()); } # destroy variables, if not can lead to segmentation fault public function tearDown(): void { - unset($this->class, $map_file, $map, $layer, $classtmp, $style); + unset($this->class, $map_file, $map, $layer, $classtmp, $style, $newClass); } } diff --git a/msautotest/php/phpunit.xml b/msautotest/php/phpunit.xml index 6ed33fe539..3c19dd2c4c 100644 --- a/msautotest/php/phpunit.xml +++ b/msautotest/php/phpunit.xml @@ -1,12 +1,12 @@ diff --git a/msautotest/php/shapeObjTest.php b/msautotest/php/shapeObjTest.php index 666d10f274..f24cbf60e9 100644 --- a/msautotest/php/shapeObjTest.php +++ b/msautotest/php/shapeObjTest.php @@ -51,9 +51,14 @@ public function test__getresultindex() $this->assertEquals(-1, $this->shape->resultindex); } + public function testClone() + { + $this->assertInstanceOf('shapeObj', $newShape = $this->shape->cloneShape()); + } + # destroy variables, if not can lead to segmentation fault public function tearDown(): void { - unset($shape, $this->shape, $point, $line, $line2, $shape2); + unset($shape, $this->shape, $point, $line, $line2, $shape2, $newShape); } } diff --git a/msautotest/php/styleObjTest.php b/msautotest/php/styleObjTest.php index 0b36e73357..2bf7b10a9b 100644 --- a/msautotest/php/styleObjTest.php +++ b/msautotest/php/styleObjTest.php @@ -26,14 +26,14 @@ public function test__getsetMinScaledenom() $this->assertEquals(2.2, $this->style->minscaledenom = 2.2); } - public function testsClone() + public function testClone() { $newStyle = $this->style->cloneStyle(); } # destroy variables, if not can lead to segmentation fault public function tearDown(): void { - unset($style, $map_file, $map, $this->style, $this->style->initialgap, $this->style->maxscaledenom, $this->style->minscaledenom); + unset($style, $map_file, $map, $this->style, $this->style->initialgap, $this->style->maxscaledenom, $this->style->minscaledenom, $newStyle); } } From c6215e6b7d05aca652f94aa7f213a7098ee7d913 Mon Sep 17 00:00:00 2001 From: Jeff McKenna Date: Mon, 17 Apr 2023 14:26:04 -0300 Subject: [PATCH 128/170] update for 8.0.1 release --- CMakeLists.txt | 2 +- HISTORY.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02a953a672..ba394ae3d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(CheckCSourceCompiles) set (MapServer_VERSION_MAJOR 8) set (MapServer_VERSION_MINOR 0) -set (MapServer_VERSION_REVISION 0) +set (MapServer_VERSION_REVISION 1) set (MapServer_VERSION_SUFFIX "") # Set C++ version diff --git a/HISTORY.md b/HISTORY.md index d104673937..47bc9fd27e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,17 @@ https://mapserver.org/development/changelog/ The online Migration Guide can be found at https://mapserver.org/MIGRATION_GUIDE.html +8.0.1 release (2023-04-17) +-------------------------- + +- fix WFS paging on Oracle (#6774) + +- allow runtime substitutions on the Web template parameter (#6804) + +- handle multiple PROJ_DATA paths through config (#6863) + +see detailed changelog for other fixes + 8.0.0 release (2022-09-12) -------------------------- From dfea2d4b336fadbb97ee26a65090b0de95e1a0cb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:14:05 -0300 Subject: [PATCH 129/170] Fix spelling errors. (#6870) * suported -> supported Co-authored-by: Bas Couwenberg --- mapshape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapshape.c b/mapshape.c index 11da092c04..03cda52641 100644 --- a/mapshape.c +++ b/mapshape.c @@ -234,7 +234,7 @@ SHPHandle msSHPOpenVirtualFile( VSILFILE * fpSHP, VSILFILE * fpSHX ) VSIFSeekL( psSHP->fpSHP, 0, SEEK_END ); vsi_l_offset nSize = VSIFTellL( psSHP->fpSHP ); if( nSize > (vsi_l_offset)INT_MAX ) { - msDebug("Actual .shp size is larger than 2 GB. Not suported. Invalidating nFileSize"); + msDebug("Actual .shp size is larger than 2 GB. Not supported. Invalidating nFileSize"); psSHP->nFileSize = 0; } else From 8c3bda2235bbfa4f22d837d7ebce3f198ba01d31 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 22 Apr 2023 14:17:26 -0300 Subject: [PATCH 130/170] CMake: Check compiler type for MSVC speicific option (#6872) The '/w' option is specific to MSVC in Windows. So, check the compiler type before adding that compiler flag. This fixes the following error in mingw toolchain. cc: error: no such file or directory: '/w' Co-authored-by: Biswapriyo Nath --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba394ae3d8..09a2c78d30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -288,8 +288,10 @@ if(WIN32) set(REGEX_MALLOC 1) set(USE_GENERIC_MS_NINT 1) set(HAVE_STRING_H 0) - # Suppress warnings for regex.c - set_source_files_properties(${REGEX_SOURCES} PROPERTIES COMPILE_FLAGS /w) + if(MSVC) + # Suppress warnings for regex.c + set_source_files_properties(${REGEX_SOURCES} PROPERTIES COMPILE_FLAGS /w) + endif(MSVC) else(WIN32) set(REGEX_SOURCES "") endif(WIN32) From 89d6e718d7f514cef437e989ea17175a9b262085 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 06:32:42 -0300 Subject: [PATCH 131/170] cmake: Define STDC_HEADERS for regex in mingw toolchain (#6874) --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09a2c78d30..5b00754634 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,6 +292,10 @@ if(WIN32) # Suppress warnings for regex.c set_source_files_properties(${REGEX_SOURCES} PROPERTIES COMPILE_FLAGS /w) endif(MSVC) + if(MINGW) + # mingw provides stdlib.h + add_definitions(-DSTDC_HEADERS=1) + endif(MINGW) else(WIN32) set(REGEX_SOURCES "") endif(WIN32) From 2898c8574f01d577d868ebdfdb94d36510dd2dda Mon Sep 17 00:00:00 2001 From: Biswapriyo Nath Date: Mon, 24 Apr 2023 15:03:48 +0530 Subject: [PATCH 132/170] [Backport] CI: update github actions versions (#6875) --- .github/workflows/build.yml | 2 +- .github/workflows/check-crlf.yml | 2 +- .github/workflows/coverity-scan.yml | 2 +- .github/workflows/cppcheck.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 04284d7d08..094a2d0ec0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Checkout repository contents - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build run: docker run -e WORK_DIR="$PWD" -v $PWD:$PWD ubuntu:20.04 $PWD/.github/workflows/start.sh diff --git a/.github/workflows/check-crlf.yml b/.github/workflows/check-crlf.yml index d5b6a81ec8..20dc50efd1 100644 --- a/.github/workflows/check-crlf.yml +++ b/.github/workflows/check-crlf.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository contents - uses: actions/checkout@v1 + uses: actions/checkout@v3 - name: Use action to check for CRLF endings uses: erclu/check-crlf@v1.2.0 diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index aecc58954c..d051131e0a 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 if: github.repository == 'MapServer/MapServer' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install Libraries run: | diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml index 1066452292..fdf1b9b7ad 100644 --- a/.github/workflows/cppcheck.yml +++ b/.github/workflows/cppcheck.yml @@ -9,7 +9,7 @@ jobs: if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install Requirements run: | From dae224708ac28bfabe60742e0e97530b95543035 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 May 2023 13:54:44 +0200 Subject: [PATCH 133/170] Fix memory leak in LayerDefaultGetNumFeatures (#6876) (#6878) Co-authored-by: Tamas Szekeres --- maplayer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/maplayer.c b/maplayer.c index 9904b0fb1b..7ef90320d2 100644 --- a/maplayer.c +++ b/maplayer.c @@ -1985,6 +1985,7 @@ int LayerDefaultGetNumFeatures(layerObj *layer) result = 0; while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { ++result; + msFreeShape(&shape); } return result; From e453622792df4852a48eef8ed95167de5d0bf09a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 15:13:14 -0300 Subject: [PATCH 134/170] Fix error message (#6883) Co-authored-by: sethg --- maprendering.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maprendering.c b/maprendering.c index 3ba67652b7..e495319f99 100755 --- a/maprendering.c +++ b/maprendering.c @@ -661,7 +661,7 @@ int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, } else if( MS_RENDERER_IMAGEMAP(image->format) ) msDrawLineSymbolIM(map, image, p, style, scalefactor); else { - msSetError(MS_RENDERERERR, "unsupported renderer", "msDrawShadeSymbol()"); + msSetError(MS_RENDERERERR, "unsupported renderer", "msDrawLineSymbol()"); status = MS_FAILURE; } } else { From 122274c907990af0b1a7b5655d906b3ecb21b748 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 15:13:26 -0300 Subject: [PATCH 135/170] cmake: respect prefix when installing mapserver-sample.conf (#6882) Co-authored-by: Nicklas Larsson --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b00754634..dc8ca3a1c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1113,5 +1113,5 @@ install( install( FILES ${PROJECT_SOURCE_DIR}/etc/mapserver-sample.conf - DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/ + DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/ ) From c9b212d7a896fd1c6280478a002fcad3565311af Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 08:20:39 -0300 Subject: [PATCH 136/170] cmake: remove repeated status message (#6886) Co-authored-by: Nicklas Larsson --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc8ca3a1c5..19c1739b7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -945,7 +945,6 @@ status_optional_component("GIF" "${USE_GIF}" "${GIF_LIBRARY}") status_optional_component("MYSQL" "${USE_MYSQL}" "${MYSQL_LIBRARY}") status_optional_component("FRIBIDI" "${USE_FRIBIDI}" "${FRIBIDI_LIBRARY}") status_optional_component("HARFBUZZ" "${USE_HARFBUZZ}" "${HARFBUZZ_LIBRARY}") -status_optional_component("GIF" "${USE_GIF}" "${GIF_LIBRARY}") status_optional_component("CAIRO" "${USE_CAIRO}" "${CAIRO_LIBRARY}") status_optional_component("SVGCAIRO" "${USE_SVG_CAIRO}" "${SVGCAIRO_LIBRARY}") status_optional_component("RSVG" "${USE_RSVG}" "${RSVG_LIBRARY}") From 8a2171584a59fd8335b9fd29095c0c5ba71e26e2 Mon Sep 17 00:00:00 2001 From: sethg Date: Fri, 26 May 2023 17:29:43 +0200 Subject: [PATCH 137/170] Re-enable test_reprojection_rect_and_datum_shift --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 328f67939d..199adf6c01 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -97,8 +97,7 @@ test_script: - cd %BUILD_FOLDER%/msautotest/mssql - "%Python_ROOT_DIR%/python run_test.py" - cd %BUILD_FOLDER%/msautotest/mspython - # skip the datum shift test - see #6824 and PROJ9 issue - - "%Python_ROOT_DIR%/python run_all_tests.py -k \"not test_reprojection_rect_and_datum_shift\"" + - "%Python_ROOT_DIR%/python run_all_tests.py" after_test: - cd %BUILD_FOLDER% From 2efe25988a42d17d6054d3841bd47c3cc4a40a93 Mon Sep 17 00:00:00 2001 From: sethg Date: Fri, 26 May 2023 17:52:32 +0200 Subject: [PATCH 138/170] Update Python versions --- appveyor.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 199adf6c01..e3d0769ab3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,12 +19,16 @@ environment: # VS 2019 VS_VERSION: Visual Studio 16 2019 matrix: - - platform: x64 - Python_ROOT_DIR: c:/python36-x64 - platform: x64 Python_ROOT_DIR: c:/python37-x64 - platform: x64 Python_ROOT_DIR: c:/python38-x64 + - platform: x64 + Python_ROOT_DIR: c:/python39-x64 + - platform: x64 + Python_ROOT_DIR: c:/python310-x64 + - platform: x64 + Python_ROOT_DIR: c:/python311-x64 matrix: fast_finish: true @@ -36,7 +40,7 @@ init: - net start MSSQL$SQL2019 - ps: | if ($env:APPVEYOR_REPO_TAG -ne $TRUE) { - if ("c:/python27-x64","c:/python36-x64" -contains $env:Python_ROOT_DIR -eq $TRUE) { + if ("c:/python37-x64" -contains $env:Python_ROOT_DIR -eq $TRUE) { Write-Host "Skipping build, not a tagged release." Exit-AppVeyorBuild } @@ -115,7 +119,7 @@ artifacts: deploy_script: - ps: | if ($env:APPVEYOR_REPO_TAG -ne $TRUE -or ($env:APPVEYOR_REPO_TAG_NAME -cSplit "-").Count -ne 4) { return } - if ($env:Python_ROOT_DIR -eq "c:/python36-x64") { + if ($env:Python_ROOT_DIR -eq "c:/python310-x64") { Write-Host "Deploying Python source distribution to PyPI. Tag $env:APPVEYOR_REPO_TAG_NAME" cd $env:APPVEYOR_BUILD_FOLDER\build\mapscript\python\Release & "$env:Python_ROOT_DIR/python" setup.py sdist From 8de60af17402a8e945b79820e2c3bc0f09414e10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 08:37:56 -0300 Subject: [PATCH 139/170] Output doxygen comments in Python MapScript module (#6894) Co-authored-by: sethg --- mapscript/python/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mapscript/python/CMakeLists.txt b/mapscript/python/CMakeLists.txt index c8dd96941a..9770cdd1ca 100644 --- a/mapscript/python/CMakeLists.txt +++ b/mapscript/python/CMakeLists.txt @@ -10,8 +10,9 @@ include_directories(${PROJECT_SOURCE_DIR}/mapscript/python) set(SwigFile ${PROJECT_SOURCE_DIR}/mapscript/mapscript.i) -# add annotations to py file output - requires >= SWIG 4.1 +# add and comments annotations to py file output - requires >= SWIG 4.1 if (WITH_PYMAPSCRIPT_ANNOTATIONS AND ${Python_VERSION_MAJOR} GREATER_EQUAL 3) + set_property(SOURCE ${SwigFile} APPEND PROPERTY SWIG_FLAGS -doxygen) if (${Python_VERSION_MINOR} GREATER_EQUAL 6) set_property(SOURCE ${SwigFile} APPEND PROPERTY SWIG_FLAGS -features python:annotations=c) else () From d84d3f1fb4ae43e3c8df31b5867253d0f3549ef1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 17:03:29 -0300 Subject: [PATCH 140/170] [Backport branch-8-0] Refresh cached reprojector when changing map projection between drawMap() calls (fixes #6896) (#6899) --- mapdraw.c | 24 +++------ maplayer.c | 19 +++++++ mapogcsos.c | 20 +++---- mapogroutput.cpp | 10 ++-- mapproject.c | 27 ++++++++++ mapproject.h | 6 ++- mapserver.h | 2 + maptemplate.c | 50 ++++++------------ msautotest/mspython/test_bug_check.py | 49 +++++++++++++++++ .../php/expected/setprojection-3857.png | Bin 0 -> 3236 bytes .../php/expected/setprojection-3978.png | Bin 0 -> 2283 bytes msautotest/php/mapObjTest.php | 34 +++++++++++- msautotest/php/result/.gitignore | 2 + 13 files changed, 169 insertions(+), 74 deletions(-) create mode 100644 msautotest/php/expected/setprojection-3857.png create mode 100644 msautotest/php/expected/setprojection-3978.png create mode 100644 msautotest/php/result/.gitignore diff --git a/mapdraw.c b/mapdraw.c index 60d6c1f2f4..431816562d 100644 --- a/mapdraw.c +++ b/mapdraw.c @@ -1770,16 +1770,12 @@ int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj if (layer->project && layer->transform == MS_TRUE) { - if( layer->reprojectorLayerToMap == NULL ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, map); + if( reprojector == NULL ) { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); - if( layer->reprojectorLayerToMap == NULL ) - { - return MS_FAILURE; - } + return MS_FAILURE; } - msProjectShapeEx(layer->reprojectorLayerToMap, shape); + msProjectShapeEx(reprojector, shape); } // Only take into account map rotation if the label and style angles are @@ -2098,16 +2094,12 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, if (layer->project && layer->transform == MS_TRUE) { - if( layer->reprojectorLayerToMap == NULL ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, map); + if( reprojector == NULL ) { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); - if( layer->reprojectorLayerToMap == NULL ) - { - return MS_FAILURE; - } + return MS_FAILURE; } - msProjectShapeEx(layer->reprojectorLayerToMap, shape); + msProjectShapeEx(reprojector, shape); } /* check if we'll need the unclipped shape */ diff --git a/maplayer.c b/maplayer.c index 7ef90320d2..2c29dd6ead 100644 --- a/maplayer.c +++ b/maplayer.c @@ -1915,6 +1915,25 @@ void msLayerEnablePaging(layerObj *layer, int value) layer->vtable->LayerEnablePaging(layer, value); } +/** Returns a cached reprojector from the layer projection to the map projection */ +reprojectionObj* msLayerGetReprojectorToMap(layerObj* layer, mapObj* map) +{ + if( layer->reprojectorLayerToMap != NULL && + !msProjectIsReprojectorStillValid(layer->reprojectorLayerToMap) ) + { + msProjectDestroyReprojector(layer->reprojectorLayerToMap); + layer->reprojectorLayerToMap = NULL; + } + + if( layer->reprojectorLayerToMap == NULL ) + { + layer->reprojectorLayerToMap = msProjectCreateReprojector( + &layer->projection, &map->projection); + } + return layer->reprojectorLayerToMap; +} + + int LayerDefaultGetExtent(layerObj *layer, rectObj *extent) { (void)layer; diff --git a/mapogcsos.c b/mapogcsos.c index eda0393dd5..5c45631f86 100644 --- a/mapogcsos.c +++ b/mapogcsos.c @@ -362,14 +362,10 @@ void msSOSAddGeometryNode(xmlNsPtr psNsGml, xmlNsPtr psNsMs, xmlNodePtr psParen if (psParent && psShape) { if (msProjectionsDiffer(&map->projection, &lp->projection) == MS_TRUE) { - if( lp->reprojectorLayerToMap == NULL ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(lp, map); + if( reprojector ) { - lp->reprojectorLayerToMap = msProjectCreateReprojector( - &lp->projection, &map->projection); - } - if( lp->reprojectorLayerToMap ) - { - msProjectShapeEx(lp->reprojectorLayerToMap, psShape); + msProjectShapeEx(reprojector, psShape); } msOWSGetEPSGProj(&(map->projection), &(lp->metadata), "SO", MS_TRUE, &pszEpsg_buf); pszEpsg = pszEpsg_buf; @@ -780,14 +776,10 @@ void msSOSAddMemberNode(xmlNsPtr psNsGml, xmlNsPtr psNsOm, xmlNsPtr psNsSwe, xml if(msProjectionsDiffer(&(lp->projection), &(map->projection))) { - if( lp->reprojectorLayerToMap == NULL ) - { - lp->reprojectorLayerToMap = msProjectCreateReprojector( - &lp->projection, &map->projection); - } - if( lp->reprojectorLayerToMap ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(lp, map); + if( reprojector ) { - msProjectShapeEx(lp->reprojectorLayerToMap, &sShape); + msProjectShapeEx(reprojector, &sShape); } } diff --git a/mapogroutput.cpp b/mapogroutput.cpp index 93f88f633b..53a2222a4f 100644 --- a/mapogroutput.cpp +++ b/mapogroutput.cpp @@ -1136,13 +1136,9 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders ) } if( layer->project && resultshape.type != MS_SHAPE_NULL) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) - status = msProjectShapeEx(layer->reprojectorLayerToMap, &resultshape); + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) + status = msProjectShapeEx(reprojector, &resultshape); else status = MS_FAILURE; } diff --git a/mapproject.c b/mapproject.c index f6dde810c3..215781575a 100644 --- a/mapproject.c +++ b/mapproject.c @@ -414,11 +414,19 @@ void msProjectionContextUnref(projectionContext* ctx) /* msProjectCreateReprojector() */ /************************************************************************/ +/* The pointed objects need to remain valid during the lifetime of the + * reprojector, as only their pointer is stored. + * + * If the *content* of in and/or out is changed, then the reprojector is + * no longer valid. This can be detected with msProjectIsReprojectorStillValid() + */ reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* out) { reprojectionObj* obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); obj->in = in; obj->out = out; + obj->generation_number_in = in ? in->generation_number : 0; + obj->generation_number_out = out ? out->generation_number : 0; obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; /* -------------------------------------------------------------------- */ @@ -551,6 +559,8 @@ reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* ou obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); obj->in = in; obj->out = out; + obj->generation_number_in = in ? in->generation_number : 0; + obj->generation_number_out = out ? out->generation_number : 0; obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; /* -------------------------------------------------------------------- */ @@ -626,6 +636,7 @@ int msInitProjection(projectionObj *p) #elif PJ_VERSION >= 480 p->proj_ctx = NULL; #endif + p->generation_number = 0; return(0); } @@ -654,6 +665,7 @@ void msFreeProjection(projectionObj *p) msFreeCharArray(p->args, p->numargs); p->args = NULL; p->numargs = 0; + p->generation_number ++; } void msFreeProjectionExceptContext(projectionObj *p) @@ -845,6 +857,8 @@ int msProcessProjection(projectionObj *p) { assert( p->proj == NULL ); + p->generation_number ++; + if( strcasecmp(p->args[0],"GEOGRAPHIC") == 0 ) { msSetError(MS_PROJERR, "PROJECTION 'GEOGRAPHIC' no longer supported.\n" @@ -1367,6 +1381,19 @@ static msLineCuttingCase msProjectGetLineCuttingCase(reprojectionObj* reprojecto } #endif +/************************************************************************/ +/* msProjectIsReprojectorStillValid() */ +/************************************************************************/ + +int msProjectIsReprojectorStillValid(reprojectionObj* reprojector) +{ + if( reprojector->in && reprojector->in->generation_number != reprojector->generation_number_in ) + return MS_FALSE; + if( reprojector->out && reprojector->out->generation_number != reprojector->generation_number_out ) + return MS_FALSE; + return MS_TRUE; +} + /************************************************************************/ /* msProjectShapeLine() */ /* */ diff --git a/mapproject.h b/mapproject.h index 2d54c60278..b84574c9a6 100644 --- a/mapproject.h +++ b/mapproject.h @@ -89,7 +89,8 @@ but are not directly exposed by the mapscript module %immutable; #endif int numargs; ///< Actual number of projection args - int automatic; ///< Projection object was to fetched from the layer + short automatic; ///< Projection object was to fetched from the layer + unsigned short generation_number; ///< To be incremented when the content of the object change, so that reprojector can be invalidated #ifdef SWIG %mutable; #endif @@ -116,12 +117,15 @@ but are not directly exposed by the mapscript module int no_op; #endif #endif + unsigned short generation_number_in; + unsigned short generation_number_out; } reprojectionObj; #ifndef SWIG MS_DLL_EXPORT reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* out); MS_DLL_EXPORT void msProjectDestroyReprojector(reprojectionObj* reprojector); + MS_DLL_EXPORT int msProjectIsReprojectorStillValid(reprojectionObj* reprojector); MS_DLL_EXPORT projectionContext* msProjectionContextGetFromPool(void); MS_DLL_EXPORT void msProjectionContextReleaseToPool(projectionContext* ctx); diff --git a/mapserver.h b/mapserver.h index 9359a2fcac..586ed07fad 100755 --- a/mapserver.h +++ b/mapserver.h @@ -2618,6 +2618,8 @@ extern "C" { int msOGRLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record); int msOGRLayerGetExtent(layerObj *layer, rectObj *extent); + reprojectionObj MS_DLL_EXPORT* msLayerGetReprojectorToMap(layerObj* layer, mapObj* map); + MS_DLL_EXPORT int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *shape, OGRwkbGeometryType type); diff --git a/maptemplate.c b/maptemplate.c index 643e5c940e..ae144e75ad 100644 --- a/maptemplate.c +++ b/maptemplate.c @@ -1619,14 +1619,10 @@ static int processShplabelTag(layerObj *layer, char **line, shapeObj *origshape) if(layer->transform == MS_TRUE) { if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection))) { - if( layer->reprojectorLayerToMap == NULL ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) - { - msProjectShapeEx(layer->reprojectorLayerToMap, shape); + msProjectShapeEx(reprojector, shape); } } @@ -1640,14 +1636,10 @@ static int processShplabelTag(layerObj *layer, char **line, shapeObj *origshape) if(layer->transform == MS_TRUE) { if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection))) { - if( layer->reprojectorLayerToMap == NULL ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) - { - msProjectShapeEx(layer->reprojectorLayerToMap, shape); + msProjectShapeEx(reprojector, shape); } } @@ -1680,14 +1672,10 @@ static int processShplabelTag(layerObj *layer, char **line, shapeObj *origshape) if(layer->transform == MS_TRUE) { if(layer->project && msProjectionsDiffer(&(layer->projection), &(layer->map->projection))) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) { - msProjectShapeEx(layer->reprojectorLayerToMap, shape); + msProjectShapeEx(reprojector, shape); } } @@ -1778,14 +1766,10 @@ static int processShplabelTag(layerObj *layer, char **line, shapeObj *origshape) /* if necessary, project the shape to match the map */ if(msProjectionsDiffer(&(layer->projection), &(layer->map->projection))) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) { - msProjectShapeEx(layer->reprojectorLayerToMap, &tShape); + msProjectShapeEx(reprojector, &tShape); } } @@ -2155,14 +2139,10 @@ static int processShpxyTag(layerObj *layer, char **line, shapeObj *shape) /* if necessary, project the shape to match the map */ if(msProjectionsDiffer(&(layer->projection), &(layer->map->projection))) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &layer->map->projection); - } - if( layer->reprojectorLayerToMap ) + reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, layer->map); + if( reprojector ) { - msProjectShapeEx(layer->reprojectorLayerToMap, &tShape); + msProjectShapeEx(reprojector, &tShape); } } diff --git a/msautotest/mspython/test_bug_check.py b/msautotest/mspython/test_bug_check.py index 168820425d..965987b569 100755 --- a/msautotest/mspython/test_bug_check.py +++ b/msautotest/mspython/test_bug_check.py @@ -232,3 +232,52 @@ def test_reprojection_from_lonlat_wrap_0(): set_x = [point11.x, point12.x, point21.x, point22.x] set_x.sort() assert set_x == pytest.approx([-180, -179, 178, 180], abs=1e-2) + + +############################################################################### +# Check that we can draw a map several times by changing the map projection + +def test_bug_6896(): + + try: + os.mkdir(get_relpath_to_this('result')) + except: + pass + + def load_map(): + # Generate a reference image + map = mapscript.mapObj(get_relpath_to_this('../misc/ogr_direct.map')) + layer = map.getLayer(0) + layer.setProjection('+proj=utm +zone=11 +datum=WGS84') + return map + + def draw_another_projection(map): + # Draw map with one reprojection. + map.setProjection('+proj=utm +zone=12 +datum=WGS84') + map.setExtent(-10675, 4781937, -7127, 4784428 ) + map.draw() + + def draw_wgs84(map): + # Draw map with WGS 84 projection + map.setProjection('+proj=latlong +datum=WGS84') + map.setExtent(-117.25,43.02,-117.21,43.05) + img = map.draw() + return img + + map = load_map() + img = draw_wgs84(map) + ref_filename = get_relpath_to_this('result/bug6896_ref.png') + img.save(ref_filename) + + # Reload map + map = load_map() + draw_another_projection(map) + img = draw_wgs84(map) + test_filename = get_relpath_to_this('result/bug6896.png') + img.save(test_filename) + + assert open(ref_filename, 'rb').read() == \ + open(test_filename, 'rb').read() + + os.unlink(ref_filename) + os.unlink(test_filename) diff --git a/msautotest/php/expected/setprojection-3857.png b/msautotest/php/expected/setprojection-3857.png new file mode 100644 index 0000000000000000000000000000000000000000..629da2cddca390d45ce39236492baf2b53f82e18 GIT binary patch literal 3236 zcmd^?`#;ltAIDc{Uxa-tsU(@YuB(fjDq?JwNU<*?1!3~}qe??2+cANLRM$K(BcJzkH;`-k`Y@p^nd36@u|axw>G zAP|V$#S7@G5Xd&op9O5+QkGTs!y%BJ-WSnlZNjny+$8Hg9uUUd#`SRPS&w`^tTGUW&V-688TU{N=1&8@ z@S3{0{psI%I*`{qOKphdBoPKvH$9UGY}18H*8g|IP{evqSy@Khj#96b@Hx}!lO^W} zfV1}p`x3XPgUEcR%pNsUf@Z1?oBas%>&2r>J>?QZ|iV7kD6As*cwG#En-!dCxQf*}A5R+>G%EC2cs#`YN% zXHk7-?);YMU(=#=+TaS=M%ywHRI8h7L)`{97N6o{haUl8ruAD+^1I{hpEa|xY_ujfgLvteDo(Tc#YLpF(6>l*L9Hu;uOKcgmoE8rZ^_Kpd zvOT@H$5uv#w|oo4tKPVMo?N3+|LpMTf^XZs?^Ibf$ifL;`Zd}$C)sSR;$-=5-j^6z zy~)MNvX;SE37W_8U(tX+24jBj-VJws)9G)r-Mqn<;qym=oLNZnw5Rc5)38!^tfxBy zN7EBH-O{7-A9W9I1M4K{XGwHbct|jgl!9u-*^F}xm+q!R;RFLi3)JYbc8sh)5q2oc z@M-ULvqvPYx+yUl1PE9>()?e(}Xd$QYA)W36 zQ+uwD^h-Y2c#l5FIgMv=KHZjAX_`B>RvW!(i;A5;L%80@s}_fz7EDYv;iMfx%Bi83 ze;jOrfNs(!PAn)fM)w<5#^!zXJ8uPmZnwn}{bh|OPbr3(-`!f_WK60o2v3h!;PP*a z>Felq{lhSthrRJFsqY5v_{w70YF@*35bg*E@v)78OYc{Ee(J+x~;9QU$;(?y@WyUFiL`$zbO^ZuoYf`><^gh_p)sIehQNwSNk#c;j#g)u9E%->wIuyl!_lX7y0K}y|XnPFf~#=s5bQEJfm+Dr>#rpn+*DXGX9<>sR)N+l=S zQI$U0_v;|FeFyPNp-zgnRZ{HG@`icjTuGroTG|JckC>|%IZ%E;@8vBPSwlqNr1Yp z(Nw5-RQEz0R}SNZ-uIb~JEioh-j&75SQD|Mw*_JeYV;^>HT($!Hdhtap|ZUi|1AB! z6U;ROUUl9i?yE3*-qSn^=6d>&@$71$km=duDD>^;l)p4LnA#1-xkMWO?chG5lbP9^ z9sRyLf(oyLtvmzuF{$*dOw1K+!%zVsEjwm+?lCOrND zNa&q#Pgd;~JrBxvNMB}L6(0BV30{ymY>D1Sz@~7HRLu7nV-oevhkLizdu!L_$5ux^ur zpXRc%iBjo1EcT1qv-&Zn=!wpy=@R6Qk$a2FGgH=HVtWn;O6@OQSWFT-=ki4bf*H{VD8CxoBEYy zhb7tr6gq>68xYg?=g|5bmA1wviv|*1SgfiMBSdIMh5iCldnyDvK-4j#nv=NQ-+7Y> zxGb$`bcPn|RoYoO`m>E;+191w%IFOEh7_-g;)Debfm#_^EQ4zSE{5ZB z9O|=_mKDcmi~SVO}7P)X}u zwxL@rpw#2ov`am|2Pm#C{$lu3|PSG!_9|EXo+?y{gv8L z@%KrcGLh~roo_q4AVq{yn5#?*^uh`G*lV^_N6Q7ga>k}?wy_oJoD@BsOxs1Hv1Iok z&>1-sqUXiV*JlL`42ET4G0Ms-TMF3tgpYNL2dwwly-e@u&5QCgT0S+j@k2Op3?Z*N z-bC=(+WsdXdc*z)2j={*esk6AKYg2A`J2RzsAQ(P0^HoynI_poz9+r7Zuou73I^uR zM)P`5nAg*L^FdgvmoDcddU{?BKOO zMo27ADKcCJl|aw^sv<`h$3O8Ds|KPDvpI1FfI``_NqQK9yo=R}8pgBP>fKV!yv#~lTI$tOEk(5yO^O{wi&kq&9Vb&^ij+HJHL*K(>okHoHqmNBoPxw52s^X?iM`f*c-Fd}>w50{!*AVd-4Erm zx0|+>o)!Xu(Drc0T|prJX8z{^)Kt!@;eH5#0BSvO&b~;zAJ_uOWXdOsK)xb z{1RI5oZ2e&@{6yXp>T5kO1XI4^;{ZGaTY)b5fRX24%FcWzkBeWA zJ#BmKLAGDV!_x9%1L(jpQ*Yl+TK98aM8CR^I=ClST~mx(ABm8VE670RyWVrXl*KKD z+-blGZZDI~G~B$pvOYPuG%4|^$ozi*3Y?Smvg2o~a*wkyKUV463Ho2;0b?_Q(n!T} z}I!MgT`I9f)7=kX%bz9f^#7HriO{Kstr- zVpF)O4n@0$I7PA$`9P)Iv)Y8enymO@uOSRToeK(Xq7^2brr5WT!*%eC6a`@oY)pR|gBv!HwhR%-JL!*&RzN%>ZY?41&ApjVZ{*Wn zCj5lyX8L$NQT%Ex5xbF=Gs}n(^xG8xW5u)VLF|?lhNNPn;axblozx}kEiaG3g7t0v zml6%}5nh+d?f!^`qARF-*~V^FmaP@rTfA~L$5}Q1%Up?@mDhqqHqIrz>ObwEH*sh_GlHEzki$E5iAZB zr56dqWRzI<@#gEw<%{v3{yooG9&g|T@XE61KLqINN{9_V0n|k02By$mB>iHIRzJ-D zgjpH*6?tI)(mtxQ4t{A@(8Oq6PY)^|p!!J_85((Nn%*!Wu*;4<_%g`s$sv9%QM5qd zF5&#S!lKJBOX8<5GuwC8Z>$I|4)!olyuAJkfK2%Op9!t;riPxk=ag})me~)l+1(mY zbm+Um8e`4LP8tiN-^e~QY`Ybk3*AL|0J5I6a!4!XWO>}&^z}Z8kYHG0PVYBhy9zDw9 zy6fAmvfKPZnf8i5v%;vMjc+D?`&rU*8wHv7N?)&)I`uAEzFVQG_kQFv9LA-(PIAHC&-jVXH@>t z0szS)1`-w3A;GE2c+xp@PxuJE;8}4?U!UC8Uk{{}$llk`hT1AC<=*~kAetq6Tm9Vb z=@6&fu3aaKyDvU9sQfd`q2HV zC3c=|^x|%+(Gh+{Pn2IUcr5mNid7`3F`(gjhMHgX1u48hu_8uRk>=|nH&+Xxv$2O- zv>Q$N-yOh?6Uetp4S#^lJ@)R+X8(mgR!A>Gt?K~z+D-+{u7jvDGgPyepS(7}&56rn;>YV-^_!X#simJ<4lFWccA aL|Aa7K3(u@n(7mS@No6UJ$L!`r~d+EN($8g literal 0 HcmV?d00001 diff --git a/msautotest/php/mapObjTest.php b/msautotest/php/mapObjTest.php index eb131d0319..f73e2f3cd9 100644 --- a/msautotest/php/mapObjTest.php +++ b/msautotest/php/mapObjTest.php @@ -74,9 +74,41 @@ public function test__setNumlayers() #$this->map->numlayers = 2; } + //also testing multiple setProjection cache issue #6896 + public function test__setProjection() + { + $map_file = 'maps/reprojection.map'; + $map = new mapObj($map_file); + $this->assertEquals(0, $map->setProjection('init=epsg:3857'), 'Failed to set MAP projection to EPSG:3857'); + $map->setExtent(-7913606, 5346829, -6120700, 6522760); + $layer = $map->getLayerByName('ns-places'); + $this->assertEquals(0, $layer->setProjection('init=epsg:4326'), 'Failed to set LAYER projection to EPSG:4326'); + $image4326 = $map->draw(); + $image4326->save('./result/setprojection-3857.png'); + //test multiple reprojections + $this->assertEquals(0, $map->setProjection('init=epsg:3978'), 'Failed to set MAP projection to EPSG:3978'); + $map->setExtent(1394924, -279190, 3376084, 1020214); + $image3978 = $map->draw(); + $image3978->save('./result/setprojection-3978.png'); + //compare the EPSG:3857 map image + $expectedImage3857 = './expected/setprojection-3857.png'; + $resultImage3857 = './result/setprojection-3857.png'; + $this->assertFileEquals($expectedImage3857 , $resultImage3857, 'Result setProjection EPSG:3857 map image is not same as Expected'); + //compare the EPSG:3978 map image + $expectedImage3978 = './expected/setprojection-3978.png'; + $resultImage3978 = './result/setprojection-3978.png'; + $this->assertFileEquals($expectedImage3978 , $resultImage3978, 'Result setProjection EPSG:3978 map image is not same as Expected'); + } + # destroy variables, if not can lead to segmentation fault public function tearDown(): void { - unset($map, $map_file, $this->map_file, $this->map->numoutputformats, $this->map->numlayers, $this->map->imagetype, $this->map->queryByRect, $this->map->saveQueryAsGML); + unset($map, $map_file); + unset($image4326, $image3978); + unset($expectedImage3857, $resultImage3857); + unset($expectedImage3978, $resultImage3978); + unset($this->map_file, $this->map->numoutputformats); + unset($this->map->numlayers, $this->map->imagetype); + unset($this->map->queryByRect, $this->map->saveQueryAsGML); } } diff --git a/msautotest/php/result/.gitignore b/msautotest/php/result/.gitignore new file mode 100644 index 0000000000..d6b7ef32c8 --- /dev/null +++ b/msautotest/php/result/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 7eb8a04c50a7960cffef6084786941d7c2b626b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:28:59 -0300 Subject: [PATCH 141/170] cmake: respect configuration of `CMAKE_INSTALL_RPATH` (#6903) --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19c1739b7d..b61f69fbc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,8 +234,10 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})") endif() -SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") -SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +if(NOT DEFINED CMAKE_INSTALL_RPATH) + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +endif() SET(CMAKE_MACOSX_RPATH ON) if(LINK_STATIC_LIBMAPSERVER) From 510e936e0180bf6c085e919f23a0bc5de74b86ce Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 8 Jun 2023 19:33:16 +0200 Subject: [PATCH 142/170] Fix build against PROJ < 6 (fixes #6905) --- maperror.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maperror.c b/maperror.c index acb9a6e3a4..2936f9a3b7 100644 --- a/maperror.c +++ b/maperror.c @@ -549,9 +549,11 @@ char *msGetVersion() sprintf(version, "MapServer version %s", MS_VERSION); // add versions of required dependencies +#if PROJ_VERSION_MAJOR >= 6 static char PROJVersion[20]; sprintf(PROJVersion, " PROJ version %d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR); strcat(version, PROJVersion); +#endif static char GDALVersion[20]; sprintf(GDALVersion, " GDAL version %d.%d", GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR); From 4467b54506cdf29bf96070b026c381fb9096172a Mon Sep 17 00:00:00 2001 From: Seth G Date: Fri, 11 Aug 2023 19:46:50 +0200 Subject: [PATCH 143/170] Add MapScript docs for the reprojectionObj (#6922) --- mapproject.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mapproject.h b/mapproject.h index b84574c9a6..82a1235616 100644 --- a/mapproject.h +++ b/mapproject.h @@ -90,7 +90,7 @@ but are not directly exposed by the mapscript module #endif int numargs; ///< Actual number of projection args short automatic; ///< Projection object was to fetched from the layer - unsigned short generation_number; ///< To be incremented when the content of the object change, so that reprojector can be invalidated + unsigned short generation_number; ///< To be incremented when the content of the object changes, so that a reprojector can be invalidated #ifdef SWIG %mutable; #endif @@ -98,6 +98,10 @@ but are not directly exposed by the mapscript module int wellknownprojection; ///< One of ``wkp_none 0``, ``wkp_lonlat 1``, or ``wkp_gmerc 2`` } projectionObj; +/** +A holder object for projection coordinate transformations, introduced in RFC 126. +This allows caching of reprojections improving performance. +*/ typedef struct { #if PROJ_VERSION_MAJOR >= 6 #ifndef SWIG @@ -117,8 +121,8 @@ but are not directly exposed by the mapscript module int no_op; #endif #endif - unsigned short generation_number_in; - unsigned short generation_number_out; + unsigned short generation_number_in; ///< A counter that is incremented when the input projectionObj changes + unsigned short generation_number_out; ///< A counter that is incremented when the output projectionObj changes } reprojectionObj; #ifndef SWIG From fd3e0bdd5575607838afebd31aed34932e214928 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:17:53 -0300 Subject: [PATCH 144/170] Fixed tile scale computation (#6912) (#6926) Co-authored-by: Michele Tessaro --- maptile.c | 2 + msautotest/misc/expected/tile_scale_z2.png | Bin 0 -> 755 bytes msautotest/misc/expected/tile_scale_z3.png | Bin 0 -> 11118 bytes msautotest/misc/expected/tile_scale_z4.png | Bin 0 -> 755 bytes msautotest/misc/tiles_scales_z2.map | 44 +++++++++++++++++++++ msautotest/misc/tiles_scales_z3.map | 44 +++++++++++++++++++++ msautotest/misc/tiles_scales_z4.map | 44 +++++++++++++++++++++ 7 files changed, 134 insertions(+) create mode 100644 msautotest/misc/expected/tile_scale_z2.png create mode 100644 msautotest/misc/expected/tile_scale_z3.png create mode 100644 msautotest/misc/expected/tile_scale_z4.png create mode 100644 msautotest/misc/tiles_scales_z2.map create mode 100644 msautotest/misc/tiles_scales_z3.map create mode 100644 msautotest/misc/tiles_scales_z4.map diff --git a/maptile.c b/maptile.c index b9e6bf46a1..ef32cad2a8 100644 --- a/maptile.c +++ b/maptile.c @@ -491,6 +491,8 @@ int msTileSetExtent(mapservObj* msObj) msDebug( "msTileSetExtent (%f, %f) (%f, %f)\n", map->extent.minx, map->extent.miny, map->extent.maxx, map->extent.maxy); } + map->units = MS_METERS; // now the units are meters + return MS_SUCCESS; #else msSetError(MS_CGIERR, "Tile API is not available.", "msTileSetExtent()"); diff --git a/msautotest/misc/expected/tile_scale_z2.png b/msautotest/misc/expected/tile_scale_z2.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1e62af393f52a5f8e20d4b4965606fb7116a6c GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLk0$>U7jwEAr*7pUN!{EaWokG zo_bP0l+XkKT^83X literal 0 HcmV?d00001 diff --git a/msautotest/misc/expected/tile_scale_z3.png b/msautotest/misc/expected/tile_scale_z3.png new file mode 100644 index 0000000000000000000000000000000000000000..e21212f28da80b560e6740ff33e484956a995b22 GIT binary patch literal 11118 zcmaKSWmuG5)b2CG&|OM5NT-1GP}0)!A|Rj$NJ~h=&|MPJ4N?M)r%rYEcJn9v)#KAt3>QPc=0)wY6g-Bj+b`jw+4s<<99txgd`wb+)M3 zSZU8gi`#<5FYfzW6XhSCWQn`}`MHtfUwOW+%^pcv2^pK1l$Vt?H#aMb2Fq!OnPcbX z=0cRWl_p=58w2IENsrOvQ&K|7{J+Q27G@yxO5!fy@v22RK8M(^FFBIT^NOLe@^V%Z zY>jIUIVBC4g{5UrcXxtFwj3qz7FKRs+d^lj`T5~mVax}u(5QYmJ2$t&iK)K+#LSG! ztOw4k&n0ZA2+{}X85xfA&B=8$WH=HfY!E4FqLlYZd_$U?IsOEKh=Ss5Tvs#UfBqYv zoJ@Z2-s4$IoDg9>Qsm2*1$lYP$JAFW-*7)nU)%4~Eugu|>x(dO)f8yb zyxrOSkmGmIiFu#zxzFyb@Mx$udpdHXysC}K9xX%;k9HJ8i=8D8o@*_v2a$aY#X;py zXu-7Vs5qg>r}F5?5t|Z-{TV(vq*(sH{m?fy)Q=xO!sz`TadO(M^(Sxq$YQo92-y!; zh3I{c63WZVGcx9qICQVBuQk-wC8eam<6L#$H)X%|*Z_qgeRKBm;!#No0|^ZDMr}*W zukmr$*}B&sKYko6xCX~QI6O>+4 zflrX1|7D5| z4u^wcbU9d(9knm2j!;Grk&y*Er%1r~EndA!OHUuIKl&D|jHrImjf069w(vkejERS5 zsK4K4C|wwwNFlX`IV=Hd2|N%ZBO^98wlOZWy0IZ4Au%^Q`_AEE2)Y6jbO5lANrr=m zX99(>{v#{O3*{Qc!OcJiLn+bwk`9fZre}6G2>$~@bg!H z`jp`60)Cnk<^#&|WhOeO<{K2`#j+17Yz zZ}-MfhSKcDtvq-H506J%0i+L}#P3l@GAS^jDl03KxeS=rmQ?N~Wo6krIQSiJ>5tON zQ^FIlP>kZ@RM|?i=eGk&#ThSN>+UwqN|Ny+*HPDXFxv z%>YQ3NT^8M(&s||wRi|bX?*d&y_v1ImAO9By%(o)-q?%yIWrT{tow4Ri!44dk@ViZ zo)=>T^wJe$F~+$2R1 z-aw#6oB_?w&4IHsdiJar$85PP1fb}@VHv9;ZLD+lQc_aV3d9@T7(_fTEbDrY3Oy$;lIgX+k{Q+<;9C#RL`Y;JpI_@`Wth z*Y@*P0spm-?#;U|y1BZ#y1R!#{EZ!#fHD2Aj}01PtA;>jG&;-&T8)p7$Af3)&@HB* zqS^y>dKNSL#l5Pk%F)Ni$Iy^cC%3s-oMsVpO!gbIRA5CZM%~LhV%hk2i=HN4b3)Gb6t7mX z{OQNTg9GdBlQZpt$BejJ=lA2ikVwdv!afz$qlt+LK<@A_tG{mAEv&4VO`5z<_xPzp z$}l|r_4W1T<%1Fuh;?qWyW0;sySi3>=E+waWlw_g2XNLiIH-;m^_4^Z_3P65`s3@% z)37lnWv?HZVnie^h6T;dv;F=307f?2!L9ln_C2t3%Y6&pO7qAG^*|I}?9;8FHtS z9YYtFe+xuan zxSV<$4ra^X6@#khzJMgVhs3;&tbKi33knL#%WZSKpM8&^#+(Yn;O6Gm(a~A@`}FD4 zRMOezDw0Q!9wj9wzb+o`4qigPE0&a$$Gu;}%=UgYv7@aIrs?YH1`+;5rKQdEB|gBk z9hfLLz{kf2AB&5Niz$&~q_0m-N{Yt%XL}nH17jr!s6!+7&N~TtbLEMD(n>+p0s$Ft z`0tY zN$QXFScRya5h~o5`Y}5(QSbS09h2UNh^}HadFS<5G2{6gXXmYRHcrk+j@TJ5JPkGQ zkR7GEA0#Cu%7?GXwFS7?wm3#LqkK;Mec`V85I@Wpj4Y3A`by> z-0rnKAS<%)@sU)E?PomDW7#X?HPbdQz+8JMB0_Lx(ED|EHl0`HqvQ)x=(ES)e08>g z-d?k>YUklaMXyv<`_25p=hini(%%$dJqyG_hhk|ZLce)c^K-b8kdR#bVjHI}^iM_8 z#;!1GjIE>*U|Au9kkJYPxhn1B6dD>D>~3D!mpWji}|>OpyVd4=Bt_QRh-VTANR z!F_ul{u|43CV3$a>+}K8`MJ5Mqelm{BRCMlO{ez5^&~1bK|yeI);Cw@LG~zBv&)m+ zLQL=hhLD8&o&r_Jt#1BSz*|pGP%$qK%E~zPWVtJUa6SFT4QPi~RJ1Wo$jW9~SopEB za`=}omneU^n;??#BP=XP02gXG=)x_0PFDdlHa5oaW+sRq{#u zAHNv0nookgadR_i^%CBcUE&j$k_s^f6>5FB+NV=mS6zMZ-qerLo?3$YSslB$c)FS+ z3sfxJWL!CzVrgmVT8f2!r37tmZUVGaR8+K|AGSHWyaXzVPSPX3&Xc>^a)|0x$}^&S zzk6a_oSZ0}YiDPlA%uzVdwks>gaJ+U^|H36#_N>UPf>h)dYb)6_>|7?Y`M2rxl%HL zh<*F`=!nc1Vb%-4FD8an3f}VgLw+s)7nhbs)Fpgn5*0P*{LKvS z{{9^_(s$6|e=Yz1{Y#-R%G_b=s;;gMyadK}XL>qSgo5*GFY)NxGEHl1_Jv`fAb2TLlf2dRHI#csXp4VYeR0|!)c3FYdd@>aIH#7$zYosVIAD^g@kgj9i+mV7K z2nk629qWFw<@2!5}lKa8RT*x0gIMs?OBMQZPr z331!Co<=&;jnN`x}YukhjhhwoPd!=yB)d;#$6rq{rREZ@|OBd8f=m z?{fg#>|7=;!$#!+OZE?9Qnj<=cGM(dJf#(N$fWv6N+cp80%QW`?z{KzG4UCMd^WP& zl?jRYw3NVC1tumYCKx|Sf4B*lq>%bhhDO{~IW3Vz4m9-$xciA#92^|LN0E_{%5fxo zTBZ;lzy{#?0a#*j0`W$=xqj8@*nSPf7<(J_(uL5Q6@|gCHan^D@uE5iM6Soj69wBuHzp>I{m7CCo58?a zc*m;7f6m|Nf=ebNBXhIybQF+z>TF{Z6T%`Q((ZdS zT(PWV)Avz_NEUFHsZkRRH=wSnS`KmQR=2jE>FX<2^K2y~B_VzT7aKJUd~Hbqzdi;! zI>-Lcl2-{5_+xlUMC?(vHa2qd@_)Ia_PYI*adJOiw!LLhwpq=cUIXqZbd2Fz|8OW$ zl0`)1p7vsIZ%JVx;uHOv_p4W|Bw~fJ#KgpdWRW?fZ0a4EGq>+V{&ktz^`%IipPy^# z?fbR8-A(^I_1^<-D7q4)9zZlCH&Rr#TMg5hnwk#I3Rw;k9gXJnzODH95fIbzUo3>Q zwDjPqlY;92@Yp|_0frPOfw*YPw*m8pvB^TBakRMc06DVIh<7a1mF|CMhM;Z#n#>z^npdDPX^YU}Gm zM$g{1=8$9IGKh&8o-3tHR+>cRvVVKwj$FD3U%{#)iBOn8W+x|ybkI;xlmyI45jhA7 z3Tg!-9VMHlhnc{4*Emj;>Gx-3WM$zG#n-2i+t}F9(9mez;H+Gc+whQag05IGvUy(( z?d@QZeGNvyHx}5vlDeR7oT{L;qVsWy$&N28gNzp$9D3<}ijz8W}%hPnRmw z_Sk4c#PDYp7M5sAq0l<=et1*!=g;AX>tbE-|Cj6;^u53f&B@96xot*P)#ddDW<##c z`$_pfNI3-98a~suik9y7n+scG#&i4!*yJnsdgwuVktXr}aST-mp>pKs17&>q=MbP3U2gmhA` z!K^b7&>+Yqa&sB1!G)dASmlr(=^>xr5hUnd@EhdM{QRl)Q;{F705&cpn5IrNh49if zG093uSpM^e{m;gBAFdflE)o(FI4ONEPwa*1vR8Qitq;lbKAfiZ_atCLQ21XQy^f_x zvhBsqEiC*tKX0P{1^B2>%&+HW^6KjJ3=9lDvknDglY%Uu>EH=I`1Vv7$VT+*snKUv z`w~^=e!!J)Nk~aScB4$4FAa1^Pfrg#3(<=UE!?gqYL?lYx(rJ_2)s{kPVzF_hF;)> zg3)QyTgG*_5(@?tz28{?F6J85A)H@O@ZxApQ@{QWxs;_6Q13+i{{y}>H&qs=Gjrtd z@Gy`9ahj|7=FO+tTA}+3rLbOH21!YpPnm|Q%B=B{EUc^vBL1I|w}Wcj+gn=zHW}{{ zM%L4A*M#(RRUh=;>FMeIepTKUU9|Z7NL$zpe`ST~ z{lNVEyf$7gJC!q^>-(Ufpnw1v;`i!mAxr|3nT^eIwKoBfX?nLYd;t%};uK8ytqaUciT z&l6&*6^%yS=i_v|0GbVb2FsP>Gpy61q`X{Wm3k<3>T5Kel-GEPcB(+Uzim%TXLKh! zp1+%r&VeF$^M^!I5)!?do3p>ao!~1f{6^!GlX8%}LntL0oL@v_UFEBGr_q1^VI9p2 zNs=ISbxARfFZbIGN@2>miU%kPd2{o;hzRUo&;CX*JfcBBYs}Y6eH;ZS6zV~?M<6r( z8W|lngg{3xJ(B)-&<%&eQRTiM;kZxrF@rb! zClbpWLSbQHcC-b*OZ&>KWZW}WRKuRle{6|)6co-X{q}PWjK?&GQs27*(}o!AEHykI zJzDOa9S9cdK<^8c5Qui?cLb)XFn zI)I;xYXGRk>U4@Z26+biVm5$ApkU>av1MN7^RZzTK30ehpz=nb9+3m{LPK*k=h*&w z+SV}m1KjM7zr!+M)?Q&XRn>S`oQphx;suq+~=F!Qt$oT_hG+zsHv)o^NwgRrV!5z0SRg4 zT%8a5xB1^nb9{e=`y3ZatWaPQ^FHBz$we{*s{Zfq?}-gjEa@^EMy955JGiB>F){e7 zVZ?t=PNd(gAPoQSn*iDNL+_p>wN#T+@_*q|$isUKsu%R)*RNlfk5ZkrZ$O~@8w^7p zkKX=r8Roc^#=QCJ4r3TOJvvetH+MiK^jQF$DU2Zz14!)L^lNx{KQD|<+-V7Q_B418 ze-XVy%g``l5K})Fv=ow_?mo_-M4gMXbFjCiE^9C&iY`?YKe0h>Ft=ZBXaCP1hTSwO zIWu?%9umESc4lSUHFlR5M<$hG;M9Shovv0 z>$u*@n!&5<>tmv#nC(M6fJSq7aTzNsYb1n|cBBftT>1T5#i*0VW#flp-acT7wY4<> z#LLUedwT?;0K(ngya6uWc?V-Lj#`wLi3u+AiL&kc$r%kLWm;+~*6@$MzRmUnua_^G zV{?FdN=gcDb#-&oH;I_nQIJ8>Zrn!Qj9H1Vi94 z@^Wc^|8^;e@ZAZ5N6`a*mnOXCnl8-C>+J3Qb2loIl2s#4g|wI>)uGp~U#E^Ke+f8Y zl7y+JKa8j&w_90SV)#k!_AQ_T0a7jyCV~Tp13C8U)vMCdQlRNq{8oZD!1K!a3;*Zf zP#F>u0-RA+mWhwg)pk|;lUd9^g0Dd9FEqJ?9sSh3 zK_=XdlHSM1gK{htxKBxf1yY*VT;t}G6^5V{OP0X-s(Jn7xK&Jme0+TYumEZUUW?fM zyqc;NiH@q2|8xnMDv{1X)szgoV}9NjOzGH18tmsV8igJ{tgERBWXa6T1Ou7xarBF$ zqxk~#FHq3v=;*^M&9J_mnOg7*4GauScn~v$*pgv`{GJ~~>sDjn_Oc~C4-b~Vf}33c z&zKi*bmSV-M2tpOa_%oq1Ef}TboASuX<4Ue4jhXAAoeMub>bZ$dL*Z_FHiRytE+z= zumIm?ZH~>r!ctgLqMXRAsvQACXlZFNBq(Ql?=>+FYbq%ySf6F$S)!t&@icC}FZ26e zxKdMRhE{@0tE+a>z}D=<`@k1f}hLyqqwiO zO>bAcusFUh%fQVhf4^5PViy<&p~ck=mUFss$@kGw9in|jMJ?3RyV&UmMr;>>I8Ztz zu4r&L5R4}~GX+~WzzcvOEFhH0=$En(py9E>TPgxSKR$ECkuu_;`}x zNHZabfkUGBp0_*_6PuZwY^bc<1GfPBX{On&JT5Lyo$cT8v0~OsE2~C}zIR|gjOXaY zAzvVLCC^}NPL{Cq!WD?Ss}C~QDoRRW1zjCoU4gf75dWD}o5|kBZtd(S44XM)5fUmf z8R+Q&yJKT#7oBt9L3XM>-l2KbH$P81$L~!m>EU#|H34jWfe_kuH3Lf8Zo0a2Xefqx zF%SacN=*C_m!7_U=LbIH&p+F({BEz^*N=<)e~ym_Z#sbV1jHk$CIVF})n|Pd9RO0wJ}&Lg9xcmXY*y8l!)0dh#8_O1mw;O@*+{+3uMwv6W_f9#PlCM zA5WMsjDc2AR8+})C?u@2)q@Mt(^bBnsxTBXYXr_$40x+o@4PSr-Xv~75H82vE`a0f z*RpdmV4OJlU2VYJ6fy(plM_1c!iu${BRvI0?}d37Ar)7Gvev-KK7OIRrp)!j!?fyZ z{=$ceY#LktR%~B&#Io~zrr_oYBZWapZvYroTpD_MHi0OO(3E&{clR3P+IZ9Cca95p zk(lhoix*l5FmXCHt<`{uiHW7^wO<{o#bT&sEGyil{7&K0`=VC3Sh>Z;p;64`_=i$y z>TiK2gL(f3k`&a&p~Qa6KLB4#Q-H9#F14rf2lWq^ehwe54bWoo4q~6r6cYA9q%h-F zuZbT&VhdP*ft$!}2#BiUE0d(JC;WNS@eCzn$q%V8=kGz`yJ3SA7y_9agH>Z(*36oD7KX zY|4%>U8E}+;>QN5wu`I00|7~%&1j6BTTlQ1PgTCK%(!B$r$ywy#5fKRE!`z;b91%M zg3{dF>Z~vnC>cPFMvV@P$AK8YmIDrm*&FKZ_1LYS@}e_o2705R>DSP~E}0a~dV>4j zFWKZ5nh91}qq9uk7?N8k~aL4|}ss#=yFkXmE@6=P>_ zeSLjzPZ|W5AW9h@*E<4HE@K(7dbD_}S-0Msf(YqmkH0Uxyu@kPrKSDA_}ZzUtgLJ~ zhgps`nvq`EhAfGQh9(+`6=o*2Syol0)C|W55qU_rw6-P$R6{jrXjUw)GxEOFswzI0 zDg`h{)X=~$=I}u_avL>7^L&h?9zu@*D-#UHMTLcDXJ<$}C*x>VL7dN1PAPPOcz}b5 ziGj<%!x@q#(`sjod)Z{v)KO@1pMV6|Il<6*B#ihu+1f_*j{f1jPC64zB_+=Ab#Tv# zp3>Cl;(DEx^-Q7D+~8Tx!5nUPu92_|$@1^u0Qn>u5*Z|lEydvFdOzU3$EceT92^X+ z-uf2#b_oxJVNFL#P{Tm81vCp__&_kd{rJ)T$&=Wuta(7BP1S};2TU4Q$5W;P!O9lI z6OUtQun8Y~emI$nC%OSB6BPusn-##>El&zTdYWa>7&O9^+Q#;XNJT z1sUrvVOg4kCs3;=7(ENrmM^#ADTh^5RDgcRxZ-l=`OF~60jO~JpY5GC2;?e-x!3+PK@3yuK(mN0Vt+ZJ5Zjf3s`i`o zv0{@Jk2l?sOGOhiwgClFBbU09=EiM0_nycyXNe9 z`+X}<;3_I9DG8*KJVp)bFJq1m52+4D#MnuDkdXjDf&6QB-(R>({Sp%L7Dh_|t;(Zq z7JY&(YsYm=Wo2fj*3_S#%G_QFVPt=i@L#gO%a+^2lK_5>t@h*IxiE7ugii3vBarRU z0XZ=}y`zoI>|*NJ2Tf`!s;(!==^{W=4GNXu=lWQyywo7YktFE=15@ooCNWAGKc5_# zJSuQ6mh;CTz}C^#Ez;re*#nDL3eT>=b_#=>JVuE=(TB8Gd>5s`7&UEDvv0abmL-JM*L@Lb5N1&+4j=?C?S4%5CAz`E^hWhUsK;Pw^ox#XcW}e5J*xy&0qJDjT!_3GC zE9PvgDs5;G5fh`V7qskcX_3^4$aGqM4{2dASSc0{MDKy=v(|~ZNO(-lt5@}69_?VB zbeEJFt2F8pKX{S}@?+%8m`i?xXuJYYWiHsmV`HSXGhkytb5Smr?uw)Xuo}Q3?~Myk zCE$`y4-P19BE#9~6HXYqSI)UqWiI|OTO8m#aW5_^ilG!LE-C3Oopf#8)g zu&9VtFw%X|_q{7=a(+#XbM>4Vs1G|kyMutbn3VuNIFJWQeG*qzJ_#E~ncOz^_Q`z~ zX9plsTlnH02i}BkNNU*w|Pw${t=Z z1y~Pss@9`n&F9#6j|1RWmA5cCJDWE_8SLeJ0b_mO&?5Ml^3|=_V2`9`aXsY;otuoq zU#!dc5JQL0@czXU)>^%K1roZuZHBtmOcyX9T6G2nPkF1-6qpp6k*@nN2Hm>_#+3|O zuvb8IS-*c_Buq@qZlR7pBL!fBEq%V42$p+97d(PC zrfS&(Q7w>G!}{ISE39SeV_n@tU^+R7YT&DCfU8;UB@_>c?sdrAo@;^`7T6U^e){NJ zk4`CBB4qfRg9%j#X`OY&0nt%5*pG#Kj~iHA3`=05CD72&tRH(v!f@Q<$vV#eZGf;M z?8uKDQ7V%O;?%!{k_R0i+&}l1Ayi}sKLIK+4!JNlm64tfreeVPfORRbnzwv0_>S(& z+uaM$x7g{b#9ZGHPGAGZBa}moHpR5g>5GpHdHh;inx4rABCV^&NsP$ z%_}LOSh9hAtnGop{VgmC!LTgDu}y4=_vjvkqeMi6w6tVnk~*YGss%eAKv966 zvMYxi&MV|Y9+auyxgscW!?~AW!v^e$f*f_O!G5fok_;!P7~Ki%0u)No(b0j>lr!1O z+gqN5sv$sbGXRN$z^^cEzX67Nw&oSCwCw_fQ-taDHspU_;kzYVX83YguEQAv_Glp$ M#U~1ta%O@52lYrEOaK4? literal 0 HcmV?d00001 diff --git a/msautotest/misc/expected/tile_scale_z4.png b/msautotest/misc/expected/tile_scale_z4.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1e62af393f52a5f8e20d4b4965606fb7116a6c GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLk0$>U7jwEAr*7pUN!{EaWokG zo_bP0l+XkKT^83X literal 0 HcmV?d00001 diff --git a/msautotest/misc/tiles_scales_z2.map b/msautotest/misc/tiles_scales_z2.map new file mode 100644 index 0000000000..52385ca544 --- /dev/null +++ b/msautotest/misc/tiles_scales_z2.map @@ -0,0 +1,44 @@ +# +# Test for mode=tile and the use of MAXSCALEDENOM and MINSCALEDENOM when +# UNITS=dd. +# This test should generate a blank tile because the layer is out of scale +# (zoom level too high). +# +# REQUIRES: INPUT=OGR OUTPUT=PNG SUPPORTS=PROJ +# +# RUN_PARMS: tile_scale_z2.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&MODE=tile&TILEMODE=gmap&TILE=1+1+2&LAYERS=canada-poly" > [RESULT_DEMIME] +# +MAP + NAME "TILE_SCALE_TEST" + IMAGETYPE PNG + EXTENT -140.992892 41.976786 -55.630945 71.990315 + SIZE 400 400 + DEBUG 5 + UNITS dd + + PROJECTION + "init=epsg:4326" + END #projection + + LAYER + DEBUG 5 + NAME "canada-poly" + TYPE POLYGON + STATUS DEFAULT + CONNECTIONTYPE OGR + CONNECTION "data/canada.dgn" + DATA "elements" + MINSCALEDENOM 30000000 + MAXSCALEDENOM 70000000 + PROJECTION + "init=epsg:4326" + END #projection + CLASS + STYLE + OUTLINECOLOR 0 0 0 + COLOR 120 120 120 + END + END #class + END #layer + +END #map diff --git a/msautotest/misc/tiles_scales_z3.map b/msautotest/misc/tiles_scales_z3.map new file mode 100644 index 0000000000..39c8415826 --- /dev/null +++ b/msautotest/misc/tiles_scales_z3.map @@ -0,0 +1,44 @@ +# +# Test for mode=tile and the use of MAXSCALEDENOM and MINSCALEDENOM when +# UNITS=dd. +# This test should generate a non-blank tile because the scale is in the +# layer range. +# +# REQUIRES: INPUT=OGR OUTPUT=PNG SUPPORTS=PROJ +# +# RUN_PARMS: tile_scale_z3.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&MODE=tile&TILEMODE=gmap&TILE=2+2+3&LAYERS=canada-poly" > [RESULT_DEMIME] +# +MAP + NAME "TILE_SCALE_TEST" + IMAGETYPE PNG + EXTENT -140.992892 41.976786 -55.630945 71.990315 + SIZE 400 400 + DEBUG 5 + UNITS dd + + PROJECTION + "init=epsg:4326" + END #projection + + LAYER + DEBUG 5 + NAME "canada-poly" + TYPE POLYGON + STATUS DEFAULT + CONNECTIONTYPE OGR + CONNECTION "data/canada.dgn" + DATA "elements" + MINSCALEDENOM 30000000 + MAXSCALEDENOM 70000000 + PROJECTION + "init=epsg:4326" + END #projection + CLASS + STYLE + OUTLINECOLOR 0 0 0 + COLOR 120 120 120 + END + END #class + END #layer + +END #map diff --git a/msautotest/misc/tiles_scales_z4.map b/msautotest/misc/tiles_scales_z4.map new file mode 100644 index 0000000000..2478ffe8fc --- /dev/null +++ b/msautotest/misc/tiles_scales_z4.map @@ -0,0 +1,44 @@ +# +# Test for mode=tile and the use of MAXSCALEDENOM and MINSCALEDENOM when +# UNITS=dd. +# This test should generate a blank tile because the layer is out of scale +# (zoom level too low). +# +# REQUIRES: INPUT=OGR OUTPUT=PNG SUPPORTS=PROJ +# +# RUN_PARMS: tile_scale_z4.png [MAPSERV] QUERY_STRING="map=[MAPFILE]&MODE=tile&TILEMODE=gmap&TILE=5+5+4&LAYERS=canada-poly" > [RESULT_DEMIME] +# +MAP + NAME "TILE_SCALE_TEST" + IMAGETYPE PNG + EXTENT -140.992892 41.976786 -55.630945 71.990315 + SIZE 400 400 + DEBUG 5 + UNITS dd + + PROJECTION + "init=epsg:4326" + END #projection + + LAYER + DEBUG 5 + NAME "canada-poly" + TYPE POLYGON + STATUS DEFAULT + CONNECTIONTYPE OGR + CONNECTION "data/canada.dgn" + DATA "elements" + MINSCALEDENOM 30000000 + MAXSCALEDENOM 70000000 + PROJECTION + "init=epsg:4326" + END #projection + CLASS + STYLE + OUTLINECOLOR 0 0 0 + COLOR 120 120 120 + END + END #class + END #layer + +END #map From df22e68f4b6b172e8917c4db47ffcc6dc97115e8 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 8 Sep 2023 01:05:09 +0200 Subject: [PATCH 145/170] msLoadMapContextGeneral(): fix use-after-free in error code path --- mapcontext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapcontext.c b/mapcontext.c index 435fe79692..458e642f91 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -696,10 +696,10 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, msProcessProjection(&map->projection); if( (nTmp = GetMapserverUnitUsingProj(&(map->projection))) == -1) { - free(pszProj); msSetError( MS_MAPCONTEXTERR, "Unable to set units for projection '%s'", "msLoadMapContext()", pszProj ); + free(pszProj); return MS_FAILURE; } else { map->units = nTmp; From 08004360ec21d865b0e3eba1a656e8ab2a67be77 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 8 Oct 2023 14:13:21 +0200 Subject: [PATCH 146/170] [backport 8.0] Whole code base reformatting (#6938) --- .clang-format | 7 + .flake8 | 19 + .git-blame-ignore-revs | 1 + .github/workflows/code_checks.yml | 19 + .pre-commit-config.yaml | 32 + apache/mod_mapserver.c | 342 +- cgiutil.c | 352 +- cgiutil.h | 24 +- classobject.c | 98 +- coshp.c | 193 +- create_mapaxisorder_csv.py | 2 +- dxfcolor.h | 322 +- fontcache.c | 246 +- fontcache.h | 28 +- fuzzers/shapefuzzer.c | 15 +- github_issue_no_activity_closer.py | 125 - hittest.c | 179 +- hittest.h | 3 +- idw.c | 76 +- interpolation.c | 407 +- kerneldensity.c | 234 +- layerobject.c | 94 +- legend.c | 21 +- map2img.c | 249 +- mapagg.cpp | 1490 +-- mapagg.h | 103 +- mapaxisorder.h | 8203 ++++++++--------- mapbits.c | 53 +- mapcairo.c | 906 +- mapchart.c | 731 +- mapcluster.c | 801 +- mapcompositingfilter.c | 230 +- mapcontext.c | 1534 ++- mapcontour.c | 611 +- mapcopy.c | 290 +- mapcopy.h | 65 +- mapcpl.c | 94 +- mapcrypto.c | 190 +- mapdebug.c | 124 +- mapdraw.c | 3550 ++++--- mapdrawgdal.c | 1903 ++-- mapdummyrenderer.c | 231 +- mapentities.h | 325 +- maperror.c | 403 +- maperror.h | 208 +- mapfile.c | 7796 +++++++++------- mapfile.h | 21 +- mapflatgeobuf.c | 187 +- mapgdal.cpp | 603 +- mapgdal.h | 2 +- mapgeomtransform.c | 380 +- mapgeomutil.cpp | 61 +- mapgeos.c | 1418 +-- mapgml.c | 2498 ++--- mapgml.h | 11 +- mapgraph.cpp | 215 +- mapgraph.h | 7 +- mapgraticule.c | 1151 +-- maphash.c | 112 +- maphash.h | 197 +- maphttp.c | 486 +- maphttp.h | 131 +- mapiconv.c | 8 +- mapiconv.h | 5 +- mapimageio.c | 958 +- mapimagemap.c | 564 +- mapio.c | 619 +- mapio.h | 144 +- mapjoin.c | 724 +- mapkml.cpp | 284 +- mapkmlrenderer.cpp | 642 +- mapkmlrenderer.h | 127 +- maplabel.c | 953 +- maplayer.c | 2105 +++-- maplegend.c | 996 +- maplibxml2.c | 33 +- maplibxml2.h | 14 +- mapmetadata.c | 609 +- mapmssql2008.c | 3834 ++++---- mapmvt.c | 481 +- mapobject.c | 370 +- mapogcapi.cpp | 1710 ++-- mapogcapi.h | 6 +- mapogcfilter.cpp | 2094 ++--- mapogcfilter.h | 124 +- mapogcfiltercommon.cpp | 316 +- mapogcsld.c | 3761 ++++---- mapogcsld.h | 48 +- mapogcsos.c | 2034 ++-- mapogl.cpp | 198 +- mapoglcontext.cpp | 451 +- mapoglcontext.h | 35 +- mapoglrenderer.cpp | 335 +- mapoglrenderer.h | 93 +- mapogr.cpp | 6438 +++++++------ mapogroutput.cpp | 1205 ++- maporaclespatial.c | 4393 +++++---- mapoutput.c | 858 +- mapows.c | 1817 ++-- mapows.h | 430 +- mapowscommon.c | 525 +- mapowscommon.h | 159 +- mappluginlayer.c | 159 +- mappool.c | 226 +- mappostgis.cpp | 3056 +++--- mappostgis.h | 126 +- mappostgresql.c | 188 +- mapprimitive.c | 2122 +++-- mapprimitive.h | 33 +- mapproject.c | 2753 +++--- mapproject.h | 189 +- mapquantization.c | 584 +- mapquery.c | 2035 ++-- mapraster.c | 1268 +-- mapraster.h | 61 +- maprasterquery.c | 993 +- mapregex.c | 31 +- mapregex.h | 86 +- maprendering.c | 1004 +- mapresample.c | 1609 ++-- mapresample.h | 21 +- mapscale.c | 708 +- mapscript/python/examples/project_csv.py | 16 +- mapscript/python/examples/shpdump.py | 23 +- mapscript/python/examples/shpinfo.py | 59 +- mapscript/python/examples/wxs.py | 7 +- mapscript/python/mapscript/__init__.py | 23 +- mapscript/python/tests/cases/class_test.py | 48 +- mapscript/python/tests/cases/clone_test.py | 28 +- mapscript/python/tests/cases/cluster_test.py | 10 +- mapscript/python/tests/cases/color_test.py | 12 +- mapscript/python/tests/cases/config_test.py | 6 +- mapscript/python/tests/cases/font_test.py | 18 +- mapscript/python/tests/cases/hash_test.py | 29 +- mapscript/python/tests/cases/image_test.py | 50 +- mapscript/python/tests/cases/label_test.py | 16 +- mapscript/python/tests/cases/layer_test.py | 119 +- mapscript/python/tests/cases/line_test.py | 12 +- mapscript/python/tests/cases/map_test.py | 128 +- .../python/tests/cases/outputformat_test.py | 62 +- mapscript/python/tests/cases/ows_test.py | 21 +- .../tests/cases/parentreference_test.py | 23 +- mapscript/python/tests/cases/pgtest.py | 20 +- mapscript/python/tests/cases/point_test.py | 41 +- mapscript/python/tests/cases/rect_test.py | 53 +- mapscript/python/tests/cases/refcount_test.py | 49 +- .../python/tests/cases/resultcache_test.py | 19 +- mapscript/python/tests/cases/shape_test.py | 65 +- .../python/tests/cases/shapefile_test.py | 13 +- mapscript/python/tests/cases/style_test.py | 81 +- mapscript/python/tests/cases/symbol_test.py | 65 +- .../python/tests/cases/symbolset_test.py | 48 +- mapscript/python/tests/cases/testing.py | 17 +- mapscript/python/tests/cases/thread_test.py | 69 +- mapscript/python/tests/cases/zoom_test.py | 26 +- mapscript/python/tests/runalldoctests.py | 12 +- mapscript/python/tests/runtests.py | 182 +- mapscript/python/tests/timing/clonemaps.py | 29 +- mapscript/python/tests/timing/drawshapes.py | 48 +- mapscript/python/tests/timing/testing.py | 46 +- mapscript/v8/line.cpp | 107 +- mapscript/v8/line.hpp | 23 +- mapscript/v8/point.cpp | 119 +- mapscript/v8/point.hpp | 19 +- mapscript/v8/shape.cpp | 192 +- mapscript/v8/shape.hpp | 41 +- mapscript/v8/v8_mapscript.cpp | 7 +- mapscript/v8/v8_mapscript.h | 45 +- mapscript/v8/v8_object_wrap.hpp | 41 +- mapsearch.c | 741 +- mapserv-config.cpp | 128 +- mapserv-config.h | 24 +- mapserv.c | 157 +- mapserv.h | 6 +- mapserver-api.c | 19 +- mapserver-api.h | 24 +- mapserver.h | 5774 +++++++----- mapservutil.c | 2138 +++-- mapshape.c | 2382 ++--- mapshape.h | 269 +- mapsmoothing.c | 220 +- mapstring.cpp | 1567 ++-- mapsymbol.c | 967 +- mapsymbol.h | 186 +- maptclutf.c | 62 +- maptemplate.c | 3683 ++++---- maptemplate.h | 118 +- mapthread.c | 104 +- mapthread.h | 60 +- maptile.c | 287 +- maptile.h | 17 +- maptime.c | 261 +- maptime.h | 26 +- maptree.c | 597 +- maptree.h | 88 +- mapunion.cpp | 358 +- maputfgrid.cpp | 441 +- maputfgrid.h | 194 +- maputil.c | 2086 +++-- mapuvraster.c | 899 +- mapv8.cpp | 132 +- mapwcs.cpp | 3194 ++++--- mapwcs.h | 246 +- mapwcs11.cpp | 1009 +- mapwcs20.cpp | 2826 +++--- mapwfs.cpp | 5913 ++++++------ mapwfs11.cpp | 408 +- mapwfs20.c | 1683 ++-- mapwfslayer.c | 500 +- mapwms.cpp | 4032 ++++---- mapwmslayer.c | 849 +- mapxbase.c | 638 +- mapxml.c | 17 +- mapxmp.c | 128 +- msautotest/api/run_test.py | 19 +- msautotest/config/run_test.py | 19 +- msautotest/conftest.py | 11 +- msautotest/gdal/run_test.py | 19 +- msautotest/misc/run_test.py | 19 +- msautotest/msoracle/run_test.py | 13 +- msautotest/mspython/run_all_tests.py | 10 +- msautotest/mspython/test_bug_check.py | 118 +- msautotest/mspython/test_mapio.py | 32 +- msautotest/mspython/test_ogr_query.py | 196 +- msautotest/mspython/test_postgis.py | 200 +- msautotest/mspython/test_rq.py | 510 +- msautotest/mspython/test_wkt.py | 66 +- msautotest/mspython/test_xmp.py | 38 +- msautotest/mssql/run_test.py | 19 +- msautotest/php/run_test.py | 4 +- msautotest/pymod/msautotest_viewer.py | 514 +- msautotest/pymod/mstestlib.py | 608 +- msautotest/pymod/pmstestlib.py | 67 +- msautotest/pymod/testlib.py | 175 +- msautotest/pymod/xmlvalidate.py | 477 +- msautotest/query/run_test.py | 19 +- msautotest/renderers/run_test.py | 19 +- msautotest/sld/run_test.py | 19 +- msautotest/wxs/run_test.py | 19 +- msencrypt.c | 19 +- scalebar.c | 21 +- shptree.c | 107 +- shptreetst.c | 120 +- shptreevis.c | 143 +- sortshp.c | 264 +- strptime.c | 527 +- sym2img.c | 128 +- testcopy.c | 12 +- testexpr.c | 11 +- textlayout.c | 670 +- tile4ms.c | 174 +- 251 files changed, 79553 insertions(+), 71659 deletions(-) create mode 100644 .clang-format create mode 100644 .flake8 create mode 100644 .git-blame-ignore-revs create mode 100644 .github/workflows/code_checks.yml create mode 100644 .pre-commit-config.yaml delete mode 100644 github_issue_no_activity_closer.py mode change 100755 => 100644 mapagg.cpp mode change 100755 => 100644 mapcopy.c mode change 100755 => 100644 mapfile.c mode change 100755 => 100644 maprendering.c mode change 100755 => 100644 mapserver.h mode change 100755 => 100644 mapwmslayer.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..16bd810a18 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +SortIncludes: false +Standard: Cpp11 +TabWidth: 2 +UseTab: Never diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000..0d1fd1c33b --- /dev/null +++ b/.flake8 @@ -0,0 +1,19 @@ +[flake8] +max_line_length = 88 +ignore = + C408 # Unnecessary dict/list/tuple call - rewrite as a literal + E203 # whitespace before ':' - doesn't work well with black + E225 # missing whitespace around operator - let black worry about that + E262 # inline comment should start with '# ' + E265 # block comment should start with '# ' + E266 # too many leading '#' for block comment + E302 # expected 2 blank lines, found 1 + E402 # module level import not at top of file + E501 # line too long - let black handle that + E711 # comparison to None should be + E712 # comparison to False/True should be + E741 # ambiguous variable name + F405 # may be undefined, or defined from star imports + W291 # trailing + W503 # line break occurred before a binary operator - let black worry about that + W504 # line break occurred adter a binary operator - let black worry about that diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000000..160503aefc --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +8c475073defe4add51fd6bba2b7e41a23f9dc55b diff --git a/.github/workflows/code_checks.yml b/.github/workflows/code_checks.yml new file mode 100644 index 0000000000..98a1518f26 --- /dev/null +++ b/.github/workflows/code_checks.yml @@ -0,0 +1,19 @@ +name: Code Checks + +on: [push, pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + + linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + - uses: pre-commit/action@v3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..ded56ecca0 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,32 @@ +repos: + - repo: https://github.com/psf/black + rev: 22.3.0 + hooks: + - id: black + - repo: https://github.com/timothycrosley/isort + rev: 5.12.0 + hooks: + - id: isort + args: ["--profile", "black"] + - repo: https://github.com/pycqa/flake8 + rev: 3.9.2 + hooks: + - id: flake8 + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: 'v15.0.7' + hooks: + - id: clang-format + exclude_types: [c#, java, javascript, json, proto] + exclude: > + (?x)^( + build | + renderers/agg/ | + flatgeobuf/ | + opengl/ | + third-party/ | + maplexer.c | + mapparser.c | + mapparser.h | + dejavu-sans-condensed.h | + uthash.h + ) diff --git a/apache/mod_mapserver.c b/apache/mod_mapserver.c index 9de35418aa..5d1512e7ee 100644 --- a/apache/mod_mapserver.c +++ b/apache/mod_mapserver.c @@ -12,7 +12,7 @@ #include "apr_tables.h" #include "apr_file_info.h" -#include "../mapserver.h" /* for mapObj */ +#include "../mapserver.h" /* for mapObj */ #include "../cgiutil.h" #include "../mapserv.h" @@ -21,45 +21,39 @@ module AP_MODULE_DECLARE_DATA mapserver_module; typedef struct { apr_pool_t *config_pool; apr_time_t mtime; - char *mapfile_name; - char *uri; + char *mapfile_name; + char *uri; mapObj *map; } mapserver_dir_config; /* These are the IO redirection hooks. They are mostly copied over from * mapio.c. Note that cbData contains Apache's request_rec! */ -static int -msIO_apacheWrite (void *cbData, void *data, int byteCount) -{ +static int msIO_apacheWrite(void *cbData, void *data, int byteCount) { /* simply use the block writing function which is very similiar to fwrite */ - return ap_rwrite (data, byteCount, (request_rec*) cbData); + return ap_rwrite(data, byteCount, (request_rec *)cbData); } -static int -msIO_apacheError (void *cbData, void *data, int byteCount) -{ +static int msIO_apacheError(void *cbData, void *data, int byteCount) { /* error reporting is done through the log file... */ - ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s", (char*) data); - return strlen ((char*) data); + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "%s", (char *)data); + return strlen((char *)data); } -int -msIO_installApacheRedirect (request_rec *r) -{ +int msIO_installApacheRedirect(request_rec *r) { msIOContext stdout_ctx, stderr_ctx; - stdout_ctx.label = "apache"; + stdout_ctx.label = "apache"; stdout_ctx.write_channel = MS_TRUE; stdout_ctx.readWriteFunc = msIO_apacheWrite; - stdout_ctx.cbData = (void*) r; + stdout_ctx.cbData = (void *)r; - stderr_ctx.label = "apache"; + stderr_ctx.label = "apache"; stderr_ctx.write_channel = MS_TRUE; stderr_ctx.readWriteFunc = msIO_apacheError; - stderr_ctx.cbData = (void*) r; + stderr_ctx.cbData = (void *)r; - msIO_installHandlers (NULL, &stdout_ctx, &stderr_ctx); + msIO_installHandlers(NULL, &stdout_ctx, &stderr_ctx); return MS_TRUE; } @@ -72,91 +66,89 @@ msIO_installApacheRedirect (request_rec *r) /* This is our simple query decoding function. Should be improved but for now * it works... */ -static int -mapserver_decode_args (apr_pool_t *p, char *args, - char ***ParamNames, char ***ParamValues) -{ +static int mapserver_decode_args(apr_pool_t *p, char *args, char ***ParamNames, + char ***ParamValues) { char **argv = NULL; - int i; - int n; - int argc = 0; - char *sep; + int i; + int n; + int argc = 0; + char *sep; /* alloc the name/value pointer list */ - argv = (char**) apr_pcalloc (p, (WMS_MAX_ARGS + 1) * 2 * sizeof (char*)); - *ParamNames = argv; + argv = (char **)apr_pcalloc(p, (WMS_MAX_ARGS + 1) * 2 * sizeof(char *)); + *ParamNames = argv; *ParamValues = argv + WMS_MAX_ARGS + 1; /* No arguments? Then we're done */ - if (!args) return 0; + if (!args) + return 0; - argv [0] = args; + argv[0] = args; /* separate the arguments */ - for (i = 1, n = 0; args [n] && (i < WMS_MAX_ARGS); n++) - if (args [n] == '&') { - argv [i++] = args + n + 1; - args [n ] = '\0'; + for (i = 1, n = 0; args[n] && (i < WMS_MAX_ARGS); n++) + if (args[n] == '&') { + argv[i++] = args + n + 1; + args[n] = '\0'; } /* eleminate empty args */ - for (n = 0, i = 0; argv [i]; i++) - if (*(argv [i]) != '\0') - argv [n++] = argv [i]; + for (n = 0, i = 0; argv[i]; i++) + if (*(argv[i]) != '\0') + argv[n++] = argv[i]; else - argv [i ] = NULL; + argv[i] = NULL; /* argument count is the number of non-zero arguments! */ argc = n; /* split the name/value pairs */ - for (i = 0; argv [i]; i++) { - sep = strchr (argv [i], '='); - if (!sep) continue; + for (i = 0; argv[i]; i++) { + sep = strchr(argv[i], '='); + if (!sep) + continue; *sep = '\0'; - argv [i + WMS_MAX_ARGS + 1] = (char*) apr_pstrdup (p, sep + 1); + argv[i + WMS_MAX_ARGS + 1] = (char *)apr_pstrdup(p, sep + 1); - if (ap_unescape_url (argv [i + WMS_MAX_ARGS + 1]) == HTTP_BAD_REQUEST) { - ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, - "%s: malformed URI, couldn't unescape parm %s", - __func__, argv [i]); + if (ap_unescape_url(argv[i + WMS_MAX_ARGS + 1]) == HTTP_BAD_REQUEST) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "%s: malformed URI, couldn't unescape parm %s", __func__, + argv[i]); - argv [i + WMS_MAX_ARGS + 1] = NULL; + argv[i + WMS_MAX_ARGS + 1] = NULL; } else { - plustospace (argv [i + WMS_MAX_ARGS + 1]); + plustospace(argv[i + WMS_MAX_ARGS + 1]); } } return argc; } -static char* -mapserver_read_post_data (request_rec *r) -{ - int size; - long blen, rsize, rpos = 0; +static char *mapserver_read_post_data(request_rec *r) { + int size; + long blen, rsize, rpos = 0; char *buffer = NULL; - char buf [512]; + char buf[512]; - if (ap_setup_client_block (r, REQUEST_CHUNKED_ERROR) != OK) + if (ap_setup_client_block(r, REQUEST_CHUNKED_ERROR) != OK) return NULL; - if (!ap_should_client_block (r)) + if (!ap_should_client_block(r)) return NULL; - buffer = (char*) apr_palloc (r->pool, r->remaining + 1); + buffer = (char *)apr_palloc(r->pool, r->remaining + 1); if (!buffer) return NULL; size = r->remaining; - buffer [size] = '\0'; + buffer[size] = '\0'; - while ((blen = ap_get_client_block (r, buf, sizeof (buf))) > 0) { + while ((blen = ap_get_client_block(r, buf, sizeof(buf))) > 0) { if (rpos + blen > size) { rsize = blen - rpos; } else { rsize = blen; } - memcpy ((char*) buffer + rpos, buf, rsize); + memcpy((char *)buffer + rpos, buf, rsize); rpos += rsize; } @@ -167,32 +159,37 @@ mapserver_read_post_data (request_rec *r) ** Extract Map File name from params and load it. ** Returns map object or NULL on error. */ -static mapObj* -msModuleLoadMap(mapservObj *mapserv, mapserver_dir_config *conf) -{ +static mapObj *msModuleLoadMap(mapservObj *mapserv, + mapserver_dir_config *conf) { int i; /* OK, here's the magic: we take the mapObj from our stored config. * We will use a copy of it created by msCopyMap since MapServer * modifies the object at several places during request processing */ - mapObj *map = msNewMapObj (); - if(!map) return NULL; - msCopyMap (map, conf->map); - + mapObj *map = msNewMapObj(); + if (!map) + return NULL; + msCopyMap(map, conf->map); - /* check for any %variable% substitutions here, also do any map_ changes, we do this here so WMS/WFS */ + /* check for any %variable% substitutions here, also do any map_ changes, we + * do this here so WMS/WFS */ /* services can take advantage of these "vendor specific" extensions */ - for(i=0; irequest->NumParams; i++) { + for (i = 0; i < mapserv->request->NumParams; i++) { /* ** a few CGI variables should be skipped altogether ** - ** qstring: there is separate per layer validation for attribute queries and the substitution checks + ** qstring: there is separate per layer validation for attribute queries and + *the substitution checks ** below conflict with that so we avoid it here */ - if(strncasecmp(mapserv->request->ParamNames[i],"qstring",7) == 0) continue; + if (strncasecmp(mapserv->request->ParamNames[i], "qstring", 7) == 0) + continue; - if(strncasecmp(mapserv->request->ParamNames[i],"map_",4) == 0 || strncasecmp(mapserv->request->ParamNames[i],"map.",4) == 0) { /* check to see if there are any additions to the mapfile */ - if(msUpdateMapFromURL(map, mapserv->request->ParamNames[i], mapserv->request->ParamValues[i]) != MS_SUCCESS) { + if (strncasecmp(mapserv->request->ParamNames[i], "map_", 4) == 0 || + strncasecmp(mapserv->request->ParamNames[i], "map.", 4) == + 0) { /* check to see if there are any additions to the mapfile */ + if (msUpdateMapFromURL(map, mapserv->request->ParamNames[i], + mapserv->request->ParamValues[i]) != MS_SUCCESS) { msFreeMap(map); return NULL; } @@ -200,18 +197,22 @@ msModuleLoadMap(mapservObj *mapserv, mapserver_dir_config *conf) } } - msApplySubstitutions(map, mapserv->request->ParamNames, mapserv->request->ParamValues, mapserv->request->NumParams); + msApplySubstitutions(map, mapserv->request->ParamNames, + mapserv->request->ParamValues, + mapserv->request->NumParams); msApplyDefaultSubstitutions(map); /* check to see if a ogc map context is passed as argument. if there */ /* is one load it */ - for(i=0; irequest->NumParams; i++) { - if(strcasecmp(mapserv->request->ParamNames[i],"context") == 0) { - if(mapserv->request->ParamValues[i] && strlen(mapserv->request->ParamValues[i]) > 0) { - if(strncasecmp(mapserv->request->ParamValues[i],"http",4) == 0) { - if(msGetConfigOption(map, "CGI_CONTEXT_URL")) - msLoadMapContextURL(map, mapserv->request->ParamValues[i], MS_FALSE); + for (i = 0; i < mapserv->request->NumParams; i++) { + if (strcasecmp(mapserv->request->ParamNames[i], "context") == 0) { + if (mapserv->request->ParamValues[i] && + strlen(mapserv->request->ParamValues[i]) > 0) { + if (strncasecmp(mapserv->request->ParamValues[i], "http", 4) == 0) { + if (msGetConfigOption(map, "CGI_CONTEXT_URL")) + msLoadMapContextURL(map, mapserv->request->ParamValues[i], + MS_FALSE); } else msLoadMapContext(map, mapserv->request->ParamValues[i], MS_FALSE); } @@ -225,9 +226,9 @@ msModuleLoadMap(mapservObj *mapserv, mapserver_dir_config *conf) * by an object that is part of the mapObject that would contain * information on the application status (such as cookie). */ - if( mapserv->request->httpcookiedata != NULL ) { - msInsertHashTable( &(map->web.metadata), "http_cookie_data", - mapserv->request->httpcookiedata ); + if (mapserv->request->httpcookiedata != NULL) { + msInsertHashTable(&(map->web.metadata), "http_cookie_data", + mapserv->request->httpcookiedata); } return map; @@ -236,66 +237,66 @@ msModuleLoadMap(mapservObj *mapserv, mapserver_dir_config *conf) /*** * The main request handler. **/ -static int -mapserver_handler (request_rec *r) -{ +static int mapserver_handler(request_rec *r) { /* aquire the apropriate configuration for this directory */ mapserver_dir_config *conf; - conf = (mapserver_dir_config*) ap_get_module_config (r->per_dir_config, - &mapserver_module); + conf = (mapserver_dir_config *)ap_get_module_config(r->per_dir_config, + &mapserver_module); /* decline the request if there's no map configured */ if (!conf || !conf->map) return DECLINED; apr_finfo_t mapstat; - if (apr_stat (&mapstat, conf->mapfile_name, APR_FINFO_MTIME, r->pool) == APR_SUCCESS) { - if (apr_time_sec (mapstat.mtime) > apr_time_sec (conf->mtime)) { - mapObj *newmap = msLoadMap (conf->mapfile_name, NULL); + if (apr_stat(&mapstat, conf->mapfile_name, APR_FINFO_MTIME, r->pool) == + APR_SUCCESS) { + if (apr_time_sec(mapstat.mtime) > apr_time_sec(conf->mtime)) { + mapObj *newmap = msLoadMap(conf->mapfile_name, NULL); if (newmap) { - msFreeMap (conf->map); - conf->map = newmap; + msFreeMap(conf->map); + conf->map = newmap; conf->mtime = mapstat.mtime; } else { - ap_log_error (APLOG_MARK, APLOG_WARNING, 0, NULL, - "unable to reload map file %s", conf->mapfile_name); + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "unable to reload map file %s", conf->mapfile_name); } } } else { - ap_log_error (APLOG_MARK, APLOG_WARNING, 0, NULL, - "%s: unable to stat file %s", __func__, conf->mapfile_name); + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "%s: unable to stat file %s", __func__, conf->mapfile_name); } /* make a copy of the URI so we can modify it safely */ - char *uri = apr_pstrdup (r->pool, r->uri); - int len = strlen (uri); - int conf_uri_len = strlen (conf->uri); + char *uri = apr_pstrdup(r->pool, r->uri); + int len = strlen(uri); + int conf_uri_len = strlen(conf->uri); /* If the URI points to a subdirectory we want to decline. */ if (len > conf_uri_len) return DECLINED; - int argc = 0; - char **ParamNames = NULL; - char **ParamValues = NULL; - char *post_data = NULL; - int szMethod = -1; - char *szContentType = NULL; + int argc = 0; + char **ParamNames = NULL; + char **ParamValues = NULL; + char *post_data = NULL; + int szMethod = -1; + char *szContentType = NULL; mapservObj *mapserv = NULL; /* Try decoding the query string */ if (r->method_number == M_GET) { - argc = mapserver_decode_args (r->pool, (char*) apr_pstrdup (r->pool, r->args), - &ParamNames, &ParamValues); + argc = mapserver_decode_args(r->pool, (char *)apr_pstrdup(r->pool, r->args), + &ParamNames, &ParamValues); szMethod = MS_GET_REQUEST; } else if (r->method_number == M_POST) { - szContentType = (char*) apr_table_get (r->headers_in, "Content-Type"); - post_data = mapserver_read_post_data (r); - szMethod = MS_POST_REQUEST; - if (strcmp (szContentType, "application/x-www-form-urlencoded") == 0) { - argc = mapserver_decode_args (r->pool, (char*) apr_pstrdup (r->pool, r->args), - &ParamNames, &ParamValues); + szContentType = (char *)apr_table_get(r->headers_in, "Content-Type"); + post_data = mapserver_read_post_data(r); + szMethod = MS_POST_REQUEST; + if (strcmp(szContentType, "application/x-www-form-urlencoded") == 0) { + argc = + mapserver_decode_args(r->pool, (char *)apr_pstrdup(r->pool, r->args), + &ParamNames, &ParamValues); } } else return HTTP_METHOD_NOT_ALLOWED; @@ -304,36 +305,34 @@ mapserver_handler (request_rec *r) return HTTP_BAD_REQUEST; /* Now we install the IO redirection. - */ - if (msIO_installApacheRedirect (r) != MS_TRUE) - ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, - "%s: could not install apache redirect", __func__); - + */ + if (msIO_installApacheRedirect(r) != MS_TRUE) + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "%s: could not install apache redirect", __func__); mapserv = msAllocMapServObj(); - mapserv->request->NumParams = argc; - mapserv->request->ParamNames = ParamNames; + mapserv->request->NumParams = argc; + mapserv->request->ParamNames = ParamNames; mapserv->request->ParamValues = ParamValues; - mapserv->request->type = (enum MS_REQUEST_TYPE) szMethod; + mapserv->request->type = (enum MS_REQUEST_TYPE)szMethod; mapserv->request->postrequest = post_data; mapserv->request->contenttype = szContentType; - //mapserv->map = msModuleLoadMap(mapserv,conf); + // mapserv->map = msModuleLoadMap(mapserv,conf); mapserv->map = conf->map; - if(!mapserv->map) { + if (!mapserv->map) { msCGIWriteError(mapserv); goto end_request; } - if(msCGIDispatchRequest(mapserv) != MS_SUCCESS) { + if (msCGIDispatchRequest(mapserv) != MS_SUCCESS) { msCGIWriteError(mapserv); goto end_request; } - end_request: - if(mapserv) { - mapserv->request->ParamNames = NULL; + if (mapserv) { + mapserv->request->ParamNames = NULL; mapserv->request->ParamValues = NULL; mapserv->request->postrequest = NULL; mapserv->request->contenttype = NULL; @@ -342,7 +341,6 @@ mapserver_handler (request_rec *r) } msResetErrorList(); - /* Check if status was set inside MapServer functions. If it was, we * return it's value instead of simply OK. This is to support redirects * from maptemplate.c @@ -356,10 +354,8 @@ mapserver_handler (request_rec *r) /* This function will be called on startup to allow us to register our * handler. We don't do anything else yet... */ -static void -mapserver_register_hooks (apr_pool_t *p) -{ - ap_hook_handler (mapserver_handler, NULL, NULL, APR_HOOK_MIDDLE); +static void mapserver_register_hooks(apr_pool_t *p) { + ap_hook_handler(mapserver_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* That's the second part of the overall magic. This function will be called @@ -368,38 +364,38 @@ mapserver_register_hooks (apr_pool_t *p) * We try to load it and store the resulting mapObj in the config of the * current directory. If we fail we throw a message... */ -static const char* -mapserver_set_map (cmd_parms *cmd, void *config, const char *arg) -{ - mapserver_dir_config *conf = (mapserver_dir_config*) config; +static const char *mapserver_set_map(cmd_parms *cmd, void *config, + const char *arg) { + mapserver_dir_config *conf = (mapserver_dir_config *)config; /* if the mapObj already exists the WMS_Map was given more than once - * may be the user forgot to comment something out... */ if (conf->map) { - msWriteError (stderr); - return (char*) apr_psprintf (cmd->temp_pool, - "An MAP-file has already been registered for " - "this URI - not accepting '%s'.", arg ); + msWriteError(stderr); + return (char *)apr_psprintf(cmd->temp_pool, + "An MAP-file has already been registered for " + "this URI - not accepting '%s'.", + arg); } /* Simply try loading the argument as map file. */ conf->mapfile_name = apr_pstrdup(cmd->pool, arg); - conf->map = msLoadMap ((char*) arg, NULL); + conf->map = msLoadMap((char *)arg, NULL); /* Ooops - we failed. We report it and fail. So beware: Always do a * configcheck before really restarting your web server! */ if (!conf->map) { - msWriteError (stderr); - return (char*) apr_psprintf (cmd->temp_pool, - "The given MAP-file '%s' could not be loaded", - arg); + msWriteError(stderr); + return (char *)apr_psprintf( + cmd->temp_pool, "The given MAP-file '%s' could not be loaded", arg); } apr_finfo_t status; - if (apr_stat (&status, conf->mapfile_name, APR_FINFO_MTIME, cmd->pool) != APR_SUCCESS) { - ap_log_error (APLOG_MARK, APLOG_WARNING, 0, NULL, - "%s: unable to stat file %s", __func__, conf->mapfile_name); + if (apr_stat(&status, conf->mapfile_name, APR_FINFO_MTIME, cmd->pool) != + APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "%s: unable to stat file %s", __func__, conf->mapfile_name); } conf->mtime = status.mtime; return NULL; @@ -408,21 +404,20 @@ mapserver_set_map (cmd_parms *cmd, void *config, const char *arg) /* This function creates the (default) directory configuration. Well, we have * no defaults to set so we simply alloc the memory... */ -static void* -mapserver_create_dir_config (apr_pool_t *p, char *dir) -{ +static void *mapserver_create_dir_config(apr_pool_t *p, char *dir) { mapserver_dir_config *newconf; - newconf = (mapserver_dir_config*) apr_pcalloc (p, sizeof (mapserver_dir_config)); + newconf = + (mapserver_dir_config *)apr_pcalloc(p, sizeof(mapserver_dir_config)); newconf->config_pool = p; - newconf->uri = apr_pstrdup (p, dir); + newconf->uri = apr_pstrdup(p, dir); newconf->map = NULL; newconf->mapfile_name = NULL; - newconf->mtime = apr_time_from_sec (0); + newconf->mtime = apr_time_from_sec(0); if (dir) { - int len = strlen (dir); - if (len > 1 && dir [len - 1] == '/' ) - newconf->uri [len - 1] = '\0'; + int len = strlen(dir); + if (len > 1 && dir[len - 1] == '/') + newconf->uri[len - 1] = '\0'; } return newconf; } @@ -431,15 +426,9 @@ mapserver_create_dir_config (apr_pool_t *p, char *dir) * argument. */ static const command_rec mapserver_options[] = { - AP_INIT_TAKE1( - "Mapfile", - mapserver_set_map, - NULL, - ACCESS_CONF, - "WMS_Map " - ), - {NULL} -}; + AP_INIT_TAKE1("Mapfile", mapserver_set_map, NULL, ACCESS_CONF, + "WMS_Map "), + {NULL}}; /* The following structure declares everything Apache needs to treat us as * a module. Merging would mean inheriting from the parent directory but that @@ -447,12 +436,11 @@ static const command_rec mapserver_options[] = { */ /* Dispatch list for API hooks */ module AP_MODULE_DECLARE_DATA mapserver_module = { - STANDARD20_MODULE_STUFF, - mapserver_create_dir_config, /* create per-dir config structures */ - NULL, /* merge per-dir config structures */ - NULL, /* create per-server config structures */ - NULL, /* merge per-server config structures */ - mapserver_options, /* table of config file commands */ - mapserver_register_hooks /* register hooks */ + STANDARD20_MODULE_STUFF, + mapserver_create_dir_config, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + mapserver_options, /* table of config file commands */ + mapserver_register_hooks /* register hooks */ }; - diff --git a/cgiutil.c b/cgiutil.c index 7d9895399e..6e47ae75b5 100644 --- a/cgiutil.c +++ b/cgiutil.c @@ -5,7 +5,8 @@ * Purpose: cgiRequestObj and CGI parameter parsing. * Author: Steve Lime and the MapServer team. * - * Notes: Portions derived from NCSA HTTPd Server's example CGI programs (util.c). + * Notes: Portions derived from NCSA HTTPd Server's example CGI programs + *(util.c). * ****************************************************************************** * Copyright (c) 1996-2005 Regents of the University of Minnesota. @@ -41,8 +42,7 @@ #define LF 10 #define CR 13 -int readPostBody( cgiRequestObj *request, char **data ) -{ +int readPostBody(cgiRequestObj *request, char **data) { size_t data_max, data_len; int chunk_size; @@ -53,26 +53,29 @@ int readPostBody( cgiRequestObj *request, char **data ) /* -------------------------------------------------------------------- */ /* If the length is provided, read in one gulp. */ /* -------------------------------------------------------------------- */ - if( getenv("CONTENT_LENGTH") != NULL ) { - data_max = (size_t) atoi(getenv("CONTENT_LENGTH")); + if (getenv("CONTENT_LENGTH") != NULL) { + data_max = (size_t)atoi(getenv("CONTENT_LENGTH")); /* Test for suspicious CONTENT_LENGTH (negative value or SIZE_MAX) */ - if( data_max >= SIZE_MAX ) { + if (data_max >= SIZE_MAX) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); // msIO_printf("Suspicious Content-Length.\n"); msSetError(MS_WEBERR, "Suspicious Content-Length.", "readPostBody()"); return MS_FAILURE; } - *data = (char *) malloc(data_max+1); - if( *data == NULL ) { + *data = (char *)malloc(data_max + 1); + if (*data == NULL) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); - // msIO_printf("malloc() failed, Content-Length: %u unreasonably large?\n", (unsigned int)data_max ); - msSetError(MS_WEBERR, "malloc() failed, Content-Length: %u unreasonably large?", "readPostBody()", (unsigned int)data_max); + // msIO_printf("malloc() failed, Content-Length: %u unreasonably + // large?\n", (unsigned int)data_max ); + msSetError(MS_WEBERR, + "malloc() failed, Content-Length: %u unreasonably large?", + "readPostBody()", (unsigned int)data_max); return MS_FAILURE; } - if( (int) msIO_fread(*data, 1, data_max, stdin) < (int) data_max ) { + if ((int)msIO_fread(*data, 1, data_max, stdin) < (int)data_max) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); // msIO_printf("POST body is short\n"); @@ -90,24 +93,29 @@ int readPostBody( cgiRequestObj *request, char **data ) data_max = DATA_ALLOC_SIZE; data_len = 0; - *data = (char *) msSmallMalloc(data_max+1); + *data = (char *)msSmallMalloc(data_max + 1); (*data)[data_max] = '\0'; - while( (chunk_size = msIO_fread( *data + data_len, 1, data_max-data_len, stdin )) > 0 ) { + while ((chunk_size = msIO_fread(*data + data_len, 1, data_max - data_len, + stdin)) > 0) { data_len += chunk_size; - if( data_len == data_max ) { + if (data_len == data_max) { /* Realloc buffer, making sure we check for possible size_t overflow */ - if ( data_max > SIZE_MAX - (DATA_ALLOC_SIZE+1) ) { + if (data_max > SIZE_MAX - (DATA_ALLOC_SIZE + 1)) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); - // msIO_printf("Possible size_t overflow, cannot reallocate input buffer, POST body too large?\n" ); - msSetError(MS_WEBERR, "Possible size_t overflow, cannot reallocate input buffer, POST body too large?", "readPostBody()"); + // msIO_printf("Possible size_t overflow, cannot reallocate input + // buffer, POST body too large?\n" ); + msSetError(MS_WEBERR, + "Possible size_t overflow, cannot reallocate input buffer, " + "POST body too large?", + "readPostBody()"); return MS_FAILURE; } data_max = data_max + DATA_ALLOC_SIZE; - *data = (char *) msSmallRealloc(*data, data_max+1); + *data = (char *)msSmallRealloc(*data, data_max + 1); } } @@ -115,27 +123,24 @@ int readPostBody( cgiRequestObj *request, char **data ) return MS_SUCCESS; } -static char* msGetEnv(const char *name, void* thread_context) -{ +static char *msGetEnv(const char *name, void *thread_context) { (void)thread_context; return getenv(name); } int loadParams(cgiRequestObj *request, - char* (*getenv2)(const char*, void* thread_context), - char *raw_post_data, - ms_uint32 raw_post_data_length, - void* thread_context) -{ - register int x,m=0; + char *(*getenv2)(const char *, void *thread_context), + char *raw_post_data, ms_uint32 raw_post_data_length, + void *thread_context) { + register int x, m = 0; char *s, *queryString = NULL, *httpCookie = NULL; int debuglevel; int maxParams = MS_DEFAULT_CGI_PARAMS; - if (getenv2==NULL) + if (getenv2 == NULL) getenv2 = &msGetEnv; - if(getenv2("REQUEST_METHOD", thread_context)==NULL) { + if (getenv2("REQUEST_METHOD", thread_context) == NULL) { msIO_printf("This script can only be used to decode form results and \n"); msIO_printf("should be initiated as a CGI process via a httpd server.\n"); msIO_printf("For other options please try using the --help switch.\n"); @@ -144,138 +149,160 @@ int loadParams(cgiRequestObj *request, debuglevel = (int)msGetGlobalDebugLevel(); - if(strcmp(getenv2("REQUEST_METHOD", thread_context),"POST") == 0 && CPLGetConfigOption("MS_NO_POST", NULL) == NULL) { /* we've got a post from a form */ + if (strcmp(getenv2("REQUEST_METHOD", thread_context), "POST") == 0 && + CPLGetConfigOption("MS_NO_POST", NULL) == + NULL) { /* we've got a post from a form */ char *post_data; int data_len; request->type = MS_POST_REQUEST; - if (request->contenttype == NULL){ - s = getenv2("CONTENT_TYPE", thread_context); - if (s != NULL){ - request->contenttype = msStrdup(s); - } - else { - /* we've to set default Content-Type which is - * application/octet-stream according to - * W3 RFC 2626 section 7.2.1 */ - request->contenttype = msStrdup("application/octet-stream"); - } + if (request->contenttype == NULL) { + s = getenv2("CONTENT_TYPE", thread_context); + if (s != NULL) { + request->contenttype = msStrdup(s); + } else { + /* we've to set default Content-Type which is + * application/octet-stream according to + * W3 RFC 2626 section 7.2.1 */ + request->contenttype = msStrdup("application/octet-stream"); + } } if (raw_post_data) { post_data = msStrdup(raw_post_data); data_len = raw_post_data_length; } else { - if(MS_SUCCESS != readPostBody( request, &post_data )) + if (MS_SUCCESS != readPostBody(request, &post_data)) return -1; data_len = strlen(post_data); } /* if the content_type is application/x-www-form-urlencoded, we have to parse it like the QUERY_STRING variable */ - if(strncmp(request->contenttype, "application/x-www-form-urlencoded", strlen("application/x-www-form-urlencoded")) == 0) { - while( data_len > 0 && isspace(post_data[data_len-1]) ) + if (strncmp(request->contenttype, "application/x-www-form-urlencoded", + strlen("application/x-www-form-urlencoded")) == 0) { + while (data_len > 0 && isspace(post_data[data_len - 1])) post_data[--data_len] = '\0'; - while( post_data[0] ) { - if(m >= maxParams) { + while (post_data[0]) { + if (m >= maxParams) { maxParams *= 2; - request->ParamNames = (char **) msSmallRealloc(request->ParamNames,sizeof(char *) * maxParams); - request->ParamValues = (char **) msSmallRealloc(request->ParamValues,sizeof(char *) * maxParams); + request->ParamNames = (char **)msSmallRealloc( + request->ParamNames, sizeof(char *) * maxParams); + request->ParamValues = (char **)msSmallRealloc( + request->ParamValues, sizeof(char *) * maxParams); } - request->ParamValues[m] = makeword(post_data,'&'); + request->ParamValues[m] = makeword(post_data, '&'); plustospace(request->ParamValues[m]); unescape_url(request->ParamValues[m]); - request->ParamNames[m] = makeword(request->ParamValues[m],'='); + request->ParamNames[m] = makeword(request->ParamValues[m], '='); m++; } - free( post_data ); + free(post_data); } else request->postrequest = post_data; /* check the QUERY_STRING even in the post request since it can contain information. Eg a wfs request with */ s = getenv2("QUERY_STRING", thread_context); - if(s) { + if (s) { if (debuglevel >= MS_DEBUGLEVEL_DEBUG) msDebug("loadParams() QUERY_STRING: %s\n", s); queryString = msStrdup(s); - for(x=0; queryString[0] != '\0'; x++) { - if(m >= maxParams) { + for (x = 0; queryString[0] != '\0'; x++) { + if (m >= maxParams) { maxParams *= 2; - request->ParamNames = (char **) msSmallRealloc(request->ParamNames,sizeof(char *) * maxParams); - request->ParamValues = (char **) msSmallRealloc(request->ParamValues,sizeof(char *) * maxParams); + request->ParamNames = (char **)msSmallRealloc( + request->ParamNames, sizeof(char *) * maxParams); + request->ParamValues = (char **)msSmallRealloc( + request->ParamValues, sizeof(char *) * maxParams); } - request->ParamValues[m] = makeword(queryString,'&'); + request->ParamValues[m] = makeword(queryString, '&'); plustospace(request->ParamValues[m]); unescape_url(request->ParamValues[m]); - request->ParamNames[m] = makeword(request->ParamValues[m],'='); + request->ParamNames[m] = makeword(request->ParamValues[m], '='); m++; } } } else { - if(strcmp(getenv2("REQUEST_METHOD", thread_context),"GET") == 0) { /* we've got a get request */ + if (strcmp(getenv2("REQUEST_METHOD", thread_context), "GET") == + 0) { /* we've got a get request */ request->type = MS_GET_REQUEST; s = getenv2("QUERY_STRING", thread_context); - if(s == NULL) { + if (s == NULL) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); - // msIO_printf("No query information to decode. QUERY_STRING not set.\n"); - msSetError(MS_WEBERR, "No query information to decode. QUERY_STRING not set.", "loadParams()"); + // msIO_printf("No query information to decode. QUERY_STRING not + // set.\n"); + msSetError(MS_WEBERR, + "No query information to decode. QUERY_STRING not set.", + "loadParams()"); return -1; } if (debuglevel >= MS_DEBUGLEVEL_DEBUG) msDebug("loadParams() QUERY_STRING: %s\n", s); - if(strlen(s)==0) { + if (strlen(s) == 0) { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); - // msIO_printf("No query information to decode. QUERY_STRING is set, but empty.\n"); - msSetError(MS_WEBERR, "No query information to decode. QUERY_STRING is set, but empty.", "loadParams()"); + // msIO_printf("No query information to decode. QUERY_STRING is set, but + // empty.\n"); + msSetError( + MS_WEBERR, + "No query information to decode. QUERY_STRING is set, but empty.", + "loadParams()"); return -1; } /* don't modify the string returned by getenv2 */ queryString = msStrdup(s); - for(x=0; queryString[0] != '\0'; x++) { - if(m >= maxParams) { + for (x = 0; queryString[0] != '\0'; x++) { + if (m >= maxParams) { maxParams *= 2; - request->ParamNames = (char **) msSmallRealloc(request->ParamNames,sizeof(char *) * maxParams); - request->ParamValues = (char **) msSmallRealloc(request->ParamValues,sizeof(char *) * maxParams); + request->ParamNames = (char **)msSmallRealloc( + request->ParamNames, sizeof(char *) * maxParams); + request->ParamValues = (char **)msSmallRealloc( + request->ParamValues, sizeof(char *) * maxParams); } - request->ParamValues[m] = makeword(queryString,'&'); + request->ParamValues[m] = makeword(queryString, '&'); plustospace(request->ParamValues[m]); unescape_url(request->ParamValues[m]); - request->ParamNames[m] = makeword(request->ParamValues[m],'='); + request->ParamNames[m] = makeword(request->ParamValues[m], '='); m++; } } else { // msIO_setHeader("Content-Type","text/html"); // msIO_sendHeaders(); - // msIO_printf("This script should be referenced with a METHOD of GET or METHOD of POST.\n"); - msSetError(MS_WEBERR, "This script should be referenced with a METHOD of GET or METHOD of POST.", "loadParams()"); + // msIO_printf("This script should be referenced with a METHOD of GET or + // METHOD of POST.\n"); + msSetError(MS_WEBERR, + "This script should be referenced with a METHOD of GET or " + "METHOD of POST.", + "loadParams()"); return -1; } } /* check for any available cookies */ s = getenv2("HTTP_COOKIE", thread_context); - if(s != NULL) { + if (s != NULL) { httpCookie = msStrdup(s); request->httpcookiedata = msStrdup(s); - for(x=0; httpCookie[0] != '\0'; x++) { - if(m >= maxParams) { + for (x = 0; httpCookie[0] != '\0'; x++) { + if (m >= maxParams) { maxParams *= 2; - request->ParamNames = (char **) msSmallRealloc(request->ParamNames,sizeof(char *) * maxParams); - request->ParamValues = (char **) msSmallRealloc(request->ParamValues,sizeof(char *) * maxParams); + request->ParamNames = (char **)msSmallRealloc( + request->ParamNames, sizeof(char *) * maxParams); + request->ParamValues = (char **)msSmallRealloc( + request->ParamValues, sizeof(char *) * maxParams); } - request->ParamValues[m] = makeword(httpCookie,';'); + request->ParamValues[m] = makeword(httpCookie, ';'); plustospace(request->ParamValues[m]); unescape_url(request->ParamValues[m]); - request->ParamNames[m] = makeword_skip(request->ParamValues[m],'=',' '); + request->ParamNames[m] = makeword_skip(request->ParamValues[m], '=', ' '); m++; } } @@ -285,142 +312,144 @@ int loadParams(cgiRequestObj *request, if (httpCookie) free(httpCookie); - return(m); + return (m); } -void getword(char *word, char *line, char stop) -{ - int x = 0,y; +void getword(char *word, char *line, char stop) { + int x = 0, y; - for(x=0; ((line[x]) && (line[x] != stop)); x++) + for (x = 0; ((line[x]) && (line[x] != stop)); x++) word[x] = line[x]; word[x] = '\0'; - if(line[x]) ++x; - y=0; + if (line[x]) + ++x; + y = 0; - while((line[y++] = line[x++])); + while ((line[y++] = line[x++])) + ; } -char *makeword_skip(char *line, char stop, char skip) -{ - int x = 0,y,offset=0; - char *word = (char *) msSmallMalloc(sizeof(char) * (strlen(line) + 1)); +char *makeword_skip(char *line, char stop, char skip) { + int x = 0, y, offset = 0; + char *word = (char *)msSmallMalloc(sizeof(char) * (strlen(line) + 1)); - for(x=0; ((line[x]) && (line[x] == skip)); x++); + for (x = 0; ((line[x]) && (line[x] == skip)); x++) + ; offset = x; - for(x=offset; ((line[x]) && (line[x] != stop)); x++) - word[x-offset] = line[x]; + for (x = offset; ((line[x]) && (line[x] != stop)); x++) + word[x - offset] = line[x]; - word[x-offset] = '\0'; - if(line[x]) ++x; - y=0; + word[x - offset] = '\0'; + if (line[x]) + ++x; + y = 0; - while((line[y++] = line[x++])); + while ((line[y++] = line[x++])) + ; return word; } -char *makeword(char *line, char stop) -{ - int x = 0,y; - char *word = (char *) msSmallMalloc(sizeof(char) * (strlen(line) + 1)); +char *makeword(char *line, char stop) { + int x = 0, y; + char *word = (char *)msSmallMalloc(sizeof(char) * (strlen(line) + 1)); - for(x=0; ((line[x]) && (line[x] != stop)); x++) + for (x = 0; ((line[x]) && (line[x] != stop)); x++) word[x] = line[x]; word[x] = '\0'; - if(line[x]) ++x; - y=0; + if (line[x]) + ++x; + y = 0; - while((line[y++] = line[x++])); + while ((line[y++] = line[x++])) + ; return word; } -char *fmakeword(FILE *f, char stop, int *cl) -{ +char *fmakeword(FILE *f, char stop, int *cl) { int wsize; char *word; int ll; wsize = 102400; - ll=0; - word = (char *) msSmallMalloc(sizeof(char) * (wsize + 1)); + ll = 0; + word = (char *)msSmallMalloc(sizeof(char) * (wsize + 1)); - while(1) { + while (1) { word[ll] = (char)fgetc(f); - if(ll==wsize) { - word[ll+1] = '\0'; - wsize+=102400; - word = (char *)msSmallRealloc(word,sizeof(char)*(wsize+1)); + if (ll == wsize) { + word[ll + 1] = '\0'; + wsize += 102400; + word = (char *)msSmallRealloc(word, sizeof(char) * (wsize + 1)); } --(*cl); - if((word[ll] == stop) || (feof(f)) || (!(*cl))) { - if(word[ll] != stop) ll++; + if ((word[ll] == stop) || (feof(f)) || (!(*cl))) { + if (word[ll] != stop) + ll++; word[ll] = '\0'; - word = (char *) msSmallRealloc(word, ll+1); + word = (char *)msSmallRealloc(word, ll + 1); return word; } ++ll; } } -char x2c(char *what) -{ +char x2c(char *what) { register char digit; - digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); + digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); - return(digit); + digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); + return (digit); } -void unescape_url(char *url) -{ - register int x,y; +void unescape_url(char *url) { + register int x, y; - for(x=0,y=0; url[y]; ++x,++y) { - if((url[x] = url[y]) == '%') { - url[x] = x2c(&url[y+1]); - y+=2; + for (x = 0, y = 0; url[y]; ++x, ++y) { + if ((url[x] = url[y]) == '%') { + url[x] = x2c(&url[y + 1]); + y += 2; } } url[x] = '\0'; } -void plustospace(char *str) -{ +void plustospace(char *str) { register int x; - for(x=0; str[x]; x++) if(str[x] == '+') str[x] = ' '; + for (x = 0; str[x]; x++) + if (str[x] == '+') + str[x] = ' '; } -int rind(char *s, char c) -{ +int rind(char *s, char c) { register int x; - for(x=strlen(s) - 1; x != -1; x--) - if(s[x] == c) return x; + for (x = strlen(s) - 1; x != -1; x--) + if (s[x] == c) + return x; return -1; } -void send_fd(FILE *f, FILE *fd) -{ +void send_fd(FILE *f, FILE *fd) { int c; while (1) { c = fgetc(f); - if(c == EOF) + if (c == EOF) return; - fputc((char)c,fd); + fputc((char)c, fd); } } -int ind(char *s, char c) -{ +int ind(char *s, char c) { register int x; - for(x=0; s[x]; x++) - if(s[x] == c) return x; + for (x = 0; s[x]; x++) + if (s[x] == c) + return x; return -1; } @@ -428,15 +457,14 @@ int ind(char *s, char c) /* ** patched version according to CERT advisory... */ -void escape_shell_cmd(char *cmd) -{ - register int x,y,l; - - l=strlen(cmd); - for(x=0; cmd[x]; x++) { - if(ind("&;`'\"|*?~<>^()[]{}$\\\n",cmd[x]) != -1) { - for(y=l+1; y>x; y--) - cmd[y] = cmd[y-1]; +void escape_shell_cmd(char *cmd) { + register int x, y, l; + + l = strlen(cmd); + for (x = 0; cmd[x]; x++) { + if (ind("&;`'\"|*?~<>^()[]{}$\\\n", cmd[x]) != -1) { + for (y = l + 1; y > x; y--) + cmd[y] = cmd[y - 1]; l++; /* length has been increased */ cmd[x] = '\\'; x++; /* skip the character */ @@ -447,15 +475,16 @@ void escape_shell_cmd(char *cmd) /* ** Allocate a new request holder structure */ -cgiRequestObj *msAllocCgiObj() -{ +cgiRequestObj *msAllocCgiObj() { cgiRequestObj *request = (cgiRequestObj *)malloc(sizeof(cgiRequestObj)); - if(!request) + if (!request) return NULL; - request->ParamNames = (char **) msSmallMalloc(MS_DEFAULT_CGI_PARAMS*sizeof(char*)); - request->ParamValues = (char **) msSmallMalloc(MS_DEFAULT_CGI_PARAMS*sizeof(char*)); + request->ParamNames = + (char **)msSmallMalloc(MS_DEFAULT_CGI_PARAMS * sizeof(char *)); + request->ParamValues = + (char **)msSmallMalloc(MS_DEFAULT_CGI_PARAMS * sizeof(char *)); request->NumParams = 0; request->type = MS_GET_REQUEST; request->contenttype = NULL; @@ -469,8 +498,7 @@ cgiRequestObj *msAllocCgiObj() return request; } -void msFreeCgiObj(cgiRequestObj *request) -{ +void msFreeCgiObj(cgiRequestObj *request) { msFreeCharArray(request->ParamNames, request->NumParams); msFreeCharArray(request->ParamValues, request->NumParams); request->ParamNames = NULL; @@ -484,7 +512,7 @@ void msFreeCgiObj(cgiRequestObj *request) request->postrequest = NULL; request->httpcookiedata = NULL; - if(request->api_path) { + if (request->api_path) { msFreeCharArray(request->api_path, request->api_path_length); request->api_path = NULL; request->api_path_length = 0; diff --git a/cgiutil.h b/cgiutil.h index 81e818a47b..b8a931c2f2 100644 --- a/cgiutil.h +++ b/cgiutil.h @@ -5,7 +5,8 @@ * Purpose: cgiRequestObj and CGI parsing utility related declarations. * Author: Steve Lime and the MapServer team. * - * Notes: Portions derived from NCSA HTTPd Server's example CGI programs (util.c). + * Notes: Portions derived from NCSA HTTPd Server's example CGI programs + *(util.c). * ****************************************************************************** * Copyright (c) 1996-2005 Regents of the University of Minnesota. @@ -37,9 +38,9 @@ extern "C" { #endif #if defined(_WIN32) && !defined(__CYGWIN__) -# define MS_DLL_EXPORT __declspec(dllexport) +#define MS_DLL_EXPORT __declspec(dllexport) #else -#define MS_DLL_EXPORT +#define MS_DLL_EXPORT #endif /* @@ -47,7 +48,7 @@ extern "C" { */ #define MS_DEFAULT_CGI_PARAMS 100 -enum MS_REQUEST_TYPE {MS_GET_REQUEST, MS_POST_REQUEST}; +enum MS_REQUEST_TYPE { MS_GET_REQUEST, MS_POST_REQUEST }; /** Class for programming OWS services @@ -66,9 +67,10 @@ typedef struct { %mutable; #endif - enum MS_REQUEST_TYPE type; ///< A :ref:`request type constant` - char *contenttype; ///< The content type of the request - char *postrequest; ///< Any POST data request + enum MS_REQUEST_TYPE + type; ///< A :ref:`request type constant` + char *contenttype; ///< The content type of the request + char *postrequest; ///< Any POST data request char *httpcookiedata; ///< Any cookie data associated with the request #ifndef SWIG @@ -78,13 +80,15 @@ typedef struct { #endif } cgiRequestObj; - /* ** Function prototypes */ #ifndef SWIG -MS_DLL_EXPORT int loadParams(cgiRequestObj *request, char* (*getenv2)(const char*, void* thread_context), - char *raw_post_data, ms_uint32 raw_post_data_length, void* thread_context); +MS_DLL_EXPORT int +loadParams(cgiRequestObj *request, + char *(*getenv2)(const char *, void *thread_context), + char *raw_post_data, ms_uint32 raw_post_data_length, + void *thread_context); MS_DLL_EXPORT void getword(char *, char *, char); MS_DLL_EXPORT char *makeword_skip(char *, char, char); MS_DLL_EXPORT char *makeword(char *, char); diff --git a/classobject.c b/classobject.c index 36fa328bb9..dc9619df0d 100644 --- a/classobject.c +++ b/classobject.c @@ -31,17 +31,17 @@ #include "mapserver.h" - /* -** Add a label to a classObj (order doesn't matter for labels like it does with styles) +** Add a label to a classObj (order doesn't matter for labels like it does with +*styles) */ -int msAddLabelToClass(classObj *class, labelObj *label) -{ +int msAddLabelToClass(classObj *class, labelObj *label) { if (!label) { msSetError(MS_CHILDERR, "Can't add a NULL label.", "msAddLabelToClass()"); return MS_FAILURE; } - if (msGrowClassLabels(class) == NULL) return MS_FAILURE; + if (msGrowClassLabels(class) == NULL) + return MS_FAILURE; /* msGrowClassLabels will alloc the label, free it in this case */ free(class->labels[class->numlabels]); @@ -54,20 +54,20 @@ int msAddLabelToClass(classObj *class, labelObj *label) /* ** Remove a label from a classObj. */ -labelObj *msRemoveLabelFromClass(classObj *class, int nLabelIndex) -{ +labelObj *msRemoveLabelFromClass(classObj *class, int nLabelIndex) { int i; labelObj *label; if (nLabelIndex < 0 || nLabelIndex >= class->numlabels) { - msSetError(MS_CHILDERR, "Cannot remove label, invalid index %d", "msRemoveLabelFromClass()", nLabelIndex); + msSetError(MS_CHILDERR, "Cannot remove label, invalid index %d", + "msRemoveLabelFromClass()", nLabelIndex); return NULL; } else { - label=class->labels[nLabelIndex]; - for (i=nLabelIndex; inumlabels-1; i++) { - class->labels[i]=class->labels[i+1]; + label = class->labels[nLabelIndex]; + for (i = nLabelIndex; i < class->numlabels - 1; i++) { + class->labels[i] = class->labels[i + 1]; } - class->labels[class->numlabels-1]=NULL; + class->labels[class->numlabels - 1] = NULL; class->numlabels--; MS_REFCNT_DECR(label); return label; @@ -77,47 +77,41 @@ labelObj *msRemoveLabelFromClass(classObj *class, int nLabelIndex) /** * Move the style up inside the array of styles. */ -int msMoveStyleUp(classObj *class, int nStyleIndex) -{ +int msMoveStyleUp(classObj *class, int nStyleIndex) { styleObj *psTmpStyle = NULL; - if (class && nStyleIndex < class->numstyles && nStyleIndex >0) { + if (class && nStyleIndex < class->numstyles && nStyleIndex > 0) { psTmpStyle = (styleObj *)malloc(sizeof(styleObj)); initStyle(psTmpStyle); msCopyStyle(psTmpStyle, class->styles[nStyleIndex]); - msCopyStyle(class->styles[nStyleIndex], - class->styles[nStyleIndex-1]); + msCopyStyle(class->styles[nStyleIndex], class->styles[nStyleIndex - 1]); - msCopyStyle(class->styles[nStyleIndex-1], psTmpStyle); + msCopyStyle(class->styles[nStyleIndex - 1], psTmpStyle); - return(MS_SUCCESS); + return (MS_SUCCESS); } - msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveStyleUp()", - nStyleIndex); + msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveStyleUp()", nStyleIndex); return (MS_FAILURE); } - /** * Move the style down inside the array of styles. */ -int msMoveStyleDown(classObj *class, int nStyleIndex) -{ +int msMoveStyleDown(classObj *class, int nStyleIndex) { styleObj *psTmpStyle = NULL; - if (class && nStyleIndex < class->numstyles-1 && nStyleIndex >=0) { + if (class && nStyleIndex < class->numstyles - 1 && nStyleIndex >= 0) { psTmpStyle = (styleObj *)malloc(sizeof(styleObj)); initStyle(psTmpStyle); msCopyStyle(psTmpStyle, class->styles[nStyleIndex]); - msCopyStyle(class->styles[nStyleIndex], - class->styles[nStyleIndex+1]); + msCopyStyle(class->styles[nStyleIndex], class->styles[nStyleIndex + 1]); - msCopyStyle(class->styles[nStyleIndex+1], psTmpStyle); + msCopyStyle(class->styles[nStyleIndex + 1], psTmpStyle); - return(MS_SUCCESS); + return (MS_SUCCESS); } msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveStyleDown()", nStyleIndex); @@ -129,8 +123,7 @@ int msMoveStyleDown(classObj *class, int nStyleIndex) * Returns the index at which the style was inserted * */ -int msInsertStyle(classObj *class, styleObj *style, int nStyleIndex) -{ +int msInsertStyle(classObj *class, styleObj *style, int nStyleIndex) { int i; if (!style) { @@ -144,39 +137,40 @@ int msInsertStyle(classObj *class, styleObj *style, int nStyleIndex) } /* Catch attempt to insert past end of styles array */ else if (nStyleIndex >= class->numstyles) { - msSetError(MS_CHILDERR, "Cannot insert style beyond index %d", "insertStyle()", class->numstyles-1); + msSetError(MS_CHILDERR, "Cannot insert style beyond index %d", + "insertStyle()", class->numstyles - 1); return -1; } else if (nStyleIndex < 0) { /* Insert at the end by default */ - class->styles[class->numstyles]=style; + class->styles[class->numstyles] = style; MS_REFCNT_INCR(style); class->numstyles++; - return class->numstyles-1; + return class->numstyles - 1; } else { /* Move styles existing at the specified nStyleIndex or greater */ /* to a higher nStyleIndex */ - for (i=class->numstyles-1; i>=nStyleIndex; i--) { - class->styles[i+1] = class->styles[i]; + for (i = class->numstyles - 1; i >= nStyleIndex; i--) { + class->styles[i + 1] = class->styles[i]; } - class->styles[nStyleIndex]=style; + class->styles[nStyleIndex] = style; MS_REFCNT_INCR(style); class->numstyles++; return nStyleIndex; } } -styleObj *msRemoveStyle(classObj *class, int nStyleIndex) -{ +styleObj *msRemoveStyle(classObj *class, int nStyleIndex) { int i; styleObj *style; if (nStyleIndex < 0 || nStyleIndex >= class->numstyles) { - msSetError(MS_CHILDERR, "Cannot remove style, invalid nStyleIndex %d", "removeStyle()", nStyleIndex); + msSetError(MS_CHILDERR, "Cannot remove style, invalid nStyleIndex %d", + "removeStyle()", nStyleIndex); return NULL; } else { - style=class->styles[nStyleIndex]; - for (i=nStyleIndex; inumstyles-1; i++) { - class->styles[i]=class->styles[i+1]; + style = class->styles[nStyleIndex]; + for (i = nStyleIndex; i < class->numstyles - 1; i++) { + class->styles[i] = class->styles[i + 1]; } - class->styles[class->numstyles-1]=NULL; + class->styles[class->numstyles - 1] = NULL; class->numstyles--; MS_REFCNT_DECR(style); return style; @@ -187,19 +181,17 @@ styleObj *msRemoveStyle(classObj *class, int nStyleIndex) * Delete the style identified by the index and shift * styles that follows the deleted style. */ -int msDeleteStyle(classObj *class, int nStyleIndex) -{ - if (class && nStyleIndex < class->numstyles && nStyleIndex >=0) { +int msDeleteStyle(classObj *class, int nStyleIndex) { + if (class && nStyleIndex < class->numstyles && nStyleIndex >= 0) { if (freeStyle(class->styles[nStyleIndex]) == MS_SUCCESS) msFree(class->styles[nStyleIndex]); - for (int i=nStyleIndex; i< class->numstyles-1; i++) { - class->styles[i] = class->styles[i+1]; + for (int i = nStyleIndex; i < class->numstyles - 1; i++) { + class->styles[i] = class->styles[i + 1]; } - class->styles[class->numstyles-1] = NULL; + class->styles[class->numstyles - 1] = NULL; class->numstyles--; - return(MS_SUCCESS); + return (MS_SUCCESS); } - msSetError(MS_CHILDERR, "Invalid index: %d", "msDeleteStyle()", - nStyleIndex); + msSetError(MS_CHILDERR, "Invalid index: %d", "msDeleteStyle()", nStyleIndex); return (MS_FAILURE); } diff --git a/coshp.c b/coshp.c index a78ae3f3a0..ed530893fe 100644 --- a/coshp.c +++ b/coshp.c @@ -33,7 +33,6 @@ #include "mapserver.h" - typedef struct { SHPHandle inSHP, outSHP; DBFHandle inDBF, outDBF; @@ -41,39 +40,37 @@ typedef struct { int numDbfFields; } writeState; -static char* AddFileSuffix ( const char * Filename, const char * Suffix ) -{ - char *pszFullname, *pszBasename; +static char *AddFileSuffix(const char *Filename, const char *Suffix) { + char *pszFullname, *pszBasename; int i; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ - pszBasename = (char *) msSmallMalloc(strlen(Filename)+5); - strcpy( pszBasename, Filename ); - for( i = (int)strlen(pszBasename)-1; - i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' - && pszBasename[i] != '\\'; - i-- ) {} - - if( pszBasename[i] == '.' ) + pszBasename = (char *)msSmallMalloc(strlen(Filename) + 5); + strcpy(pszBasename, Filename); + for (i = (int)strlen(pszBasename) - 1; + i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && + pszBasename[i] != '\\'; + i--) { + } + + if (pszBasename[i] == '.') pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ - pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5); - sprintf( pszFullname, "%s%s", pszBasename, Suffix); + pszFullname = (char *)msSmallMalloc(strlen(pszBasename) + 5); + sprintf(pszFullname, "%s%s", pszBasename, Suffix); free(pszBasename); return (pszFullname); } - -static int writeShape(writeState *state, int shapeId) -{ +static int writeShape(writeState *state, int shapeId) { int j = 0; int i = state->currentOutRecord; char fName[20]; @@ -81,33 +78,37 @@ static int writeShape(writeState *state, int shapeId) shapeObj shape; /* Copy the DBF record over */ - for(j=0; jnumDbfFields; j++) { + for (j = 0; j < state->numDbfFields; j++) { - DBFFieldType dbfField = msDBFGetFieldInfo(state->inDBF, j, fName, &fWidth, &fnDecimals); + DBFFieldType dbfField = + msDBFGetFieldInfo(state->inDBF, j, fName, &fWidth, &fnDecimals); switch (dbfField) { - case FTInteger: - msDBFWriteIntegerAttribute(state->outDBF, i, j, + case FTInteger: + msDBFWriteIntegerAttribute( + state->outDBF, i, j, msDBFReadIntegerAttribute(state->inDBF, shapeId, j)); - break; - case FTDouble: - msDBFWriteDoubleAttribute(state->outDBF, i, j, + break; + case FTDouble: + msDBFWriteDoubleAttribute( + state->outDBF, i, j, msDBFReadDoubleAttribute(state->inDBF, shapeId, j)); - break; - case FTString: - msDBFWriteStringAttribute(state->outDBF, i, j, + break; + case FTString: + msDBFWriteStringAttribute( + state->outDBF, i, j, msDBFReadStringAttribute(state->inDBF, shapeId, j)); - break; - default: - fprintf(stderr,"Unsupported data type for field: %s, exiting.\n",fName); - exit(0); + break; + default: + fprintf(stderr, "Unsupported data type for field: %s, exiting.\n", fName); + exit(0); } } /* Copy the SHP record over */ - msSHPReadShape( state->inSHP, shapeId, &shape ); - msSHPWriteShape( state->outSHP, &shape ); - msFreeShape( &shape ); + msSHPReadShape(state->inSHP, shapeId, &shape); + msSHPWriteShape(state->outSHP, &shape); + msFreeShape(&shape); /* Increment output row number */ state->currentOutRecord++; @@ -115,59 +116,59 @@ static int writeShape(writeState *state, int shapeId) return MS_SUCCESS; } - -static int writeNode(writeState *state, treeNodeObj *node) -{ +static int writeNode(writeState *state, treeNodeObj *node) { int i; if (node->ids) { - for(i = 0; i < node->numshapes; i++) { + for (i = 0; i < node->numshapes; i++) { int curRec = state->currentOutRecord; writeShape(state, node->ids[i]); node->ids[i] = curRec; } } - for(i = 0; i < node->numsubnodes; i++) { + for (i = 0; i < node->numsubnodes; i++) { if (node->subnode[i]) writeNode(state, node->subnode[i]); } return MS_SUCCESS; } - -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { treeObj *tree; /* In-memory index */ shapefileObj shapefile; /* Input shapefile */ - SHPHandle outSHP; /* Output SHP */ - DBFHandle outDBF; /* Output DBF */ + SHPHandle outSHP; /* Output SHP */ + DBFHandle outDBF; /* Output DBF */ DBFFieldType dbfField; - writeState state; - int shpType, nShapes; - char fName[20]; - int fWidth, fnDecimals; - char buffer[1024]; - int numFields; - int i; - - if(argc > 1 && strcmp(argv[1], "-v") == 0) { + writeState state; + int shpType, nShapes; + char fName[20]; + int fWidth, fnDecimals; + char buffer[1024]; + int numFields; + int i; + + if (argc > 1 && strcmp(argv[1], "-v") == 0) { printf("%s\n", msGetVersion()); exit(0); } - /* ------------------------------------------------------------------------------- */ - /* Check the number of arguments, return syntax if not correct */ - /* ------------------------------------------------------------------------------- */ - if( argc != 3 ) { - fprintf(stderr,"Syntax: %s [infile] [outfile]\n", argv[0]); + /* ------------------------------------------------------------------------------- + */ + /* Check the number of arguments, return syntax if not correct */ + /* ------------------------------------------------------------------------------- + */ + if (argc != 3) { + fprintf(stderr, "Syntax: %s [infile] [outfile]\n", argv[0]); exit(1); } msSetErrorFile("stderr", NULL); - /* ------------------------------------------------------------------------------- */ - /* Open the shapefile */ - /* ------------------------------------------------------------------------------- */ - if(msShapefileOpen(&shapefile, "rb", argv[1], MS_TRUE) < 0) { + /* ------------------------------------------------------------------------------- + */ + /* Open the shapefile */ + /* ------------------------------------------------------------------------------- + */ + if (msShapefileOpen(&shapefile, "rb", argv[1], MS_TRUE) < 0) { fprintf(stdout, "Error opening shapefile %s.\n", argv[1]); exit(0); } @@ -176,37 +177,45 @@ int main(int argc, char *argv[]) shpType = shapefile.type; numFields = msDBFGetFieldCount(shapefile.hDBF); - /* ------------------------------------------------------------------------------- */ - /* Index the shapefile (auto-calculate depth) */ - /* ------------------------------------------------------------------------------- */ + /* ------------------------------------------------------------------------------- + */ + /* Index the shapefile (auto-calculate depth) */ + /* ------------------------------------------------------------------------------- + */ tree = msCreateTree(&shapefile, 0); msTreeTrim(tree); - /* ------------------------------------------------------------------------------- */ - /* Setup the output .shp/.shx and .dbf files */ - /* ------------------------------------------------------------------------------- */ + /* ------------------------------------------------------------------------------- + */ + /* Setup the output .shp/.shx and .dbf files */ + /* ------------------------------------------------------------------------------- + */ outSHP = msSHPCreate(argv[2], shpType); - if( outSHP == NULL ) { - fprintf( stderr, "Failed to create file '%s'.\n", argv[2] ); - exit( 1 ); + if (outSHP == NULL) { + fprintf(stderr, "Failed to create file '%s'.\n", argv[2]); + exit(1); } - sprintf(buffer,"%s.dbf", argv[2]); + sprintf(buffer, "%s.dbf", argv[2]); outDBF = msDBFCreate(buffer); - if( outDBF == NULL ) { - fprintf( stderr, "Failed to create dbf file '%s'.\n", buffer ); - exit( 1 ); + if (outDBF == NULL) { + fprintf(stderr, "Failed to create dbf file '%s'.\n", buffer); + exit(1); } /* Clone the fields from the input to the output definition */ - for(i=0; iroot); - /* ------------------------------------------------------------------------------- */ - /* Write the spatial index */ - /* ------------------------------------------------------------------------------- */ - msWriteTree(tree, AddFileSuffix(argv[2], MS_INDEX_EXTENSION), MS_NEW_LSB_ORDER); + /* ------------------------------------------------------------------------------- + */ + /* Write the spatial index */ + /* ------------------------------------------------------------------------------- + */ + msWriteTree(tree, AddFileSuffix(argv[2], MS_INDEX_EXTENSION), + MS_NEW_LSB_ORDER); msDestroyTree(tree); - /* ------------------------------------------------------------------------------- */ - /* Close all files */ - /* ------------------------------------------------------------------------------- */ + /* ------------------------------------------------------------------------------- + */ + /* Close all files */ + /* ------------------------------------------------------------------------------- + */ msShapefileClose(&shapefile); msSHPClose(outSHP); msDBFClose(outDBF); - fprintf(stdout, "Wrote %d spatially sorted shapes into shapefile '%s'\n", nShapes, argv[2]); - return(0); + fprintf(stdout, "Wrote %d spatially sorted shapes into shapefile '%s'\n", + nShapes, argv[2]); + return (0); } diff --git a/create_mapaxisorder_csv.py b/create_mapaxisorder_csv.py index b5d2985d93..2e3e4598ff 100644 --- a/create_mapaxisorder_csv.py +++ b/create_mapaxisorder_csv.py @@ -31,7 +31,7 @@ from osgeo import gdal, osr sr = osr.SpatialReference() -print('epsg_code') +print("epsg_code") for code in range(32767): gdal.PushErrorHandler() ret = sr.ImportFromEPSGA(code) diff --git a/dxfcolor.h b/dxfcolor.h index 5de47065ec..1267ae5b6c 100644 --- a/dxfcolor.h +++ b/dxfcolor.h @@ -1,261 +1,69 @@ struct dxfcolor { - int r,g,b; + int r, g, b; }; struct dxfcolor ctable[256] = { - {0, 0, 0}, - {255, 0, 0}, - {255, 255, 0}, - {0, 255, 0}, - {0, 255, 255}, - {0, 0, 255}, - {255, 0, 255}, - {255, 255, 255}, - {128, 128, 128}, - {192, 192, 192}, - {255, 0, 0}, - {255, 127, 127}, - {204, 0, 0}, - {204, 102, 102}, - {153, 0, 0}, - {153, 76, 76}, - {127, 0, 0}, - {127, 63, 63}, - {76, 0, 0}, - {76, 38, 38}, - {255, 63, 0}, - {255, 159, 127}, - {204, 51, 0}, - {204, 127, 102}, - {153, 38, 0}, - {153, 95, 76}, - {127, 31, 0}, - {127, 79, 63}, - {76, 19, 0}, - {76, 47, 38}, - {255, 127, 0}, - {255, 191, 127}, - {204, 102, 0}, - {204, 153, 102}, - {153, 76, 0}, - {153, 114, 76}, - {127, 63, 0}, - {127, 95, 63}, - {76, 38, 0}, - {76, 57, 38}, - {255, 191, 0}, - {255, 223, 127}, - {204, 153, 0}, - {204, 178, 102}, - {153, 114, 0}, - {153, 133, 76}, - {127, 95, 0}, - {127, 111, 63}, - {76, 57, 0}, - {76, 66, 38}, - {255, 255, 0}, - {255, 255, 127}, - {204, 204, 0}, - {204, 204, 102}, - {153, 153, 0}, - {153, 153, 76}, - {127, 127, 0}, - {127, 127, 63}, - {76, 76, 0}, - {76, 76, 38}, - {191, 255, 0}, - {223, 255, 127}, - {153, 204, 0}, - {178, 204, 102}, - {114, 153, 0}, - {133, 153, 76}, - {95, 127, 0}, - {111, 127, 63}, - {57, 76, 0}, - {66, 76, 38}, - {127, 255, 0}, - {191, 255, 127}, - {102, 204, 0}, - {153, 204, 102}, - {76, 153, 0}, - {114, 153, 76}, - {63, 127, 0}, - {95, 127, 63}, - {38, 76, 0}, - {57, 76, 38}, - {63, 255, 0}, - {159, 255, 127}, - {51, 204, 0}, - {127, 204, 102}, - {38, 153, 0}, - {95, 153, 76}, - {31, 127, 0}, - {79, 127, 63}, - {19, 76, 0}, - {47, 76, 38}, - {0, 255, 0}, - {127, 255, 127}, - {0, 204, 0}, - {102, 204, 102}, - {0, 153, 0}, - {76, 153, 76}, - {0, 127, 0}, - {63, 127, 63}, - {0, 76, 0}, - {38, 76, 38}, - {0, 255, 63}, - {127, 255, 159}, - {0, 204, 51}, - {102, 204, 127}, - {0, 153, 38}, - {76, 153, 95}, - {0, 127, 31}, - {63, 127, 79}, - {0, 76, 19}, - {38, 76, 47}, - {0, 255, 127}, - {127, 255, 191}, - {0, 204, 102}, - {102, 204, 153}, - {0, 153, 76}, - {76, 153, 114}, - {0, 127, 63}, - {63, 127, 95}, - {0, 76, 38}, - {38, 76, 57}, - {0, 255, 191}, - {127, 255, 223}, - {0, 204, 153}, - {102, 204, 178}, - {0, 153, 114}, - {76, 153, 133}, - {0, 127, 95}, - {63, 127, 111}, - {0, 76, 57}, - {38, 76, 66}, - {0, 255, 255}, - {127, 255, 255}, - {0, 204, 204}, - {102, 204, 204}, - {0, 153, 153}, - {76, 153, 153}, - {0, 127, 127}, - {63, 127, 127}, - {0, 76, 76}, - {38, 76, 76}, - {0, 191, 255}, - {127, 223, 255}, - {0, 153, 204}, - {102, 178, 204}, - {0, 114, 153}, - {76, 133, 153}, - {0, 95, 127}, - {63, 111, 127}, - {0, 57, 76}, - {38, 66, 76}, - {0, 127, 255}, - {127, 191, 255}, - {0, 102, 204}, - {102, 153, 204}, - {0, 76, 153}, - {76, 114, 153}, - {0, 63, 127}, - {63, 95, 127}, - {0, 38, 76}, - {38, 57, 76}, - {0, 63, 255}, - {127, 159, 255}, - {0, 51, 204}, - {102, 127, 204}, - {0, 38, 153}, - {76, 95, 153}, - {0, 31, 127}, - {63, 79, 127}, - {0, 19, 76}, - {38, 47, 76}, - {0, 0, 255}, - {127, 127, 255}, - {0, 0, 204}, - {102, 102, 204}, - {0, 0, 153}, - {76, 76, 153}, - {0, 0, 127}, - {63, 63, 127}, - {0, 0, 76}, - {38, 38, 76}, - {63, 0, 255}, - {159, 127, 255}, - {51, 0, 204}, - {127, 102, 204}, - {38, 0, 153}, - {95, 76, 153}, - {31, 0, 127}, - {79, 63, 127}, - {19, 0, 76}, - {47, 38, 76}, - {127, 0, 255}, - {191, 127, 255}, - {102, 0, 204}, - {153, 102, 204}, - {76, 0, 153}, - {114, 76, 153}, - {63, 0, 127}, - {95, 63, 127}, - {38, 0, 76}, - {57, 38, 76}, - {191, 0, 255}, - {223, 127, 255}, - {153, 0, 204}, - {178, 102, 204}, - {114, 0, 153}, - {133, 76, 153}, - {95, 0, 127}, - {111, 63, 127}, - {57, 0, 76}, - {66, 38, 76}, - {255, 0, 255}, - {255, 127, 255}, - {204, 0, 204}, - {204, 102, 204}, - {153, 0, 153}, - {153, 76, 153}, - {127, 0, 127}, - {127, 63, 127}, - {76, 0, 76}, - {76, 38, 76}, - {255, 0, 191}, - {255, 127, 223}, - {204, 0, 153}, - {204, 102, 178}, - {153, 0, 114}, - {153, 76, 133}, - {127, 0, 95}, - {127, 63, 111}, - {76, 0, 57}, - {76, 38, 66}, - {255, 0, 127}, - {255, 127, 191}, - {204, 0, 102}, - {204, 102, 153}, - {153, 0, 76}, - {153, 76, 114}, - {127, 0, 63}, - {127, 63, 95}, - {76, 0, 38}, - {76, 38, 57}, - {255, 0, 63}, - {255, 127, 159}, - {204, 0, 51}, - {204, 102, 127}, - {153, 0, 38}, - {153, 76, 95}, - {127, 0, 31}, - {127, 63, 79}, - {76, 0, 19}, - {76, 38, 47}, - {51, 51, 51}, - {91, 91, 91}, - {132, 132, 132}, - {173, 173, 173}, - {214, 214, 214}, - {255, 255, 255}, + {0, 0, 0}, {255, 0, 0}, {255, 255, 0}, {0, 255, 0}, + {0, 255, 255}, {0, 0, 255}, {255, 0, 255}, {255, 255, 255}, + {128, 128, 128}, {192, 192, 192}, {255, 0, 0}, {255, 127, 127}, + {204, 0, 0}, {204, 102, 102}, {153, 0, 0}, {153, 76, 76}, + {127, 0, 0}, {127, 63, 63}, {76, 0, 0}, {76, 38, 38}, + {255, 63, 0}, {255, 159, 127}, {204, 51, 0}, {204, 127, 102}, + {153, 38, 0}, {153, 95, 76}, {127, 31, 0}, {127, 79, 63}, + {76, 19, 0}, {76, 47, 38}, {255, 127, 0}, {255, 191, 127}, + {204, 102, 0}, {204, 153, 102}, {153, 76, 0}, {153, 114, 76}, + {127, 63, 0}, {127, 95, 63}, {76, 38, 0}, {76, 57, 38}, + {255, 191, 0}, {255, 223, 127}, {204, 153, 0}, {204, 178, 102}, + {153, 114, 0}, {153, 133, 76}, {127, 95, 0}, {127, 111, 63}, + {76, 57, 0}, {76, 66, 38}, {255, 255, 0}, {255, 255, 127}, + {204, 204, 0}, {204, 204, 102}, {153, 153, 0}, {153, 153, 76}, + {127, 127, 0}, {127, 127, 63}, {76, 76, 0}, {76, 76, 38}, + {191, 255, 0}, {223, 255, 127}, {153, 204, 0}, {178, 204, 102}, + {114, 153, 0}, {133, 153, 76}, {95, 127, 0}, {111, 127, 63}, + {57, 76, 0}, {66, 76, 38}, {127, 255, 0}, {191, 255, 127}, + {102, 204, 0}, {153, 204, 102}, {76, 153, 0}, {114, 153, 76}, + {63, 127, 0}, {95, 127, 63}, {38, 76, 0}, {57, 76, 38}, + {63, 255, 0}, {159, 255, 127}, {51, 204, 0}, {127, 204, 102}, + {38, 153, 0}, {95, 153, 76}, {31, 127, 0}, {79, 127, 63}, + {19, 76, 0}, {47, 76, 38}, {0, 255, 0}, {127, 255, 127}, + {0, 204, 0}, {102, 204, 102}, {0, 153, 0}, {76, 153, 76}, + {0, 127, 0}, {63, 127, 63}, {0, 76, 0}, {38, 76, 38}, + {0, 255, 63}, {127, 255, 159}, {0, 204, 51}, {102, 204, 127}, + {0, 153, 38}, {76, 153, 95}, {0, 127, 31}, {63, 127, 79}, + {0, 76, 19}, {38, 76, 47}, {0, 255, 127}, {127, 255, 191}, + {0, 204, 102}, {102, 204, 153}, {0, 153, 76}, {76, 153, 114}, + {0, 127, 63}, {63, 127, 95}, {0, 76, 38}, {38, 76, 57}, + {0, 255, 191}, {127, 255, 223}, {0, 204, 153}, {102, 204, 178}, + {0, 153, 114}, {76, 153, 133}, {0, 127, 95}, {63, 127, 111}, + {0, 76, 57}, {38, 76, 66}, {0, 255, 255}, {127, 255, 255}, + {0, 204, 204}, {102, 204, 204}, {0, 153, 153}, {76, 153, 153}, + {0, 127, 127}, {63, 127, 127}, {0, 76, 76}, {38, 76, 76}, + {0, 191, 255}, {127, 223, 255}, {0, 153, 204}, {102, 178, 204}, + {0, 114, 153}, {76, 133, 153}, {0, 95, 127}, {63, 111, 127}, + {0, 57, 76}, {38, 66, 76}, {0, 127, 255}, {127, 191, 255}, + {0, 102, 204}, {102, 153, 204}, {0, 76, 153}, {76, 114, 153}, + {0, 63, 127}, {63, 95, 127}, {0, 38, 76}, {38, 57, 76}, + {0, 63, 255}, {127, 159, 255}, {0, 51, 204}, {102, 127, 204}, + {0, 38, 153}, {76, 95, 153}, {0, 31, 127}, {63, 79, 127}, + {0, 19, 76}, {38, 47, 76}, {0, 0, 255}, {127, 127, 255}, + {0, 0, 204}, {102, 102, 204}, {0, 0, 153}, {76, 76, 153}, + {0, 0, 127}, {63, 63, 127}, {0, 0, 76}, {38, 38, 76}, + {63, 0, 255}, {159, 127, 255}, {51, 0, 204}, {127, 102, 204}, + {38, 0, 153}, {95, 76, 153}, {31, 0, 127}, {79, 63, 127}, + {19, 0, 76}, {47, 38, 76}, {127, 0, 255}, {191, 127, 255}, + {102, 0, 204}, {153, 102, 204}, {76, 0, 153}, {114, 76, 153}, + {63, 0, 127}, {95, 63, 127}, {38, 0, 76}, {57, 38, 76}, + {191, 0, 255}, {223, 127, 255}, {153, 0, 204}, {178, 102, 204}, + {114, 0, 153}, {133, 76, 153}, {95, 0, 127}, {111, 63, 127}, + {57, 0, 76}, {66, 38, 76}, {255, 0, 255}, {255, 127, 255}, + {204, 0, 204}, {204, 102, 204}, {153, 0, 153}, {153, 76, 153}, + {127, 0, 127}, {127, 63, 127}, {76, 0, 76}, {76, 38, 76}, + {255, 0, 191}, {255, 127, 223}, {204, 0, 153}, {204, 102, 178}, + {153, 0, 114}, {153, 76, 133}, {127, 0, 95}, {127, 63, 111}, + {76, 0, 57}, {76, 38, 66}, {255, 0, 127}, {255, 127, 191}, + {204, 0, 102}, {204, 102, 153}, {153, 0, 76}, {153, 76, 114}, + {127, 0, 63}, {127, 63, 95}, {76, 0, 38}, {76, 38, 57}, + {255, 0, 63}, {255, 127, 159}, {204, 0, 51}, {204, 102, 127}, + {153, 0, 38}, {153, 76, 95}, {127, 0, 31}, {127, 63, 79}, + {76, 0, 19}, {76, 38, 47}, {51, 51, 51}, {91, 91, 91}, + {132, 132, 132}, {173, 173, 173}, {214, 214, 214}, {255, 255, 255}, }; diff --git a/fontcache.c b/fontcache.c index 434665bfbc..43f836bc38 100644 --- a/fontcache.c +++ b/fontcache.c @@ -26,7 +26,6 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ - #include "mapserver.h" #include "mapthread.h" #include "fontcache.h" @@ -42,86 +41,85 @@ typedef struct { #ifdef USE_THREAD typedef struct ft_thread_cache ft_thread_cache; -struct ft_thread_cache{ - void* thread_id; +struct ft_thread_cache { + void *thread_id; ft_thread_cache *next; ft_cache cache; }; ft_thread_cache *ft_caches; int use_global_ft_cache; #else - ft_cache global_ft_cache; +ft_cache global_ft_cache; #endif - void msInitFontCache(ft_cache *c) { - memset(c,0,sizeof(ft_cache)); + memset(c, 0, sizeof(ft_cache)); FT_Init_FreeType(&c->library); } void msFreeFontCache(ft_cache *c) { /* ... TODO ... */ - face_element *cur_face,*tmp_face; + face_element *cur_face, *tmp_face; glyph_element *cur_bitmap, *tmp_bitmap; UT_HASH_ITER(hh, c->face_cache, cur_face, tmp_face) { - index_element *cur_index,*tmp_index; - outline_element *cur_outline,*tmp_outline; - glyph_element *cur_glyph,*tmp_glyph; - UT_HASH_ITER(hh, cur_face->index_cache, cur_index, tmp_index) { - UT_HASH_DEL(cur_face->index_cache,cur_index); - free(cur_index); - } - UT_HASH_ITER(hh, cur_face->outline_cache, cur_outline, tmp_outline) { - UT_HASH_DEL(cur_face->outline_cache,cur_outline); - FT_Outline_Done(c->library,&cur_outline->outline); - free(cur_outline); - } - UT_HASH_ITER(hh, cur_face->glyph_cache, cur_glyph, tmp_glyph) { - UT_HASH_DEL(cur_face->glyph_cache,cur_glyph); - free(cur_glyph); - } + index_element *cur_index, *tmp_index; + outline_element *cur_outline, *tmp_outline; + glyph_element *cur_glyph, *tmp_glyph; + UT_HASH_ITER(hh, cur_face->index_cache, cur_index, tmp_index) { + UT_HASH_DEL(cur_face->index_cache, cur_index); + free(cur_index); + } + UT_HASH_ITER(hh, cur_face->outline_cache, cur_outline, tmp_outline) { + UT_HASH_DEL(cur_face->outline_cache, cur_outline); + FT_Outline_Done(c->library, &cur_outline->outline); + free(cur_outline); + } + UT_HASH_ITER(hh, cur_face->glyph_cache, cur_glyph, tmp_glyph) { + UT_HASH_DEL(cur_face->glyph_cache, cur_glyph); + free(cur_glyph); + } #ifdef USE_HARFBUZZ - if(cur_face->hbfont) { - hb_font_destroy(cur_face->hbfont->hbfont); - hb_font_destroy(cur_face->hbfont->hbparentfont); - hb_font_funcs_destroy(cur_face->hbfont->funcs); - free(cur_face->hbfont); - } + if (cur_face->hbfont) { + hb_font_destroy(cur_face->hbfont->hbfont); + hb_font_destroy(cur_face->hbfont->hbparentfont); + hb_font_funcs_destroy(cur_face->hbfont->funcs); + free(cur_face->hbfont); + } #endif - FT_Done_Face(cur_face->face); - free(cur_face->font); - UT_HASH_DEL(c->face_cache,cur_face); - free(cur_face); + FT_Done_Face(cur_face->face); + free(cur_face->font); + UT_HASH_DEL(c->face_cache, cur_face); + free(cur_face); } FT_Done_FreeType(c->library); - UT_HASH_ITER(hh,c->bitmap_glyph_cache, cur_bitmap, tmp_bitmap) { + UT_HASH_ITER(hh, c->bitmap_glyph_cache, cur_bitmap, tmp_bitmap) { UT_HASH_DEL(c->bitmap_glyph_cache, cur_bitmap); free(cur_bitmap); } - memset(c,0,sizeof(ft_cache)); + memset(c, 0, sizeof(ft_cache)); } -ft_cache* msGetFontCache() { +ft_cache *msGetFontCache() { #ifndef USE_THREAD return &global_ft_cache; #else - void* nThreadId = 0; + void *nThreadId = 0; ft_thread_cache *prev = NULL, *cur = ft_caches; if (!use_global_ft_cache) nThreadId = msGetThreadId(); - if( cur != NULL && cur->thread_id == nThreadId ) + if (cur != NULL && cur->thread_id == nThreadId) return &cur->cache; /* -------------------------------------------------------------------- */ /* Search for cache for this thread */ /* -------------------------------------------------------------------- */ - msAcquireLock( TLOCK_TTF ); + msAcquireLock(TLOCK_TTF); cur = ft_caches; - while( cur != NULL && cur->thread_id != nThreadId ) { + while (cur != NULL && cur->thread_id != nThreadId) { prev = cur; cur = cur->next; } @@ -130,14 +128,14 @@ ft_cache* msGetFontCache() { /* If we found it, make sure it is pushed to the front of the */ /* link for faster finding next time, and return it. */ /* -------------------------------------------------------------------- */ - if( cur != NULL ) { - if( prev != NULL ) { + if (cur != NULL) { + if (prev != NULL) { prev->next = cur->next; cur->next = ft_caches; ft_caches = cur; } - msReleaseLock( TLOCK_TTF ); + msReleaseLock(TLOCK_TTF); return &cur->cache; } @@ -151,7 +149,7 @@ ft_cache* msGetFontCache() { cur->next = ft_caches; ft_caches = cur; - msReleaseLock( TLOCK_TTF ); + msReleaseLock(TLOCK_TTF); return &cur->cache; #endif @@ -162,7 +160,8 @@ void msFontCacheSetup() { ft_cache *c = msGetFontCache(); msInitFontCache(c); #else - const char *use_global_cache = CPLGetConfigOption("MS_USE_GLOBAL_FT_CACHE", NULL); + const char *use_global_cache = + CPLGetConfigOption("MS_USE_GLOBAL_FT_CACHE", NULL); if (use_global_cache) use_global_ft_cache = atoi(use_global_cache); else @@ -177,64 +176,66 @@ void msFontCacheCleanup() { ft_cache *c = msGetFontCache(); msFreeFontCache(c); #else - ft_thread_cache *cur,*next; - msAcquireLock( TLOCK_TTF ); - cur = ft_caches; - while( cur != NULL ) { + ft_thread_cache *cur, *next; + msAcquireLock(TLOCK_TTF); + cur = ft_caches; + while (cur != NULL) { msFreeFontCache(&cur->cache); next = cur->next; free(cur); cur = next; } ft_caches = NULL; - msReleaseLock( TLOCK_TTF ); + msReleaseLock(TLOCK_TTF); #endif } unsigned int msGetGlyphIndex(face_element *face, unsigned int unicode) { index_element *ic; - if(face->face->charmap && face->face->charmap->encoding == FT_ENCODING_MS_SYMBOL) { + if (face->face->charmap && + face->face->charmap->encoding == FT_ENCODING_MS_SYMBOL) { unicode |= 0xf000; /* why? */ } #ifdef USE_THREAD if (use_global_ft_cache) - msAcquireLock(TLOCK_TTF); -#endif - UT_HASH_FIND_INT(face->index_cache,&unicode,ic); - if(!ic) { + msAcquireLock(TLOCK_TTF); +#endif + UT_HASH_FIND_INT(face->index_cache, &unicode, ic); + if (!ic) { ic = msSmallMalloc(sizeof(index_element)); - ic->codepoint = FT_Get_Char_Index(face->face,unicode); + ic->codepoint = FT_Get_Char_Index(face->face, unicode); ic->unicode = unicode; - UT_HASH_ADD_INT(face->index_cache,unicode,ic); + UT_HASH_ADD_INT(face->index_cache, unicode, ic); } #ifdef USE_THREAD if (use_global_ft_cache) - msReleaseLock(TLOCK_TTF); -#endif + msReleaseLock(TLOCK_TTF); +#endif return ic->codepoint; } #define MS_DEFAULT_FONT_KEY "_ms_default_" -face_element* msGetFontFace(char *key, fontSetObj *fontset) { +face_element *msGetFontFace(char *key, fontSetObj *fontset) { face_element *fc; int error; ft_cache *cache = msGetFontCache(); - if(!key) { + if (!key) { key = MS_DEFAULT_FONT_KEY; } #ifdef USE_THREAD if (use_global_ft_cache) msAcquireLock(TLOCK_TTF); #endif - UT_HASH_FIND_STR(cache->face_cache,key,fc); - if(!fc) { + UT_HASH_FIND_STR(cache->face_cache, key, fc); + if (!fc) { const char *fontfile = NULL; - fc = msSmallCalloc(1,sizeof(face_element)); - if(fontset && strcmp(key,MS_DEFAULT_FONT_KEY)) { - fontfile = msLookupHashTable(&(fontset->fonts),key); - if(!fontfile) { - msSetError(MS_MISCERR, "Could not find font with key \"%s\" in fontset", "msGetFontFace()", key); + fc = msSmallCalloc(1, sizeof(face_element)); + if (fontset && strcmp(key, MS_DEFAULT_FONT_KEY)) { + fontfile = msLookupHashTable(&(fontset->fonts), key); + if (!fontfile) { + msSetError(MS_MISCERR, "Could not find font with key \"%s\" in fontset", + "msGetFontFace()", key); free(fc); #ifdef USE_THREAD if (use_global_ft_cache) @@ -242,12 +243,15 @@ face_element* msGetFontFace(char *key, fontSetObj *fontset) { #endif return NULL; } - error = FT_New_Face(cache->library,fontfile,0, &(fc->face)); + error = FT_New_Face(cache->library, fontfile, 0, &(fc->face)); } else { - error = FT_New_Memory_Face(cache->library,dejavu_sans_condensed_ttf, dejavu_sans_condensed_ttf_len , 0, &(fc->face)); + error = FT_New_Memory_Face(cache->library, dejavu_sans_condensed_ttf, + dejavu_sans_condensed_ttf_len, 0, &(fc->face)); } - if(error) { - msSetError(MS_MISCERR, "Freetype was unable to load font file \"%s\" for key \"%s\"", "msGetFontFace()", fontfile, key); + if (error) { + msSetError(MS_MISCERR, + "Freetype was unable to load font file \"%s\" for key \"%s\"", + "msGetFontFace()", fontfile, key); free(fc); #ifdef USE_THREAD if (use_global_ft_cache) @@ -255,14 +259,15 @@ face_element* msGetFontFace(char *key, fontSetObj *fontset) { #endif return NULL; } - if(!fc->face->charmap) { + if (!fc->face->charmap) { /* The font file has no unicode charmap, select an alternate one */ - if( FT_Select_Charmap(fc->face, FT_ENCODING_MS_SYMBOL) ) + if (FT_Select_Charmap(fc->face, FT_ENCODING_MS_SYMBOL)) FT_Select_Charmap(fc->face, FT_ENCODING_APPLE_ROMAN); - /* the previous calls may have failed, we ignore as there's nothing much left to do */ + /* the previous calls may have failed, we ignore as there's nothing much + * left to do */ } fc->font = msStrdup(key); - UT_HASH_ADD_KEYPTR(hh,cache->face_cache,fc->font, strlen(key), fc); + UT_HASH_ADD_KEYPTR(hh, cache->face_cache, fc->font, strlen(key), fc); } #ifdef USE_THREAD if (use_global_ft_cache) @@ -271,86 +276,106 @@ face_element* msGetFontFace(char *key, fontSetObj *fontset) { return fc; } -glyph_element* msGetGlyphByIndex(face_element *face, unsigned int size, unsigned int codepoint) { +glyph_element *msGetGlyphByIndex(face_element *face, unsigned int size, + unsigned int codepoint) { glyph_element *gc; glyph_element_key key; - memset(&key,0,sizeof(glyph_element_key)); + memset(&key, 0, sizeof(glyph_element_key)); key.codepoint = codepoint; key.size = size; #ifdef USE_THREAD if (use_global_ft_cache) msAcquireLock(TLOCK_TTF); -#endif - UT_HASH_FIND(hh,face->glyph_cache,&key,sizeof(glyph_element_key),gc); - if(!gc) { +#endif + UT_HASH_FIND(hh, face->glyph_cache, &key, sizeof(glyph_element_key), gc); + if (!gc) { FT_Error error; gc = msSmallMalloc(sizeof(glyph_element)); - if(MS_NINT(size * 96.0/72.0) != face->face->size->metrics.x_ppem) { - FT_Set_Pixel_Sizes(face->face,0,MS_NINT(size * 96/72.0)); + if (MS_NINT(size * 96.0 / 72.0) != face->face->size->metrics.x_ppem) { + FT_Set_Pixel_Sizes(face->face, 0, MS_NINT(size * 96 / 72.0)); } - error = FT_Load_Glyph(face->face,key.codepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + error = + FT_Load_Glyph(face->face, key.codepoint, + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); if (error) { - msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", key.codepoint, face->font); + msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", + key.codepoint, face->font); // If we can't find a glyph then try to fallback to a question mark. unsigned int fallbackCodepoint = msGetGlyphIndex(face, 0x3F); - error = FT_Load_Glyph(face->face,fallbackCodepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + error = FT_Load_Glyph(face->face, fallbackCodepoint, + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); } - if(error) { - msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", "msGetGlyphByIndex()",key.codepoint, face->font); + if (error) { + msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", + "msGetGlyphByIndex()", key.codepoint, face->font); free(gc); #ifdef USE_THREAD if (use_global_ft_cache) msReleaseLock(TLOCK_TTF); -#endif +#endif return NULL; } gc->metrics.minx = face->face->glyph->metrics.horiBearingX / 64.0; - gc->metrics.maxx = gc->metrics.minx + face->face->glyph->metrics.width / 64.0; + gc->metrics.maxx = + gc->metrics.minx + face->face->glyph->metrics.width / 64.0; gc->metrics.maxy = face->face->glyph->metrics.horiBearingY / 64.0; - gc->metrics.miny = gc->metrics.maxy - face->face->glyph->metrics.height / 64.0; + gc->metrics.miny = + gc->metrics.maxy - face->face->glyph->metrics.height / 64.0; gc->metrics.advance = face->face->glyph->metrics.horiAdvance / 64.0; gc->key = key; - UT_HASH_ADD(hh,face->glyph_cache,key,sizeof(glyph_element_key), gc); + UT_HASH_ADD(hh, face->glyph_cache, key, sizeof(glyph_element_key), gc); } #ifdef USE_THREAD if (use_global_ft_cache) msReleaseLock(TLOCK_TTF); -#endif +#endif return gc; } -outline_element* msGetGlyphOutline(face_element *face, glyph_element *glyph) { +outline_element *msGetGlyphOutline(face_element *face, glyph_element *glyph) { outline_element *oc; outline_element_key key; ft_cache *cache = msGetFontCache(); - memset(&key,0,sizeof(outline_element_key)); + memset(&key, 0, sizeof(outline_element_key)); key.glyph = glyph; #ifdef USE_THREAD if (use_global_ft_cache) msAcquireLock(TLOCK_TTF); #endif - UT_HASH_FIND(hh,face->outline_cache,&key, sizeof(outline_element_key),oc); - if(!oc) { + UT_HASH_FIND(hh, face->outline_cache, &key, sizeof(outline_element_key), oc); + if (!oc) { FT_Matrix matrix; FT_Vector pen; FT_Error error; oc = msSmallMalloc(sizeof(outline_element)); - if(MS_NINT(glyph->key.size * 96.0/72.0) != face->face->size->metrics.x_ppem) { - FT_Set_Pixel_Sizes(face->face,0,MS_NINT(glyph->key.size * 96/72.0)); + if (MS_NINT(glyph->key.size * 96.0 / 72.0) != + face->face->size->metrics.x_ppem) { + FT_Set_Pixel_Sizes(face->face, 0, MS_NINT(glyph->key.size * 96 / 72.0)); } matrix.xx = matrix.yy = 0x10000L; matrix.xy = matrix.yx = 0x00000L; pen.x = pen.y = 0; FT_Set_Transform(face->face, &matrix, &pen); - error = FT_Load_Glyph(face->face,glyph->key.codepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP/*|FT_LOAD_IGNORE_TRANSFORM*/|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + error = FT_Load_Glyph( + face->face, glyph->key.codepoint, + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP /*|FT_LOAD_IGNORE_TRANSFORM*/ | + FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); if (error) { - msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", glyph->key.codepoint, face->font); + msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", + glyph->key.codepoint, face->font); // If we can't find a glyph then try to fallback to a question mark. unsigned int fallbackCodepoint = msGetGlyphIndex(face, 0x3F); - error = FT_Load_Glyph(face->face,fallbackCodepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP/*|FT_LOAD_IGNORE_TRANSFORM*/|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + error = FT_Load_Glyph( + face->face, fallbackCodepoint, + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP /*|FT_LOAD_IGNORE_TRANSFORM*/ | + FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); } - if(error) { - msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", "msGetGlyphOutline()",glyph->key.codepoint, face->font); + if (error) { + msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", + "msGetGlyphOutline()", glyph->key.codepoint, face->font); #ifdef USE_THREAD if (use_global_ft_cache) msReleaseLock(TLOCK_TTF); @@ -358,11 +383,11 @@ outline_element* msGetGlyphOutline(face_element *face, glyph_element *glyph) { return NULL; } error = FT_Outline_New(cache->library, face->face->glyph->outline.n_points, - face->face->glyph->outline.n_contours, &oc->outline); + face->face->glyph->outline.n_contours, &oc->outline); (void)error; FT_Outline_Copy(&face->face->glyph->outline, &oc->outline); oc->key = key; - UT_HASH_ADD(hh,face->outline_cache,key,sizeof(outline_element_key), oc); + UT_HASH_ADD(hh, face->outline_cache, key, sizeof(outline_element_key), oc); } #ifdef USE_THREAD if (use_global_ft_cache) @@ -373,8 +398,9 @@ outline_element* msGetGlyphOutline(face_element *face, glyph_element *glyph) { int msIsGlyphASpace(glyphObj *glyph) { /* space or tab, for now */ - unsigned int space,tab; - space = msGetGlyphIndex(glyph->face,0x20); - tab = msGetGlyphIndex(glyph->face,0x9); - return glyph->glyph->key.codepoint == space || glyph->glyph->key.codepoint == tab; + unsigned int space, tab; + space = msGetGlyphIndex(glyph->face, 0x20); + tab = msGetGlyphIndex(glyph->face, 0x9); + return glyph->glyph->key.codepoint == space || + glyph->glyph->key.codepoint == tab; } diff --git a/fontcache.h b/fontcache.h index 828298bbd5..8b60079f38 100644 --- a/fontcache.h +++ b/fontcache.h @@ -7,14 +7,13 @@ #include FT_OUTLINE_H #ifdef USE_FRIBIDI - #if (defined(_WIN32) && !defined(__CYGWIN__)) || defined(HAVE_FRIBIDI2) - #include "fribidi.h" - #else - #include - #endif - #include +#if (defined(_WIN32) && !defined(__CYGWIN__)) || defined(HAVE_FRIBIDI2) +#include "fribidi.h" +#else +#include +#endif +#include #endif - #ifdef __cplusplus extern "C" { @@ -38,7 +37,7 @@ typedef struct { unsigned int size; } glyph_element_key; -struct glyph_element{ +struct glyph_element { glyph_element_key key; glyph_metrics metrics; UT_hash_handle hh; @@ -64,7 +63,7 @@ typedef struct { UT_hash_handle hh; } bitmap_element; -struct face_element{ +struct face_element { char *font; FT_Face face; index_element *index_cache; @@ -74,12 +73,13 @@ struct face_element{ UT_hash_handle hh; }; - -face_element* msGetFontFace(char *key, fontSetObj *fontset); -outline_element* msGetGlyphOutline(face_element *face, glyph_element *glyph); -glyph_element* msGetBitmapGlyph(rendererVTableObj *renderer, unsigned int size, unsigned int unicode); +face_element *msGetFontFace(char *key, fontSetObj *fontset); +outline_element *msGetGlyphOutline(face_element *face, glyph_element *glyph); +glyph_element *msGetBitmapGlyph(rendererVTableObj *renderer, unsigned int size, + unsigned int unicode); unsigned int msGetGlyphIndex(face_element *face, unsigned int unicode); -glyph_element* msGetGlyphByIndex(face_element *face, unsigned int size, unsigned int codepoint); +glyph_element *msGetGlyphByIndex(face_element *face, unsigned int size, + unsigned int codepoint); int msIsGlyphASpace(glyphObj *glyph); #ifdef __cplusplus diff --git a/fuzzers/shapefuzzer.c b/fuzzers/shapefuzzer.c index 4e0f10894a..7f34166f56 100644 --- a/fuzzers/shapefuzzer.c +++ b/fuzzers/shapefuzzer.c @@ -7,9 +7,8 @@ extern int LLVMFuzzerTestOneInput(GByte *data, size_t size); -static VSILFILE * -SegmentFile(const char *filename, GByte **data_p, size_t *size_p) -{ +static VSILFILE *SegmentFile(const char *filename, GByte **data_p, + size_t *size_p) { GByte *data = *data_p; size_t size = *size_p; @@ -25,13 +24,12 @@ SegmentFile(const char *filename, GByte **data_p, size_t *size_p) return VSIFileFromMemBuffer(filename, data, size, false); } -int -LLVMFuzzerTestOneInput(GByte *data, size_t size) -{ +int LLVMFuzzerTestOneInput(GByte *data, size_t size) { /* this fuzzer expects three files concatenated, separated by the string "deadbeef"; you can generate such a file by typing: - { cat foo.shp; echo -n "deadbeef"; cat foo.shx; echo -n "deadbeef"; cat foo.dbf; } >/tmp/corpus/start + { cat foo.shp; echo -n "deadbeef"; cat foo.shx; echo -n "deadbeef"; cat + foo.dbf; } >/tmp/corpus/start then run the fuzzer: @@ -43,7 +41,8 @@ LLVMFuzzerTestOneInput(GByte *data, size_t size) VSILFILE *dbf = SegmentFile("/vsimem/foo.dbf", &data, &size); shapefileObj file; - if (msShapefileOpenVirtualFile(&file, "/vsimem/foo.shp", shp, shx, dbf, false) == 0) { + if (msShapefileOpenVirtualFile(&file, "/vsimem/foo.shp", shp, shx, dbf, + false) == 0) { for (int i = 0; i < file.numshapes; ++i) { shapeObj shape; msInitShape(&shape); diff --git a/github_issue_no_activity_closer.py b/github_issue_no_activity_closer.py deleted file mode 100644 index 85c5af1325..0000000000 --- a/github_issue_no_activity_closer.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python - -import datetime -import getpass -import json -import re -import time - -import requests - -AUTOCLOSE_MESSAGE = """\ -### This is an automated comment - -This issue has been closed due to lack of activity. This doesn't mean the \ -issue is invalid, it simply got no attention within the last year. Please \ -reopen with missing/relevant information if still valid. - -Typically, issues fall in this state for one of the following reasons: -- Hard, impossible or not enough information to reproduce -- Missing test case -- Lack of a champion with interest and/or funding to address the issue -""" - -AUTOCLOSE_LABEL = "No Recent Activity" - - -def fetch_issues(headers): - issues = [] - url = ("https://api.github.com/repos/mapserver/mapserver/issues?" - "per_page=100") - - while url: - print "Fetching %s" % url - r = requests.get(url, headers=headers) - r.raise_for_status() - time.sleep(1) - issues.extend(r.json()) - - match = re.match(r'<(.*?)>; rel="next"', r.headers['Link'] or '') - url = match.group(1) if match else None - - return issues - - -def close_issue(issue, headers): - """Attempt to close an issue and return whether it succeeded.""" - r = requests.post("https://api.github.com/repos/mapserver/mapserver/" - "issues/%s" % issue['number'], - data=json.dumps({'state': 'closed'}), headers=headers) - - try: - r.raise_for_status() - time.sleep(1) - return True - except requests.HTTPError: - return False - - -def post_issue_comment(issue, comment_text, headers): - """Attempt to post an issue comment and return whether it succeeded.""" - r = requests.post("https://api.github.com/repos/mapserver/mapserver/" - "issues/%s/comments" % issue['number'], - data=json.dumps({'body': comment_text}), headers=headers) - - try: - r.raise_for_status() - time.sleep(1) - return True - except requests.HTTPError: - return False - - -def add_issue_label(issue, label, headers): - """Attempt to add a label to the issue and return whether it succeeded.""" - r = requests.post("https://api.github.com/repos/mapserver/mapserver/" - "issues/%s/labels" % issue['number'], - data=json.dumps([label]), headers=headers) - - try: - r.raise_for_status() - time.sleep(1) - return True - except requests.HTTPError: - return False - - -def close_old_issues(close_before, headers): - all_issues = fetch_issues(headers) - - for issue in all_issues: - issue_last_activity = datetime.datetime.strptime( - issue['updated_at'], "%Y-%m-%dT%H:%M:%SZ") - - print "Processing issue %s with last activity at %s" % (issue['number'], issue_last_activity) - - if issue_last_activity < close_before and issue["state"] == "open": - if post_issue_comment(issue, AUTOCLOSE_MESSAGE, headers): - print " Added comment to old issue %s" % issue['number'] - else: - print " Error adding comment to old issue %s" % issue['number'] - continue - - if add_issue_label(issue, AUTOCLOSE_LABEL, headers): - print " Added label to old issue %s" % issue['number'] - else: - print " Error adding label to old issue %s" % issue['number'] - - if close_issue(issue, headers): - print " Closed old issue %s" % issue['number'] - else: - print " Error closing old issue %s" % issue['number'] - - -if __name__ == '__main__': - close_before = datetime.datetime.today() - datetime.timedelta(days=366) - - print - print "This script closes all issues with no activity within the last year." - print - - github_token = getpass.getpass("Please provide an oauth token: ") - print - - headers = {"Authorization": "token %s" % github_token} - close_old_issues(close_before, headers) diff --git a/hittest.c b/hittest.c index 56f86d53fb..ab1bc8019f 100644 --- a/hittest.c +++ b/hittest.c @@ -28,7 +28,6 @@ #include "mapserver.h" - void initStyleHitTests(styleObj *s, style_hittest *sh, int default_status) { (void)s; sh->status = default_status; @@ -36,51 +35,51 @@ void initStyleHitTests(styleObj *s, style_hittest *sh, int default_status) { void initLabelHitTests(labelObj *l, label_hittest *lh, int default_status) { int i; - lh->stylehits = msSmallCalloc(l->numstyles,sizeof(style_hittest)); + lh->stylehits = msSmallCalloc(l->numstyles, sizeof(style_hittest)); lh->status = default_status; - for(i=0; inumstyles; i++) { - initStyleHitTests(l->styles[i],&lh->stylehits[i],default_status); + for (i = 0; i < l->numstyles; i++) { + initStyleHitTests(l->styles[i], &lh->stylehits[i], default_status); } } void initClassHitTests(classObj *c, class_hittest *ch, int default_status) { int i; - ch->stylehits = msSmallCalloc(c->numstyles,sizeof(style_hittest)); - ch->labelhits = msSmallCalloc(c->numlabels,sizeof(label_hittest)); + ch->stylehits = msSmallCalloc(c->numstyles, sizeof(style_hittest)); + ch->labelhits = msSmallCalloc(c->numlabels, sizeof(label_hittest)); ch->status = default_status; - for(i=0; inumstyles; i++) { - initStyleHitTests(c->styles[i],&ch->stylehits[i],default_status); + for (i = 0; i < c->numstyles; i++) { + initStyleHitTests(c->styles[i], &ch->stylehits[i], default_status); } - for(i=0; inumlabels; i++) { - initLabelHitTests(c->labels[i],&ch->labelhits[i],default_status); + for (i = 0; i < c->numlabels; i++) { + initLabelHitTests(c->labels[i], &ch->labelhits[i], default_status); } } void initLayerHitTests(layerObj *l, layer_hittest *lh) { - int i,default_status; - lh->classhits = msSmallCalloc(l->numclasses,sizeof(class_hittest)); + int i, default_status; + lh->classhits = msSmallCalloc(l->numclasses, sizeof(class_hittest)); - switch(l->type) { - case MS_LAYER_POLYGON: - case MS_LAYER_POINT: - case MS_LAYER_LINE: - case MS_LAYER_ANNOTATION: - default_status = 0; /* needs testing */ - break; - default: - default_status = 1; /* no hittesting needed, use traditional mode */ - break; + switch (l->type) { + case MS_LAYER_POLYGON: + case MS_LAYER_POINT: + case MS_LAYER_LINE: + case MS_LAYER_ANNOTATION: + default_status = 0; /* needs testing */ + break; + default: + default_status = 1; /* no hittesting needed, use traditional mode */ + break; } lh->status = default_status; - for(i=0; inumclasses; i++) { - initClassHitTests(l->class[i],&lh->classhits[i], default_status); + for (i = 0; i < l->numclasses; i++) { + initClassHitTests(l->class[i], &lh -> classhits[i], default_status); } } void initMapHitTests(mapObj *map, map_hittest *mh) { int i; - mh->layerhits = msSmallCalloc(map->numlayers,sizeof(layer_hittest)); - for(i=0; inumlayers; i++) { - initLayerHitTests(GET_LAYER(map,i),&mh->layerhits[i]); + mh->layerhits = msSmallCalloc(map->numlayers, sizeof(layer_hittest)); + for (i = 0; i < map->numlayers; i++) { + initLayerHitTests(GET_LAYER(map, i), &mh->layerhits[i]); } } @@ -91,45 +90,47 @@ void freeLabelHitTests(labelObj *l, label_hittest *lh) { void freeClassHitTests(classObj *c, class_hittest *ch) { int i; - for(i=0; inumlabels; i++) { - freeLabelHitTests(c->labels[i],&ch->labelhits[i]); + for (i = 0; i < c->numlabels; i++) { + freeLabelHitTests(c->labels[i], &ch->labelhits[i]); } free(ch->stylehits); free(ch->labelhits); } void freeLayerHitTests(layerObj *l, layer_hittest *lh) { int i; - for(i=0; inumclasses; i++) { - freeClassHitTests(l->class[i],&lh->classhits[i]); + for (i = 0; i < l->numclasses; i++) { + freeClassHitTests(l->class[i], &lh -> classhits[i]); } free(lh->classhits); } void freeMapHitTests(mapObj *map, map_hittest *mh) { int i; - for(i=0; inumlayers; i++) { - freeLayerHitTests(GET_LAYER(map,i),&mh->layerhits[i]); + for (i = 0; i < map->numlayers; i++) { + freeLayerHitTests(GET_LAYER(map, i), &mh->layerhits[i]); } free(mh->layerhits); } -int msHitTestShape(mapObj *map, layerObj *layer, shapeObj *shape, int drawmode, class_hittest *hittest) { +int msHitTestShape(mapObj *map, layerObj *layer, shapeObj *shape, int drawmode, + class_hittest *hittest) { int i; classObj *cp = layer->class[shape->classindex]; - if(MS_DRAW_FEATURES(drawmode)) { - for(i=0;inumstyles;i++) { + if (MS_DRAW_FEATURES(drawmode)) { + for (i = 0; i < cp->numstyles; i++) { styleObj *sp = cp->styles[i]; - if(msScaleInBounds(map->scaledenom,sp->minscaledenom,sp->maxscaledenom)) { + if (msScaleInBounds(map->scaledenom, sp->minscaledenom, + sp->maxscaledenom)) { hittest->stylehits[i].status = 1; } } } - if(MS_DRAW_LABELS(drawmode)) { - for(i=0;inumlabels;i++) { + if (MS_DRAW_LABELS(drawmode)) { + for (i = 0; i < cp->numlabels; i++) { labelObj *l = cp->labels[i]; - if(msGetLabelStatus(map,layer,shape,l) == MS_ON) { + if (msGetLabelStatus(map, layer, shape, l) == MS_ON) { int s; hittest->labelhits[i].status = 1; - for(s=0; snumstyles;s++) { + for (s = 0; s < l->numstyles; s++) { hittest->labelhits[i].stylehits[s].status = 1; } } @@ -143,59 +144,66 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) { #ifdef USE_GEOS shapeObj searchpoly; #endif - if(!msLayerIsVisible(map,layer)) { + if (!msLayerIsVisible(map, layer)) { hittest->status = 0; return MS_SUCCESS; } - if(layer->type == MS_LAYER_LINE || layer->type == MS_LAYER_POLYGON || layer->type == MS_LAYER_POINT || layer->type == MS_LAYER_ANNOTATION) { - int maxfeatures=msLayerGetMaxFeaturesToDraw(layer, NULL); + if (layer->type == MS_LAYER_LINE || layer->type == MS_LAYER_POLYGON || + layer->type == MS_LAYER_POINT || layer->type == MS_LAYER_ANNOTATION) { + int maxfeatures = msLayerGetMaxFeaturesToDraw(layer, NULL); int annotate = msEvalContext(map, layer, layer->labelrequires); shapeObj shape; - int nclasses,featuresdrawn = 0; + int nclasses, featuresdrawn = 0; int *classgroup; rectObj searchrect; - int minfeaturesize=-1; - if(map->scaledenom > 0) { - if((layer->labelmaxscaledenom != -1) && (map->scaledenom >= layer->labelmaxscaledenom)) annotate = MS_FALSE; - if((layer->labelminscaledenom != -1) && (map->scaledenom < layer->labelminscaledenom)) annotate = MS_FALSE; + int minfeaturesize = -1; + if (map->scaledenom > 0) { + if ((layer->labelmaxscaledenom != -1) && + (map->scaledenom >= layer->labelmaxscaledenom)) + annotate = MS_FALSE; + if ((layer->labelminscaledenom != -1) && + (map->scaledenom < layer->labelminscaledenom)) + annotate = MS_FALSE; } status = msLayerOpen(layer); - if(status != MS_SUCCESS) return MS_FAILURE; + if (status != MS_SUCCESS) + return MS_FAILURE; /* build item list */ status = msLayerWhichItems(layer, MS_FALSE, NULL); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msLayerClose(layer); return MS_FAILURE; } /* identify target shapes */ - if(layer->transform == MS_TRUE) { + if (layer->transform == MS_TRUE) { searchrect = map->extent; - if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ - } - else { + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0)) + msProjectRect( + &map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ + } else { searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; } #ifdef USE_GEOS msInitShape(&searchpoly); - msRectToPolygon(searchrect,&searchpoly); + msRectToPolygon(searchrect, &searchpoly); #endif status = msLayerWhichShapes(layer, searchrect, MS_FALSE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ #ifdef USE_GEOS msFreeShape(&searchpoly); #endif msLayerClose(layer); hittest->status = 0; return MS_SUCCESS; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { #ifdef USE_GEOS msFreeShape(&searchpoly); #endif @@ -208,32 +216,33 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) { nclasses = 0; classgroup = NULL; - if(layer->classgroup && layer->numclasses > 0) + if (layer->classgroup && layer->numclasses > 0) classgroup = msAllocateValidClassGroups(layer, &nclasses); - if(layer->minfeaturesize > 0) + if (layer->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, layer, layer->minfeaturesize); - while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { + while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { int drawmode = MS_DRAWMODE_FEATURES; #ifdef USE_GEOS - if(!msGEOSIntersects(&shape,&searchpoly)) { + if (!msGEOSIntersects(&shape, &searchpoly)) { msFreeShape(&shape); continue; } #else - if(shape.type == MS_SHAPE_POLYGON) { + if (shape.type == MS_SHAPE_POLYGON) { msClipPolygonRect(&shape, map->extent); } else { msClipPolylineRect(&shape, map->extent); } - if(shape.numlines == 0) { + if (shape.numlines == 0) { msFreeShape(&shape); continue; } #endif /* Check if the shape size is ok to be drawn, we need to clip */ - if((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0)) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { msTransformShape(&shape, map->extent, map->cellsize, NULL); msComputeBounds(&shape); if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { @@ -242,26 +251,30 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) { } } - shape.classindex = msShapeGetClass(layer, map, &shape, classgroup, nclasses); - if((shape.classindex == -1) || (layer->class[shape.classindex]->status == MS_OFF)) { + shape.classindex = + msShapeGetClass(layer, map, &shape, classgroup, nclasses); + if ((shape.classindex == -1) || + (layer->class[shape.classindex] -> status == MS_OFF)) { msFreeShape(&shape); continue; } hittest->classhits[shape.classindex].status = 1; hittest->status = 1; - if(maxfeatures >=0 && featuresdrawn >= maxfeatures) { + if (maxfeatures >= 0 && featuresdrawn >= maxfeatures) { msFreeShape(&shape); status = MS_DONE; break; } featuresdrawn++; - if(annotate && layer->class[shape.classindex]->numlabels > 0) { + if (annotate && layer->class[shape.classindex] -> numlabels > 0) { drawmode |= MS_DRAWMODE_LABELS; } - status = msHitTestShape(map, layer, &shape, drawmode, &hittest->classhits[shape.classindex]); /* all styles */ + status = msHitTestShape( + map, layer, &shape, drawmode, + &hittest->classhits[shape.classindex]); /* all styles */ msFreeShape(&shape); } @@ -272,7 +285,7 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) { if (classgroup) msFree(classgroup); - if(status != MS_DONE) { + if (status != MS_DONE) { msLayerClose(layer); return MS_FAILURE; } @@ -280,21 +293,23 @@ int msHitTestLayer(mapObj *map, layerObj *layer, layer_hittest *hittest) { return MS_SUCCESS; } else { - /* we don't hittest these layers, skip as they already have been initialised */ + /* we don't hittest these layers, skip as they already have been initialised + */ return MS_SUCCESS; } } int msHitTestMap(mapObj *map, map_hittest *hittest) { - int i,status; - map->cellsize = msAdjustExtent(&(map->extent),map->width,map->height); - status = msCalculateScale(map->extent,map->units,map->width,map->height, map->resolution, &map->scaledenom); - if(status != MS_SUCCESS) { + int i, status; + map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); + status = msCalculateScale(map->extent, map->units, map->width, map->height, + map->resolution, &map->scaledenom); + if (status != MS_SUCCESS) { return MS_FAILURE; } - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { layerObj *lp = map->layers[i]; - status = msHitTestLayer(map,lp,&hittest->layerhits[i]); - if(status != MS_SUCCESS) { + status = msHitTestLayer(map, lp, &hittest->layerhits[i]); + if (status != MS_SUCCESS) { return MS_FAILURE; } } diff --git a/hittest.h b/hittest.h index c4ab89c03a..7d48d3c3bd 100644 --- a/hittest.h +++ b/hittest.h @@ -26,7 +26,6 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #ifndef HITTEST_H #define HITTEST_H @@ -50,7 +49,7 @@ typedef struct { int status; } layer_hittest; -typedef struct map_hittest{ +typedef struct map_hittest { layer_hittest *layerhits; } map_hittest; diff --git a/idw.c b/idw.c index 5520397648..2961db4766 100644 --- a/idw.c +++ b/idw.c @@ -32,45 +32,51 @@ #define EPSILON 0.000000001 #include -void msIdw(float *xyz, int width, int height, int npoints, interpolationProcessingParams *interpParams, unsigned char *iValues) { - int i,j,index; - int radius = interpParams->radius; - float power = interpParams->power; - for (j=0; j < height; j++) { - for (i=0; i < width; i++) { - double den = EPSILON, num = 0; - for(index = 0; index < npoints*3; index += 3){ - double d = (xyz[index] - i)*(xyz[index] - i)+(xyz[index+1] - j)*(xyz[index+1] - j); - if(radius*radius > d) { - double w = 1.0/(pow(d, power) + EPSILON); - num += w*xyz[index+2]; - den += w; - } - } - iValues[j*width + i] = num/den; +void msIdw(float *xyz, int width, int height, int npoints, + interpolationProcessingParams *interpParams, + unsigned char *iValues) { + int i, j, index; + int radius = interpParams->radius; + float power = interpParams->power; + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + double den = EPSILON, num = 0; + for (index = 0; index < npoints * 3; index += 3) { + double d = (xyz[index] - i) * (xyz[index] - i) + + (xyz[index + 1] - j) * (xyz[index + 1] - j); + if (radius * radius > d) { + double w = 1.0 / (pow(d, power) + EPSILON); + num += w * xyz[index + 2]; + den += w; } + } + iValues[j * width + i] = num / den; } + } } -void msIdwProcessing(layerObj *layer, interpolationProcessingParams *interpParams) { - const char *interpParamsProcessing = msLayerGetProcessingKey( layer, "IDW_POWER" ); - if(interpParamsProcessing) { - interpParams->power = atof(interpParamsProcessing); - } else{ - interpParams->power = 1.0; - } +void msIdwProcessing(layerObj *layer, + interpolationProcessingParams *interpParams) { + const char *interpParamsProcessing = + msLayerGetProcessingKey(layer, "IDW_POWER"); + if (interpParamsProcessing) { + interpParams->power = atof(interpParamsProcessing); + } else { + interpParams->power = 1.0; + } - interpParamsProcessing = msLayerGetProcessingKey( layer, "IDW_RADIUS" ); - if(interpParamsProcessing){ - interpParams->radius = atof(interpParamsProcessing); - } else { - interpParams->radius = MAX(layer->map->width,layer->map->height); - } + interpParamsProcessing = msLayerGetProcessingKey(layer, "IDW_RADIUS"); + if (interpParamsProcessing) { + interpParams->radius = atof(interpParamsProcessing); + } else { + interpParams->radius = MAX(layer->map->width, layer->map->height); + } - interpParamsProcessing = msLayerGetProcessingKey( layer, "IDW_COMPUTE_BORDERS" ); - if(interpParamsProcessing && strcasecmp(interpParamsProcessing,"OFF")){ - interpParams->expand_searchrect = 1; - } else { - interpParams->expand_searchrect = 0; - } + interpParamsProcessing = + msLayerGetProcessingKey(layer, "IDW_COMPUTE_BORDERS"); + if (interpParamsProcessing && strcasecmp(interpParamsProcessing, "OFF")) { + interpParams->expand_searchrect = 1; + } else { + interpParams->expand_searchrect = 0; + } } diff --git a/interpolation.c b/interpolation.c index 65aca8d0a4..60e3585d22 100644 --- a/interpolation.c +++ b/interpolation.c @@ -35,225 +35,258 @@ /****************************************************************************** * kernel density. ******************************************************************************/ -void msKernelDensity(imageObj *image, float *values, int width, int height, int npoints, - interpolationProcessingParams *interpParams, unsigned char *iValues); -void msKernelDensityProcessing(layerObj *layer, interpolationProcessingParams *interpParams); +void msKernelDensity(imageObj *image, float *values, int width, int height, + int npoints, interpolationProcessingParams *interpParams, + unsigned char *iValues); +void msKernelDensityProcessing(layerObj *layer, + interpolationProcessingParams *interpParams); /****************************************************************************** * kernel density. ******************************************************************************/ void msIdw(float *xyz, int width, int height, int npoints, - interpolationProcessingParams *interpParams, unsigned char *iValues); -void msIdwProcessing(layerObj *layer, interpolationProcessingParams *interpParams); + interpolationProcessingParams *interpParams, unsigned char *iValues); +void msIdwProcessing(layerObj *layer, + interpolationProcessingParams *interpParams); //---------------------------------------------------------------------------// -int msInterpolationDataset(mapObj *map, imageObj *image, layerObj *interpolation_layer, void **hDSvoid, void **cleanup_ptr) { +int msInterpolationDataset(mapObj *map, imageObj *image, + layerObj *interpolation_layer, void **hDSvoid, + void **cleanup_ptr) { - int status, layer_idx, i, nclasses=0, npoints=0, length=0; - rectObj searchrect; - shapeObj shape; - layerObj *layer = NULL; - float *values = NULL,*xyz_values=NULL; - int im_width = image->width, im_height = image->height; - double invcellsize = 1.0 / map->cellsize, georadius=0; - unsigned char *iValues; - GDALDatasetH hDS; - interpolationProcessingParams interpParams; - int *classgroup = NULL; + int status, layer_idx, i, nclasses = 0, npoints = 0, length = 0; + rectObj searchrect; + shapeObj shape; + layerObj *layer = NULL; + float *values = NULL, *xyz_values = NULL; + int im_width = image->width, im_height = image->height; + double invcellsize = 1.0 / map->cellsize, georadius = 0; + unsigned char *iValues; + GDALDatasetH hDS; + interpolationProcessingParams interpParams; + int *classgroup = NULL; - memset(&interpParams, 0, sizeof(interpParams)); + memset(&interpParams, 0, sizeof(interpParams)); - assert(interpolation_layer->connectiontype == MS_KERNELDENSITY || - interpolation_layer->connectiontype == MS_IDW); - *cleanup_ptr = NULL; + assert(interpolation_layer->connectiontype == MS_KERNELDENSITY || + interpolation_layer->connectiontype == MS_IDW); + *cleanup_ptr = NULL; - if(!interpolation_layer->connection || !*interpolation_layer->connection) { - msSetError(MS_MISCERR, "msInterpolationDataset()", "Interpolation layer has no CONNECTION defined"); - return MS_FAILURE; - } + if (!interpolation_layer->connection || !*interpolation_layer->connection) { + msSetError(MS_MISCERR, "msInterpolationDataset()", + "Interpolation layer has no CONNECTION defined"); + return MS_FAILURE; + } - if (interpolation_layer->connectiontype == MS_KERNELDENSITY) { - msKernelDensityProcessing(interpolation_layer, &interpParams); - } else if(interpolation_layer->connectiontype == MS_IDW) { - msIdwProcessing(interpolation_layer, &interpParams); - } + if (interpolation_layer->connectiontype == MS_KERNELDENSITY) { + msKernelDensityProcessing(interpolation_layer, &interpParams); + } else if (interpolation_layer->connectiontype == MS_IDW) { + msIdwProcessing(interpolation_layer, &interpParams); + } - layer_idx = msGetLayerIndex(map, interpolation_layer->connection); - if(layer_idx == -1) { - int nLayers, *aLayers; - aLayers = msGetLayersIndexByGroup(map, interpolation_layer->connection, &nLayers); - if(!aLayers || !nLayers) { - msSetError(MS_MISCERR, "Interpolation layer (%s) references unknown layer (%s)", "msInterpolationDataset()", - interpolation_layer->name,interpolation_layer->connection); - return (MS_FAILURE); - } - for(i=0; iscaledenom, layer->minscaledenom, layer->maxscaledenom)) - break; - } - free(aLayers); - if(i == nLayers) { - msSetError(MS_MISCERR, "Interpolation layer (%s) references no layer for current scale", "msInterpolationDataset()", - interpolation_layer->name); - return (MS_FAILURE); - } - } else { - layer = GET_LAYER(map, layer_idx); + layer_idx = msGetLayerIndex(map, interpolation_layer->connection); + if (layer_idx == -1) { + int nLayers, *aLayers; + aLayers = + msGetLayersIndexByGroup(map, interpolation_layer->connection, &nLayers); + if (!aLayers || !nLayers) { + msSetError(MS_MISCERR, + "Interpolation layer (%s) references unknown layer (%s)", + "msInterpolationDataset()", interpolation_layer->name, + interpolation_layer->connection); + return (MS_FAILURE); } - /* open the linked layer */ - status = msLayerOpen(layer); - if(status != MS_SUCCESS) return MS_FAILURE; - - status = msLayerWhichItems(layer, MS_FALSE, NULL); - if(status != MS_SUCCESS) { - msLayerClose(layer); - return MS_FAILURE; + for (i = 0; i < nLayers; i++) { + layer_idx = aLayers[i]; + layer = GET_LAYER(map, layer_idx); + if (msScaleInBounds(map->scaledenom, layer->minscaledenom, + layer->maxscaledenom)) + break; } + free(aLayers); + if (i == nLayers) { + msSetError( + MS_MISCERR, + "Interpolation layer (%s) references no layer for current scale", + "msInterpolationDataset()", interpolation_layer->name); + return (MS_FAILURE); + } + } else { + layer = GET_LAYER(map, layer_idx); + } + /* open the linked layer */ + status = msLayerOpen(layer); + if (status != MS_SUCCESS) + return MS_FAILURE; - /* identify target shapes */ - if(layer->transform == MS_TRUE) { - searchrect = map->extent; - if(interpParams.expand_searchrect) { - georadius = interpParams.radius * map->cellsize; - searchrect.minx -= georadius; - searchrect.miny -= georadius; - searchrect.maxx += georadius; - searchrect.maxy += georadius; - im_width += 2 * interpParams.radius; - im_height += 2 * interpParams.radius; - } - } else { - searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + status = msLayerWhichItems(layer, MS_FALSE, NULL); + if (status != MS_SUCCESS) { + msLayerClose(layer); + return MS_FAILURE; + } + + /* identify target shapes */ + if (layer->transform == MS_TRUE) { + searchrect = map->extent; + if (interpParams.expand_searchrect) { + georadius = interpParams.radius * map->cellsize; + searchrect.minx -= georadius; + searchrect.miny -= georadius; + searchrect.maxx += georadius; + searchrect.maxy += georadius; + im_width += 2 * interpParams.radius; + im_height += 2 * interpParams.radius; } + } else { + searchrect.minx = searchrect.miny = 0; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; + } - layer->project = msProjectionsDiffer(&(layer->projection), &(map->projection)); - if(layer->project) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); + if (layer->project) + msProjectRect(&map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ - status = msLayerWhichShapes(layer, searchrect, MS_FALSE); - /* nothing to do */ - if(status == MS_SUCCESS) { /* at least one sample may have overlapped */ + status = msLayerWhichShapes(layer, searchrect, MS_FALSE); + /* nothing to do */ + if (status == MS_SUCCESS) { /* at least one sample may have overlapped */ - if(layer->classgroup && layer->numclasses > 0) - classgroup = msAllocateValidClassGroups(layer, &nclasses); + if (layer->classgroup && layer->numclasses > 0) + classgroup = msAllocateValidClassGroups(layer, &nclasses); - msInitShape(&shape); - while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { - int l,p,s,c; - double weight = 1.0; - if(!values){ /* defer allocation until we effectively have a feature */ - values = (float*) msSmallCalloc(im_width * im_height, sizeof(float)); - xyz_values = (float*) msSmallCalloc(im_width * im_height, sizeof(float)); - } - if(layer->project) - msProjectShape(&layer->projection, &map->projection, &shape); + msInitShape(&shape); + while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { + int l, p, s, c; + double weight = 1.0; + if (!values) { /* defer allocation until we effectively have a feature */ + values = (float *)msSmallCalloc(im_width * im_height, sizeof(float)); + xyz_values = + (float *)msSmallCalloc(im_width * im_height, sizeof(float)); + } + if (layer->project) + msProjectShape(&layer->projection, &map->projection, &shape); - /* the weight for the sample is set to 1.0 by default. If the - * layer has some classes defined, we will read the weight from - * the class->style->size (which can be binded to an attribute) - */ - if(layer->numclasses > 0) { - c = msShapeGetClass(layer, map, &shape, classgroup, nclasses); - if((c == -1) || (layer->class[c]->status == MS_OFF)) { - goto nextshape; /* no class matched, skip */ - } - for (s = 0; s < layer->class[c]->numstyles; s++) { - if (msScaleInBounds(map->scaledenom, - layer->class[c]->styles[s]->minscaledenom, - layer->class[c]->styles[s]->maxscaledenom)) { - if(layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index != -1) { - weight = atof(shape.values[layer->class[c]->styles[s]->bindings[MS_STYLE_BINDING_SIZE].index]); - } else { - weight = layer->class[c]->styles[s]->size; - } - break; - } - } - if(s == layer->class[c]->numstyles) { - /* no style in scale bounds */ - goto nextshape; - } - } - for(l=0; lextent.minx - georadius, invcellsize); - int y = MS_MAP2IMAGE_YCELL_IC(shape.line[l].point[p].y, map->extent.maxy + georadius, invcellsize); - if(x>=0 && y>=0 && xstyle->size (which can be binded to an attribute) + */ + if (layer->numclasses > 0) { + c = msShapeGetClass(layer, map, &shape, classgroup, nclasses); + if ((c == -1) || (layer->class[c] -> status == MS_OFF)) { + goto nextshape; /* no class matched, skip */ + } + for (s = 0; s < layer->class[c] -> numstyles; s++) { + if (msScaleInBounds( + map->scaledenom, + layer->class[c] -> styles[s] -> minscaledenom, + layer -> class[c] -> styles[s] -> maxscaledenom)) { + if (layer->class[c] -> styles[s] + -> bindings[MS_STYLE_BINDING_SIZE].index != -1) { + weight = + atof(shape.values[layer->class[c] -> styles[s] + -> bindings[MS_STYLE_BINDING_SIZE].index]); + } else { + weight = layer->class[c]->styles[s]->size; } - -nextshape: - msFreeShape(&shape); + break; + } } - //number of layer points. - npoints = length/3; - } else if(status != MS_DONE) { - msLayerClose(layer); - return MS_FAILURE; - } + if (s == layer->class[c] -> numstyles) { + /* no style in scale bounds */ + goto nextshape; + } + } + for (l = 0; l < shape.numlines; l++) { + for (p = 0; p < shape.line[l].numpoints; p++) { + int x = + MS_MAP2IMAGE_XCELL_IC(shape.line[l].point[p].x, + map->extent.minx - georadius, invcellsize); + int y = + MS_MAP2IMAGE_YCELL_IC(shape.line[l].point[p].y, + map->extent.maxy + georadius, invcellsize); + if (x >= 0 && y >= 0 && x < im_width && y < im_height) { + float *value = values + y * im_width + x; + (*value) += weight; + xyz_values[length++] = x; + xyz_values[length++] = y; + xyz_values[length++] = (*value); + } + } + } - /* status == MS_DONE */ + nextshape: + msFreeShape(&shape); + } + // number of layer points. + npoints = length / 3; + } else if (status != MS_DONE) { msLayerClose(layer); - status = MS_SUCCESS; + return MS_FAILURE; + } - if(npoints > 0 && interpParams.expand_searchrect) { - iValues = msSmallMalloc(image->width*image->height*sizeof(unsigned char)); - } else { - iValues = msSmallCalloc(1,image->width*image->height*sizeof(unsigned char)); - } + /* status == MS_DONE */ + msLayerClose(layer); + status = MS_SUCCESS; - if(npoints > 0) { /* no use applying the filtering kernel if we have no samples */ - if (interpolation_layer->connectiontype == MS_KERNELDENSITY) { - msKernelDensity(image, values, im_width, im_height, npoints, &interpParams, iValues); - } else if(interpolation_layer->connectiontype == MS_IDW) { - msIdw(xyz_values, image->width, image->height, npoints, &interpParams, iValues); - } - } + if (npoints > 0 && interpParams.expand_searchrect) { + iValues = + msSmallMalloc(image->width * image->height * sizeof(unsigned char)); + } else { + iValues = + msSmallCalloc(1, image->width * image->height * sizeof(unsigned char)); + } - free(values); - free(xyz_values); + if (npoints > + 0) { /* no use applying the filtering kernel if we have no samples */ + if (interpolation_layer->connectiontype == MS_KERNELDENSITY) { + msKernelDensity(image, values, im_width, im_height, npoints, + &interpParams, iValues); + } else if (interpolation_layer->connectiontype == MS_IDW) { + msIdw(xyz_values, image->width, image->height, npoints, &interpParams, + iValues); + } + } + free(values); + free(xyz_values); - char pointer[64]; - char ds_string [1024]; - double adfGeoTransform[6]; - memset(pointer, 0, sizeof(pointer)); - CPLPrintPointer(pointer, iValues, sizeof(pointer)); - snprintf(ds_string,1024,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Byte,PIXELOFFSET=1,LINEOFFSET=%d", - pointer,image->width,image->height,image->width); - hDS = GDALOpenShared( ds_string, GA_ReadOnly ); - if(hDS == NULL) { - msSetError(MS_MISCERR,"msInterpolationDataset()","failed to create in-memory gdal dataset for interpolated data"); - status = MS_FAILURE; - free(iValues); - } - adfGeoTransform[0] = map->extent.minx - map->cellsize * 0.5; /* top left x */ - adfGeoTransform[1] = map->cellsize;/* w-e pixel resolution */ - adfGeoTransform[2] = 0; /* 0 */ - adfGeoTransform[3] = map->extent.maxy + map->cellsize * 0.5;/* top left y */ - adfGeoTransform[4] = 0; /* 0 */ - adfGeoTransform[5] = -map->cellsize;/* n-s pixel resolution (negative value) */ - GDALSetGeoTransform(hDS,adfGeoTransform); - *hDSvoid = hDS; - *cleanup_ptr = (void*)iValues; + char pointer[64]; + char ds_string[1024]; + double adfGeoTransform[6]; + memset(pointer, 0, sizeof(pointer)); + CPLPrintPointer(pointer, iValues, sizeof(pointer)); + snprintf(ds_string, 1024, + "MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Byte," + "PIXELOFFSET=1,LINEOFFSET=%d", + pointer, image->width, image->height, image->width); + hDS = GDALOpenShared(ds_string, GA_ReadOnly); + if (hDS == NULL) { + msSetError(MS_MISCERR, "msInterpolationDataset()", + "failed to create in-memory gdal dataset for interpolated data"); + status = MS_FAILURE; + free(iValues); + } + adfGeoTransform[0] = map->extent.minx - map->cellsize * 0.5; /* top left x */ + adfGeoTransform[1] = map->cellsize; /* w-e pixel resolution */ + adfGeoTransform[2] = 0; /* 0 */ + adfGeoTransform[3] = map->extent.maxy + map->cellsize * 0.5; /* top left y */ + adfGeoTransform[4] = 0; /* 0 */ + adfGeoTransform[5] = + -map->cellsize; /* n-s pixel resolution (negative value) */ + GDALSetGeoTransform(hDS, adfGeoTransform); + *hDSvoid = hDS; + *cleanup_ptr = (void *)iValues; - return status; + return status; } -int msCleanupInterpolationDataset(mapObj *map, imageObj *image, layerObj *layer, void *cleanup_ptr) { - (void)map; - (void)image; - (void)layer; - free(cleanup_ptr); - return MS_SUCCESS; +int msCleanupInterpolationDataset(mapObj *map, imageObj *image, layerObj *layer, + void *cleanup_ptr) { + (void)map; + (void)image; + (void)layer; + free(cleanup_ptr); + return MS_SUCCESS; } diff --git a/kerneldensity.c b/kerneldensity.c index 46691826b0..45ae51d153 100644 --- a/kerneldensity.c +++ b/kerneldensity.c @@ -32,128 +32,138 @@ #include "gdal.h" -static -void gaussian_blur(float *values, int width, int height, int radius) { - float *tmp = (float*)msSmallMalloc(width*height*sizeof(float)); - int length = radius*2+1; - float *kernel = (float*)msSmallMalloc(length*sizeof(float)); - float sigma=radius/3.0; - float a=1.0/ sqrt(2.0*M_PI*sigma*sigma); - float den=2.0*sigma*sigma; - int i,x,y; - - for (i=0; iradius = atoi(interpParamsProcessing); - } else { - interpParams->radius = 10; - } - - interpParamsProcessing = msLayerGetProcessingKey( layer, "KERNELDENSITY_COMPUTE_BORDERS" ); - if(interpParamsProcessing && strcasecmp(interpParamsProcessing,"OFF")) { - interpParams->expand_searchrect = 1; +void msKernelDensityProcessing(layerObj *layer, + interpolationProcessingParams *interpParams) { + const char *interpParamsProcessing = + msLayerGetProcessingKey(layer, "KERNELDENSITY_RADIUS"); + if (interpParamsProcessing) { + interpParams->radius = atoi(interpParamsProcessing); + } else { + interpParams->radius = 10; + } + + interpParamsProcessing = + msLayerGetProcessingKey(layer, "KERNELDENSITY_COMPUTE_BORDERS"); + if (interpParamsProcessing && strcasecmp(interpParamsProcessing, "OFF")) { + interpParams->expand_searchrect = 1; + } else { + interpParams->expand_searchrect = 0; + } + + interpParamsProcessing = + msLayerGetProcessingKey(layer, "KERNELDENSITY_NORMALIZATION"); + if (!interpParamsProcessing || !strcasecmp(interpParamsProcessing, "AUTO")) { + interpParams->normalization_scale = 0.0; + } else { + interpParams->normalization_scale = atof(interpParamsProcessing); + if (interpParams->normalization_scale != 0) { + interpParams->normalization_scale = + 1.0 / interpParams->normalization_scale; } else { - interpParams->expand_searchrect = 0; - } - - interpParamsProcessing = msLayerGetProcessingKey( layer, "KERNELDENSITY_NORMALIZATION" ); - if(!interpParamsProcessing || !strcasecmp(interpParamsProcessing,"AUTO")) { - interpParams->normalization_scale = 0.0; - } else { - interpParams->normalization_scale = atof(interpParamsProcessing); - if(interpParams->normalization_scale != 0) { - interpParams->normalization_scale = 1.0 / interpParams->normalization_scale; - } else { - interpParams->normalization_scale = 1.0; - } + interpParams->normalization_scale = 1.0; } + } } -void msKernelDensity(imageObj *image, float *values, int width, int height, int npoints, - interpolationProcessingParams *interpParams, unsigned char *iValues) { - int i,j; - float valmax=FLT_MIN, valmin=FLT_MAX; - int radius = interpParams->radius; - float normalization_scale = interpParams->normalization_scale; - int expand_searchrect = interpParams->expand_searchrect; - - gaussian_blur(values, width, height, radius); - - if(normalization_scale == 0.0) { /* auto normalization */ - for (j = radius; j < height-radius; j++) { - for (i = radius; i < width-radius; i++) { - float val = values[j*width + i]; - if(val >0 && val>valmax) { - valmax = val; - } - if(val>0 && valradius; + float normalization_scale = interpParams->normalization_scale; + int expand_searchrect = interpParams->expand_searchrect; + + gaussian_blur(values, width, height, radius); + + if (normalization_scale == 0.0) { /* auto normalization */ + for (j = radius; j < height - radius; j++) { + for (i = radius; i < width - radius; i++) { + float val = values[j * width + i]; + if (val > 0 && val > valmax) { + valmax = val; } - } else { - valmin = 0; - valmax = normalization_scale; - } - - if(expand_searchrect) { - for (j=0; j < image->height; j++) { - for (i=0; i < image->width; i++) { - float norm = (values[(j+radius)*width + i + radius] - valmin) / valmax; - int v = 255 * norm; - if (v<0) v=0; - else if (v>255) v = 255; - iValues[j*image->width + i] = v; - } + if (val > 0 && val < valmin) { + valmin = val; } - } else { - if(npoints > 0) { - for (j=radius; j < image->height-radius; j++) { - for (i=radius; i < image->width-radius; i++) { - float norm=(values[j*width + i] - valmin) / valmax; - int v=255 * norm; - if (v<0) v=0; - else if (v>255) v=255; - iValues[j*image->width + i]=v; - } - } + } + } + } else { + valmin = 0; + valmax = normalization_scale; + } + + if (expand_searchrect) { + for (j = 0; j < image->height; j++) { + for (i = 0; i < image->width; i++) { + float norm = + (values[(j + radius) * width + i + radius] - valmin) / valmax; + int v = 255 * norm; + if (v < 0) + v = 0; + else if (v > 255) + v = 255; + iValues[j * image->width + i] = v; + } + } + } else { + if (npoints > 0) { + for (j = radius; j < image->height - radius; j++) { + for (i = radius; i < image->width - radius; i++) { + float norm = (values[j * width + i] - valmin) / valmax; + int v = 255 * norm; + if (v < 0) + v = 0; + else if (v > 255) + v = 255; + iValues[j * image->width + i] = v; } + } } + } } diff --git a/layerobject.c b/layerobject.c index 569e6cf141..2a0c147acb 100644 --- a/layerobject.c +++ b/layerobject.c @@ -31,15 +31,13 @@ #include "mapserver.h" - /* =========================================================================== msInsertClass Returns the index at which the class was inserted. ======================================================================== */ -int msInsertClass(layerObj *layer, classObj *classobj, int nIndex) -{ +int msInsertClass(layerObj *layer, classObj *classobj, int nIndex) { int i; if (!classobj) { @@ -54,36 +52,36 @@ int msInsertClass(layerObj *layer, classObj *classobj, int nIndex) /* Catch attempt to insert past end of styles array */ else if (nIndex >= layer->numclasses) { msSetError(MS_CHILDERR, "Cannot insert class beyond index %d", - "msInsertClass()", layer->numclasses-1); + "msInsertClass()", layer->numclasses - 1); return -1; } else if (nIndex < 0) { /* Insert at the end by default */ #ifndef __cplusplus - layer->class[layer->numclasses]=classobj; + layer->class[layer->numclasses] = classobj; #else - layer->_class[layer->numclasses]=classobj; + layer->_class[layer->numclasses] = classobj; #endif /* set parent pointer */ - classobj->layer=layer; + classobj->layer = layer; MS_REFCNT_INCR(classobj); layer->numclasses++; - return layer->numclasses-1; + return layer->numclasses - 1; } else { /* Copy classes existing at the specified nIndex or greater */ /* to an index one higher */ #ifndef __cplusplus - for (i=layer->numclasses-1; i>=nIndex; i--) - layer->class[i+1] = layer->class[i]; - layer->class[nIndex]=classobj; + for (i = layer->numclasses - 1; i >= nIndex; i--) + layer->class[i + 1] = layer->class[i]; + layer->class[nIndex] = classobj; #else - for (i=layer->numclasses-1; i>=nIndex; i--) - layer->_class[i+1] = layer->_class[i]; - layer->_class[nIndex]=classobj; + for (i = layer->numclasses - 1; i >= nIndex; i--) + layer->_class[i + 1] = layer->_class[i]; + layer->_class[nIndex] = classobj; #endif /* set parent pointer */ - classobj->layer=layer; + classobj->layer = layer; MS_REFCNT_INCR(classobj); /* increment number of classes and return */ layer->numclasses++; @@ -97,8 +95,7 @@ int msInsertClass(layerObj *layer, classObj *classobj, int nIndex) remove the class at an index from a layer, returning a copy ======================================================================== */ -classObj *msRemoveClass(layerObj *layer, int nIndex) -{ +classObj *msRemoveClass(layerObj *layer, int nIndex) { int i; classObj *classobj; @@ -108,25 +105,25 @@ classObj *msRemoveClass(layerObj *layer, int nIndex) return NULL; } else { #ifndef __cplusplus - classobj=layer->class[nIndex]; + classobj = layer->class[nIndex]; #else - classobj=layer->_class[nIndex]; + classobj = layer->_class[nIndex]; #endif - classobj->layer=NULL; + classobj->layer = NULL; MS_REFCNT_DECR(classobj); /* Iteratively copy the higher index classes down one index */ - for (i=nIndex; inumclasses-1; i++) { + for (i = nIndex; i < layer->numclasses - 1; i++) { #ifndef __cplusplus - layer->class[i]=layer->class[i+1]; + layer->class[i] = layer->class[i + 1]; #else - layer->_class[i]=layer->_class[i+1]; + layer->_class[i] = layer->_class[i + 1]; #endif } #ifndef __cplusplus - layer->class[i]=NULL; + layer->class[i] = NULL; #else - layer->_class[i]=NULL; + layer->_class[i] = NULL; #endif /* decrement number of layers and return copy of removed layer */ @@ -138,38 +135,34 @@ classObj *msRemoveClass(layerObj *layer, int nIndex) /** * Move the class up inside the array of classes. */ -int msMoveClassUp(layerObj *layer, int nClassIndex) -{ +int msMoveClassUp(layerObj *layer, int nClassIndex) { classObj *psTmpClass = NULL; - if (layer && nClassIndex < layer->numclasses && nClassIndex >0) { - psTmpClass=layer->class[nClassIndex]; + if (layer && nClassIndex < layer->numclasses && nClassIndex > 0) { + psTmpClass = layer->class[nClassIndex]; - layer->class[nClassIndex] = layer->class[nClassIndex-1]; + layer->class[nClassIndex] = layer->class[nClassIndex - 1]; - layer->class[nClassIndex-1] = psTmpClass; + layer->class[nClassIndex - 1] = psTmpClass; - return(MS_SUCCESS); + return (MS_SUCCESS); } - msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveClassUp()", - nClassIndex); + msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveClassUp()", nClassIndex); return (MS_FAILURE); } - /** * Move the class down inside the array of classes. */ -int msMoveClassDown(layerObj *layer, int nClassIndex) -{ +int msMoveClassDown(layerObj *layer, int nClassIndex) { classObj *psTmpClass = NULL; - if (layer && nClassIndex < layer->numclasses-1 && nClassIndex >=0) { - psTmpClass=layer->class[nClassIndex]; + if (layer && nClassIndex < layer->numclasses - 1 && nClassIndex >= 0) { + psTmpClass = layer->class[nClassIndex]; - layer->class[nClassIndex] = layer->class[nClassIndex+1]; + layer->class[nClassIndex] = layer->class[nClassIndex + 1]; - layer->class[nClassIndex+1] = psTmpClass; + layer->class[nClassIndex + 1] = psTmpClass; - return(MS_SUCCESS); + return (MS_SUCCESS); } msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveClassDown()", nClassIndex); @@ -180,9 +173,8 @@ int msMoveClassDown(layerObj *layer, int nClassIndex) * Set the extent of a layer. */ -int msLayerSetExtent( layerObj *layer, - double minx, double miny, double maxx, double maxy) -{ +int msLayerSetExtent(layerObj *layer, double minx, double miny, double maxx, + double maxy) { layer->extent.minx = minx; layer->extent.miny = miny; @@ -190,12 +182,16 @@ int msLayerSetExtent( layerObj *layer, layer->extent.maxy = maxy; if (minx == -1.0 && miny == -1.0 && maxx == -1.0 && maxy == -1.0) - return(MS_SUCCESS); + return (MS_SUCCESS); if (!MS_VALID_EXTENT(layer->extent)) { - msSetError(MS_MISCERR, "Given layer extent is invalid. minx=%lf, miny=%lf, maxx=%lf, maxy=%lf.", "msLayerSetExtent()", layer->extent.minx, layer->extent.miny, layer->extent.maxx, layer->extent.maxy); - return(MS_FAILURE); + msSetError(MS_MISCERR, + "Given layer extent is invalid. minx=%lf, miny=%lf, maxx=%lf, " + "maxy=%lf.", + "msLayerSetExtent()", layer->extent.minx, layer->extent.miny, + layer->extent.maxx, layer->extent.maxy); + return (MS_FAILURE); } - return(MS_SUCCESS); + return (MS_SUCCESS); } diff --git a/legend.c b/legend.c index 4b1bed2445..63881c78a3 100644 --- a/legend.c +++ b/legend.c @@ -29,32 +29,29 @@ #include "mapserver.h" - - -int main(int argc, char *argv[]) -{ - mapObj *map=NULL; - imageObj *img=NULL; +int main(int argc, char *argv[]) { + mapObj *map = NULL; + imageObj *img = NULL; msSetup(); - if(argc > 1 && strcmp(argv[1], "-v") == 0) { + if (argc > 1 && strcmp(argv[1], "-v") == 0) { printf("%s\n", msGetVersion()); exit(0); } - if( argc < 3 ) { - fprintf(stdout,"Syntax: legend [mapfile] [output image]\n" ); + if (argc < 3) { + fprintf(stdout, "Syntax: legend [mapfile] [output image]\n"); exit(0); } map = msLoadMap(argv[1], NULL, NULL); - if(!map) { + if (!map) { msWriteError(stderr); exit(0); } img = msDrawLegend(map, MS_FALSE, NULL); - if(!img) { + if (!img) { msWriteError(stderr); exit(0); } @@ -64,5 +61,5 @@ int main(int argc, char *argv[]) msFreeImage(img); msFreeMap(map); - return(MS_TRUE); + return (MS_TRUE); } diff --git a/map2img.c b/map2img.c index ecb4333ded..de25a4c179 100644 --- a/map2img.c +++ b/map2img.c @@ -34,65 +34,70 @@ #include "limits.h" -int main(int argc, char *argv[]) -{ - int i,j,k; +int main(int argc, char *argv[]) { + int i, j, k; - mapObj *map=NULL; - imageObj *image = NULL; - configObj* config = NULL; + mapObj *map = NULL; + imageObj *image = NULL; + configObj *config = NULL; - char **layers=NULL; - int num_layers=0; + char **layers = NULL; + int num_layers = 0; - int layer_found=0; + int layer_found = 0; - char *outfile=NULL; /* no -o sends image to STDOUT */ + char *outfile = NULL; /* no -o sends image to STDOUT */ int iterations = 1; int draws = 0; /* ---- output version info and exit --- */ - if(argc > 1 && strcmp(argv[1], "-v") == 0) { + if (argc > 1 && strcmp(argv[1], "-v") == 0) { printf("%s\n", msGetVersion()); exit(0); } - + /* ---- check the number of arguments, return syntax if not correct ---- */ - if( argc < 3 ) { + if (argc < 3) { fprintf(stdout, "\nPurpose: convert a mapfile to an image\n\n"); - fprintf(stdout, - "Syntax: map2img -m mapfile [-o image] [-e minx miny maxx maxy] [-s sizex sizey]\n" - " [-l \"layer1 [layers2...]\"] [-i format]\n" - " [-all_debug n] [-map_debug n] [-layer_debug n] [-p n] [-c n] [-d layername datavalue]\n" - " [-conf filename]\n"); - fprintf(stdout," -m mapfile: Map file to operate on - required\n" ); - fprintf(stdout," -i format: Override the IMAGETYPE value to pick output format\n" ); - fprintf(stdout," -o image: output filename (stdout if not provided)\n"); - fprintf(stdout," -e minx miny maxx maxy: extents to render\n"); - fprintf(stdout," -s sizex sizey: output image size\n"); - fprintf(stdout," -l layers: layers / groups to enable - make sure they are quoted and space separated if more than one listed\n" ); - fprintf(stdout," -all_debug n: Set debug level for map and all layers\n" ); - fprintf(stdout," -map_debug n: Set map debug level\n" ); - fprintf(stdout," -layer_debug layer_name n: Set layer debug level\n" ); - fprintf(stdout," -c n: draw map n number of times\n" ); - fprintf(stdout," -p n: pause for n seconds after reading the map\n" ); - fprintf(stdout," -d layername datavalue: change DATA value for layer\n" ); - fprintf(stdout," -conf filename: filename of the MapServer configuration file.\n" ); + fprintf(stdout, "Syntax: map2img -m mapfile [-o image] [-e minx miny maxx " + "maxy] [-s sizex sizey]\n" + " [-l \"layer1 [layers2...]\"] [-i format]\n" + " [-all_debug n] [-map_debug n] " + "[-layer_debug n] [-p n] [-c n] [-d layername datavalue]\n" + " [-conf filename]\n"); + fprintf(stdout, " -m mapfile: Map file to operate on - required\n"); + fprintf( + stdout, + " -i format: Override the IMAGETYPE value to pick output format\n"); + fprintf(stdout, " -o image: output filename (stdout if not provided)\n"); + fprintf(stdout, " -e minx miny maxx maxy: extents to render\n"); + fprintf(stdout, " -s sizex sizey: output image size\n"); + fprintf(stdout, " -l layers: layers / groups to enable - make sure they " + "are quoted and space separated if more than one listed\n"); + fprintf(stdout, " -all_debug n: Set debug level for map and all layers\n"); + fprintf(stdout, " -map_debug n: Set map debug level\n"); + fprintf(stdout, " -layer_debug layer_name n: Set layer debug level\n"); + fprintf(stdout, " -c n: draw map n number of times\n"); + fprintf(stdout, " -p n: pause for n seconds after reading the map\n"); + fprintf(stdout, " -d layername datavalue: change DATA value for layer\n"); + fprintf( + stdout, + " -conf filename: filename of the MapServer configuration file.\n"); exit(0); } - if ( msSetup() != MS_SUCCESS ) { + if (msSetup() != MS_SUCCESS) { msWriteError(stderr); exit(1); } bool some_debug_requested = FALSE; - const char* config_filename = NULL; - for(i=1; i INT_MAX - 1 ) { + const char *config_filename = NULL; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) { /* user specified number of draws */ + iterations = atoi(argv[i + 1]); + if (iterations < 0 || iterations > INT_MAX - 1) { printf("Invalid number of iterations"); return 1; } @@ -100,7 +105,7 @@ int main(int argc, char *argv[]) continue; } - if(i < argc-1 && strcmp(argv[i], "-all_debug") == 0) { /* global debug */ + if (i < argc - 1 && strcmp(argv[i], "-all_debug") == 0) { /* global debug */ int debug_level = atoi(argv[++i]); some_debug_requested = TRUE; @@ -110,21 +115,21 @@ int main(int argc, char *argv[]) continue; } - if(i < argc-1 && (strcmp(argv[i], "-map_debug") == 0 || - strcmp(argv[i], "-layer_debug") == 0)) { + if (i < argc - 1 && (strcmp(argv[i], "-map_debug") == 0 || + strcmp(argv[i], "-layer_debug") == 0)) { some_debug_requested = TRUE; continue; } - if(i < argc-1 && strcmp(argv[i], "-conf") == 0) { - config_filename = argv[i+1]; + if (i < argc - 1 && strcmp(argv[i], "-conf") == 0) { + config_filename = argv[i + 1]; ++i; continue; } } - if( some_debug_requested ) { + if (some_debug_requested) { /* Send output to stderr by default */ if (msGetErrorFile() == NULL) msSetErrorFile("stderr", NULL); @@ -132,31 +137,30 @@ int main(int argc, char *argv[]) config = msLoadConfig(config_filename); - for(draws=0; draws= MS_DEBUGLEVEL_TUNING) + if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&requeststarttime, NULL); /* Use PROJ_DATA/PROJ_LIB env vars if set */ msProjDataInitFromEnv(); /* Use MS_ERRORFILE and MS_DEBUGLEVEL env vars if set */ - if ( msDebugInitFromEnv() != MS_SUCCESS ) { + if (msDebugInitFromEnv() != MS_SUCCESS) { msWriteError(stderr); msCleanup(); msFreeConfig(config); exit(1); } + for (i = 1; i < argc; + i++) { /* Step though the user arguments, 1st to find map file */ - - for(i=1; iimagetype ); - map->imagetype = msStrdup( argv[i+1] ); - msApplyOutputFormat( &(map->outputformat), format, MS_NOOVERRIDE); + msFree((char *)map->imagetype); + map->imagetype = msStrdup(argv[i + 1]); + msApplyOutputFormat(&(map->outputformat), format, MS_NOOVERRIDE); } - i+=1; + i += 1; } - if(strcmp(argv[i],"-d") == 0) { /* swap layer data */ - for(j=0; jnumlayers; j++) { - if(strcmp(GET_LAYER(map, j)->name, argv[i+1]) == 0) { + if (strcmp(argv[i], "-d") == 0) { /* swap layer data */ + for (j = 0; j < map->numlayers; j++) { + if (strcmp(GET_LAYER(map, j)->name, argv[i + 1]) == 0) { free(GET_LAYER(map, j)->data); - GET_LAYER(map, j)->data = msStrdup(argv[i+2]); + GET_LAYER(map, j)->data = msStrdup(argv[i + 2]); break; } } - i+=2; + i += 2; } - if(i < argc-1 && strcmp(argv[i], "-all_debug") == 0) { /* global debug */ + if (i < argc - 1 && + strcmp(argv[i], "-all_debug") == 0) { /* global debug */ int debug_level = atoi(argv[++i]); /* msSetGlobalDebugLevel() already called. Just need to force debug * level in map and all layers */ map->debug = debug_level; - for(j=0; jnumlayers; j++) { + for (j = 0; j < map->numlayers; j++) { GET_LAYER(map, j)->debug = debug_level; } - } - if(i < argc-1 && strcmp(argv[i], "-map_debug") == 0) { /* debug */ + if (i < argc - 1 && strcmp(argv[i], "-map_debug") == 0) { /* debug */ map->debug = atoi(argv[++i]); } - if(i < argc-1 && strcmp(argv[i], "-layer_debug") == 0) { /* debug */ + if (i < argc - 1 && strcmp(argv[i], "-layer_debug") == 0) { /* debug */ const char *layer_name = argv[++i]; int debug_level = atoi(argv[++i]); int got_layer = 0; - for(j=0; jnumlayers; j++) { - if(strcmp(GET_LAYER(map, j)->name,layer_name) == 0 ) { + for (j = 0; j < map->numlayers; j++) { + if (strcmp(GET_LAYER(map, j)->name, layer_name) == 0) { GET_LAYER(map, j)->debug = debug_level; got_layer = 1; } } - if( !got_layer ) - fprintf( stderr, - " Did not find layer '%s' from -layer_debug switch.\n", - layer_name ); + if (!got_layer) + fprintf(stderr, + " Did not find layer '%s' from -layer_debug switch.\n", + layer_name); } - if(strcmp(argv[i],"-e") == 0) { /* change extent */ - if( argc <= i+4 ) { - fprintf( stderr, - "Argument -e needs 4 space separated numbers as argument.\n" ); + if (strcmp(argv[i], "-e") == 0) { /* change extent */ + if (argc <= i + 4) { + fprintf(stderr, + "Argument -e needs 4 space separated numbers as argument.\n"); msCleanup(); msFreeConfig(config); exit(1); } - map->extent.minx = atof(argv[i+1]); - map->extent.miny = atof(argv[i+2]); - map->extent.maxx = atof(argv[i+3]); - map->extent.maxy = atof(argv[i+4]); - i+=4; + map->extent.minx = atof(argv[i + 1]); + map->extent.miny = atof(argv[i + 2]); + map->extent.maxx = atof(argv[i + 3]); + map->extent.maxy = atof(argv[i + 4]); + i += 4; } if (strcmp(argv[i], "-s") == 0) { - msMapSetSize(map, atoi(argv[i+1]), atoi(argv[i+2])); - i+=2; + msMapSetSize(map, atoi(argv[i + 1]), atoi(argv[i + 2])); + i += 2; } - if(strcmp(argv[i],"-l") == 0) { /* load layer list */ - layers = msStringSplit(argv[i+1], ' ', &(num_layers)); + if (strcmp(argv[i], "-l") == 0) { /* load layer list */ + layers = msStringSplit(argv[i + 1], ' ', &(num_layers)); - for(j=0; jnumlayers; k++) { - if((GET_LAYER(map, k)->name && strcasecmp(GET_LAYER(map, k)->name, layers[j]) == 0) || (GET_LAYER(map, k)->group && strcasecmp(GET_LAYER(map, k)->group, layers[j]) == 0)) { + for (j = 0; j < num_layers; j++) { /* loop over -l */ + layer_found = 0; + for (k = 0; k < map->numlayers; k++) { + if ((GET_LAYER(map, k)->name && + strcasecmp(GET_LAYER(map, k)->name, layers[j]) == 0) || + (GET_LAYER(map, k)->group && + strcasecmp(GET_LAYER(map, k)->group, layers[j]) == 0)) { layer_found = 1; break; } } - if (layer_found==0) { + if (layer_found == 0) { fprintf(stderr, "Layer (-l) \"%s\" not found\n", layers[j]); msCleanup(); msFreeConfig(config); @@ -295,14 +302,16 @@ int main(int argc, char *argv[]) } } - for(j=0; jnumlayers; j++) { - if(GET_LAYER(map, j)->status == MS_DEFAULT) + for (j = 0; j < map->numlayers; j++) { + if (GET_LAYER(map, j)->status == MS_DEFAULT) continue; else { GET_LAYER(map, j)->status = MS_OFF; - for(k=0; kname && strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) || - (GET_LAYER(map, j)->group && strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) { + for (k = 0; k < num_layers; k++) { + if ((GET_LAYER(map, j)->name && + strcasecmp(GET_LAYER(map, j)->name, layers[k]) == 0) || + (GET_LAYER(map, j)->group && + strcasecmp(GET_LAYER(map, j)->group, layers[k]) == 0)) { GET_LAYER(map, j)->status = MS_ON; break; } @@ -312,13 +321,13 @@ int main(int argc, char *argv[]) msFreeCharArray(layers, num_layers); - i+=1; + i += 1; } } image = msDrawMap(map, MS_FALSE); - if(!image) { + if (!image) { msWriteError(stderr); msFreeMap(map); @@ -327,22 +336,22 @@ int main(int argc, char *argv[]) exit(1); } - if( msSaveImage(map, image, outfile) != MS_SUCCESS ) { + if (msSaveImage(map, image, outfile) != MS_SUCCESS) { msWriteError(stderr); } msFreeImage(image); msFreeMap(map); - if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { + if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&requestendtime, NULL); msDebug("map2img total time: %.3fs\n", - (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)- - (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) ); + (requestendtime.tv_sec + requestendtime.tv_usec / 1.0e6) - + (requeststarttime.tv_sec + requeststarttime.tv_usec / 1.0e6)); } } /* for(draws=0; draws blender_pre; -typedef mapserver::comp_op_adaptor_rgba_pre compop_blender_pre; - -typedef mapserver::pixfmt_alpha_blend_rgba pixel_format; -typedef mapserver::pixfmt_custom_blend_rgba compop_pixel_format; +typedef mapserver::comp_op_adaptor_rgba_pre + compop_blender_pre; + +typedef mapserver::pixfmt_alpha_blend_rgba< + blender_pre, mapserver::rendering_buffer, pixel_type> + pixel_format; +typedef mapserver::pixfmt_custom_blend_rgba + compop_pixel_format; typedef mapserver::rendering_buffer rendering_buffer; typedef mapserver::renderer_base renderer_base; typedef mapserver::renderer_base compop_renderer_base; typedef mapserver::renderer_scanline_aa_solid renderer_scanline; -typedef mapserver::renderer_scanline_bin_solid renderer_scanline_aliased; +typedef mapserver::renderer_scanline_bin_solid + renderer_scanline_aliased; typedef mapserver::rasterizer_scanline_aa<> rasterizer_scanline; typedef mapserver::font_engine_freetype_int16 font_engine_type; typedef mapserver::font_cache_manager font_manager_type; -typedef mapserver::conv_curve font_curve_type; +typedef mapserver::conv_curve + font_curve_type; typedef mapserver::glyph_raster_bin glyph_gen; static const color_type AGG_NO_COLOR = color_type(0, 0, 0, 0); -#define aggColor(c) mapserver::rgba8_pre((c)->red, (c)->green, (c)->blue, (c)->alpha) +#define aggColor(c) \ + mapserver::rgba8_pre((c)->red, (c)->green, (c)->blue, (c)->alpha) -class aggRendererCache -{ +class aggRendererCache { public: font_engine_type m_feng; font_manager_type m_fman; - aggRendererCache(): m_fman(m_feng) {} + aggRendererCache() : m_fman(m_feng) {} }; -class AGG2Renderer -{ +class AGG2Renderer { public: std::vector buffer{}; rendering_buffer m_rendering_buffer; @@ -120,74 +126,70 @@ class AGG2Renderer renderer_scanline_aliased m_renderer_scanline_aliased; rasterizer_scanline m_rasterizer_aa; rasterizer_scanline m_rasterizer_aa_gamma; - mapserver::scanline_p8 sl_poly; /*packed scanlines, works faster when the area is larger - than the perimeter, in number of pixels*/ - mapserver::scanline_u8 sl_line; /*unpacked scanlines, works faster if the area is roughly - equal to the perimeter, in number of pixels*/ + mapserver::scanline_p8 sl_poly; /*packed scanlines, works faster when the area + is larger than the perimeter, in number of pixels*/ + mapserver::scanline_u8 sl_line; /*unpacked scanlines, works faster if the area + is roughly equal to the perimeter, in number of pixels*/ bool use_alpha = false; std::unique_ptr> stroke{}; std::unique_ptr> dash{}; - std::unique_ptr >> stroke_dash{}; + std::unique_ptr>> + stroke_dash{}; double default_gamma = 0.0; mapserver::gamma_linear gamma_function; }; -#define AGG_RENDERER(image) ((AGG2Renderer*) (image)->img.plugin) +#define AGG_RENDERER(image) ((AGG2Renderer *)(image)->img.plugin) -template -static void applyCJC(VertexSource &stroke, int caps, int joins) -{ +template +static void applyCJC(VertexSource &stroke, int caps, int joins) { switch (joins) { - case MS_CJC_ROUND: - stroke.line_join(mapserver::round_join); - break; - case MS_CJC_MITER: - stroke.line_join(mapserver::miter_join); - break; - case MS_CJC_BEVEL: - case MS_CJC_NONE: - stroke.line_join(mapserver::bevel_join); - break; + case MS_CJC_ROUND: + stroke.line_join(mapserver::round_join); + break; + case MS_CJC_MITER: + stroke.line_join(mapserver::miter_join); + break; + case MS_CJC_BEVEL: + case MS_CJC_NONE: + stroke.line_join(mapserver::bevel_join); + break; } switch (caps) { - case MS_CJC_BUTT: - case MS_CJC_NONE: - stroke.line_cap(mapserver::butt_cap); - break; - case MS_CJC_ROUND: - stroke.line_cap(mapserver::round_cap); - break; - case MS_CJC_SQUARE: - stroke.line_cap(mapserver::square_cap); - break; + case MS_CJC_BUTT: + case MS_CJC_NONE: + stroke.line_cap(mapserver::butt_cap); + break; + case MS_CJC_ROUND: + stroke.line_cap(mapserver::round_cap); + break; + case MS_CJC_SQUARE: + stroke.line_cap(mapserver::square_cap); + break; } } -int agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style) -{ +int agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style) { AGG2Renderer *r = AGG_RENDERER(img); line_adaptor lines = line_adaptor(p); r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); - if (style->antialiased== MS_FALSE) - { + if (style->antialiased == MS_FALSE) { r->m_renderer_scanline_aliased.color(aggColor(style->color)); - } - else - { + } else { r->m_renderer_scanline.color(aggColor(style->color)); } if (style->patternlength <= 0) { - if(!r->stroke) { + if (!r->stroke) { r->stroke.reset(new mapserver::conv_stroke(lines)); } else { r->stroke->attach(lines); } r->stroke->width(style->width); - if(style->width>1) { + if (style->width > 1) { applyCJC(*r->stroke, style->linecap, style->linejoin); } else { r->stroke->inner_join(mapserver::inner_bevel); @@ -195,34 +197,36 @@ int agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style) } r->m_rasterizer_aa.add_path(*r->stroke); } else { - if(!r->dash) { + if (!r->dash) { r->dash.reset(new mapserver::conv_dash(lines)); } else { r->dash->remove_all_dashes(); r->dash->dash_start(0.0); r->dash->attach(lines); } - if(!r->stroke_dash) { - r->stroke_dash.reset(new mapserver::conv_stroke > (*r->dash)); + if (!r->stroke_dash) { + r->stroke_dash.reset( + new mapserver::conv_stroke>( + *r->dash)); } else { r->stroke_dash->attach(*r->dash); } int patt_length = 0; for (int i = 0; i < style->patternlength; i += 2) { if (i < style->patternlength - 1) { - r->dash->add_dash(MS_MAX(1,MS_NINT(style->pattern[i])), - MS_MAX(1,MS_NINT(style->pattern[i + 1]))); - if(style->patternoffset) { - patt_length += MS_MAX(1,MS_NINT(style->pattern[i])) + - MS_MAX(1,MS_NINT(style->pattern[i + 1])); + r->dash->add_dash(MS_MAX(1, MS_NINT(style->pattern[i])), + MS_MAX(1, MS_NINT(style->pattern[i + 1]))); + if (style->patternoffset) { + patt_length += MS_MAX(1, MS_NINT(style->pattern[i])) + + MS_MAX(1, MS_NINT(style->pattern[i + 1])); } } } - if(style->patternoffset > 0) { + if (style->patternoffset > 0) { r->dash->dash_start(patt_length - style->patternoffset); } r->stroke_dash->width(style->width); - if(style->width>1) { + if (style->width > 1) { applyCJC(*r->stroke_dash, style->linecap, style->linejoin); } else { r->stroke_dash->inner_join(mapserver::inner_bevel); @@ -231,19 +235,25 @@ int agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style) r->m_rasterizer_aa.add_path(*r->stroke_dash); } if (style->antialiased == MS_FALSE) - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline_aliased); - else - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, + r->m_renderer_scanline_aliased); + else + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, + r->m_renderer_scanline); return MS_SUCCESS; } -int agg2RenderLineTiled(imageObj *img, shapeObj *p, imageObj * tile) -{ +int agg2RenderLineTiled(imageObj *img, shapeObj *p, imageObj *tile) { mapserver::pattern_filter_bilinear_rgba8 fltr; - typedef mapserver::line_image_pattern pattern_type; - typedef mapserver::renderer_outline_image renderer_img_type; - typedef mapserver::rasterizer_outline_aa rasterizer_img_type; + typedef mapserver::line_image_pattern< + mapserver::pattern_filter_bilinear_rgba8> + pattern_type; + typedef mapserver::renderer_outline_image + renderer_img_type; + typedef mapserver::rasterizer_outline_aa + rasterizer_img_type; pattern_type patt(fltr); AGG2Renderer *r = AGG_RENDERER(img); @@ -258,264 +268,270 @@ int agg2RenderLineTiled(imageObj *img, shapeObj *p, imageObj * tile) return MS_SUCCESS; } -int agg2RenderPolygon(imageObj *img, shapeObj *p, colorObj * color) -{ +int agg2RenderPolygon(imageObj *img, shapeObj *p, colorObj *color) { AGG2Renderer *r = AGG_RENDERER(img); polygon_adaptor polygons(p); r->m_rasterizer_aa_gamma.reset(); r->m_rasterizer_aa_gamma.filling_rule(mapserver::fill_even_odd); r->m_rasterizer_aa_gamma.add_path(polygons); r->m_renderer_scanline.color(aggColor(color)); - mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, + r->m_renderer_scanline); return MS_SUCCESS; } -static inline double int26p6_to_dbl(int p) - { - return double(p) / 64.0; +static inline double int26p6_to_dbl(int p) { return double(p) / 64.0; } + +template +bool decompose_ft_outline(const FT_Outline &outline, bool flip_y, + const mapserver::trans_affine &mtx, + PathStorage &path) { + double x1, y1, x2, y2, x3, y3; + + FT_Vector *point; + FT_Vector *limit; + char *tags; + + int n; // index of contour in outline + int first; // index of first point in contour + char tag; // current point's state + + first = 0; + + for (n = 0; n < outline.n_contours; n++) { + int last; // index of last point in contour + + last = outline.contours[n]; + limit = outline.points + last; + + FT_Vector v_start = outline.points[first]; + + FT_Vector v_control = v_start; + + point = outline.points + first; + tags = outline.tags + first; + tag = FT_CURVE_TAG(tags[0]); + + // A contour cannot start with a cubic control point! + if (tag == FT_CURVE_TAG_CUBIC) + return false; + + // check first point to determine origin + if (tag == FT_CURVE_TAG_CONIC) { + const FT_Vector v_last = outline.points[last]; + + // first point is conic control. Yes, this happens. + if (FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) { + // start at last point if it is on the curve + v_start = v_last; + limit--; + } else { + // if both first and last points are conic, + // start at their middle and record its position + // for closure + v_start.x = (v_start.x + v_last.x) / 2; + v_start.y = (v_start.y + v_last.y) / 2; + } + point--; + tags--; } -template - bool decompose_ft_outline(const FT_Outline& outline, - bool flip_y, - const mapserver::trans_affine& mtx, - PathStorage& path) - { - double x1, y1, x2, y2, x3, y3; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - int n; // index of contour in outline - int first; // index of first point in contour - char tag; // current point's state - - first = 0; - - for(n = 0; n < outline.n_contours; n++) - { - int last; // index of last point in contour - - last = outline.contours[n]; - limit = outline.points + last; - - FT_Vector v_start = outline.points[first]; - - FT_Vector v_control = v_start; - - point = outline.points + first; - tags = outline.tags + first; - tag = FT_CURVE_TAG(tags[0]); - - // A contour cannot start with a cubic control point! - if(tag == FT_CURVE_TAG_CUBIC) return false; - - // check first point to determine origin - if( tag == FT_CURVE_TAG_CONIC) - { - const FT_Vector v_last = outline.points[last]; - - // first point is conic control. Yes, this happens. - if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) - { - // start at last point if it is on the curve - v_start = v_last; - limit--; - } - else - { - // if both first and last points are conic, - // start at their middle and record its position - // for closure - v_start.x = (v_start.x + v_last.x) / 2; - v_start.y = (v_start.y + v_last.y) / 2; - } - point--; - tags--; - } + x1 = int26p6_to_dbl(v_start.x); + y1 = int26p6_to_dbl(v_start.y); + if (flip_y) + y1 = -y1; + mtx.transform(&x1, &y1); + path.move_to(x1, y1); + + while (point < limit) { + point++; + tags++; + + tag = FT_CURVE_TAG(tags[0]); + switch (tag) { + case FT_CURVE_TAG_ON: // emit a single line_to + { + x1 = int26p6_to_dbl(point->x); + y1 = int26p6_to_dbl(point->y); + if (flip_y) + y1 = -y1; + mtx.transform(&x1, &y1); + path.line_to(x1, y1); + // path.line_to(conv(point->x), flip_y ? -conv(point->y) : + // conv(point->y)); + continue; + } - x1 = int26p6_to_dbl(v_start.x); - y1 = int26p6_to_dbl(v_start.y); - if(flip_y) y1 = -y1; - mtx.transform(&x1, &y1); - path.move_to(x1,y1); - - while(point < limit) - { - point++; - tags++; - - tag = FT_CURVE_TAG(tags[0]); - switch(tag) - { - case FT_CURVE_TAG_ON: // emit a single line_to - { - x1 = int26p6_to_dbl(point->x); - y1 = int26p6_to_dbl(point->y); - if(flip_y) y1 = -y1; - mtx.transform(&x1, &y1); - path.line_to(x1,y1); - //path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); - continue; - } - - case FT_CURVE_TAG_CONIC: // consume conic arcs - { - v_control.x = point->x; - v_control.y = point->y; - - Do_Conic: - if(point < limit) - { - FT_Vector vec; - FT_Vector v_middle; - - point++; - tags++; - tag = FT_CURVE_TAG(tags[0]); - - vec.x = point->x; - vec.y = point->y; - - if(tag == FT_CURVE_TAG_ON) - { - x1 = int26p6_to_dbl(v_control.x); - y1 = int26p6_to_dbl(v_control.y); - x2 = int26p6_to_dbl(vec.x); - y2 = int26p6_to_dbl(vec.y); - if(flip_y) { y1 = -y1; y2 = -y2; } - mtx.transform(&x1, &y1); - mtx.transform(&x2, &y2); - path.curve3(x1,y1,x2,y2); - continue; - } - - if(tag != FT_CURVE_TAG_CONIC) return false; - - v_middle.x = (v_control.x + vec.x) / 2; - v_middle.y = (v_control.y + vec.y) / 2; - - x1 = int26p6_to_dbl(v_control.x); - y1 = int26p6_to_dbl(v_control.y); - x2 = int26p6_to_dbl(v_middle.x); - y2 = int26p6_to_dbl(v_middle.y); - if(flip_y) { y1 = -y1; y2 = -y2; } - mtx.transform(&x1, &y1); - mtx.transform(&x2, &y2); - path.curve3(x1,y1,x2,y2); - - //path.curve3(conv(v_control.x), - // flip_y ? -conv(v_control.y) : conv(v_control.y), - // conv(v_middle.x), - // flip_y ? -conv(v_middle.y) : conv(v_middle.y)); - - v_control = vec; - goto Do_Conic; - } - - x1 = int26p6_to_dbl(v_control.x); - y1 = int26p6_to_dbl(v_control.y); - x2 = int26p6_to_dbl(v_start.x); - y2 = int26p6_to_dbl(v_start.y); - if(flip_y) { y1 = -y1; y2 = -y2; } - mtx.transform(&x1, &y1); - mtx.transform(&x2, &y2); - path.curve3(x1,y1,x2,y2); - - //path.curve3(conv(v_control.x), - // flip_y ? -conv(v_control.y) : conv(v_control.y), - // conv(v_start.x), - // flip_y ? -conv(v_start.y) : conv(v_start.y)); - goto Close; - } - - default: // FT_CURVE_TAG_CUBIC - { - FT_Vector vec1, vec2; - - if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) - { - return false; - } - - vec1.x = point[0].x; - vec1.y = point[0].y; - vec2.x = point[1].x; - vec2.y = point[1].y; - - point += 2; - tags += 2; - - if(point <= limit) - { - FT_Vector vec; - - vec.x = point->x; - vec.y = point->y; - - x1 = int26p6_to_dbl(vec1.x); - y1 = int26p6_to_dbl(vec1.y); - x2 = int26p6_to_dbl(vec2.x); - y2 = int26p6_to_dbl(vec2.y); - x3 = int26p6_to_dbl(vec.x); - y3 = int26p6_to_dbl(vec.y); - if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } - mtx.transform(&x1, &y1); - mtx.transform(&x2, &y2); - mtx.transform(&x3, &y3); - path.curve4(x1,y1,x2,y2,x3,y3); - - //path.curve4(conv(vec1.x), - // flip_y ? -conv(vec1.y) : conv(vec1.y), - // conv(vec2.x), - // flip_y ? -conv(vec2.y) : conv(vec2.y), - // conv(vec.x), - // flip_y ? -conv(vec.y) : conv(vec.y)); - continue; - } - - x1 = int26p6_to_dbl(vec1.x); - y1 = int26p6_to_dbl(vec1.y); - x2 = int26p6_to_dbl(vec2.x); - y2 = int26p6_to_dbl(vec2.y); - x3 = int26p6_to_dbl(v_start.x); - y3 = int26p6_to_dbl(v_start.y); - if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } - mtx.transform(&x1, &y1); - mtx.transform(&x2, &y2); - mtx.transform(&x3, &y3); - path.curve4(x1,y1,x2,y2,x3,y3); - - //path.curve4(conv(vec1.x), - // flip_y ? -conv(vec1.y) : conv(vec1.y), - // conv(vec2.x), - // flip_y ? -conv(vec2.y) : conv(vec2.y), - // conv(v_start.x), - // flip_y ? -conv(v_start.y) : conv(v_start.y)); - goto Close; - } - } + case FT_CURVE_TAG_CONIC: // consume conic arcs + { + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if (point < limit) { + FT_Vector vec; + FT_Vector v_middle; + + point++; + tags++; + tag = FT_CURVE_TAG(tags[0]); + + vec.x = point->x; + vec.y = point->y; + + if (tag == FT_CURVE_TAG_ON) { + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(vec.x); + y2 = int26p6_to_dbl(vec.y); + if (flip_y) { + y1 = -y1; + y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(x1, y1, x2, y2); + continue; + } + + if (tag != FT_CURVE_TAG_CONIC) + return false; + + v_middle.x = (v_control.x + vec.x) / 2; + v_middle.y = (v_control.y + vec.y) / 2; + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_middle.x); + y2 = int26p6_to_dbl(v_middle.y); + if (flip_y) { + y1 = -y1; + y2 = -y2; + } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(x1, y1, x2, y2); + + // path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_middle.x), + // flip_y ? -conv(v_middle.y) : conv(v_middle.y)); - path.close_polygon(); + v_control = vec; + goto Do_Conic; + } + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_start.x); + y2 = int26p6_to_dbl(v_start.y); + if (flip_y) { + y1 = -y1; + y2 = -y2; + } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(x1, y1, x2, y2); + + // path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + + default: // FT_CURVE_TAG_CUBIC + { + FT_Vector vec1, vec2; + + if (point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) { + return false; + } - Close: - first = last + 1; + vec1.x = point[0].x; + vec1.y = point[0].y; + vec2.x = point[1].x; + vec2.y = point[1].y; + + point += 2; + tags += 2; + + if (point <= limit) { + FT_Vector vec; + + vec.x = point->x; + vec.y = point->y; + + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(vec.x); + y3 = int26p6_to_dbl(vec.y); + if (flip_y) { + y1 = -y1; + y2 = -y2; + y3 = -y3; + } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(x1, y1, x2, y2, x3, y3); + + // path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(vec.x), + // flip_y ? -conv(vec.y) : conv(vec.y)); + continue; } - return true; + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(v_start.x); + y3 = int26p6_to_dbl(v_start.y); + if (flip_y) { + y1 = -y1; + y2 = -y2; + y3 = -y3; + } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(x1, y1, x2, y2, x3, y3); + + // path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + } } -int agg2RenderPolygonTiled(imageObj *img, shapeObj *p, imageObj * tile) -{ + path.close_polygon(); + + Close: + first = last + 1; + } + + return true; +} + +int agg2RenderPolygonTiled(imageObj *img, shapeObj *p, imageObj *tile) { assert(img->format->renderer == tile->format->renderer); AGG2Renderer *r = AGG_RENDERER(img); AGG2Renderer *tileRenderer = AGG_RENDERER(tile); polygon_adaptor polygons(p); typedef mapserver::wrap_mode_repeat wrap_type; - typedef mapserver::image_accessor_wrap img_source_type; + typedef mapserver::image_accessor_wrap + img_source_type; typedef mapserver::span_pattern_rgba span_gen_type; mapserver::span_allocator sa; r->m_rasterizer_aa.reset(); @@ -523,79 +539,82 @@ int agg2RenderPolygonTiled(imageObj *img, shapeObj *p, imageObj * tile) img_source_type img_src(tileRenderer->m_pixel_format); span_gen_type sg(img_src, 0, 0); r->m_rasterizer_aa.add_path(polygons); - mapserver::render_scanlines_aa(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_base, sa , sg); + mapserver::render_scanlines_aa(r->m_rasterizer_aa, r->sl_poly, + r->m_renderer_base, sa, sg); return MS_SUCCESS; } -int agg2RenderGlyphsPath(imageObj *img, const textSymbolObj *ts, colorObj *c, colorObj *oc, int ow, int /*isMarker*/) { - +int agg2RenderGlyphsPath(imageObj *img, const textSymbolObj *ts, colorObj *c, + colorObj *oc, int ow, int /*isMarker*/) { + const textPathObj *tp = ts->textpath; mapserver::path_storage glyphs; mapserver::trans_affine trans; AGG2Renderer *r = AGG_RENDERER(img); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); - for(int i=0; inumglyphs; i++) { - glyphObj *gl = tp->glyphs + i; + for (int i = 0; i < tp->numglyphs; i++) { + glyphObj *gl = tp->glyphs + i; trans.reset(); trans.rotate(-gl->rot); trans.translate(gl->pnt.x, gl->pnt.y); - outline_element *ol = msGetGlyphOutline(gl->face,gl->glyph); - if(!ol) { + outline_element *ol = msGetGlyphOutline(gl->face, gl->glyph); + if (!ol) { return MS_FAILURE; } - decompose_ft_outline(ol->outline,true,trans,glyphs); + decompose_ft_outline(ol->outline, true, trans, glyphs); } mapserver::conv_curve m_curves(glyphs); if (oc) { r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); - mapserver::conv_contour > cc(m_curves); + mapserver::conv_contour> cc( + m_curves); cc.width(ow + 1); r->m_rasterizer_aa.add_path(cc); r->m_renderer_scanline.color(aggColor(oc)); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, + r->m_renderer_scanline); } - if(c) { + if (c) { r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); r->m_rasterizer_aa.add_path(m_curves); r->m_renderer_scanline.color(aggColor(c)); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, + r->m_renderer_scanline); } return MS_SUCCESS; } -mapserver::path_storage imageVectorSymbol(symbolObj *symbol) -{ +mapserver::path_storage imageVectorSymbol(symbolObj *symbol) { mapserver::path_storage path; - int is_new=1; + int is_new = 1; - for(int i=0; i < symbol->numpoints; i++) { - if((symbol->points[i].x == -99) && (symbol->points[i].y == -99)) - is_new=1; + for (int i = 0; i < symbol->numpoints; i++) { + if ((symbol->points[i].x == -99) && (symbol->points[i].y == -99)) + is_new = 1; else { - if(is_new) { - path.move_to(symbol->points[i].x,symbol->points[i].y); - is_new=0; + if (is_new) { + path.move_to(symbol->points[i].x, symbol->points[i].y); + is_new = 0; } else { - path.line_to(symbol->points[i].x,symbol->points[i].y); + path.line_to(symbol->points[i].x, symbol->points[i].y); } } } return path; } -int agg2RenderVectorSymbol(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj * style) -{ +int agg2RenderVectorSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style) { AGG2Renderer *r = AGG_RENDERER(img); double ox = symbol->sizex * 0.5; double oy = symbol->sizey * 0.5; mapserver::path_storage path = imageVectorSymbol(symbol); mapserver::trans_affine mtx; - mtx *= mapserver::trans_affine_translation(-ox,-oy); + mtx *= mapserver::trans_affine_translation(-ox, -oy); mtx *= mapserver::trans_affine_scaling(style->scale); mtx *= mapserver::trans_affine_rotation(-style->rotation); mtx *= mapserver::trans_affine_translation(x, y); @@ -605,40 +624,43 @@ int agg2RenderVectorSymbol(imageObj *img, double x, double y, r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd); r->m_rasterizer_aa.add_path(path); r->m_renderer_scanline.color(aggColor(style->color)); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, + r->m_renderer_scanline); } - if(style->outlinecolor) { + if (style->outlinecolor) { r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); r->m_renderer_scanline.color(aggColor(style->outlinecolor)); mapserver::conv_stroke stroke(path); stroke.width(style->outlinewidth); r->m_rasterizer_aa.add_path(stroke); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, + r->m_renderer_scanline); } return MS_SUCCESS; } -int agg2RenderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj * style) -{ +int agg2RenderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style) { AGG2Renderer *r = AGG_RENDERER(img); rasterBufferObj *pixmap = symbol->pixmap_buffer; assert(pixmap->type == MS_BUFFER_BYTE_RGBA); - rendering_buffer b(pixmap->data.rgba.pixels,pixmap->width,pixmap->height,pixmap->data.rgba.row_step); + rendering_buffer b(pixmap->data.rgba.pixels, pixmap->width, pixmap->height, + pixmap->data.rgba.row_step); pixel_format pf(b); r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); - if ( (style->rotation != 0 && style->rotation != MS_PI*2.)|| style->scale != 1) { + if ((style->rotation != 0 && style->rotation != MS_PI * 2.) || + style->scale != 1) { mapserver::trans_affine image_mtx; - image_mtx *= mapserver::trans_affine_translation(-(pf.width()/2.),-(pf.height()/2.)); + image_mtx *= mapserver::trans_affine_translation(-(pf.width() / 2.), + -(pf.height() / 2.)); /*agg angles are antitrigonometric*/ image_mtx *= mapserver::trans_affine_rotation(-style->rotation); image_mtx *= mapserver::trans_affine_scaling(style->scale); - - - image_mtx *= mapserver::trans_affine_translation(x,y); + image_mtx *= mapserver::trans_affine_translation(x, y); image_mtx.invert(); typedef mapserver::span_interpolator_linear<> interpolator_type; interpolator_type interpolator(image_mtx); @@ -646,63 +668,72 @@ int agg2RenderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, // "hardcoded" bilinear filter //------------------------------------------ - typedef mapserver::span_image_filter_rgba_bilinear_clip span_gen_type; - span_gen_type sg(pf, mapserver::rgba(0,0,0,0), interpolator); + typedef mapserver::span_image_filter_rgba_bilinear_clip + span_gen_type; + span_gen_type sg(pf, mapserver::rgba(0, 0, 0, 0), interpolator); mapserver::path_storage pixmap_bbox; - int ims_2 = MS_NINT(MS_MAX(pixmap->width,pixmap->height)*style->scale*1.415)/2+1; + int ims_2 = + MS_NINT(MS_MAX(pixmap->width, pixmap->height) * style->scale * 1.415) / + 2 + + 1; - pixmap_bbox.move_to(x-ims_2,y-ims_2); - pixmap_bbox.line_to(x+ims_2,y-ims_2); - pixmap_bbox.line_to(x+ims_2,y+ims_2); - pixmap_bbox.line_to(x-ims_2,y+ims_2); + pixmap_bbox.move_to(x - ims_2, y - ims_2); + pixmap_bbox.line_to(x + ims_2, y - ims_2); + pixmap_bbox.line_to(x + ims_2, y + ims_2); + pixmap_bbox.line_to(x - ims_2, y + ims_2); r->m_rasterizer_aa.add_path(pixmap_bbox); - mapserver::render_scanlines_aa(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_base, sa, sg); + mapserver::render_scanlines_aa(r->m_rasterizer_aa, r->sl_poly, + r->m_renderer_base, sa, sg); } else { - //just copy the image at the correct location (we place the pixmap on - //the nearest integer pixel to avoid blurring) - r->m_renderer_base.blend_from(pf,0,MS_NINT(x-pixmap->width/2.),MS_NINT(y-pixmap->height/2.)); + // just copy the image at the correct location (we place the pixmap on + // the nearest integer pixel to avoid blurring) + r->m_renderer_base.blend_from(pf, 0, MS_NINT(x - pixmap->width / 2.), + MS_NINT(y - pixmap->height / 2.)); } return MS_SUCCESS; } int agg2RenderEllipseSymbol(imageObj *image, double x, double y, - symbolObj *symbol, symbolStyleObj * style) -{ + symbolObj *symbol, symbolStyleObj *style) { AGG2Renderer *r = AGG_RENDERER(image); mapserver::path_storage path; - mapserver::ellipse ellipse(x,y,symbol->sizex*style->scale/2,symbol->sizey*style->scale/2); + mapserver::ellipse ellipse(x, y, symbol->sizex * style->scale / 2, + symbol->sizey * style->scale / 2); path.concat_path(ellipse); - if( style->rotation != 0) { + if (style->rotation != 0) { mapserver::trans_affine mtx; - mtx *= mapserver::trans_affine_translation(-x,-y); + mtx *= mapserver::trans_affine_translation(-x, -y); /*agg angles are antitrigonometric*/ mtx *= mapserver::trans_affine_rotation(-style->rotation); - mtx *= mapserver::trans_affine_translation(x,y); + mtx *= mapserver::trans_affine_translation(x, y); path.transform(mtx); } - if(style->color) { + if (style->color) { r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd); r->m_rasterizer_aa.add_path(path); r->m_renderer_scanline.color(aggColor(style->color)); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, + r->m_renderer_scanline); } - if(style->outlinewidth) { + if (style->outlinewidth) { r->m_rasterizer_aa.reset(); r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero); mapserver::conv_stroke stroke(path); stroke.width(style->outlinewidth); r->m_rasterizer_aa.add_path(stroke); r->m_renderer_scanline.color(aggColor(style->outlinecolor)); - mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, + r->m_renderer_scanline); } return MS_SUCCESS; } -int agg2RenderTile(imageObj * /*img*/, imageObj * /*tile*/, double /*x*/, double /*y*/) -{ +int agg2RenderTile(imageObj * /*img*/, imageObj * /*tile*/, double /*x*/, + double /*y*/) { /* AGG2Renderer *imgRenderer = agg2GetRenderer(img); AGG2Renderer *tileRenderer = agg2GetRenderer(tile); @@ -710,30 +741,27 @@ int agg2RenderTile(imageObj * /*img*/, imageObj * /*tile*/, double /*x*/, double return MS_FAILURE; } -int aggInitializeRasterBuffer(rasterBufferObj *rb, int width, int height, int mode) -{ +int aggInitializeRasterBuffer(rasterBufferObj *rb, int width, int height, + int mode) { rb->type = MS_BUFFER_BYTE_RGBA; rb->data.rgba.pixel_step = 4; rb->data.rgba.row_step = rb->data.rgba.pixel_step * width; rb->width = width; rb->height = height; int nBytes = rb->data.rgba.row_step * height; - rb->data.rgba.pixels = (band_type*)msSmallCalloc(nBytes,sizeof(band_type)); + rb->data.rgba.pixels = (band_type *)msSmallCalloc(nBytes, sizeof(band_type)); rb->data.rgba.r = &(rb->data.rgba.pixels[band_order::R]); rb->data.rgba.g = &(rb->data.rgba.pixels[band_order::G]); rb->data.rgba.b = &(rb->data.rgba.pixels[band_order::B]); - if(mode == MS_IMAGEMODE_RGBA) { + if (mode == MS_IMAGEMODE_RGBA) { rb->data.rgba.a = &(rb->data.rgba.pixels[band_order::A]); } return MS_SUCCESS; } - - -int aggGetRasterBufferHandle(imageObj *img, rasterBufferObj * rb) -{ +int aggGetRasterBufferHandle(imageObj *img, rasterBufferObj *rb) { AGG2Renderer *r = AGG_RENDERER(img); - rb->type =MS_BUFFER_BYTE_RGBA; + rb->type = MS_BUFFER_BYTE_RGBA; rb->data.rgba.pixels = r->buffer.data(); rb->data.rgba.row_step = r->m_rendering_buffer.stride(); rb->data.rgba.pixel_step = 4; @@ -742,68 +770,72 @@ int aggGetRasterBufferHandle(imageObj *img, rasterBufferObj * rb) rb->data.rgba.r = &(r->buffer[band_order::R]); rb->data.rgba.g = &(r->buffer[band_order::G]); rb->data.rgba.b = &(r->buffer[band_order::B]); - if(r->use_alpha) + if (r->use_alpha) rb->data.rgba.a = &(r->buffer[band_order::A]); else rb->data.rgba.a = NULL; return MS_SUCCESS; } -int aggGetRasterBufferCopy(imageObj *img, rasterBufferObj *rb) -{ +int aggGetRasterBufferCopy(imageObj *img, rasterBufferObj *rb) { AGG2Renderer *r = AGG_RENDERER(img); aggInitializeRasterBuffer(rb, img->width, img->height, MS_IMAGEMODE_RGBA); - int nBytes = r->m_rendering_buffer.stride()*r->m_rendering_buffer.height(); - memcpy(rb->data.rgba.pixels,r->buffer.data(), nBytes); + int nBytes = r->m_rendering_buffer.stride() * r->m_rendering_buffer.height(); + memcpy(rb->data.rgba.pixels, r->buffer.data(), nBytes); return MS_SUCCESS; } - - -int agg2MergeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, double opacity, int srcX, int srcY, - int dstX, int dstY, int width, int height) -{ +int agg2MergeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, + double opacity, int srcX, int srcY, int dstX, + int dstY, int width, int height) { assert(overlay->type == MS_BUFFER_BYTE_RGBA); - rendering_buffer b(overlay->data.rgba.pixels, overlay->width, overlay->height, overlay->data.rgba.row_step); + rendering_buffer b(overlay->data.rgba.pixels, overlay->width, overlay->height, + overlay->data.rgba.row_step); pixel_format pf(b); AGG2Renderer *r = AGG_RENDERER(dest); - mapserver::rect_base src_rect(srcX,srcY,srcX+width,srcY+height); - r->m_renderer_base.blend_from(pf,&src_rect, dstX-srcX, dstY-srcY, unsigned(opacity * 255)); + mapserver::rect_base src_rect(srcX, srcY, srcX + width, srcY + height); + r->m_renderer_base.blend_from(pf, &src_rect, dstX - srcX, dstY - srcY, + unsigned(opacity * 255)); return MS_SUCCESS; } /* image i/o */ -imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorObj * bg) -{ +imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, + colorObj *bg) { imageObj *image = NULL; - if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode != MS_IMAGEMODE_RGBA) { + if (format->imagemode != MS_IMAGEMODE_RGB && + format->imagemode != MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, - "AGG2 driver only supports RGB or RGBA pixel models.", "agg2CreateImage()"); + "AGG2 driver only supports RGB or RGBA pixel models.", + "agg2CreateImage()"); return image; } if (width > 0 && height > 0) { - image = (imageObj *) calloc(1, sizeof (imageObj)); - MS_CHECK_ALLOC(image, sizeof (imageObj), NULL); + image = (imageObj *)calloc(1, sizeof(imageObj)); + MS_CHECK_ALLOC(image, sizeof(imageObj), NULL); AGG2Renderer *r = new AGG2Renderer(); - - /* Compute size on 64bit and check that it is compatible of the platform size_t */ + + /* Compute size on 64bit and check that it is compatible of the platform + * size_t */ AGG_INT64U bufSize64 = (AGG_INT64U)width * height * 4 * sizeof(band_type); size_t bufSize = (size_t)bufSize64; - if( (AGG_INT64U)bufSize != bufSize64 ) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating " AGG_INT64U_FRMT " bytes.\n", "agg2CreateImage()", - __FILE__, __LINE__, bufSize64); + if ((AGG_INT64U)bufSize != bufSize64) { + msSetError(MS_MEMERR, + "%s: %d: Out of memory allocating " AGG_INT64U_FRMT + " bytes.\n", + "agg2CreateImage()", __FILE__, __LINE__, bufSize64); free(image); delete r; return NULL; } - try - { + try { r->buffer.resize(bufSize / sizeof(band_type)); - } - catch( const std::bad_alloc& ) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating " AGG_INT64U_FRMT " bytes.\n", "agg2CreateImage()", - __FILE__, __LINE__, bufSize64); + } catch (const std::bad_alloc &) { + msSetError(MS_MEMERR, + "%s: %d: Out of memory allocating " AGG_INT64U_FRMT + " bytes.\n", + "agg2CreateImage()", __FILE__, __LINE__, bufSize64); free(image); delete r; return NULL; @@ -815,23 +847,23 @@ imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorO r->m_compop_renderer_base.attach(r->m_compop_pixel_format); r->m_renderer_scanline.attach(r->m_renderer_base); r->m_renderer_scanline_aliased.attach(r->m_renderer_base); - r->default_gamma = atof(msGetOutputFormatOption( format, "GAMMA", "0.75" )); - if(r->default_gamma <= 0.0 || r->default_gamma >= 1.0) { + r->default_gamma = atof(msGetOutputFormatOption(format, "GAMMA", "0.75")); + if (r->default_gamma <= 0.0 || r->default_gamma >= 1.0) { r->default_gamma = 0.75; } - r->gamma_function.set(0,r->default_gamma); + r->gamma_function.set(0, r->default_gamma); r->m_rasterizer_aa_gamma.gamma(r->gamma_function); - if( bg && !format->transparent ) + if (bg && !format->transparent) r->m_renderer_base.clear(aggColor(bg)); else r->m_renderer_base.clear(AGG_NO_COLOR); - if (!bg || format->transparent || format->imagemode == MS_IMAGEMODE_RGBA ) { + if (!bg || format->transparent || format->imagemode == MS_IMAGEMODE_RGBA) { r->use_alpha = true; } else { r->use_alpha = false; } - image->img.plugin = (void*) r; + image->img.plugin = (void *)r; } else { msSetError(MS_RENDERERERR, "Cannot create cairo image of size %dx%d.", "msImageCreateCairo()", width, height); @@ -840,200 +872,204 @@ imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorO return image; } -int agg2SaveImage(imageObj * /*img*/, mapObj* /*map*/, FILE * /*fp*/, outputFormatObj * /*format*/) -{ - +int agg2SaveImage(imageObj * /*img*/, mapObj * /*map*/, FILE * /*fp*/, + outputFormatObj * /*format*/) { return MS_FAILURE; } -int agg2StartNewLayer(imageObj *img, mapObj* /*map*/, layerObj *layer) -{ +int agg2StartNewLayer(imageObj *img, mapObj * /*map*/, layerObj *layer) { AGG2Renderer *r = AGG_RENDERER(img); - const char *sgamma = msLayerGetProcessingKey( layer, "GAMMA" ); + const char *sgamma = msLayerGetProcessingKey(layer, "GAMMA"); double gamma; - if(sgamma) { + if (sgamma) { gamma = atof(sgamma); - if(gamma <= 0 || gamma >= 1) gamma = 0.75; + if (gamma <= 0 || gamma >= 1) + gamma = 0.75; } else { gamma = r->default_gamma; } - if(r->gamma_function.end() != gamma) { + if (r->gamma_function.end() != gamma) { r->gamma_function.end(gamma); r->m_rasterizer_aa_gamma.gamma(r->gamma_function); } return MS_SUCCESS; } -int agg2CloseNewLayer(imageObj * /*img*/, mapObj * /*map*/, layerObj * /*layer*/) -{ +int agg2CloseNewLayer(imageObj * /*img*/, mapObj * /*map*/, + layerObj * /*layer*/) { return MS_SUCCESS; } -int agg2FreeImage(imageObj * image) -{ +int agg2FreeImage(imageObj *image) { AGG2Renderer *r = AGG_RENDERER(image); delete r; image->img.plugin = NULL; return MS_SUCCESS; } -int agg2FreeSymbol(symbolObj * /*symbol*/) -{ - return MS_SUCCESS; -} +int agg2FreeSymbol(symbolObj * /*symbol*/) { return MS_SUCCESS; } -int agg2InitCache(void **vcache) -{ +int agg2InitCache(void **vcache) { aggRendererCache *cache = new aggRendererCache(); - *vcache = (void*)cache; + *vcache = (void *)cache; return MS_SUCCESS; } -int agg2Cleanup(void *vcache) -{ - aggRendererCache *cache = (aggRendererCache*)vcache; +int agg2Cleanup(void *vcache) { + aggRendererCache *cache = (aggRendererCache *)vcache; delete cache; return MS_SUCCESS; } - // ------------------------------------------------------------------------ // Function to create a custom hatch symbol based on an arbitrary angle. // ------------------------------------------------------------------------ -static mapserver::path_storage createHatch(double ox, double oy, - double rx, double ry, - int sx, int sy, double angle, double step) -{ +static mapserver::path_storage createHatch(double ox, double oy, double rx, + double ry, int sx, int sy, + double angle, double step) { mapserver::path_storage path; - //restrict the angle to [0 180[, i.e ]-pi/2,pi/2] in radians + // restrict the angle to [0 180[, i.e ]-pi/2,pi/2] in radians angle = fmod(angle, 360.0); - if(angle < 0) angle += 360; - if(angle >= 180) angle -= 180; - - //treat 2 easy cases which would cause divide by 0 in generic case - if(angle==0) { - double y0 = step-fmod(oy-ry,step); - if((oy - ry) < 0) { + if (angle < 0) + angle += 360; + if (angle >= 180) + angle -= 180; + + // treat 2 easy cases which would cause divide by 0 in generic case + if (angle == 0) { + double y0 = step - fmod(oy - ry, step); + if ((oy - ry) < 0) { y0 -= step; } - for(double y=y0; y=0&&y<=sy) { - pt[2*inter]=x; - pt[2*inter+1]=y; + // parametrize each line as r = x.cos(theta) + y.sin(theta) + for (double r = r0; r < rmax; r += step) { + int inter = 0; + double x, y; + double pt[4]; // array to store the coordinates of intersection of the line + // with the sides + // in the general case there will only be two intersections + // so pt[4] should be sufficient to store the coordinates of the + // intersection, but we allocate pt[8] to treat the special and + // rare/unfortunate case when the line is a perfect diagonal (and therfore + // intersects all four sides) note that the order for testing is important + // in this case so that the first two intersection points actually + // correspond to the diagonal and not a degenerate line + + // test for intersection with each side + + y = r * invst; + x = 0; // test for intersection with left of image + if (y >= 0 && y <= sy) { + pt[2 * inter] = x; + pt[2 * inter + 1] = y; inter++; } - x=sx; - y=(r-sx*ct)*invst;// test for intersection with right of image - if(y>=0&&y<=sy) { - pt[2*inter]=x; - pt[2*inter+1]=y; + x = sx; + y = (r - sx * ct) * invst; // test for intersection with right of image + if (y >= 0 && y <= sy) { + pt[2 * inter] = x; + pt[2 * inter + 1] = y; inter++; } - if(inter<2) { - y=0; - x=r*invct;// test for intersection with top of image - if(x>=0&&x<=sx) { - pt[2*inter]=x; - pt[2*inter+1]=y; + if (inter < 2) { + y = 0; + x = r * invct; // test for intersection with top of image + if (x >= 0 && x <= sx) { + pt[2 * inter] = x; + pt[2 * inter + 1] = y; inter++; } } - if(inter<2) { - y=sy; - x=(r-sy*st)*invct;// test for intersection with bottom of image - if(x>=0&&x<=sx) { - pt[2*inter]=x; - pt[2*inter+1]=y; + if (inter < 2) { + y = sy; + x = (r - sy * st) * invct; // test for intersection with bottom of image + if (x >= 0 && x <= sx) { + pt[2 * inter] = x; + pt[2 * inter + 1] = y; inter++; } } - if(inter==2 && (pt[0]!=pt[2] || pt[1]!=pt[3])) { - //the line intersects with two sides of the image, it should therefore be drawn - if(angle<90) { - path.move_to(pt[0],pt[1]); - path.line_to(pt[2],pt[3]); + if (inter == 2 && (pt[0] != pt[2] || pt[1] != pt[3])) { + // the line intersects with two sides of the image, it should therefore be + // drawn + if (angle < 90) { + path.move_to(pt[0], pt[1]); + path.line_to(pt[2], pt[3]); } else { - path.move_to(pt[0],sy-pt[1]); - path.line_to(pt[2],sy-pt[3]); + path.move_to(pt[0], sy - pt[1]); + path.line_to(pt[2], sy - pt[3]); } } } return path; } -template int renderPolygonHatches(imageObj *img,VertexSource &clipper, colorObj *color) -{ - if(img->format->renderer == MS_RENDER_WITH_AGG) { +template +int renderPolygonHatches(imageObj *img, VertexSource &clipper, + colorObj *color) { + if (img->format->renderer == MS_RENDER_WITH_AGG) { AGG2Renderer *r = AGG_RENDERER(img); r->m_rasterizer_aa_gamma.reset(); r->m_rasterizer_aa_gamma.filling_rule(mapserver::fill_non_zero); r->m_rasterizer_aa_gamma.add_path(clipper); r->m_renderer_scanline.color(aggColor(color)); - mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, r->m_renderer_scanline); + mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, + r->m_renderer_scanline); } else { shapeObj shape; msInitShape(&shape); @@ -1041,37 +1077,40 @@ template int renderPolygonHatches(imageObj *img,VertexSource lineObj line; shape.line = &line; shape.numlines = 1; - shape.line[0].point = (pointObj*)msSmallCalloc(allocated,sizeof(pointObj)); + shape.line[0].point = + (pointObj *)msSmallCalloc(allocated, sizeof(pointObj)); shape.line[0].numpoints = 0; - double x=0,y=0; + double x = 0, y = 0; unsigned int cmd; clipper.rewind(0); - while((cmd = clipper.vertex(&x,&y)) != mapserver::path_cmd_stop) { - switch(cmd) { - case mapserver::path_cmd_line_to: - if(shape.line[0].numpoints == allocated) { - allocated *= 2; - shape.line[0].point = (pointObj*)msSmallRealloc(shape.line[0].point, allocated*sizeof(pointObj)); - } - shape.line[0].point[shape.line[0].numpoints].x = x; - shape.line[0].point[shape.line[0].numpoints].y = y; - shape.line[0].numpoints++; - break; - case mapserver::path_cmd_move_to: - shape.line[0].point[0].x = x; - shape.line[0].point[0].y = y; - shape.line[0].numpoints = 1; - break; - case mapserver::path_cmd_end_poly|mapserver::path_flags_close: - if(shape.line[0].numpoints > 2) { - if(MS_UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(img)->renderPolygon(img,&shape,color))) { - free(shape.line[0].point); - return MS_FAILURE; - } + while ((cmd = clipper.vertex(&x, &y)) != mapserver::path_cmd_stop) { + switch (cmd) { + case mapserver::path_cmd_line_to: + if (shape.line[0].numpoints == allocated) { + allocated *= 2; + shape.line[0].point = (pointObj *)msSmallRealloc( + shape.line[0].point, allocated * sizeof(pointObj)); + } + shape.line[0].point[shape.line[0].numpoints].x = x; + shape.line[0].point[shape.line[0].numpoints].y = y; + shape.line[0].numpoints++; + break; + case mapserver::path_cmd_move_to: + shape.line[0].point[0].x = x; + shape.line[0].point[0].y = y; + shape.line[0].numpoints = 1; + break; + case mapserver::path_cmd_end_poly | mapserver::path_flags_close: + if (shape.line[0].numpoints > 2) { + if (MS_UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(img)->renderPolygon( + img, &shape, color))) { + free(shape.line[0].point); + return MS_FAILURE; } - break; - default: - assert(0); //WTF? + } + break; + default: + assert(0); // WTF? } } free(shape.line[0].point); @@ -1079,8 +1118,9 @@ template int renderPolygonHatches(imageObj *img,VertexSource return MS_SUCCESS; } -int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width, double *pattern, int patternlength, double angle, colorObj *color) -{ +int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width, + double *pattern, int patternlength, double angle, + colorObj *color) { assert(MS_RENDERER_PLUGIN(img->format)); msComputeBounds(poly); @@ -1088,236 +1128,246 @@ int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width, double exp = width * 0.7072; /* width and height of the bounding box we will be creating the hatch in */ - int pw=(int)(poly->bounds.maxx-poly->bounds.minx+exp*2)+1; - int ph=(int)(poly->bounds.maxy-poly->bounds.miny+exp*2)+1; + int pw = (int)(poly->bounds.maxx - poly->bounds.minx + exp * 2) + 1; + int ph = (int)(poly->bounds.maxy - poly->bounds.miny + exp * 2) + 1; /* position of the top-left corner of the bounding box */ double ox = poly->bounds.minx - exp; double oy = poly->bounds.miny - exp; - //create a rectangular hatch of size pw,ph starting at 0,0 - //the created hatch is of the size of the shape's bounding box - mapserver::path_storage hatch = createHatch(ox,oy, - img->refpt.x,img->refpt.y,pw,ph,angle,spacing); - if(hatch.total_vertices()<=0) return MS_SUCCESS; + // create a rectangular hatch of size pw,ph starting at 0,0 + // the created hatch is of the size of the shape's bounding box + mapserver::path_storage hatch = + createHatch(ox, oy, img->refpt.x, img->refpt.y, pw, ph, angle, spacing); + if (hatch.total_vertices() <= 0) + return MS_SUCCESS; - //translate the hatch so it overlaps the current shape - hatch.transform(mapserver::trans_affine_translation(ox,oy)); + // translate the hatch so it overlaps the current shape + hatch.transform(mapserver::trans_affine_translation(ox, oy)); polygon_adaptor polygons(poly); - - - if(patternlength>1) { - //dash the color-hatch and render it clipped by the shape - mapserver::conv_dash dash(hatch); - mapserver::conv_stroke > stroke(dash); - for (int i=0; i 1) { + // dash the color-hatch and render it clipped by the shape + mapserver::conv_dash dash(hatch); + mapserver::conv_stroke> + stroke(dash); + for (int i = 0; i < patternlength; i += 2) { + if (i < patternlength - 1) { + dash.add_dash(pattern[i], pattern[i + 1]); } } stroke.width(width); stroke.line_cap(mapserver::butt_cap); - mapserver::conv_clipper > > clipper(polygons,stroke, mapserver::clipper_and); - renderPolygonHatches(img,clipper,color); + mapserver::conv_clipper< + polygon_adaptor, + mapserver::conv_stroke>> + clipper(polygons, stroke, mapserver::clipper_and); + renderPolygonHatches(img, clipper, color); } else { - //render the hatch clipped by the shape - mapserver::conv_stroke stroke(hatch); + // render the hatch clipped by the shape + mapserver::conv_stroke stroke(hatch); stroke.width(width); stroke.line_cap(mapserver::butt_cap); - mapserver::conv_clipper > clipper(polygons,stroke, mapserver::clipper_and); - renderPolygonHatches(img,clipper,color); + mapserver::conv_clipper> + clipper(polygons, stroke, mapserver::clipper_and); + renderPolygonHatches(img, clipper, color); } - - //assert(prevCmd == mapserver::path_cmd_line_to); - //delete lines; + // assert(prevCmd == mapserver::path_cmd_line_to); + // delete lines; return MS_SUCCESS; } #ifdef USE_PIXMAN static pixman_op_t ms2pixman_compop(CompositingOperation c) { - switch(c) { - case MS_COMPOP_CLEAR: - return PIXMAN_OP_CLEAR; - case MS_COMPOP_SRC: - return PIXMAN_OP_SRC; - case MS_COMPOP_DST: - return PIXMAN_OP_DST; - case MS_COMPOP_SRC_OVER: - return PIXMAN_OP_OVER; - case MS_COMPOP_DST_OVER: - return PIXMAN_OP_OVER_REVERSE; - case MS_COMPOP_SRC_IN: - return PIXMAN_OP_IN; - case MS_COMPOP_DST_IN: - return PIXMAN_OP_IN_REVERSE; - case MS_COMPOP_SRC_OUT: - return PIXMAN_OP_OUT; - case MS_COMPOP_DST_OUT: - return PIXMAN_OP_OUT_REVERSE; - case MS_COMPOP_SRC_ATOP: - return PIXMAN_OP_ATOP; - case MS_COMPOP_DST_ATOP: - return PIXMAN_OP_ATOP_REVERSE; - case MS_COMPOP_XOR: - return PIXMAN_OP_XOR; - case MS_COMPOP_PLUS: - return PIXMAN_OP_ADD; - case MS_COMPOP_MULTIPLY: - return PIXMAN_OP_MULTIPLY; - case MS_COMPOP_SCREEN: - return PIXMAN_OP_SCREEN; - case MS_COMPOP_OVERLAY: - return PIXMAN_OP_OVERLAY; - case MS_COMPOP_DARKEN: - return PIXMAN_OP_DARKEN; - case MS_COMPOP_LIGHTEN: - return PIXMAN_OP_LIGHTEN; - case MS_COMPOP_COLOR_DODGE: - return PIXMAN_OP_COLOR_DODGE; - case MS_COMPOP_COLOR_BURN: - return PIXMAN_OP_COLOR_DODGE; - case MS_COMPOP_HARD_LIGHT: - return PIXMAN_OP_HARD_LIGHT; - case MS_COMPOP_SOFT_LIGHT: - return PIXMAN_OP_SOFT_LIGHT; - case MS_COMPOP_DIFFERENCE: - return PIXMAN_OP_DIFFERENCE; - case MS_COMPOP_EXCLUSION: - return PIXMAN_OP_EXCLUSION; - case MS_COMPOP_INVERT: - case MS_COMPOP_INVERT_RGB: - case MS_COMPOP_MINUS: - case MS_COMPOP_CONTRAST: - default: - return PIXMAN_OP_OVER; + switch (c) { + case MS_COMPOP_CLEAR: + return PIXMAN_OP_CLEAR; + case MS_COMPOP_SRC: + return PIXMAN_OP_SRC; + case MS_COMPOP_DST: + return PIXMAN_OP_DST; + case MS_COMPOP_SRC_OVER: + return PIXMAN_OP_OVER; + case MS_COMPOP_DST_OVER: + return PIXMAN_OP_OVER_REVERSE; + case MS_COMPOP_SRC_IN: + return PIXMAN_OP_IN; + case MS_COMPOP_DST_IN: + return PIXMAN_OP_IN_REVERSE; + case MS_COMPOP_SRC_OUT: + return PIXMAN_OP_OUT; + case MS_COMPOP_DST_OUT: + return PIXMAN_OP_OUT_REVERSE; + case MS_COMPOP_SRC_ATOP: + return PIXMAN_OP_ATOP; + case MS_COMPOP_DST_ATOP: + return PIXMAN_OP_ATOP_REVERSE; + case MS_COMPOP_XOR: + return PIXMAN_OP_XOR; + case MS_COMPOP_PLUS: + return PIXMAN_OP_ADD; + case MS_COMPOP_MULTIPLY: + return PIXMAN_OP_MULTIPLY; + case MS_COMPOP_SCREEN: + return PIXMAN_OP_SCREEN; + case MS_COMPOP_OVERLAY: + return PIXMAN_OP_OVERLAY; + case MS_COMPOP_DARKEN: + return PIXMAN_OP_DARKEN; + case MS_COMPOP_LIGHTEN: + return PIXMAN_OP_LIGHTEN; + case MS_COMPOP_COLOR_DODGE: + return PIXMAN_OP_COLOR_DODGE; + case MS_COMPOP_COLOR_BURN: + return PIXMAN_OP_COLOR_DODGE; + case MS_COMPOP_HARD_LIGHT: + return PIXMAN_OP_HARD_LIGHT; + case MS_COMPOP_SOFT_LIGHT: + return PIXMAN_OP_SOFT_LIGHT; + case MS_COMPOP_DIFFERENCE: + return PIXMAN_OP_DIFFERENCE; + case MS_COMPOP_EXCLUSION: + return PIXMAN_OP_EXCLUSION; + case MS_COMPOP_INVERT: + case MS_COMPOP_INVERT_RGB: + case MS_COMPOP_MINUS: + case MS_COMPOP_CONTRAST: + default: + return PIXMAN_OP_OVER; } } #else static mapserver::comp_op_e ms2agg_compop(CompositingOperation c) { - switch(c) { - case MS_COMPOP_CLEAR: - return mapserver::comp_op_clear; - case MS_COMPOP_SRC: - return mapserver::comp_op_src; - case MS_COMPOP_DST: - return mapserver::comp_op_dst; - case MS_COMPOP_SRC_OVER: - return mapserver::comp_op_src_over; - case MS_COMPOP_DST_OVER: - return mapserver::comp_op_dst_over; - case MS_COMPOP_SRC_IN: - return mapserver::comp_op_src_in; - case MS_COMPOP_DST_IN: - return mapserver::comp_op_dst_in; - case MS_COMPOP_SRC_OUT: - return mapserver::comp_op_src_out; - case MS_COMPOP_DST_OUT: - return mapserver::comp_op_dst_out; - case MS_COMPOP_SRC_ATOP: - return mapserver::comp_op_src_atop; - case MS_COMPOP_DST_ATOP: - return mapserver::comp_op_dst_atop; - case MS_COMPOP_XOR: - return mapserver::comp_op_xor; - case MS_COMPOP_PLUS: - return mapserver::comp_op_plus; - case MS_COMPOP_MINUS: - return mapserver::comp_op_minus; - case MS_COMPOP_MULTIPLY: - return mapserver::comp_op_multiply; - case MS_COMPOP_SCREEN: - return mapserver::comp_op_screen; - case MS_COMPOP_OVERLAY: - return mapserver::comp_op_overlay; - case MS_COMPOP_DARKEN: - return mapserver::comp_op_darken; - case MS_COMPOP_LIGHTEN: - return mapserver::comp_op_lighten; - case MS_COMPOP_COLOR_DODGE: - return mapserver::comp_op_color_dodge; - case MS_COMPOP_COLOR_BURN: - return mapserver::comp_op_color_burn; - case MS_COMPOP_HARD_LIGHT: - return mapserver::comp_op_hard_light; - case MS_COMPOP_SOFT_LIGHT: - return mapserver::comp_op_soft_light; - case MS_COMPOP_DIFFERENCE: - return mapserver::comp_op_difference; - case MS_COMPOP_EXCLUSION: - return mapserver::comp_op_exclusion; - case MS_COMPOP_CONTRAST: - return mapserver::comp_op_contrast; - case MS_COMPOP_INVERT: - return mapserver::comp_op_invert; - case MS_COMPOP_INVERT_RGB: - return mapserver::comp_op_invert_rgb; - default: - return mapserver::comp_op_src_over; + switch (c) { + case MS_COMPOP_CLEAR: + return mapserver::comp_op_clear; + case MS_COMPOP_SRC: + return mapserver::comp_op_src; + case MS_COMPOP_DST: + return mapserver::comp_op_dst; + case MS_COMPOP_SRC_OVER: + return mapserver::comp_op_src_over; + case MS_COMPOP_DST_OVER: + return mapserver::comp_op_dst_over; + case MS_COMPOP_SRC_IN: + return mapserver::comp_op_src_in; + case MS_COMPOP_DST_IN: + return mapserver::comp_op_dst_in; + case MS_COMPOP_SRC_OUT: + return mapserver::comp_op_src_out; + case MS_COMPOP_DST_OUT: + return mapserver::comp_op_dst_out; + case MS_COMPOP_SRC_ATOP: + return mapserver::comp_op_src_atop; + case MS_COMPOP_DST_ATOP: + return mapserver::comp_op_dst_atop; + case MS_COMPOP_XOR: + return mapserver::comp_op_xor; + case MS_COMPOP_PLUS: + return mapserver::comp_op_plus; + case MS_COMPOP_MINUS: + return mapserver::comp_op_minus; + case MS_COMPOP_MULTIPLY: + return mapserver::comp_op_multiply; + case MS_COMPOP_SCREEN: + return mapserver::comp_op_screen; + case MS_COMPOP_OVERLAY: + return mapserver::comp_op_overlay; + case MS_COMPOP_DARKEN: + return mapserver::comp_op_darken; + case MS_COMPOP_LIGHTEN: + return mapserver::comp_op_lighten; + case MS_COMPOP_COLOR_DODGE: + return mapserver::comp_op_color_dodge; + case MS_COMPOP_COLOR_BURN: + return mapserver::comp_op_color_burn; + case MS_COMPOP_HARD_LIGHT: + return mapserver::comp_op_hard_light; + case MS_COMPOP_SOFT_LIGHT: + return mapserver::comp_op_soft_light; + case MS_COMPOP_DIFFERENCE: + return mapserver::comp_op_difference; + case MS_COMPOP_EXCLUSION: + return mapserver::comp_op_exclusion; + case MS_COMPOP_CONTRAST: + return mapserver::comp_op_contrast; + case MS_COMPOP_INVERT: + return mapserver::comp_op_invert; + case MS_COMPOP_INVERT_RGB: + return mapserver::comp_op_invert_rgb; + default: + return mapserver::comp_op_src_over; } } #endif -int aggCompositeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, CompositingOperation comp, int opacity) { +int aggCompositeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, + CompositingOperation comp, int opacity) { assert(overlay->type == MS_BUFFER_BYTE_RGBA); AGG2Renderer *r = AGG_RENDERER(dest); #ifdef USE_PIXMAN - pixman_image_t *si = pixman_image_create_bits(PIXMAN_a8r8g8b8,overlay->width,overlay->height, - (uint32_t*)overlay->data.rgba.pixels,overlay->data.rgba.row_step); - pixman_image_t *bi = pixman_image_create_bits(PIXMAN_a8r8g8b8,dest->width,dest->height, - reinterpret_cast(&(r->buffer[0])),dest->width*4); - pixman_image_t *alpha_mask_i=NULL, *alpha_mask_i_ptr; - pixman_image_set_filter(si,PIXMAN_FILTER_NEAREST, NULL, 0); + pixman_image_t *si = pixman_image_create_bits( + PIXMAN_a8r8g8b8, overlay->width, overlay->height, + (uint32_t *)overlay->data.rgba.pixels, overlay->data.rgba.row_step); + pixman_image_t *bi = pixman_image_create_bits( + PIXMAN_a8r8g8b8, dest->width, dest->height, + reinterpret_cast(&(r->buffer[0])), dest->width * 4); + pixman_image_t *alpha_mask_i = NULL, *alpha_mask_i_ptr; + pixman_image_set_filter(si, PIXMAN_FILTER_NEAREST, NULL, 0); unsigned char *alpha_mask = NULL; - if(opacity > 0) { - if(opacity == 100) { - alpha_mask_i_ptr = NULL; - } else { - unsigned char alpha = (unsigned char)(opacity * 2.55); - if(!alpha_mask_i) { - alpha_mask = (unsigned char*)msSmallMalloc(dest->width * dest->height); - alpha_mask_i = pixman_image_create_bits(PIXMAN_a8,dest->width,dest->height, - (uint32_t*)alpha_mask,dest->width); - } - memset(alpha_mask,alpha,dest->width*dest->height); - alpha_mask_i_ptr = alpha_mask_i; + if (opacity > 0) { + if (opacity == 100) { + alpha_mask_i_ptr = NULL; + } else { + unsigned char alpha = (unsigned char)(opacity * 2.55); + if (!alpha_mask_i) { + alpha_mask = (unsigned char *)msSmallMalloc(dest->width * dest->height); + alpha_mask_i = + pixman_image_create_bits(PIXMAN_a8, dest->width, dest->height, + (uint32_t *)alpha_mask, dest->width); } - pixman_image_composite (ms2pixman_compop(comp), si, alpha_mask_i_ptr, bi, - 0, 0, 0, 0, 0, 0, dest->width,dest->height); + memset(alpha_mask, alpha, dest->width * dest->height); + alpha_mask_i_ptr = alpha_mask_i; } + pixman_image_composite(ms2pixman_compop(comp), si, alpha_mask_i_ptr, bi, 0, + 0, 0, 0, 0, 0, dest->width, dest->height); + } pixman_image_unref(si); pixman_image_unref(bi); - if(alpha_mask_i) { + if (alpha_mask_i) { pixman_image_unref(alpha_mask_i); msFree(alpha_mask); } return MS_SUCCESS; #else - rendering_buffer b(overlay->data.rgba.pixels, overlay->width, overlay->height, overlay->data.rgba.row_step); + rendering_buffer b(overlay->data.rgba.pixels, overlay->width, overlay->height, + overlay->data.rgba.row_step); pixel_format pf(b); mapserver::comp_op_e comp_op = ms2agg_compop(comp); - if(comp_op == mapserver::comp_op_src_over) { - r->m_renderer_base.blend_from(pf,0,0,0,unsigned(opacity * 2.55)); + if (comp_op == mapserver::comp_op_src_over) { + r->m_renderer_base.blend_from(pf, 0, 0, 0, unsigned(opacity * 2.55)); } else { compop_pixel_format pixf(r->m_rendering_buffer); compop_renderer_base ren(pixf); pixf.comp_op(comp_op); - ren.blend_from(pf,0,0,0,unsigned(opacity * 2.55)); + ren.blend_from(pf, 0, 0, 0, unsigned(opacity * 2.55)); } return MS_SUCCESS; #endif } -void msApplyBlurringCompositingFilter(rasterBufferObj *rb, unsigned int radius) { - rendering_buffer b(rb->data.rgba.pixels, rb->width, rb->height, rb->data.rgba.row_step); +void msApplyBlurringCompositingFilter(rasterBufferObj *rb, + unsigned int radius) { + rendering_buffer b(rb->data.rgba.pixels, rb->width, rb->height, + rb->data.rgba.row_step); pixel_format pf(b); - mapserver::stack_blur_rgba32(pf,radius,radius); + mapserver::stack_blur_rgba32(pf, radius, radius); } -int msPopulateRendererVTableAGG(rendererVTableObj * renderer) -{ +int msPopulateRendererVTableAGG(rendererVTableObj *renderer) { renderer->compositeRasterBuffer = &aggCompositeRasterBuffer; renderer->supports_pixel_buffer = 1; renderer->use_imagecache = 0; diff --git a/mapagg.h b/mapagg.h index f2478df818..b968bd0dc0 100644 --- a/mapagg.h +++ b/mapagg.h @@ -34,29 +34,31 @@ * interface to a shapeObj representing lines, providing the functions * needed by the agg rasterizer. treats shapeObjs with multiple linestrings. */ -class line_adaptor -{ +class line_adaptor { public: - explicit line_adaptor(shapeObj *shape):s(shape) { - m_line=s->line; /*first line*/ - m_point=m_line->point; /*current vertex is first vertex of first line*/ - m_lend=&(s->line[s->numlines]); /*pointer to after last line*/ - m_pend=&(m_line->point[m_line->numpoints]); /*pointer to after last vertex of first line*/ + explicit line_adaptor(shapeObj *shape) : s(shape) { + m_line = s->line; /*first line*/ + m_point = m_line->point; /*current vertex is first vertex of first line*/ + m_lend = &(s->line[s->numlines]); /*pointer to after last line*/ + m_pend = &(m_line->point[m_line->numpoints]); /*pointer to after last vertex + of first line*/ } /* a class with virtual functions should also provide a virtual destructor */ virtual ~line_adaptor() {} void rewind(unsigned) { - m_line=s->line; /*first line*/ - m_point=m_line->point; /*current vertex is first vertex of first line*/ - m_pend=&(m_line->point[m_line->numpoints]); /*pointer to after last vertex of first line*/ + m_line = s->line; /*first line*/ + m_point = m_line->point; /*current vertex is first vertex of first line*/ + m_pend = &(m_line->point[m_line->numpoints]); /*pointer to after last vertex + of first line*/ } - virtual unsigned vertex(double* x, double* y) { - if(m_point < m_pend) { + virtual unsigned vertex(double *x, double *y) { + if (m_point < m_pend) { /*here we treat the case where a real vertex is returned*/ - bool first = m_point == m_line->point; /*is this the first vertex of a line*/ + bool first = + m_point == m_line->point; /*is this the first vertex of a line*/ *x = m_point->x; *y = m_point->y; m_point++; @@ -65,34 +67,35 @@ class line_adaptor /*if here, we're at the end of a line*/ m_line++; *x = *y = 0.0; - if(m_line>=m_lend) /*is this the last line of the shapObj. normally, - (m_line==m_lend) should be a sufficient test, as the caller should not call - this function if a previous call returned path_cmd_stop.*/ + if (m_line >= m_lend) /*is this the last line of the shapObj. normally, + (m_line==m_lend) should be a sufficient test, as the caller should + not call this function if a previous call returned path_cmd_stop.*/ return mapserver::path_cmd_stop; /*no more points to process*/ /*if here, there are more lines in the shapeObj, continue with next one*/ - m_point=m_line->point; /*pointer to first point of next line*/ - m_pend=&(m_line->point[m_line->numpoints]); /*pointer to after last point of next line*/ + m_point = m_line->point; /*pointer to first point of next line*/ + m_pend = &(m_line->point[m_line->numpoints]); /*pointer to after last point + of next line*/ - return vertex(x,y); /*this will return the first point of the next line*/ + return vertex(x, y); /*this will return the first point of the next line*/ } + protected: shapeObj *s; - lineObj *m_line, /*current line pointer*/ - *m_lend; /*points to after the last line*/ + lineObj *m_line, /*current line pointer*/ + *m_lend; /*points to after the last line*/ pointObj *m_point, /*current point*/ - *m_pend; /*points to after last point of current line*/ + *m_pend; /*points to after last point of current line*/ }; - -class polygon_adaptor -{ +class polygon_adaptor { public: - explicit polygon_adaptor(shapeObj *shape):s(shape) { - m_line=s->line; /*first lines*/ - m_point=m_line->point; /*first vertex of first line*/ - m_lend=&(s->line[s->numlines]); /*pointer to after last line*/ - m_pend=&(m_line->point[m_line->numpoints]); /*pointer to after last vertex of first line*/ + explicit polygon_adaptor(shapeObj *shape) : s(shape) { + m_line = s->line; /*first lines*/ + m_point = m_line->point; /*first vertex of first line*/ + m_lend = &(s->line[s->numlines]); /*pointer to after last line*/ + m_pend = &(m_line->point[m_line->numpoints]); /*pointer to after last vertex + of first line*/ } /* a class with virtual functions should also provide a virtual destructor */ @@ -100,14 +103,14 @@ class polygon_adaptor void rewind(unsigned) { /*reset pointers*/ - m_stop=false; - m_line=s->line; - m_point=m_line->point; - m_pend=&(m_line->point[m_line->numpoints]); + m_stop = false; + m_line = s->line; + m_point = m_line->point; + m_pend = &(m_line->point[m_line->numpoints]); } - virtual unsigned vertex(double* x, double* y) { - if(m_point < m_pend) { + virtual unsigned vertex(double *x, double *y) { + if (m_point < m_pend) { /*if here, we have a real vertex*/ bool first = m_point == m_line->point; *x = m_point->x; @@ -116,36 +119,38 @@ class polygon_adaptor return first ? mapserver::path_cmd_move_to : mapserver::path_cmd_line_to; } *x = *y = 0.0; - if(!m_stop) { + if (!m_stop) { /*if here, we're after the last vertex of the current line * we return the command to close the current polygon*/ m_line++; - if(m_line>=m_lend) { + if (m_line >= m_lend) { /*if here, we've finished all the vertexes of the shape. * we still return the command to close the current polygon, * but set m_stop so the subsequent call to vertex() will return * the stop command*/ - m_stop=true; + m_stop = true; return mapserver::path_cmd_end_poly; } - /*if here, there's another line in the shape, so we set the pointers accordingly - * and return the command to close the current polygon*/ - m_point=m_line->point; /*first vertex of next line*/ - m_pend=&(m_line->point[m_line->numpoints]); /*pointer to after last vertex of next line*/ + /*if here, there's another line in the shape, so we set the pointers + * accordingly and return the command to close the current polygon*/ + m_point = m_line->point; /*first vertex of next line*/ + m_pend = &(m_line->point[m_line->numpoints]); /*pointer to after last + vertex of next line*/ return mapserver::path_cmd_end_poly; } - /*if here, a previous call to vertex informed us that we'd consumed all the vertexes - * of the shape. return the command to stop processing this shape*/ + /*if here, a previous call to vertex informed us that we'd consumed all the + * vertexes of the shape. return the command to stop processing this shape*/ return mapserver::path_cmd_stop; } + protected: shapeObj *s; double ox = 0.0; double oy = 0.0; - lineObj *m_line, /*pointer to current line*/ - *m_lend; /*pointer to after last line of the shape*/ - pointObj *m_point, /*pointer to current vertex*/ - *m_pend; /*pointer to after last vertex of current line*/ + lineObj *m_line, /*pointer to current line*/ + *m_lend; /*pointer to after last line of the shape*/ + pointObj *m_point, /*pointer to current vertex*/ + *m_pend; /*pointer to after last vertex of current line*/ bool m_stop = false; /*should next call return stop command*/ }; diff --git a/mapaxisorder.h b/mapaxisorder.h index 97181de452..f3b3dd8aff 100644 --- a/mapaxisorder.h +++ b/mapaxisorder.h @@ -14,7 +14,7 @@ * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in + * The above copyright notice and this permission notice shall be included in * all copies of this Software or works derived from this Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS @@ -25,4116 +25,4115 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - + /* * Generated file * * This file was generated from by means of a script. Do not edit manually. */ - + #ifdef __cplusplus extern "C" { #endif - + static const unsigned char axisOrientationEpsgCodes[] = { - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, - 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0 -}; - + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 1 << 6 | 1 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 1 << 7 | 1 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0, + 0 << 7 | 0 << 6 | 0 << 5 | 0 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0}; + #ifdef __cplusplus } #endif diff --git a/mapbits.c b/mapbits.c index 50469ddf9d..42b4a5607c 100644 --- a/mapbits.c +++ b/mapbits.c @@ -32,8 +32,6 @@ #include "mapserver.h" - - #include /* @@ -41,24 +39,23 @@ * See function msGetNextBit for another hardcoded value. */ -/* #define msGetBit(array, index) (*((array) + (index)/MS_ARRAY_BIT) & ( 1 << ((index) % MS_ARRAY_BIT))) */ +/* #define msGetBit(array, index) (*((array) + (index)/MS_ARRAY_BIT) & ( 1 << + * ((index) % MS_ARRAY_BIT))) */ -size_t msGetBitArraySize(int numbits) -{ - return((numbits + MS_ARRAY_BIT - 1) / MS_ARRAY_BIT); +size_t msGetBitArraySize(int numbits) { + return ((numbits + MS_ARRAY_BIT - 1) / MS_ARRAY_BIT); } -ms_bitarray msAllocBitArray(int numbits) -{ - ms_bitarray array = calloc((numbits + MS_ARRAY_BIT - 1) / MS_ARRAY_BIT, MS_ARRAY_BIT); +ms_bitarray msAllocBitArray(int numbits) { + ms_bitarray array = + calloc((numbits + MS_ARRAY_BIT - 1) / MS_ARRAY_BIT, MS_ARRAY_BIT); - return(array); + return (array); } -int msGetBit(ms_const_bitarray array, int index) -{ +int msGetBit(ms_const_bitarray array, int index) { array += index / MS_ARRAY_BIT; - return (*array & (1U << (index % MS_ARRAY_BIT))) != 0; /* 0 or 1 */ + return (*array & (1U << (index % MS_ARRAY_BIT))) != 0; /* 0 or 1 */ } /* @@ -68,17 +65,16 @@ int msGetBit(ms_const_bitarray array, int index) ** If hits end of bitmap without finding set bit, will return -1. ** */ -int msGetNextBit(ms_const_bitarray array, int i, int size) -{ +int msGetNextBit(ms_const_bitarray array, int i, int size) { register ms_uint32 b; - while(i < size) { - b = *(array + (i/MS_ARRAY_BIT)); - if( b && (b >> (i % MS_ARRAY_BIT)) ) { + while (i < size) { + b = *(array + (i / MS_ARRAY_BIT)); + if (b && (b >> (i % MS_ARRAY_BIT))) { /* There is something in this byte */ /* And it is not to the right of us */ - if( b & ( 1U << (i % MS_ARRAY_BIT)) ) { + if (b & (1U << (i % MS_ARRAY_BIT))) { /* There is something at this bit! */ return i; } else { @@ -94,25 +90,22 @@ int msGetNextBit(ms_const_bitarray array, int i, int size) return -1; } -void msSetBit(ms_bitarray array, int index, int value) -{ +void msSetBit(ms_bitarray array, int index, int value) { array += index / MS_ARRAY_BIT; if (value) - *array |= 1U << (index % MS_ARRAY_BIT); /* set bit */ + *array |= 1U << (index % MS_ARRAY_BIT); /* set bit */ else - *array &= ~(1U << (index % MS_ARRAY_BIT)); /* clear bit */ + *array &= ~(1U << (index % MS_ARRAY_BIT)); /* clear bit */ } -void msSetAllBits(ms_bitarray array, int numbits, int value) -{ +void msSetAllBits(ms_bitarray array, int numbits, int value) { if (value) - memset(array, 0xff, ((numbits + 7) / 8) ); /* set bit */ + memset(array, 0xff, ((numbits + 7) / 8)); /* set bit */ else - memset(array, 0x0, ((numbits + 7) / 8) ); /* clear bit */ + memset(array, 0x0, ((numbits + 7) / 8)); /* clear bit */ } -void msFlipBit(ms_bitarray array, int index) -{ +void msFlipBit(ms_bitarray array, int index) { array += index / MS_ARRAY_BIT; - *array ^= 1U << (index % MS_ARRAY_BIT); /* flip bit */ + *array ^= 1U << (index % MS_ARRAY_BIT); /* flip bit */ } diff --git a/mapcairo.c b/mapcairo.c index aada546c63..05fb8dd069 100644 --- a/mapcairo.c +++ b/mapcairo.c @@ -44,14 +44,14 @@ #include #else #ifdef USE_RSVG - #include - #ifndef LIBRSVG_CHECK_VERSION - #include - #endif - #ifndef RSVG_CAIRO_H - #include - #endif - #include +#include +#ifndef LIBRSVG_CHECK_VERSION +#include +#endif +#ifndef RSVG_CAIRO_H +#include +#endif +#include #endif #endif @@ -61,7 +61,7 @@ #include "fontcache.h" -# include +#include /* #include #include @@ -93,46 +93,41 @@ typedef struct { cairo_t *dummycr; } cairoCacheData; -void initializeCache(void **vcache) -{ - cairoCacheData *cache = (cairoCacheData*)malloc(sizeof(cairoCacheData)); +void initializeCache(void **vcache) { + cairoCacheData *cache = (cairoCacheData *)malloc(sizeof(cairoCacheData)); *vcache = cache; cache->cairofacecache = NULL; /* dummy surface and context */ - cache->dummysurface = cairo_image_surface_create_for_data(cache->dummydata, CAIRO_FORMAT_ARGB32, 1,1,4); + cache->dummysurface = cairo_image_surface_create_for_data( + cache->dummydata, CAIRO_FORMAT_ARGB32, 1, 1, 4); cache->dummycr = cairo_create(cache->dummysurface); } -int cleanupCairo(void *cache) -{ - cairoCacheData *ccache = (cairoCacheData*)cache; +int cleanupCairo(void *cache) { + cairoCacheData *ccache = (cairoCacheData *)cache; - if(ccache->dummycr) { + if (ccache->dummycr) { cairo_destroy(ccache->dummycr); } - if(ccache->dummysurface) { + if (ccache->dummysurface) { cairo_surface_destroy(ccache->dummysurface); } - if(ccache->cairofacecache) { - cairoFaceCache *next,*cur; + if (ccache->cairofacecache) { + cairoFaceCache *next, *cur; cur = ccache->cairofacecache; do { next = cur->next; freeCairoFaceCache(cur); free(cur); - cur=next; - } while(cur); + cur = next; + } while (cur); } free(ccache); return MS_SUCCESS; } - - - - typedef struct { cairo_surface_t *surface; cairo_t *cr; @@ -140,18 +135,15 @@ typedef struct { int use_alpha; } cairo_renderer; +#define CAIRO_RENDERER(im) ((cairo_renderer *)(im->img.plugin)) -#define CAIRO_RENDERER(im) ((cairo_renderer*)(im->img.plugin)) - - -int freeImageCairo(imageObj *img) -{ +int freeImageCairo(imageObj *img) { cairo_renderer *r = CAIRO_RENDERER(img); - if(r) { + if (r) { cairo_destroy(r->cr); cairo_surface_finish(r->surface); cairo_surface_destroy(r->surface); - if(r->outputStream) { + if (r->outputStream) { msBufferFree(r->outputStream); free(r->outputStream); } @@ -160,10 +152,11 @@ int freeImageCairo(imageObj *img) return MS_SUCCESS; } -static cairoFaceCache* getCairoFontFace(cairoCacheData *cache, FT_Face ftface) { +static cairoFaceCache *getCairoFontFace(cairoCacheData *cache, FT_Face ftface) { cairoFaceCache *cur = cache->cairofacecache; - while(cur) { - if(cur->ftface == ftface) return cur; + while (cur) { + if (cur->ftface == ftface) + return cur; cur = cur->next; } cur = msSmallMalloc(sizeof(cairoFaceCache)); @@ -172,62 +165,64 @@ static cairoFaceCache* getCairoFontFace(cairoCacheData *cache, FT_Face ftface) { cur->ftface = ftface; cur->face = cairo_ft_font_face_create_for_ft_face(ftface, 0); cur->options = cairo_font_options_create(); - cairo_font_options_set_hint_style(cur->options,CAIRO_HINT_STYLE_NONE); + cairo_font_options_set_hint_style(cur->options, CAIRO_HINT_STYLE_NONE); return cur; } -#define msCairoSetSourceColor(cr, c) cairo_set_source_rgba((cr),(c)->red/255.0,(c)->green/255.0,(c)->blue/255.0,(c)->alpha/255.0); +#define msCairoSetSourceColor(cr, c) \ + cairo_set_source_rgba((cr), (c)->red / 255.0, (c)->green / 255.0, \ + (c)->blue / 255.0, (c)->alpha / 255.0); -int renderLineCairo(imageObj *img, shapeObj *p, strokeStyleObj *stroke) -{ - int i,j; +int renderLineCairo(imageObj *img, shapeObj *p, strokeStyleObj *stroke) { + int i, j; cairo_renderer *r = CAIRO_RENDERER(img); assert(stroke->color); cairo_new_path(r->cr); - msCairoSetSourceColor(r->cr,stroke->color); - for(i=0; inumlines; i++) { + msCairoSetSourceColor(r->cr, stroke->color); + for (i = 0; i < p->numlines; i++) { lineObj *l = &(p->line[i]); - if(l->numpoints == 0) continue; - cairo_move_to(r->cr,l->point[0].x,l->point[0].y); - for(j=1; jnumpoints; j++) { - cairo_line_to(r->cr,l->point[j].x,l->point[j].y); + if (l->numpoints == 0) + continue; + cairo_move_to(r->cr, l->point[0].x, l->point[0].y); + for (j = 1; j < l->numpoints; j++) { + cairo_line_to(r->cr, l->point[j].x, l->point[j].y); } } - if(stroke->patternlength>0) { - cairo_set_dash(r->cr,stroke->pattern,stroke->patternlength,-stroke->patternoffset); + if (stroke->patternlength > 0) { + cairo_set_dash(r->cr, stroke->pattern, stroke->patternlength, + -stroke->patternoffset); } - switch(stroke->linecap) { - case MS_CJC_BUTT: - cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_BUTT); - break; - case MS_CJC_SQUARE: - cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_SQUARE); - break; - case MS_CJC_ROUND: - case MS_CJC_NONE: - default: - cairo_set_line_cap(r->cr,CAIRO_LINE_CAP_ROUND); + switch (stroke->linecap) { + case MS_CJC_BUTT: + cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_BUTT); + break; + case MS_CJC_SQUARE: + cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_SQUARE); + break; + case MS_CJC_ROUND: + case MS_CJC_NONE: + default: + cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_ROUND); } - cairo_set_line_width (r->cr, stroke->width); - cairo_stroke (r->cr); - if(stroke->patternlength>0) { - cairo_set_dash(r->cr,stroke->pattern,0,0); + cairo_set_line_width(r->cr, stroke->width); + cairo_stroke(r->cr); + if (stroke->patternlength > 0) { + cairo_set_dash(r->cr, stroke->pattern, 0, 0); } return MS_SUCCESS; } -int renderPolygonCairo(imageObj *img, shapeObj *p, colorObj *c) -{ +int renderPolygonCairo(imageObj *img, shapeObj *p, colorObj *c) { cairo_renderer *r = CAIRO_RENDERER(img); - int i,j; + int i, j; cairo_new_path(r->cr); - cairo_set_fill_rule(r->cr,CAIRO_FILL_RULE_EVEN_ODD); - msCairoSetSourceColor(r->cr,c); - for(i=0; inumlines; i++) { + cairo_set_fill_rule(r->cr, CAIRO_FILL_RULE_EVEN_ODD); + msCairoSetSourceColor(r->cr, c); + for (i = 0; i < p->numlines; i++) { lineObj *l = &(p->line[i]); - cairo_move_to(r->cr,l->point[0].x,l->point[0].y); - for(j=1; jnumpoints; j++) { - cairo_line_to(r->cr,l->point[j].x,l->point[j].y); + cairo_move_to(r->cr, l->point[0].x, l->point[0].y); + for (j = 1; j < l->numpoints; j++) { + cairo_line_to(r->cr, l->point[j].x, l->point[j].y); } cairo_close_path(r->cr); } @@ -235,12 +230,12 @@ int renderPolygonCairo(imageObj *img, shapeObj *p, colorObj *c) return MS_SUCCESS; } -int renderPolygonTiledCairo(imageObj *img, shapeObj *p, imageObj *tile) -{ - int i,j; +int renderPolygonTiledCairo(imageObj *img, shapeObj *p, imageObj *tile) { + int i, j; cairo_renderer *r = CAIRO_RENDERER(img); cairo_renderer *tileRenderer = CAIRO_RENDERER(tile); - cairo_pattern_t *pattern = cairo_pattern_create_for_surface(tileRenderer->surface); + cairo_pattern_t *pattern = + cairo_pattern_create_for_surface(tileRenderer->surface); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_set_source(r->cr, pattern); @@ -257,76 +252,72 @@ int renderPolygonTiledCairo(imageObj *img, shapeObj *p, imageObj *tile) return MS_SUCCESS; } -cairo_surface_t *createSurfaceFromBuffer(rasterBufferObj *b) -{ +cairo_surface_t *createSurfaceFromBuffer(rasterBufferObj *b) { assert(b->type == MS_BUFFER_BYTE_RGBA); - return cairo_image_surface_create_for_data (b->data.rgba.pixels, - CAIRO_FORMAT_ARGB32, - b->width, - b->height, - b->data.rgba.row_step); + return cairo_image_surface_create_for_data(b->data.rgba.pixels, + CAIRO_FORMAT_ARGB32, b->width, + b->height, b->data.rgba.row_step); } - -int renderPixmapSymbolCairo(imageObj *img, double x, double y,symbolObj *symbol, - symbolStyleObj *style) -{ +int renderPixmapSymbolCairo(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { cairo_renderer *r = CAIRO_RENDERER(img); cairo_surface_t *im; rasterBufferObj *b = symbol->pixmap_buffer; assert(b); - if(!symbol->renderer_cache) { - symbol->renderer_cache = (void*)createSurfaceFromBuffer(b); + if (!symbol->renderer_cache) { + symbol->renderer_cache = (void *)createSurfaceFromBuffer(b); } assert(symbol->renderer_cache); - im=(cairo_surface_t*)symbol->renderer_cache; + im = (cairo_surface_t *)symbol->renderer_cache; cairo_save(r->cr); - if(style->rotation != 0 || style->scale != 1) { - cairo_translate (r->cr, x,y); - cairo_rotate (r->cr, -style->rotation); - cairo_scale (r->cr, style->scale,style->scale); - cairo_translate (r->cr, -0.5*b->width, -0.5*b->height); + if (style->rotation != 0 || style->scale != 1) { + cairo_translate(r->cr, x, y); + cairo_rotate(r->cr, -style->rotation); + cairo_scale(r->cr, style->scale, style->scale); + cairo_translate(r->cr, -0.5 * b->width, -0.5 * b->height); } else { - cairo_translate (r->cr, MS_NINT(x-0.5*b->width),MS_NINT(y-0.5*b->height)); + cairo_translate(r->cr, MS_NINT(x - 0.5 * b->width), + MS_NINT(y - 0.5 * b->height)); } - cairo_set_source_surface (r->cr, im, 0, 0); - cairo_paint (r->cr); + cairo_set_source_surface(r->cr, im, 0, 0); + cairo_paint(r->cr); cairo_restore(r->cr); return MS_SUCCESS; } -int renderVectorSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +int renderVectorSymbolCairo(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { cairo_renderer *r = CAIRO_RENDERER(img); - double ox=symbol->sizex*0.5,oy=symbol->sizey*0.5; - int is_new = 1,i; + double ox = symbol->sizex * 0.5, oy = symbol->sizey * 0.5; + int is_new = 1, i; cairo_new_path(r->cr); cairo_save(r->cr); - cairo_translate(r->cr,x,y); - cairo_scale(r->cr,style->scale,style->scale); - cairo_rotate(r->cr,-style->rotation); - cairo_translate(r->cr,-ox,-oy); + cairo_translate(r->cr, x, y); + cairo_scale(r->cr, style->scale, style->scale); + cairo_rotate(r->cr, -style->rotation); + cairo_translate(r->cr, -ox, -oy); for (i = 0; i < symbol->numpoints; i++) { - if ((symbol->points[i].x == -99) && (symbol->points[i].y == -99)) { /* (PENUP) */ + if ((symbol->points[i].x == -99) && + (symbol->points[i].y == -99)) { /* (PENUP) */ is_new = 1; } else { if (is_new) { - cairo_move_to(r->cr,symbol->points[i].x,symbol->points[i].y); + cairo_move_to(r->cr, symbol->points[i].x, symbol->points[i].y); is_new = 0; } else { - cairo_line_to(r->cr,symbol->points[i].x,symbol->points[i].y); + cairo_line_to(r->cr, symbol->points[i].x, symbol->points[i].y); } } } cairo_restore(r->cr); - if(style->color) { - msCairoSetSourceColor(r->cr,style->color); + if (style->color) { + msCairoSetSourceColor(r->cr, style->color); cairo_fill_preserve(r->cr); } - if(style->outlinewidth>0) { - msCairoSetSourceColor(r->cr,style->outlinecolor); - cairo_set_line_width (r->cr, style->outlinewidth); + if (style->outlinewidth > 0) { + msCairoSetSourceColor(r->cr, style->outlinecolor); + cairo_set_line_width(r->cr, style->outlinewidth); cairo_stroke_preserve(r->cr); } cairo_new_path(r->cr); @@ -341,38 +332,37 @@ struct svg_symbol_cache { #else svg_cairo_t *svgc; #endif - double scale,rotation; -} ; + double scale, rotation; +}; #endif int renderSVGSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ + symbolStyleObj *style) { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) struct svg_symbol_cache *cache; cairo_renderer *r = CAIRO_RENDERER(img); - - msPreloadSVGSymbol(symbol); assert(symbol->renderer_cache); cache = symbol->renderer_cache; cairo_save(r->cr); - cairo_translate(r->cr,x,y); - cairo_scale(r->cr,style->scale,style->scale); + cairo_translate(r->cr, x, y); + cairo_scale(r->cr, style->scale, style->scale); if (style->rotation != 0) { cairo_rotate(r->cr, -style->rotation); - cairo_translate (r->cr, -(int)(symbol->sizex/2), -(int)(symbol->sizey/2)); + cairo_translate(r->cr, -(int)(symbol->sizex / 2), + -(int)(symbol->sizey / 2)); } else - cairo_translate (r->cr, -(int)(symbol->sizex/2), -(int)(symbol->sizey/2)); + cairo_translate(r->cr, -(int)(symbol->sizex / 2), + -(int)(symbol->sizey / 2)); #ifdef USE_SVG_CAIRO { svg_cairo_status_t status; status = svg_cairo_render(cache->svgc, r->cr); - if(status != SVG_CAIRO_STATUS_SUCCESS) { + if (status != SVG_CAIRO_STATUS_SUCCESS) { cairo_restore(r->cr); return MS_FAILURE; } @@ -385,30 +375,30 @@ int renderSVGSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, return MS_SUCCESS; - #else - msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", + msSetError(MS_MISCERR, + "SVG Symbols requested but is not built with libsvgcairo", "renderSVGSymbolCairo()"); return MS_FAILURE; #endif } -int renderTileCairo(imageObj *img, imageObj *tile, double x, double y) -{ +int renderTileCairo(imageObj *img, imageObj *tile, double x, double y) { cairo_renderer *r = CAIRO_RENDERER(img); cairo_surface_t *im = CAIRO_RENDERER(tile)->surface; - int w = cairo_image_surface_get_width (im); - int h = cairo_image_surface_get_height (im); + int w = cairo_image_surface_get_width(im); + int h = cairo_image_surface_get_height(im); cairo_save(r->cr); - cairo_translate(r->cr, MS_NINT(x-0.5 * w), MS_NINT(y -0.5 * h)); + cairo_translate(r->cr, MS_NINT(x - 0.5 * w), MS_NINT(y - 0.5 * h)); cairo_set_source_surface(r->cr, im, 0, 0); - cairo_pattern_set_filter (cairo_get_source (r->cr), CAIRO_FILTER_NEAREST); + cairo_pattern_set_filter(cairo_get_source(r->cr), CAIRO_FILTER_NEAREST); cairo_paint(r->cr); cairo_restore(r->cr); return MS_SUCCESS; } -int renderGlyphs2Cairo(imageObj *img, const textSymbolObj *ts, colorObj *c, colorObj *oc, int ow, int isMarker) { +int renderGlyphs2Cairo(imageObj *img, const textSymbolObj *ts, colorObj *c, + colorObj *oc, int ow, int isMarker) { const textPathObj *tp = ts->textpath; cairo_renderer *r = CAIRO_RENDERER(img); cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img); @@ -417,25 +407,25 @@ int renderGlyphs2Cairo(imageObj *img, const textSymbolObj *ts, colorObj *c, colo int g; (void)isMarker; - cairo_set_font_size(r->cr,MS_NINT(tp->glyph_size * 96.0/72.0)); - for(g=0;gnumglyphs;g++) { + cairo_set_font_size(r->cr, MS_NINT(tp->glyph_size * 96.0 / 72.0)); + for (g = 0; g < tp->numglyphs; g++) { glyphObj *gl = &tp->glyphs[g]; cairo_glyph_t glyph; /* load the glyph's face into cairo, if not already present */ - if(gl->face->face != prevface) { - cairo_face = getCairoFontFace(cache,gl->face->face); + if (gl->face->face != prevface) { + cairo_face = getCairoFontFace(cache, gl->face->face); cairo_set_font_face(r->cr, cairo_face->face); - cairo_set_font_options(r->cr,cairo_face->options); + cairo_set_font_options(r->cr, cairo_face->options); prevface = gl->face->face; - cairo_set_font_size(r->cr,MS_NINT(tp->glyph_size * 96.0/72.0)); + cairo_set_font_size(r->cr, MS_NINT(tp->glyph_size * 96.0 / 72.0)); } cairo_save(r->cr); - cairo_translate(r->cr,gl->pnt.x,gl->pnt.y); - if(gl->rot != 0.0) + cairo_translate(r->cr, gl->pnt.x, gl->pnt.y); + if (gl->rot != 0.0) cairo_rotate(r->cr, -gl->rot); glyph.x = glyph.y = 0; glyph.index = gl->glyph->key.codepoint; - cairo_glyph_path(r->cr,&glyph,1); + cairo_glyph_path(r->cr, &glyph, 1); cairo_restore(r->cr); } if (oc) { @@ -445,7 +435,7 @@ int renderGlyphs2Cairo(imageObj *img, const textSymbolObj *ts, colorObj *c, colo cairo_stroke_preserve(r->cr); cairo_restore(r->cr); } - if(c) { + if (c) { msCairoSetSourceColor(r->cr, c); cairo_fill(r->cr); } @@ -453,85 +443,88 @@ int renderGlyphs2Cairo(imageObj *img, const textSymbolObj *ts, colorObj *c, colo return MS_SUCCESS; } -cairo_status_t _stream_write_fn(void *b, const unsigned char *data, unsigned int length) -{ - msBufferAppend((bufferObj*)b,(void*)data,length); +cairo_status_t _stream_write_fn(void *b, const unsigned char *data, + unsigned int length) { + msBufferAppend((bufferObj *)b, (void *)data, length); return CAIRO_STATUS_SUCCESS; } -imageObj* createImageCairo(int width, int height, outputFormatObj *format,colorObj* bg) -{ +imageObj *createImageCairo(int width, int height, outputFormatObj *format, + colorObj *bg) { imageObj *image = NULL; - cairo_renderer *r=NULL; - if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode!= MS_IMAGEMODE_RGBA) { + cairo_renderer *r = NULL; + if (format->imagemode != MS_IMAGEMODE_RGB && + format->imagemode != MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, - "Cairo driver only supports RGB or RGBA pixel models.","msImageCreateCairo()"); + "Cairo driver only supports RGB or RGBA pixel models.", + "msImageCreateCairo()"); return image; } if (width > 0 && height > 0) { - image = (imageObj *) calloc(1, sizeof(imageObj)); - r = (cairo_renderer*)calloc(1,sizeof(cairo_renderer)); - if(!strcasecmp(format->driver,"cairo/pdf")) { - r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); + image = (imageObj *)calloc(1, sizeof(imageObj)); + r = (cairo_renderer *)calloc(1, sizeof(cairo_renderer)); + if (!strcasecmp(format->driver, "cairo/pdf")) { + r->outputStream = (bufferObj *)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_pdf_surface_create_for_stream( - _stream_write_fn, - r->outputStream, - width,height); -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,15,10) + _stream_write_fn, r->outputStream, width, height); +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) { - const char *msPDFCreationDate = CPLGetConfigOption("MS_PDF_CREATION_DATE", NULL); - if( msPDFCreationDate ) - { - cairo_pdf_surface_set_metadata (r->surface, - CAIRO_PDF_METADATA_CREATE_DATE, - msPDFCreationDate); - } + const char *msPDFCreationDate = + CPLGetConfigOption("MS_PDF_CREATION_DATE", NULL); + if (msPDFCreationDate) { + cairo_pdf_surface_set_metadata( + r->surface, CAIRO_PDF_METADATA_CREATE_DATE, msPDFCreationDate); + } } #endif - } else if(!strcasecmp(format->driver,"cairo/svg")) { - r->outputStream = (bufferObj*)malloc(sizeof(bufferObj)); + } else if (!strcasecmp(format->driver, "cairo/svg")) { + r->outputStream = (bufferObj *)malloc(sizeof(bufferObj)); msBufferInit(r->outputStream); r->surface = cairo_svg_surface_create_for_stream( - _stream_write_fn, - r->outputStream, - width,height); - } else if(!strcasecmp(format->driver,"cairo/winGDI") && format->device) { + _stream_write_fn, r->outputStream, width, height); + } else if (!strcasecmp(format->driver, "cairo/winGDI") && format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_surface_create(format->device); #else - msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", + msSetError(MS_RENDERERERR, + "Cannot create cairo image. Cairo was not compiled with " + "support for the win32 backend.", "msImageCreateCairo()"); #endif - } else if(!strcasecmp(format->driver,"cairo/winGDIPrint") && format->device) { + } else if (!strcasecmp(format->driver, "cairo/winGDIPrint") && + format->device) { #if CAIRO_HAS_WIN32_SURFACE r->outputStream = NULL; r->surface = cairo_win32_printing_surface_create(format->device); #else - msSetError(MS_RENDERERERR, "Cannot create cairo image. Cairo was not compiled with support for the win32 backend.", + msSetError(MS_RENDERERERR, + "Cannot create cairo image. Cairo was not compiled with " + "support for the win32 backend.", "msImageCreateCairo()"); #endif } else { r->outputStream = NULL; - r->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + r->surface = + cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); } r->cr = cairo_create(r->surface); - if(format->transparent || !bg || !MS_VALID_COLOR(*bg)) { + if (format->transparent || !bg || !MS_VALID_COLOR(*bg)) { r->use_alpha = 1; - cairo_set_source_rgba (r->cr, 0,0,0,0); + cairo_set_source_rgba(r->cr, 0, 0, 0, 0); } else { r->use_alpha = 0; - msCairoSetSourceColor(r->cr,bg); + msCairoSetSourceColor(r->cr, bg); } - cairo_save (r->cr); - cairo_set_operator (r->cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (r->cr); - cairo_restore (r->cr); - - cairo_set_line_cap (r->cr,CAIRO_LINE_CAP_ROUND); - cairo_set_line_join(r->cr,CAIRO_LINE_JOIN_ROUND); - image->img.plugin = (void*)r; + cairo_save(r->cr); + cairo_set_operator(r->cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(r->cr); + cairo_restore(r->cr); + + cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(r->cr, CAIRO_LINE_JOIN_ROUND); + image->img.plugin = (void *)r; } else { msSetError(MS_RENDERERERR, "Cannot create cairo image of size %dx%d.", "msImageCreateCairo()", width, height); @@ -539,23 +532,27 @@ imageObj* createImageCairo(int width, int height, outputFormatObj *format,colorO return image; } -/* msSaveImagePostPDFProcessing() will call the GDAL PDF driver to add geospatial */ -/* information to the regular PDF generated by cairo. This is only triggered if the */ -/* GEO_ENCODING outputformat option is set (to ISO32000 or OGC_BP). Additionnal */ +/* msSaveImagePostPDFProcessing() will call the GDAL PDF driver to add + * geospatial */ +/* information to the regular PDF generated by cairo. This is only triggered if + * the */ +/* GEO_ENCODING outputformat option is set (to ISO32000 or OGC_BP). Additionnal + */ /* options can be provided by specifying outputformat options starting with */ /* METADATA_ITEM: prefix. For example METADATA_ITEM:PRODUCER=MapServer */ -/* Those options are AUTHOR, CREATOR, CREATION_DATE, KEYWORDS, PRODUCER, SUBJECT, TITLE */ +/* Those options are AUTHOR, CREATOR, CREATION_DATE, KEYWORDS, PRODUCER, + * SUBJECT, TITLE */ /* See http://gdal.org/frmt_pdf.html documentation. */ -static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) -{ +static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, + cairo_renderer *r) { GDALDatasetH hDS = NULL; - const char* pszGEO_ENCODING = NULL; + const char *pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; - const char* pszVirtualIO = NULL; + const char *pszVirtualIO = NULL; int bVirtualIO = FALSE; - char* pszTmpFilename = NULL; - VSILFILE* fp = NULL; + char *pszTmpFilename = NULL; + VSILFILE *fp = NULL; if (map == NULL) return; @@ -572,7 +569,7 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ - pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); + pszVirtualIO = GDALGetMetadataItem(hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); @@ -592,20 +589,19 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); - if ( hDS != NULL ) { - char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); - if( pszWKT != NULL ) { + if (hDS != NULL) { + char *pszWKT = msProjectionObj2OGCWKT(&(map->projection)); + if (pszWKT != NULL) { double adfGeoTransform[6]; int i; /* Add user-specified options */ - for( i = 0; i < img->format->numformatoptions; i++ ) { - const char* pszOption = img->format->formatoptions[i]; - if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { - char* pszKey = NULL; - const char* pszValue = CPLParseNameValue(pszOption + 14, - &pszKey); - if( pszKey != NULL ) { + for (i = 0; i < img->format->numformatoptions; i++) { + const char *pszOption = img->format->formatoptions[i]; + if (strncasecmp(pszOption, "METADATA_ITEM:", 14) == 0) { + char *pszKey = NULL; + const char *pszValue = CPLParseNameValue(pszOption + 14, &pszKey); + if (pszKey != NULL) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } @@ -615,12 +611,14 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); - adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); - adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); + adfGeoTransform[1] = + adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); + adfGeoTransform[5] = + adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); - msFree( pszWKT ); + msFree(pszWKT); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); @@ -632,7 +630,7 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); - if( fp != NULL ) { + if (fp != NULL) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); @@ -641,7 +639,8 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); - r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp); + r->outputStream->size = + VSIFReadL(r->outputStream->data, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; @@ -649,7 +648,7 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere } } - if ( hDS != NULL ) + if (hDS != NULL) GDALClose(hDS); VSIUnlink(pszTmpFilename); @@ -657,55 +656,57 @@ static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_rendere msFree(pszTmpFilename); } -int saveImageCairo(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *format_unused) -{ +int saveImageCairo(imageObj *img, mapObj *map, FILE *fp, + outputFormatObj *format_unused) { (void)format_unused; cairo_renderer *r = CAIRO_RENDERER(img); - if(!strcasecmp(img->format->driver,"cairo/pdf") || !strcasecmp(img->format->driver,"cairo/svg")) { - cairo_surface_finish (r->surface); + if (!strcasecmp(img->format->driver, "cairo/pdf") || + !strcasecmp(img->format->driver, "cairo/svg")) { + cairo_surface_finish(r->surface); - if (map != NULL && !strcasecmp(img->format->driver,"cairo/pdf")) + if (map != NULL && !strcasecmp(img->format->driver, "cairo/pdf")) msTransformToGeospatialPDF(img, map, r); - msIO_fwrite(r->outputStream->data,r->outputStream->size,1,fp); + msIO_fwrite(r->outputStream->data, r->outputStream->size, 1, fp); } else { /* not supported */ } return MS_SUCCESS; } -unsigned char* saveImageBufferCairo(imageObj *img, int *size_ptr, outputFormatObj *format_unused) -{ +unsigned char *saveImageBufferCairo(imageObj *img, int *size_ptr, + outputFormatObj *format_unused) { (void)format_unused; cairo_renderer *r = CAIRO_RENDERER(img); unsigned char *data; - assert(!strcasecmp(img->format->driver,"cairo/pdf") || !strcasecmp(img->format->driver,"cairo/svg")); - cairo_surface_finish (r->surface); + assert(!strcasecmp(img->format->driver, "cairo/pdf") || + !strcasecmp(img->format->driver, "cairo/svg")); + cairo_surface_finish(r->surface); data = msSmallMalloc(r->outputStream->size); - memcpy(data,r->outputStream->data,r->outputStream->size); + memcpy(data, r->outputStream->data, r->outputStream->size); *size_ptr = (int)r->outputStream->size; return data; } -int renderEllipseSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +int renderEllipseSymbolCairo(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { cairo_renderer *r = CAIRO_RENDERER(img); cairo_save(r->cr); cairo_set_line_cap(r->cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(r->cr, CAIRO_LINE_JOIN_MITER); - cairo_translate(r->cr,x,y); - cairo_rotate(r->cr,-style->rotation); - cairo_scale(r->cr,symbol->sizex*style->scale/2,symbol->sizey*style->scale/2); - cairo_arc (r->cr, 0,0,1, 0, 2 * MS_PI); + cairo_translate(r->cr, x, y); + cairo_rotate(r->cr, -style->rotation); + cairo_scale(r->cr, symbol->sizex * style->scale / 2, + symbol->sizey * style->scale / 2); + cairo_arc(r->cr, 0, 0, 1, 0, 2 * MS_PI); cairo_restore(r->cr); - if(style->color) { + if (style->color) { msCairoSetSourceColor(r->cr, style->color); cairo_fill_preserve(r->cr); } - if(style->outlinewidth > 0) { - cairo_set_line_width (r->cr, style->outlinewidth); + if (style->outlinewidth > 0) { + cairo_set_line_width(r->cr, style->outlinewidth); msCairoSetSourceColor(r->cr, style->outlinecolor); cairo_stroke_preserve(r->cr); } @@ -713,83 +714,76 @@ int renderEllipseSymbolCairo(imageObj *img, double x, double y, symbolObj *symbo return MS_SUCCESS; } - - -int startLayerVectorCairo(imageObj *img, mapObj *map, layerObj *layer) -{ +int startLayerVectorCairo(imageObj *img, mapObj *map, layerObj *layer) { (void)map; - if(layer->compositer && layer->compositer->opacity<100) { + if (layer->compositer && layer->compositer->opacity < 100) { cairo_renderer *r = CAIRO_RENDERER(img); - cairo_push_group (r->cr); + cairo_push_group(r->cr); } return MS_SUCCESS; } -int closeLayerVectorCairo(imageObj *img, mapObj *map, layerObj *layer) -{ +int closeLayerVectorCairo(imageObj *img, mapObj *map, layerObj *layer) { (void)map; - if(layer->compositer && layer->compositer->opacity<100) { + if (layer->compositer && layer->compositer->opacity < 100) { cairo_renderer *r = CAIRO_RENDERER(img); - cairo_pop_group_to_source (r->cr); - cairo_paint_with_alpha (r->cr, layer->compositer->opacity*0.01); + cairo_pop_group_to_source(r->cr); + cairo_paint_with_alpha(r->cr, layer->compositer->opacity * 0.01); } return MS_SUCCESS; } -int startLayerRasterCairo(imageObj *img, mapObj *map, layerObj *layer) -{ +int startLayerRasterCairo(imageObj *img, mapObj *map, layerObj *layer) { (void)img; (void)map; (void)layer; return MS_SUCCESS; } -int closeLayerRasterCairo(imageObj *img, mapObj *map, layerObj *layer) -{ +int closeLayerRasterCairo(imageObj *img, mapObj *map, layerObj *layer) { (void)img; (void)map; (void)layer; return MS_SUCCESS; } - -int getRasterBufferHandleCairo(imageObj *img, rasterBufferObj *rb) -{ +int getRasterBufferHandleCairo(imageObj *img, rasterBufferObj *rb) { unsigned char *pb; cairo_renderer *r = CAIRO_RENDERER(img); rb->type = MS_BUFFER_BYTE_RGBA; pb = cairo_image_surface_get_data(r->surface); rb->data.rgba.pixels = pb; rb->data.rgba.row_step = cairo_image_surface_get_stride(r->surface); - rb->data.rgba.pixel_step=4; + rb->data.rgba.pixel_step = 4; rb->width = cairo_image_surface_get_width(r->surface); rb->height = cairo_image_surface_get_height(r->surface); rb->data.rgba.r = &(pb[2]); rb->data.rgba.g = &(pb[1]); rb->data.rgba.b = &(pb[0]); - if(r->use_alpha) + if (r->use_alpha) rb->data.rgba.a = &(pb[3]); else rb->data.rgba.a = NULL; return MS_SUCCESS; } -int getRasterBufferCopyCairo(imageObj *img, rasterBufferObj *rb) -{ +int getRasterBufferCopyCairo(imageObj *img, rasterBufferObj *rb) { cairo_renderer *r = CAIRO_RENDERER(img); unsigned char *pb; rb->type = MS_BUFFER_BYTE_RGBA; rb->data.rgba.row_step = cairo_image_surface_get_stride(r->surface); - rb->data.rgba.pixel_step=4; + rb->data.rgba.pixel_step = 4; rb->width = cairo_image_surface_get_width(r->surface); rb->height = cairo_image_surface_get_height(r->surface); - pb = (unsigned char*)malloc(rb->height * rb->data.rgba.row_step * sizeof(unsigned char)); - memcpy(pb,cairo_image_surface_get_data(r->surface),rb->height * rb->data.rgba.row_step); + pb = (unsigned char *)malloc(rb->height * rb->data.rgba.row_step * + sizeof(unsigned char)); + memcpy(pb, cairo_image_surface_get_data(r->surface), + rb->height * rb->data.rgba.row_step); rb->data.rgba.pixels = pb; rb->data.rgba.r = &(pb[2]); rb->data.rgba.g = &(pb[1]); rb->data.rgba.b = &(pb[0]); - if(r->use_alpha) + if (r->use_alpha) rb->data.rgba.a = &(pb[3]); else rb->data.rgba.a = NULL; @@ -797,166 +791,167 @@ int getRasterBufferCopyCairo(imageObj *img, rasterBufferObj *rb) } static cairo_operator_t ms2cairo_compop(CompositingOperation op) { - switch(op) { - case MS_COMPOP_CLEAR: - return CAIRO_OPERATOR_CLEAR; - case MS_COMPOP_SRC: - return CAIRO_OPERATOR_SOURCE; - case MS_COMPOP_DST: - return CAIRO_OPERATOR_DEST; - case MS_COMPOP_SRC_OVER: - return CAIRO_OPERATOR_OVER; - case MS_COMPOP_DST_OVER: - return CAIRO_OPERATOR_DEST_OVER; - case MS_COMPOP_SRC_IN: - return CAIRO_OPERATOR_IN; - case MS_COMPOP_DST_IN: - return CAIRO_OPERATOR_DEST_IN; - case MS_COMPOP_SRC_OUT: - return CAIRO_OPERATOR_OUT; - case MS_COMPOP_DST_OUT: - return CAIRO_OPERATOR_DEST_OUT; - case MS_COMPOP_SRC_ATOP: - return CAIRO_OPERATOR_ATOP; - case MS_COMPOP_DST_ATOP: - return CAIRO_OPERATOR_DEST_ATOP; - case MS_COMPOP_XOR: - return CAIRO_OPERATOR_XOR; - case MS_COMPOP_PLUS: - return CAIRO_OPERATOR_ADD; - case MS_COMPOP_MULTIPLY: - return CAIRO_OPERATOR_MULTIPLY; - case MS_COMPOP_SCREEN: - return CAIRO_OPERATOR_SCREEN; - case MS_COMPOP_OVERLAY: - return CAIRO_OPERATOR_OVERLAY; - case MS_COMPOP_DARKEN: - return CAIRO_OPERATOR_DARKEN; - case MS_COMPOP_LIGHTEN: - return CAIRO_OPERATOR_LIGHTEN; - case MS_COMPOP_COLOR_DODGE: - return CAIRO_OPERATOR_COLOR_DODGE; - case MS_COMPOP_COLOR_BURN: - return CAIRO_OPERATOR_COLOR_BURN; - case MS_COMPOP_HARD_LIGHT: - return CAIRO_OPERATOR_HARD_LIGHT; - case MS_COMPOP_SOFT_LIGHT: - return CAIRO_OPERATOR_SOFT_LIGHT; - case MS_COMPOP_DIFFERENCE: - return CAIRO_OPERATOR_DIFFERENCE; - case MS_COMPOP_EXCLUSION: - return CAIRO_OPERATOR_EXCLUSION; - case MS_COMPOP_INVERT: - case MS_COMPOP_INVERT_RGB: - case MS_COMPOP_MINUS: - case MS_COMPOP_CONTRAST: - default: - return CAIRO_OPERATOR_OVER; + switch (op) { + case MS_COMPOP_CLEAR: + return CAIRO_OPERATOR_CLEAR; + case MS_COMPOP_SRC: + return CAIRO_OPERATOR_SOURCE; + case MS_COMPOP_DST: + return CAIRO_OPERATOR_DEST; + case MS_COMPOP_SRC_OVER: + return CAIRO_OPERATOR_OVER; + case MS_COMPOP_DST_OVER: + return CAIRO_OPERATOR_DEST_OVER; + case MS_COMPOP_SRC_IN: + return CAIRO_OPERATOR_IN; + case MS_COMPOP_DST_IN: + return CAIRO_OPERATOR_DEST_IN; + case MS_COMPOP_SRC_OUT: + return CAIRO_OPERATOR_OUT; + case MS_COMPOP_DST_OUT: + return CAIRO_OPERATOR_DEST_OUT; + case MS_COMPOP_SRC_ATOP: + return CAIRO_OPERATOR_ATOP; + case MS_COMPOP_DST_ATOP: + return CAIRO_OPERATOR_DEST_ATOP; + case MS_COMPOP_XOR: + return CAIRO_OPERATOR_XOR; + case MS_COMPOP_PLUS: + return CAIRO_OPERATOR_ADD; + case MS_COMPOP_MULTIPLY: + return CAIRO_OPERATOR_MULTIPLY; + case MS_COMPOP_SCREEN: + return CAIRO_OPERATOR_SCREEN; + case MS_COMPOP_OVERLAY: + return CAIRO_OPERATOR_OVERLAY; + case MS_COMPOP_DARKEN: + return CAIRO_OPERATOR_DARKEN; + case MS_COMPOP_LIGHTEN: + return CAIRO_OPERATOR_LIGHTEN; + case MS_COMPOP_COLOR_DODGE: + return CAIRO_OPERATOR_COLOR_DODGE; + case MS_COMPOP_COLOR_BURN: + return CAIRO_OPERATOR_COLOR_BURN; + case MS_COMPOP_HARD_LIGHT: + return CAIRO_OPERATOR_HARD_LIGHT; + case MS_COMPOP_SOFT_LIGHT: + return CAIRO_OPERATOR_SOFT_LIGHT; + case MS_COMPOP_DIFFERENCE: + return CAIRO_OPERATOR_DIFFERENCE; + case MS_COMPOP_EXCLUSION: + return CAIRO_OPERATOR_EXCLUSION; + case MS_COMPOP_INVERT: + case MS_COMPOP_INVERT_RGB: + case MS_COMPOP_MINUS: + case MS_COMPOP_CONTRAST: + default: + return CAIRO_OPERATOR_OVER; } } -int cairoCompositeRasterBuffer(imageObj *img, rasterBufferObj *rb, CompositingOperation comp, int opacity) { +int cairoCompositeRasterBuffer(imageObj *img, rasterBufferObj *rb, + CompositingOperation comp, int opacity) { cairo_surface_t *src; cairo_renderer *r; - if(rb->type != MS_BUFFER_BYTE_RGBA) { + if (rb->type != MS_BUFFER_BYTE_RGBA) { return MS_FAILURE; } r = CAIRO_RENDERER(img); - src = cairo_image_surface_create_for_data(rb->data.rgba.pixels,CAIRO_FORMAT_ARGB32, - rb->width,rb->height, - rb->data.rgba.row_step); + src = cairo_image_surface_create_for_data(rb->data.rgba.pixels, + CAIRO_FORMAT_ARGB32, rb->width, + rb->height, rb->data.rgba.row_step); - cairo_set_source_surface (r->cr,src,0,0); + cairo_set_source_surface(r->cr, src, 0, 0); cairo_set_operator(r->cr, ms2cairo_compop(comp)); - cairo_paint_with_alpha(r->cr,opacity/100.0); + cairo_paint_with_alpha(r->cr, opacity / 100.0); cairo_surface_finish(src); cairo_surface_destroy(src); - cairo_set_operator(r->cr,CAIRO_OPERATOR_OVER); + cairo_set_operator(r->cr, CAIRO_OPERATOR_OVER); return MS_SUCCESS; } int mergeRasterBufferCairo(imageObj *img, rasterBufferObj *rb, double opacity, - int srcX, int srcY, int dstX, int dstY, - int width, int height) -{ + int srcX, int srcY, int dstX, int dstY, int width, + int height) { cairo_surface_t *src; cairo_renderer *r; /* not implemented for src,dst,width and height */ - if(rb->type != MS_BUFFER_BYTE_RGBA) { + if (rb->type != MS_BUFFER_BYTE_RGBA) { return MS_FAILURE; } r = CAIRO_RENDERER(img); - src = cairo_image_surface_create_for_data(rb->data.rgba.pixels,CAIRO_FORMAT_ARGB32, - rb->width,rb->height, - rb->data.rgba.row_step); + src = cairo_image_surface_create_for_data(rb->data.rgba.pixels, + CAIRO_FORMAT_ARGB32, rb->width, + rb->height, rb->data.rgba.row_step); - if(dstX||dstY||srcX||srcY||width!=img->width||height!=img->height) { - cairo_set_source_surface (r->cr, src, dstX - srcX, dstY - srcY); - cairo_rectangle (r->cr, dstX, dstY, width, height); - cairo_fill (r->cr); + if (dstX || dstY || srcX || srcY || width != img->width || + height != img->height) { + cairo_set_source_surface(r->cr, src, dstX - srcX, dstY - srcY); + cairo_rectangle(r->cr, dstX, dstY, width, height); + cairo_fill(r->cr); } else { - cairo_set_source_surface (r->cr,src,0,0); - cairo_paint_with_alpha(r->cr,opacity); + cairo_set_source_surface(r->cr, src, 0, 0); + cairo_paint_with_alpha(r->cr, opacity); } cairo_surface_finish(src); cairo_surface_destroy(src); return MS_SUCCESS; } - void freeSVGCache(symbolObj *s) { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) - struct svg_symbol_cache *cache = s->renderer_cache; - if(!cache) return; - assert(cache->svgc); + struct svg_symbol_cache *cache = s->renderer_cache; + if (!cache) + return; + assert(cache->svgc); #ifdef USE_SVG_CAIRO - svg_cairo_destroy(cache->svgc); + svg_cairo_destroy(cache->svgc); #else - #if LIBRSVG_CHECK_VERSION(2,35,0) - g_object_unref(cache->svgc); - #else - rsvg_handle_free(cache->svgc); - #endif +#if LIBRSVG_CHECK_VERSION(2, 35, 0) + g_object_unref(cache->svgc); +#else + rsvg_handle_free(cache->svgc); #endif - if(cache->pixmap_buffer) { - msFreeRasterBuffer(cache->pixmap_buffer); - free(cache->pixmap_buffer); - } - msFree(s->renderer_cache); - s->renderer_cache = NULL; +#endif + if (cache->pixmap_buffer) { + msFreeRasterBuffer(cache->pixmap_buffer); + free(cache->pixmap_buffer); + } + msFree(s->renderer_cache); + s->renderer_cache = NULL; #endif } -int freeSymbolCairo(symbolObj *s) -{ - if(!s->renderer_cache) +int freeSymbolCairo(symbolObj *s) { + if (!s->renderer_cache) return MS_SUCCESS; - switch(s->type) { - case MS_SYMBOL_VECTOR: - cairo_path_destroy(s->renderer_cache); - break; - case MS_SYMBOL_PIXMAP: - cairo_surface_destroy(s->renderer_cache); - break; - case MS_SYMBOL_SVG: - freeSVGCache(s); - break; + switch (s->type) { + case MS_SYMBOL_VECTOR: + cairo_path_destroy(s->renderer_cache); + break; + case MS_SYMBOL_PIXMAP: + cairo_surface_destroy(s->renderer_cache); + break; + case MS_SYMBOL_SVG: + freeSVGCache(s); + break; } - s->renderer_cache=NULL; + s->renderer_cache = NULL; return MS_SUCCESS; } -int initializeRasterBufferCairo(rasterBufferObj *rb, int width, int height, int mode) -{ +int initializeRasterBufferCairo(rasterBufferObj *rb, int width, int height, + int mode) { (void)mode; rb->type = MS_BUFFER_BYTE_RGBA; rb->width = width; rb->height = height; rb->data.rgba.pixel_step = 4; rb->data.rgba.row_step = width * 4; - rb->data.rgba.pixels = (unsigned char*)calloc(width*height*4,sizeof(unsigned char)); + rb->data.rgba.pixels = + (unsigned char *)calloc(width * height * 4, sizeof(unsigned char)); rb->data.rgba.r = &(rb->data.rgba.pixels[2]); rb->data.rgba.g = &(rb->data.rgba.pixels[1]); rb->data.rgba.b = &(rb->data.rgba.pixels[0]); @@ -964,19 +959,17 @@ int initializeRasterBufferCairo(rasterBufferObj *rb, int width, int height, int return MS_SUCCESS; } - -int msPreloadSVGSymbol(symbolObj *symbol) -{ +int msPreloadSVGSymbol(symbolObj *symbol) { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) struct svg_symbol_cache *cache; - if(!symbol->renderer_cache) { - cache = msSmallCalloc(1,sizeof(struct svg_symbol_cache)); + if (!symbol->renderer_cache) { + cache = msSmallCalloc(1, sizeof(struct svg_symbol_cache)); symbol->renderer_free_func = &freeSVGCache; } else { cache = symbol->renderer_cache; } - if(cache->svgc) + if (cache->svgc) return MS_SUCCESS; #ifdef USE_SVG_CAIRO @@ -985,17 +978,20 @@ int msPreloadSVGSymbol(symbolObj *symbol) int status; status = svg_cairo_create(&cache->svgc); if (status) { - msSetError(MS_RENDERERERR, "problem creating cairo svg", "msPreloadSVGSymbol()"); + msSetError(MS_RENDERERERR, "problem creating cairo svg", + "msPreloadSVGSymbol()"); return MS_FAILURE; } status = svg_cairo_parse(cache->svgc, symbol->full_pixmap_path); if (status) { - msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); + msSetError(MS_RENDERERERR, "problem parsing svg symbol", + "msPreloadSVGSymbol()"); return MS_FAILURE; } - svg_cairo_get_size (cache->svgc, &svg_width, &svg_height); + svg_cairo_get_size(cache->svgc, &svg_width, &svg_height); if (svg_width == 0 || svg_height == 0) { - msSetError(MS_RENDERERERR, "problem parsing svg symbol", "msPreloadSVGSymbol()"); + msSetError(MS_RENDERERERR, "problem parsing svg symbol", + "msPreloadSVGSymbol()"); return MS_FAILURE; } @@ -1004,39 +1000,37 @@ int msPreloadSVGSymbol(symbolObj *symbol) } #else { - cache->svgc = rsvg_handle_new_from_file(symbol->full_pixmap_path,NULL); - if(!cache->svgc) { - msSetError(MS_RENDERERERR,"failed to load svg file %s", "msPreloadSVGSymbol()", symbol->full_pixmap_path); + cache->svgc = rsvg_handle_new_from_file(symbol->full_pixmap_path, NULL); + if (!cache->svgc) { + msSetError(MS_RENDERERERR, "failed to load svg file %s", + "msPreloadSVGSymbol()", symbol->full_pixmap_path); return MS_FAILURE; } -#if LIBRSVG_CHECK_VERSION(2,46,0) +#if LIBRSVG_CHECK_VERSION(2, 46, 0) /* rsvg_handle_get_dimensions_sub() is deprecated since librsvg 2.46 */ /* It seems rsvg_handle_get_intrinsic_dimensions() is the best equivalent */ - /* when the root node includes a width and height attributes in pixels */ + /* when the root node includes a width and height attributes in pixels + */ gboolean has_width = FALSE; RsvgLength width = {0, RSVG_UNIT_PX}; gboolean has_height = FALSE; RsvgLength height = {0, RSVG_UNIT_PX}; - rsvg_handle_get_intrinsic_dimensions(cache->svgc, - &has_width, &width, - &has_height, &height, - NULL, NULL); - if( has_width && width.unit == RSVG_UNIT_PX && - has_height && height.unit == RSVG_UNIT_PX ) - { - symbol->sizex = width.length; - symbol->sizey = height.length; - } - else - { - RsvgRectangle ink_rect = { 0, 0, 0, 0 }; - rsvg_handle_get_geometry_for_element (cache->svgc, NULL, &ink_rect, NULL, NULL); - symbol->sizex = ink_rect.width; - symbol->sizey = ink_rect.height; + rsvg_handle_get_intrinsic_dimensions(cache->svgc, &has_width, &width, + &has_height, &height, NULL, NULL); + if (has_width && width.unit == RSVG_UNIT_PX && has_height && + height.unit == RSVG_UNIT_PX) { + symbol->sizex = width.length; + symbol->sizey = height.length; + } else { + RsvgRectangle ink_rect = {0, 0, 0, 0}; + rsvg_handle_get_geometry_for_element(cache->svgc, NULL, &ink_rect, NULL, + NULL); + symbol->sizex = ink_rect.width; + symbol->sizey = ink_rect.height; } #else RsvgDimensionData dim; - rsvg_handle_get_dimensions_sub (cache->svgc, &dim, NULL); + rsvg_handle_get_dimensions_sub(cache->svgc, &dim, NULL); symbol->sizex = dim.width; symbol->sizey = dim.height; #endif @@ -1048,16 +1042,15 @@ int msPreloadSVGSymbol(symbolObj *symbol) return MS_SUCCESS; #else - msSetError(MS_MISCERR, "SVG Symbols requested but is not built with libsvgcairo", + msSetError(MS_MISCERR, + "SVG Symbols requested but is not built with libsvgcairo", "msPreloadSVGSymbol()"); return MS_FAILURE; #endif } - - -int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) -{ +int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) struct svg_symbol_cache *svg_cache; @@ -1065,24 +1058,25 @@ int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *sy symbolObj pixsymbol; int status; - if(MS_SUCCESS != msPreloadSVGSymbol(symbol)) + if (MS_SUCCESS != msPreloadSVGSymbol(symbol)) return MS_FAILURE; - svg_cache = (struct svg_symbol_cache*) symbol->renderer_cache; + svg_cache = (struct svg_symbol_cache *)symbol->renderer_cache; - //already rendered at the right size and scale? return - if(svg_cache->scale != style->scale || svg_cache->rotation != style->rotation) { + // already rendered at the right size and scale? return + if (svg_cache->scale != style->scale || + svg_cache->rotation != style->rotation) { cairo_t *cr; cairo_surface_t *surface; unsigned char *pb; int width, height, surface_w, surface_h; /* need to recompute the pixmap */ - if(svg_cache->pixmap_buffer) { + if (svg_cache->pixmap_buffer) { msFreeRasterBuffer(svg_cache->pixmap_buffer); } else { - svg_cache->pixmap_buffer = msSmallCalloc(1,sizeof(rasterBufferObj)); + svg_cache->pixmap_buffer = msSmallCalloc(1, sizeof(rasterBufferObj)); } - //increase pixmap size to accomodate scaling/rotation + // increase pixmap size to accomodate scaling/rotation if (style->scale != 1.0) { width = surface_w = (symbol->sizex * style->scale + 0.5); height = surface_h = (symbol->sizey * style->scale + 0.5); @@ -1094,7 +1088,8 @@ int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *sy surface_w = surface_h = MS_NINT(MS_MAX(height, width) * 1.415); } - surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, surface_w, surface_h); + surface = + cairo_image_surface_create(CAIRO_FORMAT_ARGB32, surface_w, surface_h); cr = cairo_create(surface); if (style->rotation != 0) { @@ -1106,17 +1101,19 @@ int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *sy cairo_scale(cr, style->scale, style->scale); } #ifdef USE_SVG_CAIRO - if(svg_cairo_render(svg_cache->svgc, cr) != SVG_CAIRO_STATUS_SUCCESS) { + if (svg_cairo_render(svg_cache->svgc, cr) != SVG_CAIRO_STATUS_SUCCESS) { return MS_FAILURE; } #else - rsvg_handle_render_cairo(svg_cache->svgc, cr); + rsvg_handle_render_cairo(svg_cache->svgc, cr); #endif pb = cairo_image_surface_get_data(surface); - //set up raster - initializeRasterBufferCairo(svg_cache->pixmap_buffer, surface_w, surface_h, 0); - memcpy(svg_cache->pixmap_buffer->data.rgba.pixels, pb, surface_w * surface_h * 4 * sizeof (unsigned char)); + // set up raster + initializeRasterBufferCairo(svg_cache->pixmap_buffer, surface_w, surface_h, + 0); + memcpy(svg_cache->pixmap_buffer->data.rgba.pixels, pb, + surface_w * surface_h * 4 * sizeof(unsigned char)); svg_cache->scale = style->scale; svg_cache->rotation = style->rotation; cairo_destroy(cr); @@ -1131,27 +1128,26 @@ int msRenderRasterizedSVGSymbol(imageObj *img, double x, double y, symbolObj *sy pixsymbol.pixmap_buffer = svg_cache->pixmap_buffer; pixsymbol.type = MS_SYMBOL_PIXMAP; - status = MS_IMAGE_RENDERER(img)->renderPixmapSymbol(img,x,y,&pixsymbol,&pixstyle); + status = MS_IMAGE_RENDERER(img)->renderPixmapSymbol(img, x, y, &pixsymbol, + &pixstyle); MS_IMAGE_RENDERER(img)->freeSymbol(&pixsymbol); return status; #else - msSetError(MS_MISCERR, "SVG Symbols requested but MapServer is not built with libsvgcairo", - "renderSVGSymbolCairo()"); + msSetError( + MS_MISCERR, + "SVG Symbols requested but MapServer is not built with libsvgcairo", + "renderSVGSymbolCairo()"); return MS_FAILURE; #endif } -void msCairoCleanup() { - cairo_debug_reset_static_data(); -} +void msCairoCleanup() { cairo_debug_reset_static_data(); } #endif /*USE_CAIRO*/ - -int msPopulateRendererVTableCairoRaster( rendererVTableObj *renderer ) -{ +int msPopulateRendererVTableCairoRaster(rendererVTableObj *renderer) { #ifdef USE_CAIRO - renderer->supports_pixel_buffer=1; + renderer->supports_pixel_buffer = 1; renderer->compositeRasterBuffer = cairoCompositeRasterBuffer; renderer->supports_svg = 1; renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY; @@ -1159,14 +1155,14 @@ int msPopulateRendererVTableCairoRaster( rendererVTableObj *renderer ) renderer->startLayer = startLayerRasterCairo; renderer->endLayer = closeLayerRasterCairo; renderer->renderLineTiled = NULL; - renderer->renderLine=&renderLineCairo; - renderer->createImage=&createImageCairo; - renderer->saveImage=&saveImageCairo; - renderer->getRasterBufferHandle=&getRasterBufferHandleCairo; - renderer->getRasterBufferCopy=&getRasterBufferCopyCairo; - renderer->renderPolygon=&renderPolygonCairo; - renderer->renderGlyphs=&renderGlyphs2Cairo; - renderer->freeImage=&freeImageCairo; + renderer->renderLine = &renderLineCairo; + renderer->createImage = &createImageCairo; + renderer->saveImage = &saveImageCairo; + renderer->getRasterBufferHandle = &getRasterBufferHandleCairo; + renderer->getRasterBufferCopy = &getRasterBufferCopyCairo; + renderer->renderPolygon = &renderPolygonCairo; + renderer->renderGlyphs = &renderGlyphs2Cairo; + renderer->freeImage = &freeImageCairo; renderer->renderEllipseSymbol = &renderEllipseSymbolCairo; renderer->renderVectorSymbol = &renderVectorSymbolCairo; renderer->renderSVGSymbol = &renderSVGSymbolCairo; @@ -1185,26 +1181,25 @@ int msPopulateRendererVTableCairoRaster( rendererVTableObj *renderer ) #endif } -int populateRendererVTableCairoVector( rendererVTableObj *renderer ) -{ +int populateRendererVTableCairoVector(rendererVTableObj *renderer) { #ifdef USE_CAIRO - renderer->use_imagecache=0; - renderer->supports_pixel_buffer=0; + renderer->use_imagecache = 0; + renderer->supports_pixel_buffer = 0; renderer->compositeRasterBuffer = NULL; renderer->supports_svg = 1; renderer->default_transform_mode = MS_TRANSFORM_SIMPLIFY; initializeCache(&MS_RENDERER_CACHE(renderer)); renderer->startLayer = startLayerVectorCairo; renderer->endLayer = closeLayerVectorCairo; - renderer->renderLine=&renderLineCairo; + renderer->renderLine = &renderLineCairo; renderer->renderLineTiled = NULL; - renderer->createImage=&createImageCairo; - renderer->saveImage=&saveImageCairo; + renderer->createImage = &createImageCairo; + renderer->saveImage = &saveImageCairo; renderer->saveImageBuffer = &saveImageBufferCairo; - renderer->getRasterBufferHandle=&getRasterBufferHandleCairo; - renderer->renderPolygon=&renderPolygonCairo; - renderer->renderGlyphs=&renderGlyphs2Cairo; - renderer->freeImage=&freeImageCairo; + renderer->getRasterBufferHandle = &getRasterBufferHandleCairo; + renderer->renderPolygon = &renderPolygonCairo; + renderer->renderGlyphs = &renderGlyphs2Cairo; + renderer->freeImage = &freeImageCairo; renderer->renderEllipseSymbol = &renderEllipseSymbolCairo; renderer->renderVectorSymbol = &renderVectorSymbolCairo; renderer->renderSVGSymbol = &renderSVGSymbolCairo; @@ -1224,12 +1219,9 @@ int populateRendererVTableCairoVector( rendererVTableObj *renderer ) #endif } -int msPopulateRendererVTableCairoSVG( rendererVTableObj *renderer ) -{ +int msPopulateRendererVTableCairoSVG(rendererVTableObj *renderer) { return populateRendererVTableCairoVector(renderer); } -int msPopulateRendererVTableCairoPDF( rendererVTableObj *renderer ) -{ +int msPopulateRendererVTableCairoPDF(rendererVTableObj *renderer) { return populateRendererVTableCairoVector(renderer); } - diff --git a/mapchart.c b/mapchart.c index bb0be04833..3829fd3430 100644 --- a/mapchart.c +++ b/mapchart.c @@ -27,19 +27,19 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #include "mapserver.h" - - #define MS_CHART_TYPE_PIE 1 #define MS_CHART_TYPE_BAR 2 #define MS_CHART_TYPE_VBAR 3 /* -** check if an object of width w and height h placed at point x,y can fit in an image of width mw and height mh +** check if an object of width w and height h placed at point x,y can fit in an +*image of width mw and height mh */ -#define MS_CHART_FITS(x,y,w,h,mw,mh) (((x)-(w)/2.>0.)&&((x)+(w)/2.<(mw))&&((y)-(h)/2.>0.)&&((y)+(h)/2.)<(mh)) +#define MS_CHART_FITS(x, y, w, h, mw, mh) \ + (((x) - (w) / 2. > 0.) && ((x) + (w) / 2. < (mw)) && \ + ((y) - (h) / 2. > 0.) && ((y) + (h) / 2.) < (mh)) /* ** find a point on a shape. check if it fits in image @@ -47,69 +47,85 @@ ** MS_SUCCESS and point coordinates in 'p' if chart fits in image ** MS_FAILURE if no point could be found */ -int findChartPoint(mapObj *map, shapeObj *shape, int width, int height, pointObj *center) -{ - int middle,numpoints; - double invcellsize = 1.0/map->cellsize; /*speed up MAP2IMAGE_X/Y_IC_DBL*/ - switch(shape->type) { - case MS_SHAPE_POINT: - center->x=MS_MAP2IMAGE_X_IC_DBL(shape->line[0].point[0].x, map->extent.minx, invcellsize); - center->y=MS_MAP2IMAGE_Y_IC_DBL(shape->line[0].point[0].y, map->extent.maxy, invcellsize); - - if(MS_CHART_FITS(center->x,center->y,width,height,map->width,map->height)) - return MS_SUCCESS; - else - return MS_FAILURE; - break; - case MS_SHAPE_LINE: - /*loop through line segments starting from middle (alternate between before and after middle point) - **first segment that fits is chosen - */ - middle=shape->line[0].numpoints/2; /*start with middle segment of line*/ - numpoints=shape->line[0].numpoints; - if( 1 <= middle ) { - int idx=middle+1; - if(idxx=(shape->line[0].point[idx-1].x+shape->line[0].point[idx].x)/2.; - center->y=(shape->line[0].point[idx-1].y+shape->line[0].point[idx].y)/2.; - center->x=MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); - center->y=MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); - - if(MS_CHART_FITS(center->x,center->y,width,height,map->width,map->height)) - return MS_SUCCESS; - - return MS_FAILURE; - } - idx=middle-1; - center->x=(shape->line[0].point[idx].x+shape->line[0].point[idx+1].x)/2; - center->y=(shape->line[0].point[idx].y+shape->line[0].point[idx+1].y)/2; - center->x=MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); - center->y=MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); - - if(MS_CHART_FITS(center->x,center->y,width,height,map->width,map->height)) +int findChartPoint(mapObj *map, shapeObj *shape, int width, int height, + pointObj *center) { + int middle, numpoints; + double invcellsize = 1.0 / map->cellsize; /*speed up MAP2IMAGE_X/Y_IC_DBL*/ + switch (shape->type) { + case MS_SHAPE_POINT: + center->x = MS_MAP2IMAGE_X_IC_DBL(shape->line[0].point[0].x, + map->extent.minx, invcellsize); + center->y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[0].point[0].y, + map->extent.maxy, invcellsize); + + if (MS_CHART_FITS(center->x, center->y, width, height, map->width, + map->height)) + return MS_SUCCESS; + else + return MS_FAILURE; + break; + case MS_SHAPE_LINE: + /*loop through line segments starting from middle (alternate between before + *and after middle point) *first segment that fits is chosen + */ + middle = shape->line[0].numpoints / 2; /*start with middle segment of line*/ + numpoints = shape->line[0].numpoints; + if (1 <= middle) { + int idx = middle + 1; + if (idx < numpoints) { + center->x = + (shape->line[0].point[idx - 1].x + shape->line[0].point[idx].x) / + 2.; + center->y = + (shape->line[0].point[idx - 1].y + shape->line[0].point[idx].y) / + 2.; + center->x = + MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); + center->y = + MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); + + if (MS_CHART_FITS(center->x, center->y, width, height, map->width, + map->height)) return MS_SUCCESS; + return MS_FAILURE; } - return MS_FAILURE; - break; - case MS_SHAPE_POLYGON: - msPolygonLabelPoint(shape, center, -1); - center->x=MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); - center->y=MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); - - if(MS_CHART_FITS(center->x,center->y,width,height,map->width,map->height)) + idx = middle - 1; + center->x = + (shape->line[0].point[idx].x + shape->line[0].point[idx + 1].x) / 2; + center->y = + (shape->line[0].point[idx].y + shape->line[0].point[idx + 1].y) / 2; + center->x = + MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); + center->y = + MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); + + if (MS_CHART_FITS(center->x, center->y, width, height, map->width, + map->height)) return MS_SUCCESS; - else - return MS_FAILURE; - break; - default: return MS_FAILURE; + } + return MS_FAILURE; + break; + case MS_SHAPE_POLYGON: + msPolygonLabelPoint(shape, center, -1); + center->x = MS_MAP2IMAGE_X_IC_DBL(center->x, map->extent.minx, invcellsize); + center->y = MS_MAP2IMAGE_Y_IC_DBL(center->y, map->extent.maxy, invcellsize); + + if (MS_CHART_FITS(center->x, center->y, width, height, map->width, + map->height)) + return MS_SUCCESS; + else + return MS_FAILURE; + break; + default: + return MS_FAILURE; } } -int WARN_UNUSED drawRectangle(mapObj *map, imageObj *image, double mx, double my, double Mx, double My, - styleObj *style) -{ +int WARN_UNUSED drawRectangle(mapObj *map, imageObj *image, double mx, + double my, double Mx, double My, + styleObj *style) { shapeObj shape; lineObj line; pointObj point[5]; @@ -125,56 +141,56 @@ int WARN_UNUSED drawRectangle(mapObj *map, imageObj *image, double mx, double my /* cppcheck-suppress unreadVariable */ point[2].y = point[3].y = My; - return msDrawShadeSymbol(map,image,&shape,style,1.0); + return msDrawShadeSymbol(map, image, &shape, style, 1.0); } int WARN_UNUSED msDrawVBarChart(mapObj *map, imageObj *image, pointObj *center, - double *values, styleObj **styles, int numvalues, - double barWidth) -{ + double *values, styleObj **styles, + int numvalues, double barWidth) { int c; - double left,bottom,cur; /*shortcut to pixel boundaries of the chart*/ + double left, bottom, cur; /*shortcut to pixel boundaries of the chart*/ double height = 0; - for(c=0; cy+height/2.; - left = center->x-barWidth/2.; + cur = bottom = center->y + height / 2.; + left = center->x - barWidth / 2.; - for(c=0; cy-height/2.; - bottom=center->y+height/2.; - left=center->x-width/2.; - - shapeMaxVal=shapeMinVal=values[0]; - for(c=1; cshapeMaxVal) - shapeMaxVal=values[c]; - if(values[c]y - height / 2.; + bottom = center->y + height / 2.; + left = center->x - width / 2.; + + shapeMaxVal = shapeMinVal = values[0]; + for (c = 1; c < numvalues; c++) { + if (maxVal == NULL || minVal == NULL) { /*compute bounds if not specified*/ + if (values[c] > shapeMaxVal) + shapeMaxVal = values[c]; + if (values[c] < shapeMinVal) + shapeMinVal = values[c]; } } @@ -182,96 +198,106 @@ int msDrawBarChart(mapObj *map, imageObj *image, pointObj *center, * use specified bounds if wanted * if not, always show the origin */ - upperLimit = (maxVal!=NULL)? *maxVal : MS_MAX(shapeMaxVal,0); - lowerLimit = (minVal!=NULL)? *minVal : MS_MIN(shapeMinVal,0); - if(upperLimit==lowerLimit) { + upperLimit = (maxVal != NULL) ? *maxVal : MS_MAX(shapeMaxVal, 0); + lowerLimit = (minVal != NULL) ? *minVal : MS_MIN(shapeMinVal, 0); + if (upperLimit == lowerLimit) { /* treat the case where we would have an unspecified behavior */ - upperLimit+=0.5; - lowerLimit-=0.5; + upperLimit += 0.5; + lowerLimit -= 0.5; } - pixperval=height/(upperLimit-lowerLimit); - vertOrigin=bottom+lowerLimit*pixperval; - vertOriginClipped=(vertOriginbottom) ? bottom : vertOrigin; - horizStart=left; - - for(c=0; c bottom) ? bottom + : vertOrigin; + horizStart = left; + + for (c = 0; c < numvalues; c++) { + double barHeight = values[c] * pixperval; /*clip bars*/ - y=((vertOrigin-barHeight)bottom) ? bottom : vertOrigin-barHeight; - if(y!=vertOriginClipped) { /*don't draw bars of height == 0 (i.e. either values==0, or clipped)*/ - if(values[c]>0) { - if(MS_UNLIKELY(MS_FAILURE == drawRectangle(map, image, horizStart, y, horizStart+barWidth-1, vertOriginClipped, styles[c]))) + y = ((vertOrigin - barHeight) < top) ? top + : (vertOrigin - barHeight > bottom) ? bottom + : vertOrigin - barHeight; + if (y != vertOriginClipped) { /*don't draw bars of height == 0 (i.e. either + values==0, or clipped)*/ + if (values[c] > 0) { + if (MS_UNLIKELY(MS_FAILURE == drawRectangle(map, image, horizStart, y, + horizStart + barWidth - 1, + vertOriginClipped, + styles[c]))) return MS_FAILURE; - } - else { - if(MS_UNLIKELY(MS_FAILURE == drawRectangle(map,image, horizStart, vertOriginClipped, horizStart+barWidth-1 , y, styles[c]))) + } else { + if (MS_UNLIKELY(MS_FAILURE == + drawRectangle(map, image, horizStart, vertOriginClipped, + horizStart + barWidth - 1, y, styles[c]))) return MS_FAILURE; } } - horizStart+=barWidth; + horizStart += barWidth; } return MS_SUCCESS; } -int WARN_UNUSED msDrawPieChart(mapObj *map, imageObj *image, - pointObj *center, double diameter, - double *values, styleObj **styles, int numvalues) -{ +int WARN_UNUSED msDrawPieChart(mapObj *map, imageObj *image, pointObj *center, + double diameter, double *values, + styleObj **styles, int numvalues) { int i; - double dTotal=0.,start=0; + double dTotal = 0., start = 0; - for(i=0; iproject) - { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); - if( layer->reprojectorLayerToMap == NULL ) - { - return MS_FAILURE; + if (status == MS_SUCCESS) { + + if (layer->project) { + if (layer->reprojectorLayerToMap == NULL) { + layer->reprojectorLayerToMap = + msProjectCreateReprojector(&layer->projection, &map->projection); + if (layer->reprojectorLayerToMap == NULL) { + return MS_FAILURE; } } msProjectShapeEx(layer->reprojectorLayerToMap, shape); } - if(msBindLayerToShape(layer, shape, MS_DRAWMODE_FEATURES|MS_DRAWMODE_LABELS) != MS_SUCCESS) + if (msBindLayerToShape(layer, shape, + MS_DRAWMODE_FEATURES | MS_DRAWMODE_LABELS) != + MS_SUCCESS) return MS_FAILURE; /* error message is set in msBindLayerToShape() */ *nvalues = 0; - for(c=0; cnumclasses; c++) { - if(msEvalExpression(layer, shape, &(layer->class[c]->expression), layer->classitemindex) == MS_TRUE) { - values[*nvalues]=(layer->class[c]->styles[0]->size); - styles[*nvalues]=layer->class[c]->styles[0]; + for (c = 0; c < layer->numclasses; c++) { + if (msEvalExpression(layer, shape, &(layer->class[c] -> expression), + layer->classitemindex) == MS_TRUE) { + values[*nvalues] = (layer->class[c] -> styles[0] -> size); + styles[*nvalues] = layer->class[c]->styles[0]; (*nvalues)++; } } @@ -280,38 +306,40 @@ int getNextShape(mapObj *map, layerObj *layer, double *values, int *nvalues, sty } /* eventually add a class to the layer to get the diameter from an attribute */ -int pieLayerProcessDynamicDiameter(layerObj *layer) -{ - const char *chartRangeProcessingKey=NULL; +int pieLayerProcessDynamicDiameter(layerObj *layer) { + const char *chartRangeProcessingKey = NULL; char *attrib; - double mindiameter=-1, maxdiameter, minvalue, maxvalue; + double mindiameter = -1, maxdiameter, minvalue, maxvalue; classObj *newclass; styleObj *newstyle; - const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); - if(chartSizeProcessingKey != NULL) + const char *chartSizeProcessingKey = + msLayerGetProcessingKey(layer, "CHART_SIZE"); + if (chartSizeProcessingKey != NULL) return MS_FALSE; - chartRangeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE_RANGE" ); - if(chartRangeProcessingKey==NULL) + chartRangeProcessingKey = msLayerGetProcessingKey(layer, "CHART_SIZE_RANGE"); + if (chartRangeProcessingKey == NULL) return MS_FALSE; attrib = msStrdup(chartRangeProcessingKey); - char* space = strchr(attrib, ' '); - if( space ) { - *space = '\0'; - switch(sscanf(space+1,"%lf %lf %lf %lf", - &mindiameter,&maxdiameter,&minvalue,&maxvalue)) { - case 4: /*we have the attribute and the four range values*/ - break; - default: - free(attrib); - msSetError(MS_MISCERR, "Chart Layer format error for processing key \"CHART_RANGE\"", "msDrawChartLayer()"); - return MS_FAILURE; - } + char *space = strchr(attrib, ' '); + if (space) { + *space = '\0'; + switch (sscanf(space + 1, "%lf %lf %lf %lf", &mindiameter, &maxdiameter, + &minvalue, &maxvalue)) { + case 4: /*we have the attribute and the four range values*/ + break; + default: + free(attrib); + msSetError(MS_MISCERR, + "Chart Layer format error for processing key \"CHART_RANGE\"", + "msDrawChartLayer()"); + return MS_FAILURE; + } } /*create a new class in the layer containing the wanted attribute * as the SIZE of its first STYLE*/ - newclass=msGrowLayerClasses(layer); - if(newclass==NULL) { + newclass = msGrowLayerClasses(layer); + if (newclass == NULL) { free(attrib); return MS_FAILURE; } @@ -321,112 +349,117 @@ int pieLayerProcessDynamicDiameter(layerObj *layer) /*create and attach a new styleObj to our temp class * and bind the wanted attribute to its SIZE */ - newstyle=msGrowClassStyles(newclass); - if(newstyle==NULL) { + newstyle = msGrowClassStyles(newclass); + if (newstyle == NULL) { free(attrib); return MS_FAILURE; } initStyle(newstyle); newclass->numstyles++; - newclass->name=(char*)msStrdup("__MS_SIZE_ATTRIBUTE_"); - newstyle->bindings[MS_STYLE_BINDING_SIZE].item=msStrdup(attrib); + newclass->name = (char *)msStrdup("__MS_SIZE_ATTRIBUTE_"); + newstyle->bindings[MS_STYLE_BINDING_SIZE].item = msStrdup(attrib); newstyle->numbindings++; free(attrib); return MS_TRUE; - } /* clean up the class added temporarily */ -static void pieLayerCleanupDynamicDiameter(layerObj *layer) -{ - if( layer->numclasses > 0 && EQUALN(layer->class[layer->numclasses - 1]->name, "__MS_SIZE_ATTRIBUTE_", 20) ) { - classObj *c=msRemoveClass(layer, layer->numclasses - 1); +static void pieLayerCleanupDynamicDiameter(layerObj *layer) { + if (layer->numclasses > 0 && + EQUALN(layer->class[layer->numclasses - 1] -> name, + "__MS_SIZE_ATTRIBUTE_", 20)) { + classObj *c = msRemoveClass(layer, layer->numclasses - 1); freeClass(c); msFree(c); } } - -int msDrawPieChartLayer(mapObj *map, layerObj *layer, imageObj *image) -{ - shapeObj shape; - int status=MS_SUCCESS; - const char *chartRangeProcessingKey=NULL; - const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); - double diameter=0, mindiameter=-1, maxdiameter=0, minvalue=0, maxvalue=0, exponent=0; +int msDrawPieChartLayer(mapObj *map, layerObj *layer, imageObj *image) { + shapeObj shape; + int status = MS_SUCCESS; + const char *chartRangeProcessingKey = NULL; + const char *chartSizeProcessingKey = + msLayerGetProcessingKey(layer, "CHART_SIZE"); + double diameter = 0, mindiameter = -1, maxdiameter = 0, minvalue = 0, + maxvalue = 0, exponent = 0; double *values; styleObj **styles; pointObj center; - int numvalues = layer->numclasses; /* the number of classes to represent in the graph */ + int numvalues = + layer->numclasses; /* the number of classes to represent in the graph */ int numvalues_for_shape = 0; - if(chartSizeProcessingKey==NULL) { - chartRangeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE_RANGE" ); - if(chartRangeProcessingKey==NULL) - diameter=20; + if (chartSizeProcessingKey == NULL) { + chartRangeProcessingKey = + msLayerGetProcessingKey(layer, "CHART_SIZE_RANGE"); + if (chartRangeProcessingKey == NULL) + diameter = 20; else { - sscanf(chartRangeProcessingKey,"%*s %lf %lf %lf %lf %lf", - &mindiameter,&maxdiameter,&minvalue,&maxvalue,&exponent); + sscanf(chartRangeProcessingKey, "%*s %lf %lf %lf %lf %lf", &mindiameter, + &maxdiameter, &minvalue, &maxvalue, &exponent); } } else { - if(sscanf(chartSizeProcessingKey ,"%lf",&diameter)!=1) { - msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawPieChartLayer()"); + if (sscanf(chartSizeProcessingKey, "%lf", &diameter) != 1) { + msSetError(MS_MISCERR, + "msDrawChart format error for processing key \"CHART_SIZE\"", + "msDrawPieChartLayer()"); return MS_FAILURE; } } - layer->project = msProjectionsDiffer(&(layer->projection), &(map->projection)); + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); /* step through the target shapes */ msInitShape(&shape); - values=(double*)calloc(numvalues,sizeof(double)); - MS_CHECK_ALLOC(values, numvalues*sizeof(double), MS_FAILURE); - styles = (styleObj**)malloc((numvalues)*sizeof(styleObj*)); + values = (double *)calloc(numvalues, sizeof(double)); + MS_CHECK_ALLOC(values, numvalues * sizeof(double), MS_FAILURE); + styles = (styleObj **)malloc((numvalues) * sizeof(styleObj *)); if (styles == NULL) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawPieChartLayer()", - __FILE__, __LINE__, (unsigned int)(numvalues*sizeof(styleObj*))); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msDrawPieChartLayer()", __FILE__, __LINE__, + (unsigned int)(numvalues * sizeof(styleObj *))); free(values); return MS_FAILURE; } - while(MS_SUCCESS == getNextShape(map,layer,values,&numvalues_for_shape,styles,&shape)) { - if(chartRangeProcessingKey!=NULL) + while (MS_SUCCESS == getNextShape(map, layer, values, &numvalues_for_shape, + styles, &shape)) { + if (chartRangeProcessingKey != NULL) numvalues_for_shape--; - if(numvalues_for_shape == 0) { + if (numvalues_for_shape == 0) { msFreeShape(&shape); continue; } msDrawStartShape(map, layer, image, &shape); - if(chartRangeProcessingKey!=NULL) { + if (chartRangeProcessingKey != NULL) { diameter = values[numvalues_for_shape]; - if(mindiameter>=0) { - if(diameter<=minvalue) - diameter=mindiameter; - else if(diameter>=maxvalue) - diameter=maxdiameter; + if (mindiameter >= 0) { + if (diameter <= minvalue) + diameter = mindiameter; + else if (diameter >= maxvalue) + diameter = maxdiameter; else { if (exponent <= 0) - diameter=MS_NINT( - mindiameter+ - ((diameter-minvalue)/(maxvalue-minvalue))* - (maxdiameter-mindiameter) - ); + diameter = MS_NINT(mindiameter + + ((diameter - minvalue) / (maxvalue - minvalue)) * + (maxdiameter - mindiameter)); else - diameter=MS_NINT( - mindiameter+ - pow((diameter-minvalue)/(maxvalue-minvalue),1.0/exponent)* - (maxdiameter-mindiameter) - ); + diameter = MS_NINT( + mindiameter + pow((diameter - minvalue) / (maxvalue - minvalue), + 1.0 / exponent) * + (maxdiameter - mindiameter)); } } } - if(findChartPoint(map, &shape, diameter, diameter, ¢er) == MS_SUCCESS) { - status = msDrawPieChart(map,image, ¢er, diameter, - values,styles,numvalues_for_shape); + if (findChartPoint(map, &shape, diameter, diameter, ¢er) == + MS_SUCCESS) { + status = msDrawPieChart(map, image, ¢er, diameter, values, styles, + numvalues_for_shape); } - msDrawEndShape(map,layer,image,&shape); + msDrawEndShape(map, layer, image, &shape); msFreeShape(&shape); } free(values); @@ -434,63 +467,68 @@ int msDrawPieChartLayer(mapObj *map, layerObj *layer, imageObj *image) return status; } -int msDrawVBarChartLayer(mapObj *map, layerObj *layer, imageObj *image) -{ - shapeObj shape; - int status=MS_SUCCESS; - const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); - const char *chartScaleProcessingKey=msLayerGetProcessingKey( layer,"CHART_SCALE" ); - double barWidth,scale=1.0; +int msDrawVBarChartLayer(mapObj *map, layerObj *layer, imageObj *image) { + shapeObj shape; + int status = MS_SUCCESS; + const char *chartSizeProcessingKey = + msLayerGetProcessingKey(layer, "CHART_SIZE"); + const char *chartScaleProcessingKey = + msLayerGetProcessingKey(layer, "CHART_SCALE"); + double barWidth, scale = 1.0; double *values; styleObj **styles; pointObj center; int numvalues = layer->numclasses; int numvalues_for_shape; - if(chartSizeProcessingKey==NULL) { - barWidth=20; + if (chartSizeProcessingKey == NULL) { + barWidth = 20; } else { - if(sscanf(chartSizeProcessingKey ,"%lf",&barWidth) != 1) { - msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawVBarChartLayer()"); + if (sscanf(chartSizeProcessingKey, "%lf", &barWidth) != 1) { + msSetError(MS_MISCERR, + "msDrawChart format error for processing key \"CHART_SIZE\"", + "msDrawVBarChartLayer()"); return MS_FAILURE; } } - if(chartScaleProcessingKey) { - if(sscanf(chartScaleProcessingKey,"%lf",&scale)!=1) { - msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_SCALE\"", "msDrawVBarChartLayer()"); + if (chartScaleProcessingKey) { + if (sscanf(chartScaleProcessingKey, "%lf", &scale) != 1) { + msSetError(MS_MISCERR, + "Error reading value for processing key \"CHART_SCALE\"", + "msDrawVBarChartLayer()"); return MS_FAILURE; } } msInitShape(&shape); - values=(double*)calloc(numvalues,sizeof(double)); - MS_CHECK_ALLOC(values, numvalues*sizeof(double), MS_FAILURE); - styles = (styleObj**)malloc(numvalues*sizeof(styleObj*)); + values = (double *)calloc(numvalues, sizeof(double)); + MS_CHECK_ALLOC(values, numvalues * sizeof(double), MS_FAILURE); + styles = (styleObj **)malloc(numvalues * sizeof(styleObj *)); if (styles == NULL) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawVBarChartLayer()", - __FILE__, __LINE__, (unsigned int)(numvalues*sizeof(styleObj*))); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msDrawVBarChartLayer()", __FILE__, __LINE__, + (unsigned int)(numvalues * sizeof(styleObj *))); free(values); return MS_FAILURE; } - while(MS_SUCCESS == getNextShape(map,layer,values,&numvalues_for_shape,styles,&shape)) { + while (MS_SUCCESS == getNextShape(map, layer, values, &numvalues_for_shape, + styles, &shape)) { int i; - double h=0; - if(numvalues_for_shape == 0) { + double h = 0; + if (numvalues_for_shape == 0) { continue; } - for(i=0; inumclasses; int numvalues_for_shape; - if(chartSizeProcessingKey==NULL) { - width=height=20; + if (chartSizeProcessingKey == NULL) { + width = height = 20; } else { - switch(sscanf(chartSizeProcessingKey ,"%lf %lf",&width,&height)) { - case 2: - break; - case 1: - height = width; - break; - default: - msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawBarChartLayer()"); - return MS_FAILURE; + switch (sscanf(chartSizeProcessingKey, "%lf %lf", &width, &height)) { + case 2: + break; + case 1: + height = width; + break; + default: + msSetError(MS_MISCERR, + "msDrawChart format error for processing key \"CHART_SIZE\"", + "msDrawBarChartLayer()"); + return MS_FAILURE; } } - if(barMax) { - if(sscanf(barMax,"%lf",&barMaxVal)!=1) { - msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_BAR_MAXVAL\"", "msDrawBarChartLayer()"); + if (barMax) { + if (sscanf(barMax, "%lf", &barMaxVal) != 1) { + msSetError(MS_MISCERR, + "Error reading value for processing key \"CHART_BAR_MAXVAL\"", + "msDrawBarChartLayer()"); return MS_FAILURE; } } - if(barMin) { - if(sscanf(barMin,"%lf",&barMinVal)!=1) { - msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_BAR_MINVAL\"", "msDrawBarChartLayer()"); + if (barMin) { + if (sscanf(barMin, "%lf", &barMinVal) != 1) { + msSetError(MS_MISCERR, + "Error reading value for processing key \"CHART_BAR_MINVAL\"", + "msDrawBarChartLayer()"); return MS_FAILURE; } } - if(barMin && barMax && barMinVal>=barMaxVal) { - msSetError(MS_MISCERR, "\"CHART_BAR_MINVAL\" must be less than \"CHART_BAR_MAXVAL\"", "msDrawBarChartLayer()"); + if (barMin && barMax && barMinVal >= barMaxVal) { + msSetError(MS_MISCERR, + "\"CHART_BAR_MINVAL\" must be less than \"CHART_BAR_MAXVAL\"", + "msDrawBarChartLayer()"); return MS_FAILURE; } - barWidth=(double)width/(double)layer->numclasses; - if(!barWidth) { - msSetError(MS_MISCERR, "Specified width of chart too small to fit given number of classes", "msDrawBarChartLayer()"); + barWidth = (double)width / (double)layer->numclasses; + if (!barWidth) { + msSetError( + MS_MISCERR, + "Specified width of chart too small to fit given number of classes", + "msDrawBarChartLayer()"); return MS_FAILURE; } msInitShape(&shape); - values=(double*)calloc(numvalues,sizeof(double)); - MS_CHECK_ALLOC(values, numvalues*sizeof(double), MS_FAILURE); - styles = (styleObj**)malloc(numvalues*sizeof(styleObj*)); + values = (double *)calloc(numvalues, sizeof(double)); + MS_CHECK_ALLOC(values, numvalues * sizeof(double), MS_FAILURE); + styles = (styleObj **)malloc(numvalues * sizeof(styleObj *)); if (styles == NULL) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawBarChartLayer()", - __FILE__, __LINE__, (unsigned int)(numvalues*sizeof(styleObj*))); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msDrawBarChartLayer()", __FILE__, __LINE__, + (unsigned int)(numvalues * sizeof(styleObj *))); free(values); return MS_FAILURE; } - while(MS_SUCCESS == getNextShape(map,layer,values,&numvalues_for_shape,styles,&shape)) { - if(numvalues_for_shape == 0 ) continue; + while (MS_SUCCESS == getNextShape(map, layer, values, &numvalues_for_shape, + styles, &shape)) { + if (numvalues_for_shape == 0) + continue; msDrawStartShape(map, layer, image, &shape); - if(findChartPoint(map, &shape, width,height, ¢er)==MS_SUCCESS) { - status = msDrawBarChart(map,image, - ¢er, - values, styles, numvalues_for_shape, - width,height, - (barMax!=NULL)?&barMaxVal:NULL, - (barMin!=NULL)?&barMinVal:NULL, - barWidth); + if (findChartPoint(map, &shape, width, height, ¢er) == MS_SUCCESS) { + status = msDrawBarChart(map, image, ¢er, values, styles, + numvalues_for_shape, width, height, + (barMax != NULL) ? &barMaxVal : NULL, + (barMin != NULL) ? &barMinVal : NULL, barWidth); } - msDrawEndShape(map,layer,image,&shape); + msDrawEndShape(map, layer, image, &shape); msFreeShape(&shape); } free(values); @@ -586,86 +634,93 @@ int msDrawBarChartLayer(mapObj *map, layerObj *layer, imageObj *image) /** * Generic function to render chart layers. */ -int msDrawChartLayer(mapObj *map, layerObj *layer, imageObj *image) -{ +int msDrawChartLayer(mapObj *map, layerObj *layer, imageObj *image) { - rectObj searchrect; - const char *chartTypeProcessingKey=msLayerGetProcessingKey( layer,"CHART_TYPE" ); - int chartType=MS_CHART_TYPE_PIE; + rectObj searchrect; + const char *chartTypeProcessingKey = + msLayerGetProcessingKey(layer, "CHART_TYPE"); + int chartType = MS_CHART_TYPE_PIE; int status = MS_FAILURE; if (image && map) { - if( !(MS_RENDERER_PLUGIN(image->format) )) { - msSetError(MS_MISCERR, "chart drawing currently only supports GD and AGG renderers", "msDrawChartLayer()"); + if (!(MS_RENDERER_PLUGIN(image->format))) { + msSetError(MS_MISCERR, + "chart drawing currently only supports GD and AGG renderers", + "msDrawChartLayer()"); return MS_FAILURE; } - if(chartTypeProcessingKey!=NULL) { - if( strcasecmp(chartTypeProcessingKey,"PIE") == 0 ) { - chartType=MS_CHART_TYPE_PIE; - } else if( strcasecmp(chartTypeProcessingKey,"BAR") == 0 ) { - chartType=MS_CHART_TYPE_BAR; - } else if( strcasecmp(chartTypeProcessingKey,"VBAR") == 0 ) { - chartType=MS_CHART_TYPE_VBAR; + if (chartTypeProcessingKey != NULL) { + if (strcasecmp(chartTypeProcessingKey, "PIE") == 0) { + chartType = MS_CHART_TYPE_PIE; + } else if (strcasecmp(chartTypeProcessingKey, "BAR") == 0) { + chartType = MS_CHART_TYPE_BAR; + } else if (strcasecmp(chartTypeProcessingKey, "VBAR") == 0) { + chartType = MS_CHART_TYPE_VBAR; } else { - msSetError(MS_MISCERR,"unknown chart type for processing key \"CHART_TYPE\", must be one of \"PIE\" or \"BAR\"", "msDrawChartLayer()"); + msSetError(MS_MISCERR, + "unknown chart type for processing key \"CHART_TYPE\", must " + "be one of \"PIE\" or \"BAR\"", + "msDrawChartLayer()"); return MS_FAILURE; } } - if(chartType == MS_CHART_TYPE_PIE) { + if (chartType == MS_CHART_TYPE_PIE) { pieLayerProcessDynamicDiameter(layer); } /* open this layer */ status = msLayerOpen(layer); - if(status != MS_SUCCESS) return MS_FAILURE; + if (status != MS_SUCCESS) + return MS_FAILURE; status = msLayerWhichItems(layer, MS_FALSE, NULL); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msLayerClose(layer); return MS_FAILURE; } /* identify target shapes */ - if(layer->transform == MS_TRUE) + if (layer->transform == MS_TRUE) searchrect = map->extent; else { searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; } - if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0)) + msProjectRect(&map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ status = msLayerWhichShapes(layer, searchrect, MS_FALSE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(layer); - if(chartType == MS_CHART_TYPE_PIE) + if (chartType == MS_CHART_TYPE_PIE) pieLayerCleanupDynamicDiameter(layer); return MS_SUCCESS; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(layer); - if(chartType == MS_CHART_TYPE_PIE) + if (chartType == MS_CHART_TYPE_PIE) pieLayerCleanupDynamicDiameter(layer); return MS_FAILURE; } - switch(chartType) { - case MS_CHART_TYPE_PIE: - status = msDrawPieChartLayer(map, layer, image); - break; - case MS_CHART_TYPE_BAR: - status = msDrawBarChartLayer(map, layer, image); - break; - case MS_CHART_TYPE_VBAR: - status = msDrawVBarChartLayer(map, layer, image); - break; - default: - return MS_FAILURE;/*shouldn't be here anyways*/ + switch (chartType) { + case MS_CHART_TYPE_PIE: + status = msDrawPieChartLayer(map, layer, image); + break; + case MS_CHART_TYPE_BAR: + status = msDrawBarChartLayer(map, layer, image); + break; + case MS_CHART_TYPE_VBAR: + status = msDrawVBarChartLayer(map, layer, image); + break; + default: + return MS_FAILURE; /*shouldn't be here anyways*/ } msLayerClose(layer); - if(chartType == MS_CHART_TYPE_PIE) + if (chartType == MS_CHART_TYPE_PIE) pieLayerCleanupDynamicDiameter(layer); } return status; diff --git a/mapcluster.c b/mapcluster.c index 548b0e74ed..1467dee3c1 100644 --- a/mapcluster.c +++ b/mapcluster.c @@ -33,36 +33,35 @@ #include #include "mapserver.h" - - - #ifdef USE_CLUSTER_PLUGIN #define USE_CLUSTER_EXTERNAL #endif /* custom attributes provided by this layer data source */ -#define MSCLUSTER_NUMITEMS 3 -#define MSCLUSTER_FEATURECOUNT "Cluster_FeatureCount" -#define MSCLUSTER_FEATURECOUNTINDEX -100 -#define MSCLUSTER_GROUP "Cluster_Group" -#define MSCLUSTER_GROUPINDEX -101 -#define MSCLUSTER_BASEFID "Cluster_BaseFID" -#define MSCLUSTER_BASEFIDINDEX -102 +#define MSCLUSTER_NUMITEMS 3 +#define MSCLUSTER_FEATURECOUNT "Cluster_FeatureCount" +#define MSCLUSTER_FEATURECOUNTINDEX -100 +#define MSCLUSTER_GROUP "Cluster_Group" +#define MSCLUSTER_GROUPINDEX -101 +#define MSCLUSTER_BASEFID "Cluster_BaseFID" +#define MSCLUSTER_BASEFIDINDEX -102 typedef struct cluster_tree_node clusterTreeNode; typedef struct cluster_info clusterInfo; typedef struct cluster_layer_info msClusterLayerInfo; /* forward declarations */ -void msClusterLayerCopyVirtualTable(layerVTableObj* vtable); -static void clusterTreeNodeDestroy(msClusterLayerInfo* layerinfo, clusterTreeNode *node); +void msClusterLayerCopyVirtualTable(layerVTableObj *vtable); +static void clusterTreeNodeDestroy(msClusterLayerInfo *layerinfo, + clusterTreeNode *node); /* cluster compare func */ -typedef int (*clusterCompareRegionFunc)(clusterInfo* current, clusterInfo* other); +typedef int (*clusterCompareRegionFunc)(clusterInfo *current, + clusterInfo *other); /* quadtree constants */ -#define SPLITRATIO 0.55 -#define TREE_MAX_DEPTH 10 +#define SPLITRATIO 0.55 +#define TREE_MAX_DEPTH 10 /* cluster algorithm */ #define MSCLUSTER_ALGORITHM_FULL 0 @@ -70,12 +69,12 @@ typedef int (*clusterCompareRegionFunc)(clusterInfo* current, clusterInfo* other /* cluster data */ struct cluster_info { - double x; /* x position of the current point */ - double y; /* y position of the current point */ - double avgx; /* average x positions of this cluster */ - double avgy; /* average y positions of this cluster */ - double varx; /* variance of the x positions of this cluster */ - double vary; /* variance of the y positions of this cluster */ + double x; /* x position of the current point */ + double y; /* y position of the current point */ + double avgx; /* average x positions of this cluster */ + double avgy; /* average y positions of this cluster */ + double varx; /* variance of the x positions of this cluster */ + double vary; /* variance of the y positions of this cluster */ shapeObj shape; /* current shape */ rectObj bounds; /* clustering region */ /* number of the neighbouring shapes */ @@ -84,13 +83,13 @@ struct cluster_info { int numcollected; int numremoved; int index; - clusterTreeNode* node; + clusterTreeNode *node; /* collection of the siblings */ - clusterInfo* siblings; + clusterInfo *siblings; /* next shape in the linked list */ - clusterInfo* next; + clusterInfo *next; /* current group */ - char* group; + char *group; int filter; }; @@ -102,34 +101,36 @@ struct cluster_tree_node { int numshapes; int index; int position; - clusterInfo* shapes; + clusterInfo *shapes; /* quad tree subnodes */ - clusterTreeNode* subnode[4]; + clusterTreeNode *subnode[4]; }; /* layeinfo */ struct cluster_layer_info { /* array of features (finalized clusters) */ - clusterInfo* finalized; - clusterInfo* finalizedSiblings; - clusterInfo* filtered; + clusterInfo *finalized; + clusterInfo *finalizedSiblings; + clusterInfo *filtered; int numFeatures; int numFinalized; int numFinalizedSiblings; int numFiltered; /* variables for collecting the best cluster and iterating with NextShape */ - clusterInfo* current; + clusterInfo *current; /* check whether all shapes should be returned behind a cluster */ int get_all_shapes; - /* check whether the location of the shapes should be preserved (no averaging) */ + /* check whether the location of the shapes should be preserved (no averaging) + */ int keep_locations; - /* the maxdistance and the buffer parameters are specified in map units (scale independent clustering) */ + /* the maxdistance and the buffer parameters are specified in map units (scale + * independent clustering) */ int use_map_units; double rank; /* root node of the quad tree */ - clusterTreeNode* root; + clusterTreeNode *root; int numNodes; - clusterTreeNode* finalizedNodes; + clusterTreeNode *finalizedNodes; int numFinalizedNodes; /* map extent used for building cluster data */ rectObj searchRect; @@ -143,12 +144,10 @@ struct cluster_layer_info { int algorithm; }; - extern int yyparse(parseObj *p); /* evaluate the filter expression */ -int msClusterEvaluateFilter(expressionObj* expression, shapeObj *shape) -{ +int msClusterEvaluateFilter(expressionObj *expression, shapeObj *shape) { if (expression->type == MS_EXPRESSION) { int status; parseObj p; @@ -161,7 +160,8 @@ int msClusterEvaluateFilter(expressionObj* expression, shapeObj *shape) status = yyparse(&p); if (status != 0) { - msSetError(MS_PARSEERR, "Failed to parse expression: %s", "msClusterEvaluateFilter", expression->string); + msSetError(MS_PARSEERR, "Failed to parse expression: %s", + "msClusterEvaluateFilter", expression->string); return 0; } @@ -172,58 +172,59 @@ int msClusterEvaluateFilter(expressionObj* expression, shapeObj *shape) } /* get the group text when creating the clusters */ -char *msClusterGetGroupText(expressionObj* expression, shapeObj *shape) -{ - char *tmpstr=NULL; - - if(expression->string) { - switch(expression->type) { - case(MS_STRING): - tmpstr = msStrdup(expression->string); - break; - case(MS_EXPRESSION): { - int status; - parseObj p; - - p.shape = shape; - p.expr = expression; - p.expr->curtoken = p.expr->tokens; /* reset */ - p.type = MS_PARSE_TYPE_STRING; - - status = yyparse(&p); - - if (status != 0) { - msSetError(MS_PARSEERR, "Failed to process text expression: %s", "msClusterGetGroupText", expression->string); - return NULL; - } +char *msClusterGetGroupText(expressionObj *expression, shapeObj *shape) { + char *tmpstr = NULL; - tmpstr = p.result.strval; - break; + if (expression->string) { + switch (expression->type) { + case (MS_STRING): + tmpstr = msStrdup(expression->string); + break; + case (MS_EXPRESSION): { + int status; + parseObj p; + + p.shape = shape; + p.expr = expression; + p.expr->curtoken = p.expr->tokens; /* reset */ + p.type = MS_PARSE_TYPE_STRING; + + status = yyparse(&p); + + if (status != 0) { + msSetError(MS_PARSEERR, "Failed to process text expression: %s", + "msClusterGetGroupText", expression->string); + return NULL; } - default: - break; + + tmpstr = p.result.strval; + break; + } + default: + break; } } - return(tmpstr); + return (tmpstr); } -int CompareEllipseRegion(clusterInfo* current, clusterInfo* other) -{ +int CompareEllipseRegion(clusterInfo *current, clusterInfo *other) { if (current->group && other->group && !EQUAL(current->group, other->group)) return MS_FALSE; if ((other->x - current->x) * (other->x - current->x) / - ((current->bounds.maxx - current->x) * (current->bounds.maxx - current->x)) + - (other->y - current->y) * (other->y - current->y) / - ((current->bounds.maxy - current->y) * (current->bounds.maxy - current->y)) > 1) + ((current->bounds.maxx - current->x) * + (current->bounds.maxx - current->x)) + + (other->y - current->y) * (other->y - current->y) / + ((current->bounds.maxy - current->y) * + (current->bounds.maxy - current->y)) > + 1) return MS_FALSE; return MS_TRUE; } -int CompareRectangleRegion(clusterInfo* current, clusterInfo* other) -{ +int CompareRectangleRegion(clusterInfo *current, clusterInfo *other) { if (current->group && other->group && !EQUAL(current->group, other->group)) return MS_FALSE; @@ -239,8 +240,7 @@ int CompareRectangleRegion(clusterInfo* current, clusterInfo* other) return MS_TRUE; } -static void treeSplitBounds( rectObj *in, rectObj *out1, rectObj *out2) -{ +static void treeSplitBounds(rectObj *in, rectObj *out1, rectObj *out2) { double range; /* -------------------------------------------------------------------- */ @@ -253,7 +253,7 @@ static void treeSplitBounds( rectObj *in, rectObj *out1, rectObj *out2) /* -------------------------------------------------------------------- */ /* Split in X direction. */ /* -------------------------------------------------------------------- */ - if((in->maxx - in->minx) > (in->maxy - in->miny)) { + if ((in->maxx - in->minx) > (in->maxy - in->miny)) { range = in->maxx - in->minx; out1->maxx = in->minx + range * SPLITRATIO; @@ -272,9 +272,8 @@ static void treeSplitBounds( rectObj *in, rectObj *out1, rectObj *out2) } /* alloc memory for a new tentative cluster */ -static clusterInfo *clusterInfoCreate(msClusterLayerInfo* layerinfo) -{ - clusterInfo* feature = (clusterInfo*)msSmallMalloc(sizeof(clusterInfo)); +static clusterInfo *clusterInfoCreate(msClusterLayerInfo *layerinfo) { + clusterInfo *feature = (clusterInfo *)msSmallMalloc(sizeof(clusterInfo)); msInitShape(&feature->shape); feature->numsiblings = 0; feature->numcollected = 0; @@ -290,10 +289,10 @@ static clusterInfo *clusterInfoCreate(msClusterLayerInfo* layerinfo) } /* destroy memory of the cluster list */ -static void clusterInfoDestroyList(msClusterLayerInfo* layerinfo, clusterInfo* feature) -{ - clusterInfo* s = feature; - clusterInfo* next; +static void clusterInfoDestroyList(msClusterLayerInfo *layerinfo, + clusterInfo *feature) { + clusterInfo *s = feature; + clusterInfo *next; /* destroy the shapes added to this node */ while (s) { next = s->next; @@ -309,13 +308,15 @@ static void clusterInfoDestroyList(msClusterLayerInfo* layerinfo, clusterInfo* f } /* alloc memory for a new treenode */ -static clusterTreeNode *clusterTreeNodeCreate(msClusterLayerInfo* layerinfo, rectObj rect) -{ - clusterTreeNode* node = (clusterTreeNode*)msSmallMalloc(sizeof(clusterTreeNode)); +static clusterTreeNode *clusterTreeNodeCreate(msClusterLayerInfo *layerinfo, + rectObj rect) { + clusterTreeNode *node = + (clusterTreeNode *)msSmallMalloc(sizeof(clusterTreeNode)); node->rect = rect; node->numshapes = 0; node->shapes = NULL; - node->subnode[0] = node->subnode[1] = node->subnode[2] = node->subnode[3] = NULL; + node->subnode[0] = node->subnode[1] = node->subnode[2] = node->subnode[3] = + NULL; node->index = layerinfo->numNodes; node->position = 0; ++layerinfo->numNodes; @@ -323,8 +324,8 @@ static clusterTreeNode *clusterTreeNodeCreate(msClusterLayerInfo* layerinfo, rec } /* traverse the quadtree and destroy all sub elements */ -static void clusterTreeNodeDestroy(msClusterLayerInfo* layerinfo, clusterTreeNode *node) -{ +static void clusterTreeNodeDestroy(msClusterLayerInfo *layerinfo, + clusterTreeNode *node) { int i; /* destroy the shapes added to this node */ clusterInfoDestroyList(layerinfo, node->shapes); @@ -340,10 +341,10 @@ static void clusterTreeNodeDestroy(msClusterLayerInfo* layerinfo, clusterTreeNod } /* destroy memory of the cluster finalized list (without recursion) */ -static void clusterTreeNodeDestroyList(msClusterLayerInfo* layerinfo, clusterTreeNode *node) -{ - clusterTreeNode* n = node; - clusterTreeNode* next; +static void clusterTreeNodeDestroyList(msClusterLayerInfo *layerinfo, + clusterTreeNode *node) { + clusterTreeNode *n = node; + clusterTreeNode *next; /* destroy the list of nodes */ while (n) { next = n->subnode[0]; @@ -354,8 +355,7 @@ static void clusterTreeNodeDestroyList(msClusterLayerInfo* layerinfo, clusterTre } } -void clusterDestroyData(msClusterLayerInfo *layerinfo) -{ +void clusterDestroyData(msClusterLayerInfo *layerinfo) { if (layerinfo->finalized) { clusterInfoDestroyList(layerinfo, layerinfo->finalized); layerinfo->finalized = NULL; @@ -391,17 +391,16 @@ void clusterDestroyData(msClusterLayerInfo *layerinfo) /* traverse the quadtree to find the neighbouring shapes and update some data on the related shapes (when adding a new feature)*/ -static void findRelatedShapes(msClusterLayerInfo* layerinfo, - clusterTreeNode *node, clusterInfo* current) -{ +static void findRelatedShapes(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, clusterInfo *current) { int i; - clusterInfo* s; + clusterInfo *s; /* -------------------------------------------------------------------- */ /* Does this node overlap the area of interest at all? If not, */ /* return without adding to the list at all. */ /* -------------------------------------------------------------------- */ - if(!msRectOverlap(&node->rect, ¤t->bounds)) + if (!msRectOverlap(&node->rect, ¤t->bounds)) return; /* Modify the feature count of the related shapes */ @@ -410,25 +409,35 @@ static void findRelatedShapes(msClusterLayerInfo* layerinfo, if (layerinfo->fnCompare(current, s)) { ++current->numsiblings; /* calculating the average positions */ - current->avgx = (current->avgx * current->numsiblings + s->x) / (current->numsiblings + 1); - current->avgy = (current->avgy * current->numsiblings + s->y) / (current->numsiblings + 1); + current->avgx = (current->avgx * current->numsiblings + s->x) / + (current->numsiblings + 1); + current->avgy = (current->avgy * current->numsiblings + s->y) / + (current->numsiblings + 1); /* calculating the variance */ - current->varx = current->varx * current->numsiblings / (current->numsiblings + 1) + - (s->x - current->avgx) * (s->x - current->avgx) / (current->numsiblings + 1); - current->vary = current->vary * current->numsiblings / (current->numsiblings + 1) + - (s->y - current->avgy) * (s->y - current->avgy) / (current->numsiblings + 1); + current->varx = + current->varx * current->numsiblings / (current->numsiblings + 1) + + (s->x - current->avgx) * (s->x - current->avgx) / + (current->numsiblings + 1); + current->vary = + current->vary * current->numsiblings / (current->numsiblings + 1) + + (s->y - current->avgy) * (s->y - current->avgy) / + (current->numsiblings + 1); if (layerinfo->fnCompare(s, current)) { /* this feature falls into the region of the other as well */ ++s->numsiblings; /* calculating the average positions */ - s->avgx = (s->avgx * s->numsiblings + current->x) / (s->numsiblings + 1); - s->avgy = (s->avgy * s->numsiblings + current->y) / (s->numsiblings + 1); + s->avgx = + (s->avgx * s->numsiblings + current->x) / (s->numsiblings + 1); + s->avgy = + (s->avgy * s->numsiblings + current->y) / (s->numsiblings + 1); /* calculating the variance */ s->varx = s->varx * s->numsiblings / (s->numsiblings + 1) + - (current->x - s->avgx) * (current->x - s->avgx) / (s->numsiblings + 1); + (current->x - s->avgx) * (current->x - s->avgx) / + (s->numsiblings + 1); s->vary = s->vary * s->numsiblings / (s->numsiblings + 1) + - (current->y - s->avgy) * (current->y - s->avgy) / (s->numsiblings + 1); + (current->y - s->avgy) * (current->y - s->avgy) / + (s->numsiblings + 1); } } s = s->next; @@ -444,18 +453,18 @@ static void findRelatedShapes(msClusterLayerInfo* layerinfo, } } -/* traverse the quadtree to find the neighbouring clusters and update data on the cluster*/ -static void findRelatedShapes2(msClusterLayerInfo* layerinfo, - clusterTreeNode *node, clusterInfo* current) -{ +/* traverse the quadtree to find the neighbouring clusters and update data on + * the cluster*/ +static void findRelatedShapes2(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, clusterInfo *current) { int i; - clusterInfo* s; - + clusterInfo *s; + /* -------------------------------------------------------------------- */ /* Does this node overlap the area of interest at all? If not, */ /* return without adding to the list at all. */ /* -------------------------------------------------------------------- */ - if(!msRectOverlap(&node->rect, ¤t->bounds)) + if (!msRectOverlap(&node->rect, ¤t->bounds)) return; /* Modify the feature count of the related shapes */ @@ -463,17 +472,17 @@ static void findRelatedShapes2(msClusterLayerInfo* layerinfo, while (s) { if (layerinfo->fnCompare(s, current)) { if (layerinfo->rank > 0) { - double r = (current->x - s->x) * (current->x - s->x) + (current->y - s->y) * (current->y - s->y); + double r = (current->x - s->x) * (current->x - s->x) + + (current->y - s->y) * (current->y - s->y); if (r < layerinfo->rank) { layerinfo->current = s; layerinfo->rank = r; } - } - else { + } else { /* no rank was specified, return immediately */ layerinfo->current = s; return; - } + } } s = s->next; } @@ -490,16 +499,17 @@ static void findRelatedShapes2(msClusterLayerInfo* layerinfo, /* traverse the quadtree to find the neighbouring shapes and update some data on the related shapes (when removing a feature) */ -static void findRelatedShapesRemove(msClusterLayerInfo* layerinfo, clusterTreeNode *node, clusterInfo* current) -{ +static void findRelatedShapesRemove(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, + clusterInfo *current) { int i; - clusterInfo* s; + clusterInfo *s; /* -------------------------------------------------------------------- */ /* Does this node overlap the area of interest at all? If not, */ /* return without adding to the list at all. */ /* -------------------------------------------------------------------- */ - if(!msRectOverlap(&node->rect, ¤t->bounds)) + if (!msRectOverlap(&node->rect, ¤t->bounds)) return; /* Modify the feature count of the related shapes */ @@ -508,12 +518,16 @@ static void findRelatedShapesRemove(msClusterLayerInfo* layerinfo, clusterTreeNo if (layerinfo->fnCompare(current, s)) { if (s->numsiblings > 0) { /* calculating the average positions */ - s->avgx = (s->avgx * (s->numsiblings + 1) - current->x) / s->numsiblings; - s->avgy = (s->avgy * (s->numsiblings + 1) - current->y) / s->numsiblings; + s->avgx = + (s->avgx * (s->numsiblings + 1) - current->x) / s->numsiblings; + s->avgy = + (s->avgy * (s->numsiblings + 1) - current->y) / s->numsiblings; /* calculating the variance */ - s->varx = (s->varx - (current->x - s->avgx) * (current->x - s->avgx) / s->numsiblings) * + s->varx = (s->varx - (current->x - s->avgx) * (current->x - s->avgx) / + s->numsiblings) * (s->numsiblings + 1) / s->numsiblings; - s->vary = (s->vary - (current->y - s->avgy) * (current->y - s->avgy) / s->numsiblings) * + s->vary = (s->vary - (current->y - s->avgy) * (current->y - s->avgy) / + s->numsiblings) * (s->numsiblings + 1) / s->numsiblings; --s->numsiblings; ++s->numremoved; @@ -530,10 +544,9 @@ static void findRelatedShapesRemove(msClusterLayerInfo* layerinfo, clusterTreeNo } /* setting the aggregated attributes */ -static void InitShapeAttributes(layerObj* layer, clusterInfo* base) -{ +static void InitShapeAttributes(layerObj *layer, clusterInfo *base) { int i; - int* itemindexes = layer->iteminfo; + int *itemindexes = layer->iteminfo; for (i = 0; i < layer->numitems; i++) { if (base->shape.numvalues <= i) @@ -567,10 +580,10 @@ static void InitShapeAttributes(layerObj* layer, clusterInfo* base) } /* update the shape attributes (aggregate) */ -static void UpdateShapeAttributes(layerObj* layer, clusterInfo* base, clusterInfo* current) -{ +static void UpdateShapeAttributes(layerObj *layer, clusterInfo *base, + clusterInfo *current) { int i; - int* itemindexes = layer->iteminfo; + int *itemindexes = layer->iteminfo; for (i = 0; i < layer->numitems; i++) { if (base->shape.numvalues <= i) @@ -585,8 +598,8 @@ static void UpdateShapeAttributes(layerObj* layer, clusterInfo* base, clusterInf /* setting the base feature index for each cluster member */ if (itemindexes[i] == MSCLUSTER_BASEFIDINDEX) { - msFree(current->shape.values[i]); - current->shape.values[i] = msIntToString(base->shape.index); + msFree(current->shape.values[i]); + current->shape.values[i] = msIntToString(base->shape.index); } if (current->shape.values[i]) { @@ -601,7 +614,8 @@ static void UpdateShapeAttributes(layerObj* layer, clusterInfo* base, clusterInf base->shape.values[i] = msStrdup(current->shape.values[i]); } } else if (EQUALN(layer->items[i], "Sum:", 4)) { - double sum = atof(base->shape.values[i]) + atof(current->shape.values[i]); + double sum = + atof(base->shape.values[i]) + atof(current->shape.values[i]); msFree(base->shape.values[i]); base->shape.values[i] = msDoubleToString(sum, MS_FALSE); } else if (EQUALN(layer->items[i], "Count:", 6)) { @@ -613,16 +627,18 @@ static void UpdateShapeAttributes(layerObj* layer, clusterInfo* base, clusterInf } } -static int BuildFeatureAttributes(layerObj* layer, msClusterLayerInfo* layerinfo, shapeObj* shape) -{ - char** values; +static int BuildFeatureAttributes(layerObj *layer, + msClusterLayerInfo *layerinfo, + shapeObj *shape) { + char **values; int i; - int* itemindexes = layer->iteminfo; + int *itemindexes = layer->iteminfo; if (layer->numitems == layerinfo->srcLayer.numitems) - return MS_SUCCESS; /* we don't have custom attributes, no need to reconstruct the array */ + return MS_SUCCESS; /* we don't have custom attributes, no need to + reconstruct the array */ - values = msSmallMalloc(sizeof(char*) * (layer->numitems)); + values = msSmallMalloc(sizeof(char *) * (layer->numitems)); for (i = 0; i < layer->numitems; i++) { if (itemindexes[i] == MSCLUSTER_FEATURECOUNTINDEX) { @@ -647,11 +663,11 @@ static int BuildFeatureAttributes(layerObj* layer, msClusterLayerInfo* layerinfo } /* traverse the quadtree to find the best renking cluster */ -static void findBestCluster(layerObj* layer, msClusterLayerInfo* layerinfo, clusterTreeNode *node) -{ +static void findBestCluster(layerObj *layer, msClusterLayerInfo *layerinfo, + clusterTreeNode *node) { int i; double rank; - clusterInfo* s = node->shapes; + clusterInfo *s = node->shapes; while (s) { if (s->filter < 0 && layer->cluster.filter.string != NULL) { InitShapeAttributes(layer, s); @@ -665,7 +681,9 @@ static void findBestCluster(layerObj* layer, msClusterLayerInfo* layerinfo, clus } /* calculating the rank */ - rank = (s->x - s->avgx) * (s->x - s->avgx) + (s->y - s->avgy) * (s->y - s->avgy) /*+ s->varx + s->vary*/ + (double)1/ (1 + s->numsiblings); + rank = (s->x - s->avgx) * (s->x - s->avgx) + + (s->y - s->avgy) * (s->y - s->avgy) /*+ s->varx + s->vary*/ + + (double)1 / (1 + s->numsiblings); if (rank < layerinfo->rank) { layerinfo->current = s; @@ -682,18 +700,19 @@ static void findBestCluster(layerObj* layer, msClusterLayerInfo* layerinfo, clus } /* adding the shape based on the shape bounds (point) */ -static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node, clusterInfo* shape, int depth) -{ +static int treeNodeAddShape(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, clusterInfo *shape, + int depth) { int i; /* -------------------------------------------------------------------- */ /* If there are subnodes, then consider whether this object */ /* will fit in them. */ /* -------------------------------------------------------------------- */ - if( depth > 1 && node->subnode[0] != NULL ) { - for(i = 0; i < 4; i++ ) { - if( msRectContained(&shape->shape.bounds, &node->subnode[i]->rect)) { - return treeNodeAddShape( layerinfo, node->subnode[i], shape, depth-1); + if (depth > 1 && node->subnode[0] != NULL) { + for (i = 0; i < 4; i++) { + if (msRectContained(&shape->shape.bounds, &node->subnode[i]->rect)) { + return treeNodeAddShape(layerinfo, node->subnode[i], shape, depth - 1); } } } @@ -702,7 +721,7 @@ static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node /* Otherwise, consider creating four subnodes if could fit into */ /* them, and adding to the appropriate subnode. */ /* -------------------------------------------------------------------- */ - else if( depth > 1 && node->subnode[0] == NULL ) { + else if (depth > 1 && node->subnode[0] == NULL) { rectObj half1, half2, quad1, quad2, quad3, quad4; int subnode = -1; @@ -710,13 +729,13 @@ static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node treeSplitBounds(&half1, &quad1, &quad2); treeSplitBounds(&half2, &quad3, &quad4); - if(msRectContained(&shape->shape.bounds, &quad1)) + if (msRectContained(&shape->shape.bounds, &quad1)) subnode = 0; - else if(msRectContained(&shape->shape.bounds, &quad2)) + else if (msRectContained(&shape->shape.bounds, &quad2)) subnode = 1; - else if(msRectContained(&shape->shape.bounds, &quad3)) + else if (msRectContained(&shape->shape.bounds, &quad3)) subnode = 2; - else if(msRectContained(&shape->shape.bounds, &quad4)) + else if (msRectContained(&shape->shape.bounds, &quad4)) subnode = 3; if (subnode >= 0) { @@ -737,7 +756,8 @@ static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node node->subnode[3]->position = node->position * 4 + 3; /* add to subnode */ - return treeNodeAddShape(layerinfo, node->subnode[subnode], shape, depth-1); + return treeNodeAddShape(layerinfo, node->subnode[subnode], shape, + depth - 1); } } @@ -750,16 +770,17 @@ static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node return MS_SUCCESS; } -/* collecting the cluster shapes, returns true if this subnode must be removed */ -static int collectClusterShapes(msClusterLayerInfo* layerinfo, clusterTreeNode *node, clusterInfo* current) -{ +/* collecting the cluster shapes, returns true if this subnode must be removed + */ +static int collectClusterShapes(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, clusterInfo *current) { int i; - clusterInfo* prev = NULL; - clusterInfo* s = node->shapes; + clusterInfo *prev = NULL; + clusterInfo *s = node->shapes; - if(!msRectOverlap(&node->rect, ¤t->bounds)) - return (!node->shapes && !node->subnode[0] && !node->subnode[1] - && !node->subnode[2] && !node->subnode[3]); + if (!msRectOverlap(&node->rect, ¤t->bounds)) + return (!node->shapes && !node->subnode[0] && !node->subnode[1] && + !node->subnode[2] && !node->subnode[3]); /* removing the shapes from this node if overlap with the cluster */ while (s) { @@ -809,7 +830,8 @@ static int collectClusterShapes(msClusterLayerInfo* layerinfo, clusterTreeNode * /* Recurse to subnodes if they exist */ for (i = 0; i < 4; i++) { - if (node->subnode[i] && collectClusterShapes(layerinfo, node->subnode[i], current)) { + if (node->subnode[i] && + collectClusterShapes(layerinfo, node->subnode[i], current)) { /* placing this empty node to the finalization queue */ node->subnode[i]->subnode[0] = layerinfo->finalizedNodes; layerinfo->finalizedNodes = node->subnode[i]; @@ -819,16 +841,17 @@ static int collectClusterShapes(msClusterLayerInfo* layerinfo, clusterTreeNode * } /* returns true is this subnode must be removed */ - return (!node->shapes && !node->subnode[0] && !node->subnode[1] - && !node->subnode[2] && !node->subnode[3]); + return (!node->shapes && !node->subnode[0] && !node->subnode[1] && + !node->subnode[2] && !node->subnode[3]); } -/* collecting the cluster shapes, returns true if this subnode must be removed */ -static int collectClusterShapes2(layerObj* layer, msClusterLayerInfo* layerinfo, clusterTreeNode *node) -{ +/* collecting the cluster shapes, returns true if this subnode must be removed + */ +static int collectClusterShapes2(layerObj *layer, msClusterLayerInfo *layerinfo, + clusterTreeNode *node) { int i; - clusterInfo* current = NULL; - clusterInfo* s; + clusterInfo *current = NULL; + clusterInfo *s; while (node->shapes) { s = node->shapes; @@ -838,20 +861,20 @@ static int collectClusterShapes2(layerObj* layer, msClusterLayerInfo* layerinfo, InitShapeAttributes(layer, s); if (s->filter) { - s->next = layerinfo->finalized; - layerinfo->finalized = s; - ++layerinfo->numFinalized; + s->next = layerinfo->finalized; + layerinfo->finalized = s; + ++layerinfo->numFinalized; } else { - /* this shape is filtered */ - s->next = layerinfo->filtered; - layerinfo->filtered = s; - ++layerinfo->numFiltered; + /* this shape is filtered */ + s->next = layerinfo->filtered; + layerinfo->filtered = s; + ++layerinfo->numFiltered; } /* update the parameters of the related shapes if any */ if (s->siblings) { current = s->siblings; - while(current) { + while (current) { UpdateShapeAttributes(layer, s, current); /* setting the average position to the cluster position */ @@ -875,7 +898,8 @@ static int collectClusterShapes2(layerObj* layer, msClusterLayerInfo* layerinfo, /* Recurse to subnodes if they exist */ for (i = 0; i < 4; i++) { - if (node->subnode[i] && collectClusterShapes2(layer, layerinfo, node->subnode[i])) { + if (node->subnode[i] && + collectClusterShapes2(layer, layerinfo, node->subnode[i])) { /* placing this empty node to the finalization queue */ node->subnode[i]->subnode[0] = layerinfo->finalizedNodes; layerinfo->finalizedNodes = node->subnode[i]; @@ -885,18 +909,18 @@ static int collectClusterShapes2(layerObj* layer, msClusterLayerInfo* layerinfo, } /* returns true is this subnode must be removed */ - return (!node->shapes && !node->subnode[0] && !node->subnode[1] - && !node->subnode[2] && !node->subnode[3]); + return (!node->shapes && !node->subnode[0] && !node->subnode[1] && + !node->subnode[2] && !node->subnode[3]); } -int selectClusterShape(layerObj* layer, long shapeindex) -{ +int selectClusterShape(layerObj *layer, long shapeindex) { int i; - clusterInfo* current; - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; + clusterInfo *current; + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer not open: %s", "selectClusterShape()", layer->name); + msSetError(MS_MISCERR, "Layer not open: %s", "selectClusterShape()", + layer->name); return MS_FAILURE; } @@ -912,8 +936,10 @@ int selectClusterShape(layerObj* layer, long shapeindex) layerinfo->current = current; if (layerinfo->keep_locations == MS_FALSE) { - current->shape.line[0].point[0].x = current->shape.bounds.minx = current->shape.bounds.maxx = current->avgx; - current->shape.line[0].point[0].y = current->shape.bounds.miny = current->shape.bounds.maxy = current->avgy; + current->shape.line[0].point[0].x = current->shape.bounds.minx = + current->shape.bounds.maxx = current->avgx; + current->shape.line[0].point[0].y = current->shape.bounds.miny = + current->shape.bounds.maxy = current->avgy; } return MS_SUCCESS; @@ -921,10 +947,10 @@ int selectClusterShape(layerObj* layer, long shapeindex) /* update the parameters from the related shapes */ #ifdef ms_notused -static void UpdateClusterParameters(msClusterLayerInfo* layerinfo, clusterTreeNode *node, clusterInfo *shape) -{ +static void UpdateClusterParameters(msClusterLayerInfo *layerinfo, + clusterTreeNode *node, clusterInfo *shape) { int i; - clusterInfo* s = node->shapes; + clusterInfo *s = node->shapes; while (s) { if (layerinfo->fnCompare(shape, s)) { @@ -942,13 +968,13 @@ static void UpdateClusterParameters(msClusterLayerInfo* layerinfo, clusterTreeNo } } -/* check for the validity of the clusters added to the tree (for debug purposes) */ -static int ValidateTree(msClusterLayerInfo* layerinfo, clusterTreeNode *node) -{ +/* check for the validity of the clusters added to the tree (for debug purposes) + */ +static int ValidateTree(msClusterLayerInfo *layerinfo, clusterTreeNode *node) { int i; int isValid = MS_TRUE; - clusterInfo* s = node->shapes; + clusterInfo *s = node->shapes; while (s) { double avgx = s->avgx; double avgy = s->avgy; @@ -979,7 +1005,8 @@ static int ValidateTree(msClusterLayerInfo* layerinfo, clusterTreeNode *node) /* Recurse to subnodes if they exist */ for (i = 0; i < 4; i++) { - if (node->subnode[i] && ValidateTree(layerinfo, node->subnode[i]) == MS_FALSE) + if (node->subnode[i] && + ValidateTree(layerinfo, node->subnode[i]) == MS_FALSE) return MS_FALSE; } @@ -989,30 +1016,31 @@ static int ValidateTree(msClusterLayerInfo* layerinfo, clusterTreeNode *node) #endif /* rebuild the clusters according to the current extent */ -int RebuildClusters(layerObj *layer, int isQuery) -{ - mapObj* map; - layerObj* srcLayer; +int RebuildClusters(layerObj *layer, int isQuery) { + mapObj *map; + layerObj *srcLayer; double distance, maxDistanceX, maxDistanceY, cellSizeX, cellSizeY; rectObj searchrect; int status; - clusterInfo* current; + clusterInfo *current; int depth; const char *pszProcessing; #ifdef USE_CLUSTER_EXTERNAL int layerIndex; #endif - reprojectionObj* reprojector = NULL; + reprojectionObj *reprojector = NULL; - msClusterLayerInfo* layerinfo = layer->layerinfo; + msClusterLayerInfo *layerinfo = layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer is not open: %s", "RebuildClusters()", layer->name); + msSetError(MS_MISCERR, "Layer is not open: %s", "RebuildClusters()", + layer->name); return MS_FAILURE; } if (!layer->map) { - msSetError(MS_MISCERR, "No map associated with this layer: %s", "RebuildClusters()", layer->name); + msSetError(MS_MISCERR, "No map associated with this layer: %s", + "RebuildClusters()", layer->name); return MS_FAILURE; } @@ -1025,37 +1053,37 @@ int RebuildClusters(layerObj *layer, int isQuery) /* check whether the simplified algorithm was selected */ pszProcessing = msLayerGetProcessingKey(layer, "CLUSTER_ALGORITHM"); - if(pszProcessing && !strncasecmp(pszProcessing,"SIMPLE",6)) - layerinfo->algorithm = MSCLUSTER_ALGORITHM_SIMPLE; + if (pszProcessing && !strncasecmp(pszProcessing, "SIMPLE", 6)) + layerinfo->algorithm = MSCLUSTER_ALGORITHM_SIMPLE; else - layerinfo->algorithm = MSCLUSTER_ALGORITHM_FULL; + layerinfo->algorithm = MSCLUSTER_ALGORITHM_FULL; /* check whether all shapes should be returned from a query */ - if(msLayerGetProcessingKey(layer, "CLUSTER_GET_ALL_SHAPES") != NULL) + if (msLayerGetProcessingKey(layer, "CLUSTER_GET_ALL_SHAPES") != NULL) layerinfo->get_all_shapes = MS_TRUE; else layerinfo->get_all_shapes = MS_FALSE; /* check whether the location of the shapes should be preserved */ - if(msLayerGetProcessingKey(layer, "CLUSTER_KEEP_LOCATIONS") != NULL) + if (msLayerGetProcessingKey(layer, "CLUSTER_KEEP_LOCATIONS") != NULL) layerinfo->keep_locations = MS_TRUE; else - layerinfo->keep_locations = MS_FALSE; + layerinfo->keep_locations = MS_FALSE; - /* check whether the maxdistance and the buffer parameters + /* check whether the maxdistance and the buffer parameters are specified in map units (scale independent clustering) */ - if(msLayerGetProcessingKey(layer, "CLUSTER_USE_MAP_UNITS") != NULL) + if (msLayerGetProcessingKey(layer, "CLUSTER_USE_MAP_UNITS") != NULL) layerinfo->use_map_units = MS_TRUE; else layerinfo->use_map_units = MS_FALSE; /* identify the current extent */ - if(layer->transform == MS_TRUE) + if (layer->transform == MS_TRUE) searchrect = map->extent; else { searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; } if (searchrect.minx == layerinfo->searchRect.minx && @@ -1072,8 +1100,9 @@ int RebuildClusters(layerObj *layer, int isQuery) layerinfo->searchRect = searchrect; /* reproject the rectangle to layer coordinates */ - if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0)) + msProjectRect(&map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ /* determine the compare method */ layerinfo->fnCompare = CompareRectangleRegion; @@ -1086,15 +1115,17 @@ int RebuildClusters(layerObj *layer, int isQuery) depth = 0; distance = layer->cluster.maxdistance; if (layerinfo->use_map_units == MS_TRUE) { - while ((distance < (searchrect.maxx - searchrect.minx) || distance < (searchrect.maxy - searchrect.miny)) && depth <= TREE_MAX_DEPTH) { + while ((distance < (searchrect.maxx - searchrect.minx) || + distance < (searchrect.maxy - searchrect.miny)) && + depth <= TREE_MAX_DEPTH) { distance *= 2; ++depth; } cellSizeX = 1; cellSizeY = 1; - } - else { - while ((distance < map->width || distance < map->height) && depth <= TREE_MAX_DEPTH) { + } else { + while ((distance < map->width || distance < map->height) && + depth <= TREE_MAX_DEPTH) { distance *= 2; ++depth; } @@ -1107,7 +1138,8 @@ int RebuildClusters(layerObj *layer, int isQuery) maxDistanceX = layer->cluster.maxdistance * cellSizeX; maxDistanceY = layer->cluster.maxdistance * cellSizeY; - /* increase the search rectangle so that the neighbouring shapes are also retrieved */ + /* increase the search rectangle so that the neighbouring shapes are also + * retrieved */ searchrect.minx -= layer->cluster.buffer * cellSizeX; searchrect.maxx += layer->cluster.buffer * cellSizeX; searchrect.miny -= layer->cluster.buffer * cellSizeY; @@ -1122,28 +1154,31 @@ int RebuildClusters(layerObj *layer, int isQuery) /* start retrieving the shapes */ status = msLayerWhichShapes(srcLayer, searchrect, isQuery); - if(status == MS_DONE) { + if (status == MS_DONE) { /* no overlap */ return MS_SUCCESS; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { return MS_FAILURE; } - /* step through the source shapes and populate the quadtree with the tentative clusters */ + /* step through the source shapes and populate the quadtree with the tentative + * clusters */ if ((current = clusterInfoCreate(layerinfo)) == NULL) return MS_FAILURE; #if defined(USE_CLUSTER_EXTERNAL) - if(srcLayer->transform == MS_TRUE && srcLayer->project && layer->transform == MS_TRUE && layer->project &&msProjectionsDiffer(&(srcLayer->projection), &(layer->projection))) - { - reprojector = msProjectCreateReprojector(&srcLayer->projection, &layer->projection); - } + if (srcLayer->transform == MS_TRUE && srcLayer->project && + layer->transform == MS_TRUE && layer->project && + msProjectionsDiffer(&(srcLayer->projection), &(layer->projection))) { + reprojector = + msProjectCreateReprojector(&srcLayer->projection, &layer->projection); + } #endif - - while((status = msLayerNextShape(srcLayer, ¤t->shape)) == MS_SUCCESS) { + + while ((status = msLayerNextShape(srcLayer, ¤t->shape)) == MS_SUCCESS) { #if defined(USE_CLUSTER_EXTERNAL) /* transform the shape to the projection of this layer */ - if( reprojector ) + if (reprojector) msProjectShapeEx(reprojector, ¤t->shape); #endif /* set up positions and variance */ @@ -1157,11 +1192,12 @@ int RebuildClusters(layerObj *layer, int isQuery) current->bounds.maxy = current->y + maxDistanceY; /* if the shape doesn't overlap we must skip it to avoid further issues */ - if(!msRectOverlap(&searchrect, ¤t->bounds)) { + if (!msRectOverlap(&searchrect, ¤t->bounds)) { msFreeShape(¤t->shape); msInitShape(¤t->shape); - msDebug("Skipping an invalid shape falling outside of the given extent\n"); + msDebug( + "Skipping an invalid shape falling outside of the given extent\n"); continue; } @@ -1171,20 +1207,21 @@ int RebuildClusters(layerObj *layer, int isQuery) /* evaluate the group expression */ if (layer->cluster.group.string) - current->group = msClusterGetGroupText(&layer->cluster.group, ¤t->shape); + current->group = + msClusterGetGroupText(&layer->cluster.group, ¤t->shape); if (layerinfo->algorithm == MSCLUSTER_ALGORITHM_FULL) { /*start a query for the related shapes */ findRelatedShapes(layerinfo, layerinfo->root, current); /* add this shape to the tree */ - if (treeNodeAddShape(layerinfo, layerinfo->root, current, depth) != MS_SUCCESS) { + if (treeNodeAddShape(layerinfo, layerinfo->root, current, depth) != + MS_SUCCESS) { clusterInfoDestroyList(layerinfo, current); msProjectDestroyReprojector(reprojector); return MS_FAILURE; } - } - else if (layerinfo->algorithm == MSCLUSTER_ALGORITHM_SIMPLE) { + } else if (layerinfo->algorithm == MSCLUSTER_ALGORITHM_SIMPLE) { /* find a related cluster and try to assign */ layerinfo->rank = 0; layerinfo->current = NULL; @@ -1193,10 +1230,10 @@ int RebuildClusters(layerObj *layer, int isQuery) /* store these points until all clusters are created */ current->next = layerinfo->finalizedSiblings; layerinfo->finalizedSiblings = current; - } - else { + } else { /* if not found add this shape as a new cluster */ - if (treeNodeAddShape(layerinfo, layerinfo->root, current, depth) != MS_SUCCESS) { + if (treeNodeAddShape(layerinfo, layerinfo->root, current, depth) != + MS_SUCCESS) { clusterInfoDestroyList(layerinfo, current); msProjectDestroyReprojector(reprojector); return MS_FAILURE; @@ -1224,12 +1261,15 @@ int RebuildClusters(layerObj *layer, int isQuery) /* pick up the best cluster from the tree and do the finalization */ /* the initial rank must be big enough */ - layerinfo->rank = (searchrect.maxx - searchrect.minx) * (searchrect.maxx - searchrect.minx) + - (searchrect.maxy - searchrect.miny) * (searchrect.maxy - searchrect.miny) + 1; - + layerinfo->rank = (searchrect.maxx - searchrect.minx) * + (searchrect.maxx - searchrect.minx) + + (searchrect.maxy - searchrect.miny) * + (searchrect.maxy - searchrect.miny) + + 1; + layerinfo->current = NULL; findBestCluster(layer, layerinfo, layerinfo->root); - + if (layerinfo->current == NULL) { if (layer->debug >= MS_DEBUGLEVEL_VVV) msDebug("Clustering terminated.\n"); @@ -1238,18 +1278,23 @@ int RebuildClusters(layerObj *layer, int isQuery) /* Update the feature count of the shape */ InitShapeAttributes(layer, layerinfo->current); - + /* collecting the shapes of the cluster */ collectClusterShapes(layerinfo, layerinfo->root, layerinfo->current); if (layer->debug >= MS_DEBUGLEVEL_VVV) { - msDebug("processing cluster %p: rank=%lf fcount=%d ncoll=%d nfin=%d nfins=%d nflt=%d bounds={%lf %lf %lf %lf}\n", layerinfo->current, layerinfo->rank, layerinfo->current->numsiblings + 1, - layerinfo->current->numcollected, layerinfo->numFinalized, layerinfo->numFinalizedSiblings, - layerinfo->numFiltered, layerinfo->current->bounds.minx, layerinfo->current->bounds.miny, - layerinfo->current->bounds.maxx, layerinfo->current->bounds.maxy); + msDebug( + "processing cluster %p: rank=%lf fcount=%d ncoll=%d nfin=%d " + "nfins=%d nflt=%d bounds={%lf %lf %lf %lf}\n", + layerinfo->current, layerinfo->rank, + layerinfo->current->numsiblings + 1, + layerinfo->current->numcollected, layerinfo->numFinalized, + layerinfo->numFinalizedSiblings, layerinfo->numFiltered, + layerinfo->current->bounds.minx, layerinfo->current->bounds.miny, + layerinfo->current->bounds.maxx, layerinfo->current->bounds.maxy); if (layerinfo->current->node) { char pszBuffer[TREE_MAX_DEPTH + 1]; - clusterTreeNode* node = layerinfo->current->node; + clusterTreeNode *node = layerinfo->current->node; int position = node->position; int i = 1; while (position > 0 && i <= TREE_MAX_DEPTH) { @@ -1258,11 +1303,14 @@ int RebuildClusters(layerObj *layer, int isQuery) ++i; } pszBuffer[TREE_MAX_DEPTH] = 0; - - msDebug(" ->node %p: count=%d index=%d pos=%s subn={%p %p %p %p} rect={%lf %lf %lf %lf}\n", - node, node->numshapes, node->index, pszBuffer + TREE_MAX_DEPTH - i + 1, - node->subnode[0], node->subnode[1], node->subnode[2], node->subnode[3], - node->rect.minx, node->rect.miny, node->rect.maxx, node->rect.maxy); + + msDebug(" ->node %p: count=%d index=%d pos=%s subn={%p %p %p %p} " + "rect={%lf %lf %lf %lf}\n", + node, node->numshapes, node->index, + pszBuffer + TREE_MAX_DEPTH - i + 1, node->subnode[0], + node->subnode[1], node->subnode[2], node->subnode[3], + node->rect.minx, node->rect.miny, node->rect.maxx, + node->rect.maxy); } } @@ -1275,7 +1323,7 @@ int RebuildClusters(layerObj *layer, int isQuery) if (layerinfo->current->numsiblings > 0) { /* update the parameters due to the shape removal */ findRelatedShapesRemove(layerinfo, layerinfo->root, layerinfo->current); - + if (layerinfo->current->filter == 0) { /* filtered shapes has no siblings */ layerinfo->current->numsiblings = 0; @@ -1286,7 +1334,7 @@ int RebuildClusters(layerObj *layer, int isQuery) /* update the parameters of the related shapes if any */ if (layerinfo->finalizedSiblings) { current = layerinfo->finalizedSiblings; - while(current) { + while (current) { /* update the parameters due to the shape removal */ findRelatedShapesRemove(layerinfo, layerinfo->root, current); UpdateShapeAttributes(layer, layerinfo->current, current); @@ -1305,7 +1353,7 @@ int RebuildClusters(layerObj *layer, int isQuery) current->next = layerinfo->finalized; layerinfo->finalized = layerinfo->finalizedSiblings; } else { - /* preserve the clustered siblings for later use */ + /* preserve the clustered siblings for later use */ layerinfo->current->siblings = layerinfo->finalizedSiblings; } break; @@ -1332,32 +1380,31 @@ int RebuildClusters(layerObj *layer, int isQuery) } #endif } - } - else if (layerinfo->algorithm == MSCLUSTER_ALGORITHM_SIMPLE) { + } else if (layerinfo->algorithm == MSCLUSTER_ALGORITHM_SIMPLE) { /* assingn stired points to clusters */ while (layerinfo->finalizedSiblings) { current = layerinfo->finalizedSiblings; - layerinfo->rank = maxDistanceX * maxDistanceX + maxDistanceY * maxDistanceY; - layerinfo->current = NULL; + layerinfo->rank = + maxDistanceX * maxDistanceX + maxDistanceY * maxDistanceY; + layerinfo->current = NULL; findRelatedShapes2(layerinfo, layerinfo->root, current); if (layerinfo->current) { - clusterInfo* s = layerinfo->current; + clusterInfo *s = layerinfo->current; /* found a matching cluster */ ++s->numsiblings; /* assign to cluster */ layerinfo->finalizedSiblings = current->next; current->next = s->siblings; s->siblings = current; - } - else { + } else { /* this appears to be a bug */ layerinfo->finalizedSiblings = current->next; current->next = layerinfo->filtered; layerinfo->filtered = current; ++layerinfo->numFiltered; - } + } } - + /* collecting the shapes of the cluster */ collectClusterShapes2(layer, layerinfo, layerinfo->root); } @@ -1369,9 +1416,8 @@ int RebuildClusters(layerObj *layer, int isQuery) } /* Close the the combined layer */ -int msClusterLayerClose(layerObj *layer) -{ - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; +int msClusterLayerClose(layerObj *layer) { + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; if (!layerinfo) return MS_SUCCESS; @@ -1386,39 +1432,35 @@ int msClusterLayerClose(layerObj *layer) #ifndef USE_CLUSTER_EXTERNAL /* switch back to the source layer vtable */ - if( msInitializeVirtualTable(layer) != MS_SUCCESS ) - return MS_FAILURE; + if (msInitializeVirtualTable(layer) != MS_SUCCESS) + return MS_FAILURE; #endif return MS_SUCCESS; } /* Return MS_TRUE if layer is open, MS_FALSE otherwise. */ -int msClusterLayerIsOpen(layerObj *layer) -{ +int msClusterLayerIsOpen(layerObj *layer) { if (layer->layerinfo) - return(MS_TRUE); + return (MS_TRUE); else - return(MS_FALSE); + return (MS_FALSE); } /* Free the itemindexes array in a layer. */ -void msClusterLayerFreeItemInfo(layerObj *layer) -{ +void msClusterLayerFreeItemInfo(layerObj *layer) { msFree(layer->iteminfo); layer->iteminfo = NULL; } - /* allocate the iteminfo index array - same order as the item list */ -int msClusterLayerInitItemInfo(layerObj *layer) -{ +int msClusterLayerInitItemInfo(layerObj *layer) { int i, numitems; int *itemindexes; - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; - if(layer->numitems == 0) { + if (layer->numitems == 0) { return MS_SUCCESS; } @@ -1428,7 +1470,7 @@ int msClusterLayerInitItemInfo(layerObj *layer) /* Cleanup any previous item selection */ msClusterLayerFreeItemInfo(layer); - layer->iteminfo = (int *) msSmallMalloc(sizeof(int) * layer->numitems); + layer->iteminfo = (int *)msSmallMalloc(sizeof(int) * layer->numitems); itemindexes = layer->iteminfo; @@ -1446,7 +1488,7 @@ int msClusterLayerInitItemInfo(layerObj *layer) } msLayerFreeItemInfo(&layerinfo->srcLayer); - if(layerinfo->srcLayer.items) { + if (layerinfo->srcLayer.items) { msFreeCharArray(layerinfo->srcLayer.items, layerinfo->srcLayer.numitems); layerinfo->srcLayer.items = NULL; layerinfo->srcLayer.numitems = 0; @@ -1454,19 +1496,24 @@ int msClusterLayerInitItemInfo(layerObj *layer) if (numitems > 0) { /* now allocate and set the layer item parameters */ - layerinfo->srcLayer.items = (char **)msSmallMalloc(sizeof(char *)*numitems); + layerinfo->srcLayer.items = + (char **)msSmallMalloc(sizeof(char *) * numitems); layerinfo->srcLayer.numitems = numitems; for (i = 0; i < layer->numitems; i++) { if (itemindexes[i] >= 0) { if (EQUALN(layer->items[i], "Min:", 4)) - layerinfo->srcLayer.items[itemindexes[i]] = msStrdup(layer->items[i] + 4); + layerinfo->srcLayer.items[itemindexes[i]] = + msStrdup(layer->items[i] + 4); else if (EQUALN(layer->items[i], "Max:", 4)) - layerinfo->srcLayer.items[itemindexes[i]] = msStrdup(layer->items[i] + 4); + layerinfo->srcLayer.items[itemindexes[i]] = + msStrdup(layer->items[i] + 4); else if (EQUALN(layer->items[i], "Sum:", 4)) - layerinfo->srcLayer.items[itemindexes[i]] = msStrdup(layer->items[i] + 4); + layerinfo->srcLayer.items[itemindexes[i]] = + msStrdup(layer->items[i] + 4); else if (EQUALN(layer->items[i], "Count:", 6)) - layerinfo->srcLayer.items[itemindexes[i]] = msStrdup(layer->items[i] + 6); + layerinfo->srcLayer.items[itemindexes[i]] = + msStrdup(layer->items[i] + 6); else layerinfo->srcLayer.items[itemindexes[i]] = msStrdup(layer->items[i]); } @@ -1480,38 +1527,43 @@ int msClusterLayerInitItemInfo(layerObj *layer) } /* Execute a query for this layer */ -int msClusterLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msClusterLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)rect; /* rebuild the cluster database */ return RebuildClusters(layer, isQuery); } -static int prepareShape(layerObj* layer, msClusterLayerInfo* layerinfo, clusterInfo* current, shapeObj* shape) -{ +static int prepareShape(layerObj *layer, msClusterLayerInfo *layerinfo, + clusterInfo *current, shapeObj *shape) { (void)layer; if (msCopyShape(&(current->shape), shape) != MS_SUCCESS) { - msSetError(MS_SHPERR, "Cannot retrieve inline shape. There some problem with the shape", "msClusterLayerNextShape()"); + msSetError( + MS_SHPERR, + "Cannot retrieve inline shape. There some problem with the shape", + "msClusterLayerNextShape()"); return MS_FAILURE; } /* update the positions of the cluster shape */ if (layerinfo->keep_locations == MS_FALSE) { - shape->line[0].point[0].x = shape->bounds.minx = shape->bounds.maxx = current->avgx; - shape->line[0].point[0].y = shape->bounds.miny = shape->bounds.maxy = current->avgy; + shape->line[0].point[0].x = shape->bounds.minx = shape->bounds.maxx = + current->avgx; + shape->line[0].point[0].y = shape->bounds.miny = shape->bounds.maxy = + current->avgy; } return MS_SUCCESS; } /* Execute a query on the DB based on fid. */ -int msClusterLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - clusterInfo* current; - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; +int msClusterLayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { + clusterInfo *current; + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer not open: %s", "msClusterLayerGetShape()", layer->name); + msSetError(MS_MISCERR, "Layer not open: %s", "msClusterLayerGetShape()", + layer->name); return MS_FAILURE; } @@ -1524,7 +1576,8 @@ int msClusterLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) } if (current == NULL) { - msSetError(MS_SHPERR, "No feature with this index.", "msClusterLayerGetShape()"); + msSetError(MS_SHPERR, "No feature with this index.", + "msClusterLayerGetShape()"); return MS_FAILURE; } @@ -1534,13 +1587,13 @@ int msClusterLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) /* find the next shape with the appropriate shape type */ /* also, load in the attribute data */ /* MS_DONE => no more data */ -int msClusterLayerNextShape(layerObj *layer, shapeObj *shape) -{ +int msClusterLayerNextShape(layerObj *layer, shapeObj *shape) { int rv; - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer not open: %s", "msClusterLayerNextShape()", layer->name); + msSetError(MS_MISCERR, "Layer not open: %s", "msClusterLayerNextShape()", + layer->name); return MS_FAILURE; } @@ -1555,11 +1608,10 @@ int msClusterLayerNextShape(layerObj *layer, shapeObj *shape) } /* Query for the items collection */ -int msClusterLayerGetItems(layerObj *layer) -{ +int msClusterLayerGetItems(layerObj *layer) { /* we support certain built in attributes */ layer->numitems = MSCLUSTER_NUMITEMS; - layer->items = msSmallMalloc(sizeof(char*) * (layer->numitems)); + layer->items = msSmallMalloc(sizeof(char *) * (layer->numitems)); layer->items[0] = msStrdup(MSCLUSTER_FEATURECOUNT); layer->items[1] = msStrdup(MSCLUSTER_GROUP); layer->items[2] = msStrdup(MSCLUSTER_BASEFID); @@ -1567,10 +1619,8 @@ int msClusterLayerGetItems(layerObj *layer) return msClusterLayerInitItemInfo(layer); } - -int msClusterLayerGetNumFeatures(layerObj *layer) -{ - msClusterLayerInfo* layerinfo = (msClusterLayerInfo*)layer->layerinfo; +int msClusterLayerGetNumFeatures(layerObj *layer) { + msClusterLayerInfo *layerinfo = (msClusterLayerInfo *)layer->layerinfo; if (!layerinfo) return -1; @@ -1579,8 +1629,7 @@ int msClusterLayerGetNumFeatures(layerObj *layer) } static int msClusterLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, - shapeObj* shape) -{ + shapeObj *shape) { (void)map; (void)layer; (void)c; @@ -1589,9 +1638,9 @@ static int msClusterLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, return MS_SUCCESS; } -msClusterLayerInfo* msClusterInitialize(layerObj *layer) -{ - msClusterLayerInfo *layerinfo =(msClusterLayerInfo*)msSmallMalloc(sizeof(msClusterLayerInfo)); +msClusterLayerInfo *msClusterInitialize(layerObj *layer) { + msClusterLayerInfo *layerinfo = + (msClusterLayerInfo *)msSmallMalloc(sizeof(msClusterLayerInfo)); layer->layerinfo = layerinfo; @@ -1620,24 +1669,23 @@ msClusterLayerInfo* msClusterInitialize(layerObj *layer) return layerinfo; } -int msClusterLayerOpen(layerObj *layer) -{ - msClusterLayerInfo* layerinfo; +int msClusterLayerOpen(layerObj *layer) { + msClusterLayerInfo *layerinfo; if (layer->type != MS_LAYER_POINT) { - msSetError(MS_MISCERR, "Only point layers are supported for clustering: %s", "msClusterLayerOpen()", layer->name); + msSetError(MS_MISCERR, "Only point layers are supported for clustering: %s", + "msClusterLayerOpen()", layer->name); return MS_FAILURE; } if (!layer->map) return MS_FAILURE; - if (layer->layerinfo) - { + if (layer->layerinfo) { if (layer->vtable->LayerOpen != msClusterLayerOpen) - msLayerClose(layer); + msLayerClose(layer); else - return MS_SUCCESS; /* already open */ + return MS_SUCCESS; /* already open */ } layerinfo = msClusterInitialize(layer); @@ -1646,7 +1694,7 @@ int msClusterLayerOpen(layerObj *layer) return MS_FAILURE; /* prepare the source layer */ - if(initLayer(&layerinfo->srcLayer, layer->map) == -1) + if (initLayer(&layerinfo->srcLayer, layer->map) == -1) return MS_FAILURE; #ifdef USE_CLUSTER_EXTERNAL @@ -1656,17 +1704,21 @@ int msClusterLayerOpen(layerObj *layer) layerIndex = msGetLayerIndex(layer->map, layer->connection); if (layerIndex < 0 && layerIndex >= layer->map->numlayers) { - msSetError(MS_MISCERR, "No source layers specified in layer: %s", "msClusterLayerOpen()", layer->name); + msSetError(MS_MISCERR, "No source layers specified in layer: %s", + "msClusterLayerOpen()", layer->name); return MS_FAILURE; } if (layer->map->layers[layerIndex]->type != MS_LAYER_POINT) { - msSetError(MS_MISCERR, "Only point layers are supported for cluster data source: %s", "msClusterLayerOpen()", layer->name); + msSetError(MS_MISCERR, + "Only point layers are supported for cluster data source: %s", + "msClusterLayerOpen()", layer->name); return MS_FAILURE; } - if (msCopyLayer(&layerinfo->srcLayer, layer->map->layers[layerIndex]) != MS_SUCCESS) - return(MS_FAILURE); + if (msCopyLayer(&layerinfo->srcLayer, layer->map->layers[layerIndex]) != + MS_SUCCESS) + return (MS_FAILURE); #else /* hook the vtable to this driver, will be restored in LayerClose*/ if (!layer->vtable) { @@ -1677,79 +1729,84 @@ int msClusterLayerOpen(layerObj *layer) msClusterLayerCopyVirtualTable(layer->vtable); if (msCopyLayer(&layerinfo->srcLayer, layer) != MS_SUCCESS) - return(MS_FAILURE); + return (MS_FAILURE); #endif /* disable the connection pool for this layer */ msLayerSetProcessingKey(&layerinfo->srcLayer, "CLOSE_CONNECTION", "ALWAYS"); /* open the source layer */ - if ( !layerinfo->srcLayer.vtable) { + if (!layerinfo->srcLayer.vtable) { if (msInitializeVirtualTable(&layerinfo->srcLayer) != MS_SUCCESS) return MS_FAILURE; } - if (layerinfo->srcLayer.vtable->LayerOpen(&layerinfo->srcLayer) != MS_SUCCESS) { + if (layerinfo->srcLayer.vtable->LayerOpen(&layerinfo->srcLayer) != + MS_SUCCESS) { return MS_FAILURE; } return MS_SUCCESS; } -int msClusterLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ +int msClusterLayerTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { (void)filter; - msClusterLayerInfo* layerinfo = layer->layerinfo; + msClusterLayerInfo *layerinfo = layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerTranslateFilter()", layer->name); + msSetError(MS_MISCERR, "Layer is not open: %s", + "msClusterLayerTranslateFilter()", layer->name); return MS_FAILURE; } - if (layerinfo->srcLayer.filter.type == MS_EXPRESSION && layerinfo->srcLayer.filter.tokens == NULL) - msTokenizeExpression(&(layerinfo->srcLayer.filter), layer->items, &(layer->numitems)); + if (layerinfo->srcLayer.filter.type == MS_EXPRESSION && + layerinfo->srcLayer.filter.tokens == NULL) + msTokenizeExpression(&(layerinfo->srcLayer.filter), layer->items, + &(layer->numitems)); - return layerinfo->srcLayer.vtable->LayerTranslateFilter(&layerinfo->srcLayer, &layerinfo->srcLayer.filter, filteritem); + return layerinfo->srcLayer.vtable->LayerTranslateFilter( + &layerinfo->srcLayer, &layerinfo->srcLayer.filter, filteritem); } -char* msClusterLayerEscapeSQLParam(layerObj *layer, const char* pszString) -{ - msClusterLayerInfo* layerinfo = layer->layerinfo; +char *msClusterLayerEscapeSQLParam(layerObj *layer, const char *pszString) { + msClusterLayerInfo *layerinfo = layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerEscapeSQLParam()", layer->name); + msSetError(MS_MISCERR, "Layer is not open: %s", + "msClusterLayerEscapeSQLParam()", layer->name); return msStrdup(""); } - return layerinfo->srcLayer.vtable->LayerEscapeSQLParam(&layerinfo->srcLayer, pszString); + return layerinfo->srcLayer.vtable->LayerEscapeSQLParam(&layerinfo->srcLayer, + pszString); } -int msClusterLayerGetAutoProjection(layerObj *layer, projectionObj* projection) -{ - msClusterLayerInfo* layerinfo = layer->layerinfo; +int msClusterLayerGetAutoProjection(layerObj *layer, + projectionObj *projection) { + msClusterLayerInfo *layerinfo = layer->layerinfo; if (!layerinfo) { - msSetError(MS_MISCERR, "Layer is not open: %s", "msClusterLayerGetAutoProjection()", layer->name); + msSetError(MS_MISCERR, "Layer is not open: %s", + "msClusterLayerGetAutoProjection()", layer->name); return MS_FAILURE; } - return layerinfo->srcLayer.vtable->LayerGetAutoProjection(&layerinfo->srcLayer, projection); + return layerinfo->srcLayer.vtable->LayerGetAutoProjection( + &layerinfo->srcLayer, projection); } -int msClusterLayerGetPaging(layerObj *layer) -{ +int msClusterLayerGetPaging(layerObj *layer) { (void)layer; return MS_FALSE; } -void msClusterLayerEnablePaging(layerObj *layer, int value) -{ +void msClusterLayerEnablePaging(layerObj *layer, int value) { (void)layer; (void)value; } -void msClusterLayerCopyVirtualTable(layerVTableObj* vtable) -{ +void msClusterLayerCopyVirtualTable(layerVTableObj *vtable) { vtable->LayerInitItemInfo = msClusterLayerInitItemInfo; vtable->LayerFreeItemInfo = msClusterLayerFreeItemInfo; vtable->LayerOpen = msClusterLayerOpen; @@ -1778,9 +1835,8 @@ void msClusterLayerCopyVirtualTable(layerVTableObj* vtable) #ifdef USE_CLUSTER_PLUGIN -MS_DLL_EXPORT int -PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer) -{ +MS_DLL_EXPORT int PluginInitializeVirtualTable(layerVTableObj *vtable, + layerObj *layer) { assert(layer != NULL); assert(vtable != NULL); @@ -1791,8 +1847,7 @@ PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer) #endif -int msClusterLayerInitializeVirtualTable(layerObj *layer) -{ +int msClusterLayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); diff --git a/mapcompositingfilter.c b/mapcompositingfilter.c index 0f67eec7c4..d75b82cab8 100644 --- a/mapcompositingfilter.c +++ b/mapcompositingfilter.c @@ -27,194 +27,208 @@ *****************************************************************************/ #include "mapserver.h" #include -#define pixmove(rb,srcx,srcy,dstx,dsty) \ - memcpy(rb->data.rgba.pixels+dsty*rb->data.rgba.row_step+dstx*4,\ - rb->data.rgba.pixels+srcy*rb->data.rgba.row_step+srcx*4,\ - 4) -#define pixerase(rb,x,y) memset(rb->data.rgba.pixels+y*rb->data.rgba.row_step+x*4,0,4) +#define pixmove(rb, srcx, srcy, dstx, dsty) \ + memcpy(rb->data.rgba.pixels + dsty * rb->data.rgba.row_step + dstx * 4, \ + rb->data.rgba.pixels + srcy * rb->data.rgba.row_step + srcx * 4, 4) +#define pixerase(rb, x, y) \ + memset(rb->data.rgba.pixels + y * rb->data.rgba.row_step + x * 4, 0, 4) -void msApplyTranslationCompositingFilter(rasterBufferObj *rb, int xtrans, int ytrans) { - int src_sx,src_sy,dst_sx,dst_sy; - if((unsigned)abs(xtrans)>=rb->width || (unsigned)abs(ytrans)>=rb->height) { - for(unsigned y = 0; yheight; y++) - for(unsigned x = 0; xwidth; x++) - pixerase(rb,x,y); +void msApplyTranslationCompositingFilter(rasterBufferObj *rb, int xtrans, + int ytrans) { + int src_sx, src_sy, dst_sx, dst_sy; + if ((unsigned)abs(xtrans) >= rb->width || + (unsigned)abs(ytrans) >= rb->height) { + for (unsigned y = 0; y < rb->height; y++) + for (unsigned x = 0; x < rb->width; x++) + pixerase(rb, x, y); } - if(xtrans == 0 && ytrans == 0) + if (xtrans == 0 && ytrans == 0) return; - if(xtrans>=0) { - if(ytrans>=0) { + if (xtrans >= 0) { + if (ytrans >= 0) { src_sx = rb->width - xtrans - 1; src_sy = rb->height - ytrans - 1; dst_sx = rb->width - 1; - dst_sy = rb->height -1; - for(int y = src_sy,dst_y= dst_sy;y>=0;y--,dst_y--) { - for(int x = src_sx,dst_x= dst_sx;x>=0;x--,dst_x--) { - pixmove(rb,x,y,dst_x,dst_y); + dst_sy = rb->height - 1; + for (int y = src_sy, dst_y = dst_sy; y >= 0; y--, dst_y--) { + for (int x = src_sx, dst_x = dst_sx; x >= 0; x--, dst_x--) { + pixmove(rb, x, y, dst_x, dst_y); } } - for(int y=0;ywidth;x++) - pixerase(rb,x,y); - for(unsigned y=ytrans;yheight;y++) - for(int x=0;xwidth; x++) + pixerase(rb, x, y); + for (unsigned y = ytrans; y < rb->height; y++) + for (int x = 0; x < xtrans; x++) + pixerase(rb, x, y); } else { src_sx = rb->width - xtrans - 1; - src_sy = - ytrans; + src_sy = -ytrans; dst_sx = rb->width - 1; dst_sy = 0; - for(unsigned y = src_sy,dst_y= dst_sy;yheight;y++,dst_y++) { - for(int x = src_sx,dst_x= dst_sx;x>=0;x--,dst_x--) { - pixmove(rb,x,y,dst_x,dst_y); + for (unsigned y = src_sy, dst_y = dst_sy; y < rb->height; y++, dst_y++) { + for (int x = src_sx, dst_x = dst_sx; x >= 0; x--, dst_x--) { + pixmove(rb, x, y, dst_x, dst_y); } } - for(unsigned y=0;yheight+ytrans;y++) - for(int x=0;xheight+ytrans;yheight;y++) - for(unsigned x=0;xwidth;x++) - pixerase(rb,x,y); + for (unsigned y = 0; y < rb->height + ytrans; y++) + for (int x = 0; x < xtrans; x++) + pixerase(rb, x, y); + for (unsigned y = rb->height + ytrans; y < rb->height; y++) + for (unsigned x = 0; x < rb->width; x++) + pixerase(rb, x, y); } } else { - if(ytrans>=0) { - src_sx = - xtrans; + if (ytrans >= 0) { + src_sx = -xtrans; src_sy = rb->height - ytrans - 1; dst_sx = 0; - dst_sy = rb->height -1; - for(int y = src_sy,dst_y= dst_sy;y>=0;y--,dst_y--) { - for(unsigned x = src_sx,dst_x= dst_sx;xwidth;x++,dst_x++) { - pixmove(rb,x,y,dst_x,dst_y); + dst_sy = rb->height - 1; + for (int y = src_sy, dst_y = dst_sy; y >= 0; y--, dst_y--) { + for (unsigned x = src_sx, dst_x = dst_sx; x < rb->width; x++, dst_x++) { + pixmove(rb, x, y, dst_x, dst_y); } } - for(int y=0;ywidth;x++) - pixerase(rb,x,y); - for(unsigned y=ytrans;yheight;y++) - for(unsigned x=rb->width+xtrans;xwidth;x++) - pixerase(rb,x,y); + for (int y = 0; y < ytrans; y++) + for (unsigned x = 0; x < rb->width; x++) + pixerase(rb, x, y); + for (unsigned y = ytrans; y < rb->height; y++) + for (unsigned x = rb->width + xtrans; x < rb->width; x++) + pixerase(rb, x, y); } else { - src_sx = - xtrans; - src_sy = - ytrans; + src_sx = -xtrans; + src_sy = -ytrans; dst_sx = 0; dst_sy = 0; - for(unsigned y = src_sy,dst_y= dst_sy;yheight;y++,dst_y++) { - for(unsigned x = src_sx,dst_x= dst_sx;xwidth;x++,dst_x++) { - pixmove(rb,x,y,dst_x,dst_y); + for (unsigned y = src_sy, dst_y = dst_sy; y < rb->height; y++, dst_y++) { + for (unsigned x = src_sx, dst_x = dst_sx; x < rb->width; x++, dst_x++) { + pixmove(rb, x, y, dst_x, dst_y); } } - for(unsigned y=0;yheight+ytrans;y++) - for(unsigned x=rb->width+xtrans;xwidth;x++) - pixerase(rb,x,y); - for(unsigned y=rb->height+ytrans;yheight;y++) - for(unsigned x=0;xwidth;x++) - pixerase(rb,x,y); + for (unsigned y = 0; y < rb->height + ytrans; y++) + for (unsigned x = rb->width + xtrans; x < rb->width; x++) + pixerase(rb, x, y); + for (unsigned y = rb->height + ytrans; y < rb->height; y++) + for (unsigned x = 0; x < rb->width; x++) + pixerase(rb, x, y); } } } void msApplyBlackeningCompositingFilter(rasterBufferObj *rb) { - unsigned char *r,*g,*b; - for(unsigned row=0;rowheight;row++) { - r = rb->data.rgba.r + row*rb->data.rgba.row_step; - g = rb->data.rgba.g + row*rb->data.rgba.row_step; - b = rb->data.rgba.b + row*rb->data.rgba.row_step; - for(unsigned col=0;colwidth;col++) { + unsigned char *r, *g, *b; + for (unsigned row = 0; row < rb->height; row++) { + r = rb->data.rgba.r + row * rb->data.rgba.row_step; + g = rb->data.rgba.g + row * rb->data.rgba.row_step; + b = rb->data.rgba.b + row * rb->data.rgba.row_step; + for (unsigned col = 0; col < rb->width; col++) { *r = *g = *b = 0; - r+=4;g+=4;b+=4; - } + r += 4; + g += 4; + b += 4; + } } } void msApplyWhiteningCompositingFilter(rasterBufferObj *rb) { - unsigned char *r,*g,*b,*a; - for(unsigned row=0;rowheight;row++) { - r = rb->data.rgba.r + row*rb->data.rgba.row_step; - g = rb->data.rgba.g + row*rb->data.rgba.row_step; - b = rb->data.rgba.b + row*rb->data.rgba.row_step; - a = rb->data.rgba.a + row*rb->data.rgba.row_step; - for(unsigned col=0;colwidth;col++) { + unsigned char *r, *g, *b, *a; + for (unsigned row = 0; row < rb->height; row++) { + r = rb->data.rgba.r + row * rb->data.rgba.row_step; + g = rb->data.rgba.g + row * rb->data.rgba.row_step; + b = rb->data.rgba.b + row * rb->data.rgba.row_step; + a = rb->data.rgba.a + row * rb->data.rgba.row_step; + for (unsigned col = 0; col < rb->width; col++) { *r = *g = *b = *a; - r+=4;g+=4;b+=4;a+=4; - } + r += 4; + g += 4; + b += 4; + a += 4; + } } } void msApplyGrayscaleCompositingFilter(rasterBufferObj *rb) { - unsigned char *r,*g,*b; - for(unsigned row=0;rowheight;row++) { - r = rb->data.rgba.r + row*rb->data.rgba.row_step; - g = rb->data.rgba.g + row*rb->data.rgba.row_step; - b = rb->data.rgba.b + row*rb->data.rgba.row_step; - for(unsigned col=0;colwidth;col++) { + unsigned char *r, *g, *b; + for (unsigned row = 0; row < rb->height; row++) { + r = rb->data.rgba.r + row * rb->data.rgba.row_step; + g = rb->data.rgba.g + row * rb->data.rgba.row_step; + b = rb->data.rgba.b + row * rb->data.rgba.row_step; + for (unsigned col = 0; col < rb->width; col++) { unsigned int mix = (unsigned int)*r + (unsigned int)*g + (unsigned int)*b; - mix /=3; + mix /= 3; *r = *g = *b = (unsigned char)mix; - r+=4;g+=4;b+=4; - } + r += 4; + g += 4; + b += 4; + } } } -int msApplyCompositingFilter(mapObj *map, rasterBufferObj *rb, CompositingFilter *filter) { +int msApplyCompositingFilter(mapObj *map, rasterBufferObj *rb, + CompositingFilter *filter) { int rstatus; regex_t regex; regmatch_t pmatch[3]; - + /* test for blurring filter */ regcomp(®ex, "blur\\(([0-9]+)\\)", REG_EXTENDED); rstatus = regexec(®ex, filter->filter, 2, pmatch, 0); regfree(®ex); - if(!rstatus) { + if (!rstatus) { char *rad = malloc(pmatch[1].rm_eo - pmatch[1].rm_so + 1); unsigned int irad; - strncpy(rad,filter->filter+pmatch[1].rm_so,pmatch[1].rm_eo-pmatch[1].rm_so); - rad[pmatch[1].rm_eo - pmatch[1].rm_so]=0; - //msDebug("got blur filter with radius %s\n",rad); + strncpy(rad, filter->filter + pmatch[1].rm_so, + pmatch[1].rm_eo - pmatch[1].rm_so); + rad[pmatch[1].rm_eo - pmatch[1].rm_so] = 0; + // msDebug("got blur filter with radius %s\n",rad); irad = atoi(rad); free(rad); - irad = MS_NINT(irad*map->resolution/map->defresolution); - msApplyBlurringCompositingFilter(rb,irad); + irad = MS_NINT(irad * map->resolution / map->defresolution); + msApplyBlurringCompositingFilter(rb, irad); return MS_SUCCESS; } - + /* test for translation filter */ regcomp(®ex, "translate\\((-?[0-9]+),(-?[0-9]+)\\)", REG_EXTENDED); rstatus = regexec(®ex, filter->filter, 3, pmatch, 0); regfree(®ex); - if(!rstatus) { + if (!rstatus) { char *num; - int xtrans,ytrans; + int xtrans, ytrans; num = malloc(pmatch[1].rm_eo - pmatch[1].rm_so + 1); - strncpy(num,filter->filter+pmatch[1].rm_so,pmatch[1].rm_eo-pmatch[1].rm_so); - num[pmatch[1].rm_eo - pmatch[1].rm_so]=0; + strncpy(num, filter->filter + pmatch[1].rm_so, + pmatch[1].rm_eo - pmatch[1].rm_so); + num[pmatch[1].rm_eo - pmatch[1].rm_so] = 0; xtrans = atoi(num); free(num); num = malloc(pmatch[2].rm_eo - pmatch[2].rm_so + 1); - strncpy(num,filter->filter+pmatch[2].rm_so,pmatch[2].rm_eo-pmatch[2].rm_so); - num[pmatch[2].rm_eo - pmatch[2].rm_so]=0; + strncpy(num, filter->filter + pmatch[2].rm_so, + pmatch[2].rm_eo - pmatch[2].rm_so); + num[pmatch[2].rm_eo - pmatch[2].rm_so] = 0; ytrans = atoi(num); free(num); - //msDebug("got translation filter of radius %d,%d\n",xtrans,ytrans); - xtrans = MS_NINT(xtrans*map->resolution/map->defresolution); - ytrans = MS_NINT(ytrans*map->resolution/map->defresolution); - msApplyTranslationCompositingFilter(rb,xtrans,ytrans); + // msDebug("got translation filter of radius %d,%d\n",xtrans,ytrans); + xtrans = MS_NINT(xtrans * map->resolution / map->defresolution); + ytrans = MS_NINT(ytrans * map->resolution / map->defresolution); + msApplyTranslationCompositingFilter(rb, xtrans, ytrans); return MS_SUCCESS; } - + /* test for grayscale filter */ - if(!strncmp(filter->filter,"grayscale()",strlen("grayscale()"))) { + if (!strncmp(filter->filter, "grayscale()", strlen("grayscale()"))) { msApplyGrayscaleCompositingFilter(rb); return MS_SUCCESS; } - if(!strncmp(filter->filter,"blacken()",strlen("blacken()"))) { + if (!strncmp(filter->filter, "blacken()", strlen("blacken()"))) { msApplyBlackeningCompositingFilter(rb); return MS_SUCCESS; } - if(!strncmp(filter->filter,"whiten()",strlen("whiten()"))) { + if (!strncmp(filter->filter, "whiten()", strlen("whiten()"))) { msApplyWhiteningCompositingFilter(rb); return MS_SUCCESS; } - - msSetError(MS_MISCERR,"unknown compositing filter (%s)", "msApplyCompositingFilter()", filter->filter); + + msSetError(MS_MISCERR, "unknown compositing filter (%s)", + "msApplyCompositingFilter()", filter->filter); return MS_FAILURE; } diff --git a/mapcontext.c b/mapcontext.c index 458e642f91..28cf429402 100644 --- a/mapcontext.c +++ b/mapcontext.c @@ -32,7 +32,6 @@ #include "cpl_vsi.h" #include "cpl_conv.h" - #if defined(USE_WMS_LYR) /* There is a dependency to GDAL/OGR for the GML driver and MiniXML parser */ @@ -47,16 +46,15 @@ ** Take the filename in argument ** Return value must be freed by caller */ -static char * msGetMapContextFileText(const char *filename) -{ +static char *msGetMapContextFileText(const char *filename) { char *pszBuffer; VSILFILE *stream; - vsi_l_offset nLength; + vsi_l_offset nLength; /* open file */ - if(filename != NULL && strlen(filename) > 0) { + if (filename != NULL && strlen(filename) > 0) { stream = VSIFOpenL(filename, "rb"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "msGetMapContextFileText()", filename); return NULL; } @@ -65,37 +63,36 @@ static char * msGetMapContextFileText(const char *filename) return NULL; } - VSIFSeekL( stream, 0, SEEK_END ); - nLength = VSIFTellL( stream ); - VSIFSeekL( stream, 0, SEEK_SET ); - if( nLength > 100 * 1024 * 1024U ) - { - msSetError(MS_MEMERR, "(%s): too big file", "msGetMapContextFileText()", filename); - VSIFCloseL( stream ); + VSIFSeekL(stream, 0, SEEK_END); + nLength = VSIFTellL(stream); + VSIFSeekL(stream, 0, SEEK_SET); + if (nLength > 100 * 1024 * 1024U) { + msSetError(MS_MEMERR, "(%s): too big file", "msGetMapContextFileText()", + filename); + VSIFCloseL(stream); return NULL; } - pszBuffer = (char *) malloc((size_t)nLength+1); - if( pszBuffer == NULL ) { + pszBuffer = (char *)malloc((size_t)nLength + 1); + if (pszBuffer == NULL) { msSetError(MS_MEMERR, "(%s)", "msGetMapContextFileText()", filename); - VSIFCloseL( stream ); + VSIFCloseL(stream); return NULL; } - if(VSIFReadL( pszBuffer, nLength, 1, stream ) == 0) { - free( pszBuffer ); - VSIFCloseL( stream ); + if (VSIFReadL(pszBuffer, nLength, 1, stream) == 0) { + free(pszBuffer); + VSIFCloseL(stream); msSetError(MS_IOERR, "(%s)", "msGetMapContextFileText()", filename); return NULL; } pszBuffer[nLength] = '\0'; - VSIFCloseL( stream ); + VSIFCloseL(stream); return pszBuffer; } - #if defined(USE_WMS_LYR) /* @@ -104,15 +101,14 @@ static char * msGetMapContextFileText(const char *filename) **Get the xml value and put it in the hash table ** */ -int msGetMapContextXMLHashValue( CPLXMLNode *psRoot, const char *pszXMLPath, - hashTableObj *metadata, char *pszMetadata ) -{ +int msGetMapContextXMLHashValue(CPLXMLNode *psRoot, const char *pszXMLPath, + hashTableObj *metadata, char *pszMetadata) { char *pszValue; - pszValue = (char*)CPLGetXMLValue( psRoot, pszXMLPath, NULL); - if(pszValue != NULL) { - if( metadata != NULL ) { - msInsertHashTable(metadata, pszMetadata, pszValue ); + pszValue = (char *)CPLGetXMLValue(psRoot, pszXMLPath, NULL); + if (pszValue != NULL) { + if (metadata != NULL) { + msInsertHashTable(metadata, pszMetadata, pszValue); } else { return MS_FAILURE; } @@ -129,18 +125,17 @@ int msGetMapContextXMLHashValue( CPLXMLNode *psRoot, const char *pszXMLPath, **Get the xml value and put it in the hash table ** */ -int msGetMapContextXMLHashValueDecode( CPLXMLNode *psRoot, - const char *pszXMLPath, - hashTableObj *metadata, - char *pszMetadata ) -{ +int msGetMapContextXMLHashValueDecode(CPLXMLNode *psRoot, + const char *pszXMLPath, + hashTableObj *metadata, + char *pszMetadata) { char *pszValue; - pszValue = (char*)CPLGetXMLValue( psRoot, pszXMLPath, NULL); - if(pszValue != NULL) { - if( metadata != NULL ) { + pszValue = (char *)CPLGetXMLValue(psRoot, pszXMLPath, NULL); + if (pszValue != NULL) { + if (metadata != NULL) { msDecodeHTMLEntities(pszValue); - msInsertHashTable(metadata, pszMetadata, pszValue ); + msInsertHashTable(metadata, pszMetadata, pszValue); } else { return MS_FAILURE; } @@ -151,21 +146,19 @@ int msGetMapContextXMLHashValueDecode( CPLXMLNode *psRoot, return MS_SUCCESS; } - /* **msGetMapContextXMLStringValue() ** **Get the xml value and put it in the string field ** */ -int msGetMapContextXMLStringValue( CPLXMLNode *psRoot, char *pszXMLPath, - char **pszField) -{ +int msGetMapContextXMLStringValue(CPLXMLNode *psRoot, char *pszXMLPath, + char **pszField) { char *pszValue; - pszValue = (char*)CPLGetXMLValue( psRoot, pszXMLPath, NULL); - if(pszValue != NULL) { - if( pszField != NULL ) { + pszValue = (char *)CPLGetXMLValue(psRoot, pszXMLPath, NULL); + if (pszValue != NULL) { + if (pszField != NULL) { *pszField = msStrdup(pszValue); } else { return MS_FAILURE; @@ -177,21 +170,19 @@ int msGetMapContextXMLStringValue( CPLXMLNode *psRoot, char *pszXMLPath, return MS_SUCCESS; } - /* **msGetMapContextXMLStringValue() ** **Get the xml value and put it in the string field ** */ -int msGetMapContextXMLStringValueDecode( CPLXMLNode *psRoot, char *pszXMLPath, - char **pszField) -{ +int msGetMapContextXMLStringValueDecode(CPLXMLNode *psRoot, char *pszXMLPath, + char **pszField) { char *pszValue; - pszValue = (char*)CPLGetXMLValue( psRoot, pszXMLPath, NULL); - if(pszValue != NULL) { - if( pszField != NULL ) { + pszValue = (char *)CPLGetXMLValue(psRoot, pszXMLPath, NULL); + if (pszValue != NULL) { + if (pszField != NULL) { msDecodeHTMLEntities(pszValue); *pszField = msStrdup(pszValue); } else { @@ -204,21 +195,19 @@ int msGetMapContextXMLStringValueDecode( CPLXMLNode *psRoot, char *pszXMLPath, return MS_SUCCESS; } - /* **msGetMapContextXMLFloatValue() ** **Get the xml value and put it in the string field ** */ -int msGetMapContextXMLFloatValue( CPLXMLNode *psRoot, char *pszXMLPath, - double *pszField) -{ +int msGetMapContextXMLFloatValue(CPLXMLNode *psRoot, char *pszXMLPath, + double *pszField) { char *pszValue; - pszValue = (char*)CPLGetXMLValue( psRoot, pszXMLPath, NULL); - if(pszValue != NULL) { - if( pszField != NULL ) { + pszValue = (char *)CPLGetXMLValue(psRoot, pszXMLPath, NULL); + if (pszValue != NULL) { + if (pszField != NULL) { *pszField = atof(pszValue); } else { return MS_FAILURE; @@ -236,28 +225,27 @@ int msGetMapContextXMLFloatValue( CPLXMLNode *psRoot, char *pszXMLPath, ** Take a Node and get the width, height, format and href from it. ** Then put this info in metadatas. */ -int msLoadMapContextURLELements( CPLXMLNode *psRoot, hashTableObj *metadata, - const char *pszMetadataRoot) -{ +int msLoadMapContextURLELements(CPLXMLNode *psRoot, hashTableObj *metadata, + const char *pszMetadataRoot) { char *pszMetadataName; - if( psRoot == NULL || metadata == NULL || pszMetadataRoot == NULL ) + if (psRoot == NULL || metadata == NULL || pszMetadataRoot == NULL) return MS_FAILURE; - pszMetadataName = (char*) malloc( strlen(pszMetadataRoot) + 10 ); + pszMetadataName = (char *)malloc(strlen(pszMetadataRoot) + 10); - sprintf( pszMetadataName, "%s_width", pszMetadataRoot ); - msGetMapContextXMLHashValue( psRoot, "width", metadata, pszMetadataName ); + sprintf(pszMetadataName, "%s_width", pszMetadataRoot); + msGetMapContextXMLHashValue(psRoot, "width", metadata, pszMetadataName); - sprintf( pszMetadataName, "%s_height", pszMetadataRoot ); - msGetMapContextXMLHashValue( psRoot, "height", metadata, pszMetadataName ); + sprintf(pszMetadataName, "%s_height", pszMetadataRoot); + msGetMapContextXMLHashValue(psRoot, "height", metadata, pszMetadataName); - sprintf( pszMetadataName, "%s_format", pszMetadataRoot ); - msGetMapContextXMLHashValue( psRoot, "format", metadata, pszMetadataName ); + sprintf(pszMetadataName, "%s_format", pszMetadataRoot); + msGetMapContextXMLHashValue(psRoot, "format", metadata, pszMetadataName); - sprintf( pszMetadataName, "%s_href", pszMetadataRoot ); - msGetMapContextXMLHashValue( psRoot, "OnlineResource.xlink:href", metadata, - pszMetadataName ); + sprintf(pszMetadataName, "%s_href", pszMetadataRoot); + msGetMapContextXMLHashValue(psRoot, "OnlineResource.xlink:href", metadata, + pszMetadataName); free(pszMetadataName); @@ -269,15 +257,14 @@ int msLoadMapContextURLELements( CPLXMLNode *psRoot, hashTableObj *metadata, ** Put the keywords from a XML node and put them in a metadata. ** psRoot should be set to keywordlist */ -int msLoadMapContextListInMetadata( CPLXMLNode *psRoot, hashTableObj *metadata, - char *pszXMLName, char *pszMetadataName, - char *pszHashDelimiter) -{ +int msLoadMapContextListInMetadata(CPLXMLNode *psRoot, hashTableObj *metadata, + char *pszXMLName, char *pszMetadataName, + char *pszHashDelimiter) { const char *pszHash, *pszXMLValue; char *pszMetadata; - if(psRoot == NULL || psRoot->psChild == NULL || - metadata == NULL || pszMetadataName == NULL || pszXMLName == NULL) + if (psRoot == NULL || psRoot->psChild == NULL || metadata == NULL || + pszMetadataName == NULL || pszXMLName == NULL) return MS_FAILURE; /* Pass from KeywordList to Keyword level */ @@ -289,13 +276,12 @@ int msLoadMapContextListInMetadata( CPLXMLNode *psRoot, hashTableObj *metadata, pszXMLValue = psRoot->psChild->pszValue; pszHash = msLookupHashTable(metadata, pszMetadataName); if (pszHash != NULL) { - pszMetadata = (char*)malloc(strlen(pszHash)+ - strlen(pszXMLValue)+2); - if(pszHashDelimiter == NULL) - sprintf( pszMetadata, "%s%s", pszHash, pszXMLValue ); + pszMetadata = (char *)malloc(strlen(pszHash) + strlen(pszXMLValue) + 2); + if (pszHashDelimiter == NULL) + sprintf(pszMetadata, "%s%s", pszHash, pszXMLValue); else - sprintf( pszMetadata, "%s%s%s", pszHash, pszHashDelimiter, - pszXMLValue ); + sprintf(pszMetadata, "%s%s%s", pszHash, pszHashDelimiter, + pszXMLValue); msInsertHashTable(metadata, pszMetadataName, pszMetadata); free(pszMetadata); } else @@ -312,43 +298,40 @@ int msLoadMapContextListInMetadata( CPLXMLNode *psRoot, hashTableObj *metadata, ** Put the Contact informations from a XML node and put them in a metadata. ** */ -int msLoadMapContextContactInfo( CPLXMLNode *psRoot, hashTableObj *metadata ) -{ - if(psRoot == NULL || metadata == NULL) +int msLoadMapContextContactInfo(CPLXMLNode *psRoot, hashTableObj *metadata) { + if (psRoot == NULL || metadata == NULL) return MS_FAILURE; /* Contact Person primary */ - msGetMapContextXMLHashValue(psRoot, - "ContactPersonPrimary.ContactPerson", + msGetMapContextXMLHashValue(psRoot, "ContactPersonPrimary.ContactPerson", metadata, "wms_contactperson"); msGetMapContextXMLHashValue(psRoot, "ContactPersonPrimary.ContactOrganization", metadata, "wms_contactorganization"); /* Contact Position */ - msGetMapContextXMLHashValue(psRoot, - "ContactPosition", - metadata, "wms_contactposition"); + msGetMapContextXMLHashValue(psRoot, "ContactPosition", metadata, + "wms_contactposition"); /* Contact Address */ - msGetMapContextXMLHashValue(psRoot, "ContactAddress.AddressType", - metadata, "wms_addresstype"); - msGetMapContextXMLHashValue(psRoot, "ContactAddress.Address", - metadata, "wms_address"); - msGetMapContextXMLHashValue(psRoot, "ContactAddress.City", - metadata, "wms_city"); + msGetMapContextXMLHashValue(psRoot, "ContactAddress.AddressType", metadata, + "wms_addresstype"); + msGetMapContextXMLHashValue(psRoot, "ContactAddress.Address", metadata, + "wms_address"); + msGetMapContextXMLHashValue(psRoot, "ContactAddress.City", metadata, + "wms_city"); msGetMapContextXMLHashValue(psRoot, "ContactAddress.StateOrProvince", metadata, "wms_stateorprovince"); - msGetMapContextXMLHashValue(psRoot, "ContactAddress.PostCode", - metadata, "wms_postcode"); - msGetMapContextXMLHashValue(psRoot, "ContactAddress.Country", - metadata, "wms_country"); + msGetMapContextXMLHashValue(psRoot, "ContactAddress.PostCode", metadata, + "wms_postcode"); + msGetMapContextXMLHashValue(psRoot, "ContactAddress.Country", metadata, + "wms_country"); /* Others */ - msGetMapContextXMLHashValue(psRoot, "ContactVoiceTelephone", - metadata, "wms_contactvoicetelephone"); - msGetMapContextXMLHashValue(psRoot, "ContactFacsimileTelephone", - metadata, "wms_contactfacsimiletelephone"); - msGetMapContextXMLHashValue(psRoot, "ContactElectronicMailAddress", - metadata, "wms_contactelectronicmailaddress"); + msGetMapContextXMLHashValue(psRoot, "ContactVoiceTelephone", metadata, + "wms_contactvoicetelephone"); + msGetMapContextXMLHashValue(psRoot, "ContactFacsimileTelephone", metadata, + "wms_contactfacsimiletelephone"); + msGetMapContextXMLHashValue(psRoot, "ContactElectronicMailAddress", metadata, + "wms_contactelectronicmailaddress"); return MS_SUCCESS; } @@ -358,42 +341,35 @@ int msLoadMapContextContactInfo( CPLXMLNode *psRoot, hashTableObj *metadata ) ** ** */ -int msLoadMapContextLayerFormat(CPLXMLNode *psFormat, layerObj *layer) -{ +int msLoadMapContextLayerFormat(CPLXMLNode *psFormat, layerObj *layer) { const char *pszValue; char *pszValue1; - const char* pszHash; + const char *pszHash; - if(psFormat->psChild != NULL && - strcasecmp(psFormat->pszValue, "Format") == 0 ) { - if(psFormat->psChild->psNext == NULL) + if (psFormat->psChild != NULL && + strcasecmp(psFormat->pszValue, "Format") == 0) { + if (psFormat->psChild->psNext == NULL) pszValue = psFormat->psChild->pszValue; else pszValue = psFormat->psChild->psNext->pszValue; } else pszValue = NULL; - if(pszValue != NULL && strcasecmp(pszValue, "") != 0) { + if (pszValue != NULL && strcasecmp(pszValue, "") != 0) { /* wms_format */ - pszValue1 = (char*)CPLGetXMLValue(psFormat, - "current", NULL); - if(pszValue1 != NULL && - (strcasecmp(pszValue1, "1") == 0 || strcasecmp(pszValue1, "true")==0)) - msInsertHashTable(&(layer->metadata), - "wms_format", pszValue); + pszValue1 = (char *)CPLGetXMLValue(psFormat, "current", NULL); + if (pszValue1 != NULL && + (strcasecmp(pszValue1, "1") == 0 || strcasecmp(pszValue1, "true") == 0)) + msInsertHashTable(&(layer->metadata), "wms_format", pszValue); /* wms_formatlist */ - pszHash = msLookupHashTable(&(layer->metadata), - "wms_formatlist"); - if(pszHash != NULL) { - pszValue1 = (char*)malloc(strlen(pszHash)+ - strlen(pszValue)+2); + pszHash = msLookupHashTable(&(layer->metadata), "wms_formatlist"); + if (pszHash != NULL) { + pszValue1 = (char *)malloc(strlen(pszHash) + strlen(pszValue) + 2); sprintf(pszValue1, "%s,%s", pszHash, pszValue); - msInsertHashTable(&(layer->metadata), - "wms_formatlist", pszValue1); + msInsertHashTable(&(layer->metadata), "wms_formatlist", pszValue1); free(pszValue1); } else - msInsertHashTable(&(layer->metadata), - "wms_formatlist", pszValue); + msInsertHashTable(&(layer->metadata), "wms_formatlist", pszValue); } /* Make sure selected format is supported or select another @@ -403,46 +379,43 @@ int msLoadMapContextLayerFormat(CPLXMLNode *psFormat, layerObj *layer) */ pszValue = msLookupHashTable(&(layer->metadata), "wms_format"); - if ( - pszValue && ( + if (pszValue && ( #if !(defined USE_PNG) - strcasecmp(pszValue, "image/png") == 0 || - strcasecmp(pszValue, "PNG") == 0 || + strcasecmp(pszValue, "image/png") == 0 || + strcasecmp(pszValue, "PNG") == 0 || #endif #if !(defined USE_JPEG) - strcasecmp(pszValue, "image/jpeg") == 0 || - strcasecmp(pszValue, "JPEG") == 0 || + strcasecmp(pszValue, "image/jpeg") == 0 || + strcasecmp(pszValue, "JPEG") == 0 || #endif - 0 )) { - char **papszList=NULL; - int i, numformats=0; + 0)) { + char **papszList = NULL; + int i, numformats = 0; - pszValue = msLookupHashTable(&(layer->metadata), - "wms_formatlist"); + pszValue = msLookupHashTable(&(layer->metadata), "wms_formatlist"); papszList = msStringSplit(pszValue, ',', &numformats); - for(i=0; i < numformats; i++) { + for (i = 0; i < numformats; i++) { if ( #if (defined USE_PNG) - strcasecmp(papszList[i], "image/png") == 0 || - strcasecmp(papszList[i], "PNG") == 0 || + strcasecmp(papszList[i], "image/png") == 0 || + strcasecmp(papszList[i], "PNG") == 0 || #endif #if (defined USE_JPEG) - strcasecmp(papszList[i], "image/jpeg") == 0 || - strcasecmp(papszList[i], "JPEG") == 0 || + strcasecmp(papszList[i], "image/jpeg") == 0 || + strcasecmp(papszList[i], "JPEG") == 0 || #endif #ifdef USE_GD_GIF - strcasecmp(papszList[i], "image/gif") == 0 || - strcasecmp(papszList[i], "GIF") == 0 || + strcasecmp(papszList[i], "image/gif") == 0 || + strcasecmp(papszList[i], "GIF") == 0 || #endif - 0 ) { + 0) { /* Found a match */ - msInsertHashTable(&(layer->metadata), - "wms_format", papszList[i]); + msInsertHashTable(&(layer->metadata), "wms_format", papszList[i]); break; } } - if(papszList) + if (papszList) msFreeCharArray(papszList, numformats); } /* end if unsupported format */ @@ -451,81 +424,74 @@ int msLoadMapContextLayerFormat(CPLXMLNode *psFormat, layerObj *layer) } int msLoadMapContextLayerStyle(CPLXMLNode *psStyle, layerObj *layer, - int nStyle) -{ + int nStyle) { char *pszValue, *pszValue1, *pszValue2; const char *pszHash; - char* pszStyle=NULL; + char *pszStyle = NULL; char *pszStyleName; CPLXMLNode *psStyleSLDBody; - pszStyleName =(char*)CPLGetXMLValue(psStyle,"Name",NULL); - if(pszStyleName == NULL) { - pszStyleName = (char*)malloc(20); + pszStyleName = (char *)CPLGetXMLValue(psStyle, "Name", NULL); + if (pszStyleName == NULL) { + pszStyleName = (char *)malloc(20); sprintf(pszStyleName, "Style{%d}", nStyle); } else pszStyleName = msStrdup(pszStyleName); /* wms_style */ - pszValue = (char*)CPLGetXMLValue(psStyle,"current",NULL); - if(pszValue != NULL && - (strcasecmp(pszValue, "1") == 0 || - strcasecmp(pszValue, "true") == 0)) - msInsertHashTable(&(layer->metadata), - "wms_style", pszStyleName); + pszValue = (char *)CPLGetXMLValue(psStyle, "current", NULL); + if (pszValue != NULL && + (strcasecmp(pszValue, "1") == 0 || strcasecmp(pszValue, "true") == 0)) + msInsertHashTable(&(layer->metadata), "wms_style", pszStyleName); /* wms_stylelist */ - pszHash = msLookupHashTable(&(layer->metadata), - "wms_stylelist"); - if(pszHash != NULL) { - pszValue1 = (char*)malloc(strlen(pszHash)+ - strlen(pszStyleName)+2); + pszHash = msLookupHashTable(&(layer->metadata), "wms_stylelist"); + if (pszHash != NULL) { + pszValue1 = (char *)malloc(strlen(pszHash) + strlen(pszStyleName) + 2); sprintf(pszValue1, "%s,%s", pszHash, pszStyleName); - msInsertHashTable(&(layer->metadata), - "wms_stylelist", pszValue1); + msInsertHashTable(&(layer->metadata), "wms_stylelist", pszValue1); free(pszValue1); } else - msInsertHashTable(&(layer->metadata), - "wms_stylelist", pszStyleName); + msInsertHashTable(&(layer->metadata), "wms_stylelist", pszStyleName); /* Title */ - pszStyle = (char*)malloc(strlen(pszStyleName)+20); - sprintf(pszStyle,"wms_style_%s_title",pszStyleName); + pszStyle = (char *)malloc(strlen(pszStyleName) + 20); + sprintf(pszStyle, "wms_style_%s_title", pszStyleName); - if( msGetMapContextXMLHashValue(psStyle, "Title", &(layer->metadata), - pszStyle) == MS_FAILURE ) + if (msGetMapContextXMLHashValue(psStyle, "Title", &(layer->metadata), + pszStyle) == MS_FAILURE) msInsertHashTable(&(layer->metadata), pszStyle, layer->name); free(pszStyle); /* SLD */ - pszStyle = (char*)malloc(strlen(pszStyleName)+15); + pszStyle = (char *)malloc(strlen(pszStyleName) + 15); sprintf(pszStyle, "wms_style_%s_sld", pszStyleName); - msGetMapContextXMLHashValueDecode( psStyle, "SLD.OnlineResource.xlink:href", - &(layer->metadata), pszStyle ); + msGetMapContextXMLHashValueDecode(psStyle, "SLD.OnlineResource.xlink:href", + &(layer->metadata), pszStyle); free(pszStyle); /* SLDBODY */ - pszStyle = (char*)malloc(strlen(pszStyleName)+20); + pszStyle = (char *)malloc(strlen(pszStyleName) + 20); sprintf(pszStyle, "wms_style_%s_sld_body", pszStyleName); psStyleSLDBody = CPLGetXMLNode(psStyle, "SLD.StyledLayerDescriptor"); - /*some clients such as OpenLayers add a name space, which I believe is wrong but - added this additional test for compatibility #3115*/ + /*some clients such as OpenLayers add a name space, which I believe is wrong + but added this additional test for compatibility #3115*/ if (psStyleSLDBody == NULL) psStyleSLDBody = CPLGetXMLNode(psStyle, "SLD.sld:StyledLayerDescriptor"); - if(psStyleSLDBody != NULL && &(layer->metadata) != NULL) { + if (psStyleSLDBody != NULL && &(layer->metadata) != NULL) { pszValue = CPLSerializeXMLTree(psStyleSLDBody); - if(pszValue != NULL) { + if (pszValue != NULL) { /* Before including SLDBody in the mapfile, we must replace the */ /* double quote for single quote. This is to prevent having this: */ /* "metadata" "" */ char *c; - for(c=pszValue; *c != '\0'; c++) - if(*c == '"') + for (c = pszValue; *c != '\0'; c++) + if (*c == '"') *c = '\''; - msInsertHashTable(&(layer->metadata), pszStyle, pszValue ); + msInsertHashTable(&(layer->metadata), pszStyle, pszValue); msFree(pszValue); } } @@ -533,12 +499,11 @@ int msLoadMapContextLayerStyle(CPLXMLNode *psStyle, layerObj *layer, free(pszStyle); /* LegendURL */ - pszStyle = (char*) malloc(strlen(pszStyleName) + 25); + pszStyle = (char *)malloc(strlen(pszStyleName) + 25); - sprintf( pszStyle, "wms_style_%s_legendurl", - pszStyleName); - msLoadMapContextURLELements( CPLGetXMLNode(psStyle, "LegendURL"), - &(layer->metadata), pszStyle ); + sprintf(pszStyle, "wms_style_%s_legendurl", pszStyleName); + msLoadMapContextURLELements(CPLGetXMLNode(psStyle, "LegendURL"), + &(layer->metadata), pszStyle); free(pszStyle); @@ -547,20 +512,18 @@ int msLoadMapContextLayerStyle(CPLXMLNode *psStyle, layerObj *layer, /* */ /* Add the stylelist to the layer connection */ /* */ - if(msLookupHashTable(&(layer->metadata), - "wms_stylelist") == NULL) { - if(layer->connection) + if (msLookupHashTable(&(layer->metadata), "wms_stylelist") == NULL) { + if (layer->connection) pszValue = msStrdup(layer->connection); else - pszValue = msStrdup( "" ); + pszValue = msStrdup(""); pszValue1 = strstr(pszValue, "STYLELIST="); - if(pszValue1 != NULL) { + if (pszValue1 != NULL) { pszValue1 += 10; pszValue2 = strchr(pszValue, '&'); - if(pszValue2 != NULL) - pszValue1[pszValue2-pszValue1] = '\0'; - msInsertHashTable(&(layer->metadata), "wms_stylelist", - pszValue1); + if (pszValue2 != NULL) + pszValue1[pszValue2 - pszValue1] = '\0'; + msInsertHashTable(&(layer->metadata), "wms_stylelist", pszValue1); } free(pszValue); } @@ -568,19 +531,18 @@ int msLoadMapContextLayerStyle(CPLXMLNode *psStyle, layerObj *layer, /* */ /* Add the style to the layer connection */ /* */ - if(msLookupHashTable(&(layer->metadata), "wms_style") == NULL) { - if(layer->connection) + if (msLookupHashTable(&(layer->metadata), "wms_style") == NULL) { + if (layer->connection) pszValue = msStrdup(layer->connection); else - pszValue = msStrdup( "" ); + pszValue = msStrdup(""); pszValue1 = strstr(pszValue, "STYLE="); - if(pszValue1 != NULL) { + if (pszValue1 != NULL) { pszValue1 += 6; pszValue2 = strchr(pszValue, '&'); - if(pszValue2 != NULL) - pszValue1[pszValue2-pszValue1] = '\0'; - msInsertHashTable(&(layer->metadata), "wms_style", - pszValue1); + if (pszValue2 != NULL) + pszValue1[pszValue2 - pszValue1] = '\0'; + msInsertHashTable(&(layer->metadata), "wms_style", pszValue1); } free(pszValue); } @@ -588,39 +550,34 @@ int msLoadMapContextLayerStyle(CPLXMLNode *psStyle, layerObj *layer, return MS_SUCCESS; } -int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) -{ +int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) { char *pszValue; const char *pszHash; - char *pszDimension=NULL, *pszDimensionName=NULL; + char *pszDimension = NULL, *pszDimensionName = NULL; - pszDimensionName =(char*)CPLGetXMLValue(psDimension,"name",NULL); - if(pszDimensionName == NULL) { + pszDimensionName = (char *)CPLGetXMLValue(psDimension, "name", NULL); + if (pszDimensionName == NULL) { return MS_FALSE; } else pszDimensionName = msStrdup(pszDimensionName); - pszDimension = (char*)malloc(strlen(pszDimensionName)+50); + pszDimension = (char *)malloc(strlen(pszDimensionName) + 50); /* wms_dimension: This is the current dimension */ - pszValue = (char*)CPLGetXMLValue(psDimension, "current", NULL); - if(pszValue != NULL && (strcasecmp(pszValue, "1") == 0 || - strcasecmp(pszValue, "true") == 0)) - msInsertHashTable(&(layer->metadata), - "wms_dimension", pszDimensionName); + pszValue = (char *)CPLGetXMLValue(psDimension, "current", NULL); + if (pszValue != NULL && + (strcasecmp(pszValue, "1") == 0 || strcasecmp(pszValue, "true") == 0)) + msInsertHashTable(&(layer->metadata), "wms_dimension", pszDimensionName); /* wms_dimensionlist */ - pszHash = msLookupHashTable(&(layer->metadata), - "wms_dimensionlist"); - if(pszHash != NULL) { - pszValue = (char*)malloc(strlen(pszHash)+ - strlen(pszDimensionName)+2); + pszHash = msLookupHashTable(&(layer->metadata), "wms_dimensionlist"); + if (pszHash != NULL) { + pszValue = (char *)malloc(strlen(pszHash) + strlen(pszDimensionName) + 2); sprintf(pszValue, "%s,%s", pszHash, pszDimensionName); - msInsertHashTable(&(layer->metadata), - "wms_dimensionlist", pszValue); + msInsertHashTable(&(layer->metadata), "wms_dimensionlist", pszValue); free(pszValue); } else - msInsertHashTable(&(layer->metadata), - "wms_dimensionlist", pszDimensionName); + msInsertHashTable(&(layer->metadata), "wms_dimensionlist", + pszDimensionName); /* Units */ sprintf(pszDimension, "wms_dimension_%s_units", pszDimensionName); @@ -636,7 +593,7 @@ int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) sprintf(pszDimension, "wms_dimension_%s_uservalue", pszDimensionName); msGetMapContextXMLHashValue(psDimension, "userValue", &(layer->metadata), pszDimension); - if(strcasecmp(pszDimensionName, "time") == 0) + if (strcasecmp(pszDimensionName, "time") == 0) msGetMapContextXMLHashValue(psDimension, "userValue", &(layer->metadata), "wms_time"); @@ -647,7 +604,7 @@ int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) /* multipleValues */ sprintf(pszDimension, "wms_dimension_%s_multiplevalues", pszDimensionName); - msGetMapContextXMLHashValue(psDimension, "multipleValues",&(layer->metadata), + msGetMapContextXMLHashValue(psDimension, "multipleValues", &(layer->metadata), pszDimension); /* nearestValue */ @@ -662,8 +619,6 @@ int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) return MS_SUCCESS; } - - /* ** msLoadMapContextGeneral ** @@ -671,22 +626,20 @@ int msLoadMapContextLayerDimension(CPLXMLNode *psDimension, layerObj *layer) */ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, CPLXMLNode *psMapContext, int nVersion, - const char *filename) -{ + const char *filename) { - char *pszProj=NULL; + char *pszProj = NULL; char *pszValue, *pszValue1, *pszValue2; int nTmp; /* Projection */ - pszValue = (char*)CPLGetXMLValue(psGeneral, - "BoundingBox.SRS", NULL); - if(pszValue != NULL && !EQUAL(pszValue, "(null)")) { - if(strncasecmp(pszValue, "AUTO:", 5) == 0) { + pszValue = (char *)CPLGetXMLValue(psGeneral, "BoundingBox.SRS", NULL); + if (pszValue != NULL && !EQUAL(pszValue, "(null)")) { + if (strncasecmp(pszValue, "AUTO:", 5) == 0) { pszProj = msStrdup(pszValue); } else { - pszProj = (char*) malloc(sizeof(char)*(strlen(pszValue)+10)); - sprintf(pszProj, "init=epsg:%s", pszValue+5); + pszProj = (char *)malloc(sizeof(char) * (strlen(pszValue) + 10)); + sprintf(pszProj, "init=epsg:%s", pszValue + 5); } msFreeProjection(&map->projection); @@ -695,10 +648,9 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, map->projection.numargs++; msProcessProjection(&map->projection); - if( (nTmp = GetMapserverUnitUsingProj(&(map->projection))) == -1) { - msSetError( MS_MAPCONTEXTERR, - "Unable to set units for projection '%s'", - "msLoadMapContext()", pszProj ); + if ((nTmp = GetMapserverUnitUsingProj(&(map->projection))) == -1) { + msSetError(MS_MAPCONTEXTERR, "Unable to set units for projection '%s'", + "msLoadMapContext()", pszProj); free(pszProj); return MS_FAILURE; } else { @@ -706,93 +658,84 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, } free(pszProj); } else { - msDebug("Mandatory data General.BoundingBox.SRS missing in %s.", - filename); + msDebug("Mandatory data General.BoundingBox.SRS missing in %s.", filename); } /* Extent */ - if( msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.minx", + if (msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.minx", &(map->extent.minx)) == MS_FAILURE) { - msDebug("Mandatory data General.BoundingBox.minx missing in %s.", - filename); + msDebug("Mandatory data General.BoundingBox.minx missing in %s.", filename); } - if( msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.miny", + if (msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.miny", &(map->extent.miny)) == MS_FAILURE) { - msDebug("Mandatory data General.BoundingBox.miny missing in %s.", - filename); + msDebug("Mandatory data General.BoundingBox.miny missing in %s.", filename); } - if( msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.maxx", + if (msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.maxx", &(map->extent.maxx)) == MS_FAILURE) { - msDebug("Mandatory data General.BoundingBox.maxx missing in %s.", - filename); + msDebug("Mandatory data General.BoundingBox.maxx missing in %s.", filename); } - if( msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.maxy", + if (msGetMapContextXMLFloatValue(psGeneral, "BoundingBox.maxy", &(map->extent.maxy)) == MS_FAILURE) { - msDebug("Mandatory data General.BoundingBox.maxy missing in %s.", - filename); + msDebug("Mandatory data General.BoundingBox.maxy missing in %s.", filename); } /* Title */ - if( msGetMapContextXMLHashValue(psGeneral, "Title", - &(map->web.metadata), "wms_title") == MS_FAILURE) { - if ( nVersion >= OWS_1_0_0 ) + if (msGetMapContextXMLHashValue(psGeneral, "Title", &(map->web.metadata), + "wms_title") == MS_FAILURE) { + if (nVersion >= OWS_1_0_0) msDebug("Mandatory data General.Title missing in %s.", filename); else { - if( msGetMapContextXMLHashValue(psGeneral, "gml:name", - &(map->web.metadata), "wms_title") == MS_FAILURE ) { - if( nVersion < OWS_0_1_7 ) + if (msGetMapContextXMLHashValue(psGeneral, "gml:name", + &(map->web.metadata), + "wms_title") == MS_FAILURE) { + if (nVersion < OWS_0_1_7) msDebug("Mandatory data General.Title missing in %s.", filename); else - msDebug("Mandatory data General.gml:name missing in %s.", - filename); + msDebug("Mandatory data General.gml:name missing in %s.", filename); } } } /* Name */ - if( nVersion >= OWS_1_0_0 ) { - pszValue = (char*)CPLGetXMLValue(psMapContext, - "id", NULL); - if (pszValue) - { + if (nVersion >= OWS_1_0_0) { + pszValue = (char *)CPLGetXMLValue(psMapContext, "id", NULL); + if (pszValue) { msFree(map->name); map->name = msStrdup(pszValue); } } else { - char* pszMapName = NULL; - if(msGetMapContextXMLStringValue(psGeneral, "Name", - &pszMapName) == MS_FAILURE) { - msGetMapContextXMLStringValue(psGeneral, "gml:name", - &pszMapName); + char *pszMapName = NULL; + if (msGetMapContextXMLStringValue(psGeneral, "Name", &pszMapName) == + MS_FAILURE) { + msGetMapContextXMLStringValue(psGeneral, "gml:name", &pszMapName); } - if( pszMapName ) { + if (pszMapName) { msFree(map->name); map->name = pszMapName; } } /* Keyword */ - if( nVersion >= OWS_1_0_0 ) { - msLoadMapContextListInMetadata( - CPLGetXMLNode(psGeneral, "KeywordList"), - &(map->web.metadata), "KEYWORD", "wms_keywordlist", "," ); + if (nVersion >= OWS_1_0_0) { + msLoadMapContextListInMetadata(CPLGetXMLNode(psGeneral, "KeywordList"), + &(map->web.metadata), "KEYWORD", + "wms_keywordlist", ","); } else - msGetMapContextXMLHashValue(psGeneral, "Keywords", - &(map->web.metadata), "wms_keywordlist"); + msGetMapContextXMLHashValue(psGeneral, "Keywords", &(map->web.metadata), + "wms_keywordlist"); /* Window */ - pszValue1 = (char*)CPLGetXMLValue(psGeneral,"Window.width",NULL); - pszValue2 = (char*)CPLGetXMLValue(psGeneral,"Window.height",NULL); - if(pszValue1 != NULL && pszValue2 != NULL) { + pszValue1 = (char *)CPLGetXMLValue(psGeneral, "Window.width", NULL); + pszValue2 = (char *)CPLGetXMLValue(psGeneral, "Window.height", NULL); + if (pszValue1 != NULL && pszValue2 != NULL) { map->width = atoi(pszValue1); map->height = atoi(pszValue2); } /* Abstract */ - if( msGetMapContextXMLHashValue( psGeneral, - "Abstract", &(map->web.metadata), - "wms_abstract") == MS_FAILURE ) { - msGetMapContextXMLHashValue( psGeneral, "gml:description", - &(map->web.metadata), "wms_abstract"); + if (msGetMapContextXMLHashValue(psGeneral, "Abstract", &(map->web.metadata), + "wms_abstract") == MS_FAILURE) { + msGetMapContextXMLHashValue(psGeneral, "gml:description", + &(map->web.metadata), "wms_abstract"); } /* DataURL */ @@ -802,19 +745,17 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, /* LogoURL */ /* The logourl have a width, height, format and an URL */ - msLoadMapContextURLELements( CPLGetXMLNode(psGeneral, "LogoURL"), - &(map->web.metadata), "wms_logourl" ); + msLoadMapContextURLELements(CPLGetXMLNode(psGeneral, "LogoURL"), + &(map->web.metadata), "wms_logourl"); /* DescriptionURL */ /* The descriptionurl have a width, height, format and an URL */ - msLoadMapContextURLELements( CPLGetXMLNode(psGeneral, - "DescriptionURL"), - &(map->web.metadata), "wms_descriptionurl" ); + msLoadMapContextURLELements(CPLGetXMLNode(psGeneral, "DescriptionURL"), + &(map->web.metadata), "wms_descriptionurl"); /* Contact Info */ - msLoadMapContextContactInfo( - CPLGetXMLNode(psGeneral, "ContactInformation"), - &(map->web.metadata) ); + msLoadMapContextContactInfo(CPLGetXMLNode(psGeneral, "ContactInformation"), + &(map->web.metadata)); return MS_SUCCESS; } @@ -825,18 +766,17 @@ int msLoadMapContextGeneral(mapObj *map, CPLXMLNode *psGeneral, ** Load a Layer block from a MapContext document */ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, - const char *filename, int unique_layer_names) -{ + const char *filename, int unique_layer_names) { char *pszValue; const char *pszHash; - char *pszName=NULL; + char *pszName = NULL; CPLXMLNode *psFormatList, *psFormat, *psStyleList, *psStyle, *psExtension; CPLXMLNode *psDimensionList, *psDimension; int nStyle; layerObj *layer; /* Init new layer */ - if(msGrowMapLayers(map) == NULL) + if (msGrowMapLayers(map) == NULL) return MS_FAILURE; layer = (GET_LAYER(map, map->numlayers)); @@ -848,57 +788,57 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, map->layerorder[map->numlayers] = map->numlayers; map->numlayers++; - /* Status */ - pszValue = (char*)CPLGetXMLValue(psLayer, "hidden", "1"); - if((pszValue != NULL) && (atoi(pszValue) == 0 && - strcasecmp(pszValue, "true") != 0)) + pszValue = (char *)CPLGetXMLValue(psLayer, "hidden", "1"); + if ((pszValue != NULL) && + (atoi(pszValue) == 0 && strcasecmp(pszValue, "true") != 0)) layer->status = MS_ON; else layer->status = MS_OFF; /* Queryable */ - pszValue = (char*)CPLGetXMLValue(psLayer, "queryable", "0"); - if(pszValue !=NULL && (atoi(pszValue) == 1 || - strcasecmp(pszValue, "true") == 0)) + pszValue = (char *)CPLGetXMLValue(psLayer, "queryable", "0"); + if (pszValue != NULL && + (atoi(pszValue) == 1 || strcasecmp(pszValue, "true") == 0)) layer->template = msStrdup("ttt"); /* Name and Title */ - pszValue = (char*)CPLGetXMLValue(psLayer, "Name", NULL); - if(pszValue != NULL) { - msInsertHashTable( &(layer->metadata), "wms_name", pszValue ); + pszValue = (char *)CPLGetXMLValue(psLayer, "Name", NULL); + if (pszValue != NULL) { + msInsertHashTable(&(layer->metadata), "wms_name", pszValue); if (unique_layer_names) { - pszName = (char*)malloc(sizeof(char)*(strlen(pszValue)+15)); + pszName = (char *)malloc(sizeof(char) * (strlen(pszValue) + 15)); sprintf(pszName, "l%d:%s", layer->index, pszValue); layer->name = msStrdup(pszName); free(pszName); } else - layer->name = msStrdup(pszValue); + layer->name = msStrdup(pszValue); } else { - pszName = (char*)malloc(sizeof(char)*15); + pszName = (char *)malloc(sizeof(char) * 15); sprintf(pszName, "l%d:", layer->index); layer->name = msStrdup(pszName); free(pszName); } - if(msGetMapContextXMLHashValue(psLayer, "Title", &(layer->metadata), - "wms_title") == MS_FAILURE) { - if(msGetMapContextXMLHashValue(psLayer, "Server.title", - &(layer->metadata), "wms_title") == MS_FAILURE) { + if (msGetMapContextXMLHashValue(psLayer, "Title", &(layer->metadata), + "wms_title") == MS_FAILURE) { + if (msGetMapContextXMLHashValue(psLayer, "Server.title", &(layer->metadata), + "wms_title") == MS_FAILURE) { msDebug("Mandatory data Layer.Title missing in %s.", filename); } } /* Server Title */ - msGetMapContextXMLHashValue(psLayer, "Server.title", &(layer->metadata), "wms_server_title"); + msGetMapContextXMLHashValue(psLayer, "Server.title", &(layer->metadata), + "wms_server_title"); /* Abstract */ msGetMapContextXMLHashValue(psLayer, "Abstract", &(layer->metadata), "wms_abstract"); /* DataURL */ - if(nVersion <= OWS_0_1_4) { + if (nVersion <= OWS_0_1_4) { msGetMapContextXMLHashValueDecode(psLayer, "DataURL.OnlineResource.xlink:href", &(layer->metadata), "wms_dataurl"); @@ -906,71 +846,74 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, /* The DataURL have a width, height, format and an URL */ /* Width and height are not used, but they are included to */ /* be consistent with the spec. */ - msLoadMapContextURLELements( CPLGetXMLNode(psLayer, "DataURL"), - &(layer->metadata), "wms_dataurl" ); + msLoadMapContextURLELements(CPLGetXMLNode(psLayer, "DataURL"), + &(layer->metadata), "wms_dataurl"); } /* The MetadataURL have a width, height, format and an URL */ /* Width and height are not used, but they are included to */ /* be consistent with the spec. */ - msLoadMapContextURLELements( CPLGetXMLNode(psLayer, "MetadataURL"), - &(layer->metadata), "wms_metadataurl" ); - + msLoadMapContextURLELements(CPLGetXMLNode(psLayer, "MetadataURL"), + &(layer->metadata), "wms_metadataurl"); /* MinScale && MaxScale */ - pszValue = (char*)CPLGetXMLValue(psLayer, "sld:MinScaleDenominator", NULL); - if(pszValue != NULL) { + pszValue = (char *)CPLGetXMLValue(psLayer, "sld:MinScaleDenominator", NULL); + if (pszValue != NULL) { layer->minscaledenom = atof(pszValue); } - pszValue = (char*)CPLGetXMLValue(psLayer, "sld:MaxScaleDenominator", NULL); - if(pszValue != NULL) { + pszValue = (char *)CPLGetXMLValue(psLayer, "sld:MaxScaleDenominator", NULL); + if (pszValue != NULL) { layer->maxscaledenom = atof(pszValue); } /* */ /* Server */ /* */ - if(nVersion >= OWS_0_1_4) { - if(msGetMapContextXMLStringValueDecode(psLayer, - "Server.OnlineResource.xlink:href", - &(layer->connection)) == MS_FAILURE) { - msSetError(MS_MAPCONTEXTERR, - "Mandatory data Server.OnlineResource.xlink:href missing in %s.", - "msLoadMapContext()", filename); + if (nVersion >= OWS_0_1_4) { + if (msGetMapContextXMLStringValueDecode( + psLayer, "Server.OnlineResource.xlink:href", + &(layer->connection)) == MS_FAILURE) { + msSetError( + MS_MAPCONTEXTERR, + "Mandatory data Server.OnlineResource.xlink:href missing in %s.", + "msLoadMapContext()", filename); return MS_FAILURE; } else { - msGetMapContextXMLHashValueDecode(psLayer, - "Server.OnlineResource.xlink:href", - &(layer->metadata), "wms_onlineresource"); + msGetMapContextXMLHashValueDecode( + psLayer, "Server.OnlineResource.xlink:href", &(layer->metadata), + "wms_onlineresource"); layer->connectiontype = MS_WMS; } } else { - if(msGetMapContextXMLStringValueDecode(psLayer, - "Server.onlineResource", - &(layer->connection)) == MS_FAILURE) { + if (msGetMapContextXMLStringValueDecode(psLayer, "Server.onlineResource", + &(layer->connection)) == + MS_FAILURE) { msSetError(MS_MAPCONTEXTERR, "Mandatory data Server.onlineResource missing in %s.", "msLoadMapContext()", filename); return MS_FAILURE; } else { msGetMapContextXMLHashValueDecode(psLayer, "Server.onlineResource", - &(layer->metadata), "wms_onlineresource"); + &(layer->metadata), + "wms_onlineresource"); layer->connectiontype = MS_WMS; } } - if(nVersion >= OWS_0_1_4) { - if(msGetMapContextXMLHashValue(psLayer, "Server.version", - &(layer->metadata), "wms_server_version") == MS_FAILURE) { + if (nVersion >= OWS_0_1_4) { + if (msGetMapContextXMLHashValue(psLayer, "Server.version", + &(layer->metadata), + "wms_server_version") == MS_FAILURE) { msSetError(MS_MAPCONTEXTERR, "Mandatory data Server.version missing in %s.", "msLoadMapContext()", filename); return MS_FAILURE; } } else { - if(msGetMapContextXMLHashValue(psLayer, "Server.wmtver", - &(layer->metadata), "wms_server_version") == MS_FAILURE) { + if (msGetMapContextXMLHashValue(psLayer, "Server.wmtver", + &(layer->metadata), + "wms_server_version") == MS_FAILURE) { msSetError(MS_MAPCONTEXTERR, "Mandatory data Server.wmtver missing in %s.", "msLoadMapContext()", filename); @@ -979,23 +922,23 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, } /* Projection */ - msLoadMapContextListInMetadata( psLayer, &(layer->metadata), - "SRS", "wms_srs", " " ); + msLoadMapContextListInMetadata(psLayer, &(layer->metadata), "SRS", "wms_srs", + " "); pszHash = msLookupHashTable(&(layer->metadata), "wms_srs"); - if(((pszHash == NULL) || (strcasecmp(pszHash, "") == 0)) && + if (((pszHash == NULL) || (strcasecmp(pszHash, "") == 0)) && map->projection.numargs != 0) { - char* pszProj = map->projection.args[map->projection.numargs-1]; + char *pszProj = map->projection.args[map->projection.numargs - 1]; - if(pszProj != NULL) { - if(strncasecmp(pszProj, "AUTO:", 5) == 0) { - msInsertHashTable(&(layer->metadata),"wms_srs", pszProj); + if (pszProj != NULL) { + if (strncasecmp(pszProj, "AUTO:", 5) == 0) { + msInsertHashTable(&(layer->metadata), "wms_srs", pszProj); } else { - if(strlen(pszProj) > 10) { - pszProj = (char*) malloc(sizeof(char) * (strlen(pszProj))); - sprintf( pszProj, "EPSG:%s", - map->projection.args[map->projection.numargs-1]+10); - msInsertHashTable(&(layer->metadata),"wms_srs", pszProj); + if (strlen(pszProj) > 10) { + pszProj = (char *)malloc(sizeof(char) * (strlen(pszProj))); + sprintf(pszProj, "EPSG:%s", + map->projection.args[map->projection.numargs - 1] + 10); + msInsertHashTable(&(layer->metadata), "wms_srs", pszProj); } else { msDebug("Unable to set data for layer wms_srs from this" " value %s.", @@ -1009,34 +952,32 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, /* */ /* Format */ /* */ - if( nVersion >= OWS_0_1_4 ) { + if (nVersion >= OWS_0_1_4) { psFormatList = CPLGetXMLNode(psLayer, "FormatList"); } else { psFormatList = psLayer; } - if(psFormatList != NULL) { - for(psFormat = psFormatList->psChild; - psFormat != NULL; - psFormat = psFormat->psNext) { + if (psFormatList != NULL) { + for (psFormat = psFormatList->psChild; psFormat != NULL; + psFormat = psFormat->psNext) { msLoadMapContextLayerFormat(psFormat, layer); } } /* end FormatList parsing */ /* Style */ - if( nVersion >= OWS_0_1_4 ) { + if (nVersion >= OWS_0_1_4) { psStyleList = CPLGetXMLNode(psLayer, "StyleList"); } else { psStyleList = psLayer; } - if(psStyleList != NULL) { + if (psStyleList != NULL) { nStyle = 0; - for(psStyle = psStyleList->psChild; - psStyle != NULL; - psStyle = psStyle->psNext) { - if(strcasecmp(psStyle->pszValue, "Style") == 0) { + for (psStyle = psStyleList->psChild; psStyle != NULL; + psStyle = psStyle->psNext) { + if (strcasecmp(psStyle->pszValue, "Style") == 0) { nStyle++; msLoadMapContextLayerStyle(psStyle, layer, nStyle); } @@ -1045,11 +986,10 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, /* Dimension */ psDimensionList = CPLGetXMLNode(psLayer, "DimensionList"); - if(psDimensionList != NULL) { - for(psDimension = psDimensionList->psChild; - psDimension != NULL; - psDimension = psDimension->psNext) { - if(strcasecmp(psDimension->pszValue, "Dimension") == 0) { + if (psDimensionList != NULL) { + for (psDimension = psDimensionList->psChild; psDimension != NULL; + psDimension = psDimension->psNext) { + if (strcasecmp(psDimension->pszValue, "Dimension") == 0) { msLoadMapContextLayerDimension(psDimension, layer); } } @@ -1058,13 +998,13 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, /* Extension */ psExtension = CPLGetXMLNode(psLayer, "Extension"); if (psExtension != NULL) { - pszValue = (char*)CPLGetXMLValue(psExtension, "ol:opacity", NULL); - if(pszValue != NULL) { - if(!layer->compositer) { + pszValue = (char *)CPLGetXMLValue(psExtension, "ol:opacity", NULL); + if (pszValue != NULL) { + if (!layer->compositer) { layer->compositer = msSmallMalloc(sizeof(LayerCompositer)); initLayerCompositer(layer->compositer); } - layer->compositer->opacity = atof(pszValue)*100; + layer->compositer->opacity = atof(pszValue) * 100; } } @@ -1073,8 +1013,6 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, #endif - - /* msLoadMapContextURL() ** ** load an OGC Web Map Context format from an URL @@ -1082,25 +1020,24 @@ int msLoadMapContextLayer(mapObj *map, CPLXMLNode *psLayer, int nVersion, ** Take a map object and a URL to a conect file in arguments */ -int msLoadMapContextURL(mapObj *map, char *urlfilename, int unique_layer_names) -{ +int msLoadMapContextURL(mapObj *map, char *urlfilename, + int unique_layer_names) { #if defined(USE_WMS_LYR) char *pszTmpFile = NULL; int status = 0; if (!map || !urlfilename) { - msSetError(MS_MAPCONTEXTERR, - "Invalid map or url given.", + msSetError(MS_MAPCONTEXTERR, "Invalid map or url given.", "msGetMapContextURL()"); return MS_FAILURE; } pszTmpFile = msTmpFile(map, map->mappath, NULL, "context.xml"); - if (msHTTPGetFile(urlfilename, pszTmpFile, &status,-1, 0, 0, 0) == MS_SUCCESS) { + if (msHTTPGetFile(urlfilename, pszTmpFile, &status, -1, 0, 0, 0) == + MS_SUCCESS) { return msLoadMapContext(map, pszTmpFile, unique_layer_names); } else { - msSetError(MS_MAPCONTEXTERR, - "Could not open context file %s.", + msSetError(MS_MAPCONTEXTERR, "Could not open context file %s.", "msGetMapContextURL()", urlfilename); return MS_FAILURE; } @@ -1118,22 +1055,25 @@ int msLoadMapContextURL(mapObj *map, char *urlfilename, int unique_layer_names) ** ** Take as first map object and a file in arguments ** If The 2nd aregument unique_layer_names is set to MS_TRUE, the layer -** name created would be unique and be prefixed with an l plus the layers's index +** name created would be unique and be prefixed with an l plus the layers's +*index ** (eg l:1:park. l:2:road ...). If It is set to MS_FALSE, the layer name ** would be the same name as the layer name in the context */ -int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) -{ +int msLoadMapContext(mapObj *map, const char *filename, + int unique_layer_names) { #if defined(USE_WMS_LYR) char *pszWholeText, *pszValue; CPLXMLNode *psRoot, *psMapContext, *psLayer, *psLayerList, *psChild; char szPath[MS_MAXPATHLEN]; - int nVersion=-1; + int nVersion = -1; char szVersionBuf[OWS_VERSION_MAXLEN]; - const char *ms_contextfile_pattern = CPLGetConfigOption("MS_CONTEXTFILE_PATTERN", MS_DEFAULT_CONTEXTFILE_PATTERN); - if(msEvalRegex(ms_contextfile_pattern, filename) != MS_TRUE) { - msSetError(MS_REGEXERR, "Filename validation failed." , "msLoadMapContext()"); + const char *ms_contextfile_pattern = CPLGetConfigOption( + "MS_CONTEXTFILE_PATTERN", MS_DEFAULT_CONTEXTFILE_PATTERN); + if (msEvalRegex(ms_contextfile_pattern, filename) != MS_TRUE) { + msSetError(MS_REGEXERR, "Filename validation failed.", + "msLoadMapContext()"); return MS_FAILURE; } @@ -1141,35 +1081,35 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) /* Load the raw XML file */ /* */ - pszWholeText = msGetMapContextFileText( - msBuildPath(szPath, map->mappath, filename)); - if(pszWholeText == NULL) { - msSetError( MS_MAPCONTEXTERR, "Unable to read %s", - "msLoadMapContext()", filename ); + pszWholeText = + msGetMapContextFileText(msBuildPath(szPath, map->mappath, filename)); + if (pszWholeText == NULL) { + msSetError(MS_MAPCONTEXTERR, "Unable to read %s", "msLoadMapContext()", + filename); return MS_FAILURE; } - if( ( strstr( pszWholeText, "eType == CXT_Element && - (EQUAL(psChild->pszValue,"WMS_Viewer_Context") || - EQUAL(psChild->pszValue,"View_Context") || - EQUAL(psChild->pszValue,"ViewContext")) ) { + while (psChild != NULL) { + if (psChild->eType == CXT_Element && + (EQUAL(psChild->pszValue, "WMS_Viewer_Context") || + EQUAL(psChild->pszValue, "View_Context") || + EQUAL(psChild->pszValue, "ViewContext"))) { psMapContext = psChild; break; } else { @@ -1190,19 +1130,19 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) } } - if( psMapContext == NULL ) { + if (psMapContext == NULL) { CPLDestroyXMLNode(psRoot); - msSetError( MS_MAPCONTEXTERR, "Invalid Map Context File (%s)", - "msLoadMapContext()", filename ); + msSetError(MS_MAPCONTEXTERR, "Invalid Map Context File (%s)", + "msLoadMapContext()", filename); return MS_FAILURE; } /* Fetch document version number */ - pszValue = (char*)CPLGetXMLValue(psMapContext, - "version", NULL); - if( !pszValue ) { - msDebug( "msLoadMapContext(): Mandatory data version missing in %s, assuming 0.1.4.", - filename ); + pszValue = (char *)CPLGetXMLValue(psMapContext, "version", NULL); + if (!pszValue) { + msDebug("msLoadMapContext(): Mandatory data version missing in %s, " + "assuming 0.1.4.", + filename); pszValue = "0.1.4"; } @@ -1210,29 +1150,29 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) /* Make sure this is a supported version */ switch (nVersion) { - case OWS_0_1_2: - case OWS_0_1_4: - case OWS_0_1_7: - case OWS_1_0_0: - case OWS_1_1_0: - /* All is good, this is a supported version. */ - break; - default: - /* Not a supported version */ - msSetError(MS_MAPCONTEXTERR, - "This version of Map Context is not supported (%s).", - "msLoadMapContext()", pszValue); - CPLDestroyXMLNode(psRoot); - return MS_FAILURE; + case OWS_0_1_2: + case OWS_0_1_4: + case OWS_0_1_7: + case OWS_1_0_0: + case OWS_1_1_0: + /* All is good, this is a supported version. */ + break; + default: + /* Not a supported version */ + msSetError(MS_MAPCONTEXTERR, + "This version of Map Context is not supported (%s).", + "msLoadMapContext()", pszValue); + CPLDestroyXMLNode(psRoot); + return MS_FAILURE; } /* Reformat and save Version in metadata */ - msInsertHashTable( &(map->web.metadata), "wms_context_version", - msOWSGetVersionString(nVersion, szVersionBuf)); + msInsertHashTable(&(map->web.metadata), "wms_context_version", + msOWSGetVersionString(nVersion, szVersionBuf)); - if( nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { - if( msGetMapContextXMLHashValue(psMapContext, "fid", - &(map->web.metadata), "wms_context_fid") == MS_FAILURE ) { + if (nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { + if (msGetMapContextXMLHashValue(psMapContext, "fid", &(map->web.metadata), + "wms_context_fid") == MS_FAILURE) { msDebug("Mandatory data fid missing in %s.", filename); } } @@ -1240,8 +1180,8 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) /* */ /* Load the General bloc */ /* */ - psChild = CPLGetXMLNode( psMapContext, "General" ); - if( psChild == NULL ) { + psChild = CPLGetXMLNode(psMapContext, "General"); + if (psChild == NULL) { CPLDestroyXMLNode(psRoot); msSetError(MS_MAPCONTEXTERR, "The Map Context document provided (%s) does not contain any " @@ -1250,8 +1190,8 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) return MS_FAILURE; } - if( msLoadMapContextGeneral(map, psChild, psMapContext, - nVersion, filename) == MS_FAILURE ) { + if (msLoadMapContextGeneral(map, psChild, psMapContext, nVersion, filename) == + MS_FAILURE) { CPLDestroyXMLNode(psRoot); return MS_FAILURE; } @@ -1260,18 +1200,17 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) /* Load the bloc LayerList */ /* */ psLayerList = CPLGetXMLNode(psMapContext, "LayerList"); - if( psLayerList != NULL ) { - for(psLayer = psLayerList->psChild; - psLayer != NULL; - psLayer = psLayer->psNext) { - if(EQUAL(psLayer->pszValue, "Layer")) { - if( msLoadMapContextLayer(map, psLayer, nVersion, - filename, unique_layer_names) == MS_FAILURE ) { + if (psLayerList != NULL) { + for (psLayer = psLayerList->psChild; psLayer != NULL; + psLayer = psLayer->psNext) { + if (EQUAL(psLayer->pszValue, "Layer")) { + if (msLoadMapContextLayer(map, psLayer, nVersion, filename, + unique_layer_names) == MS_FAILURE) { CPLDestroyXMLNode(psRoot); return MS_FAILURE; } - }/* end Layer parsing */ - }/* for */ + } /* end Layer parsing */ + } /* for */ } CPLDestroyXMLNode(psRoot); @@ -1286,26 +1225,24 @@ int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names) #endif } - /* msSaveMapContext() ** ** Save a mapfile into the OGC Web Map Context format ** ** Take a map object and a file in arguments */ -int msSaveMapContext(mapObj *map, char *filename) -{ +int msSaveMapContext(mapObj *map, char *filename) { #if defined(USE_WMS_LYR) FILE *stream; char szPath[MS_MAXPATHLEN]; int nStatus; /* open file */ - if(filename != NULL && strlen(filename) > 0) { + if (filename != NULL && strlen(filename) > 0) { stream = fopen(msBuildPath(szPath, map->mappath, filename), "wb"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "msSaveMapContext()", filename); - return(MS_FAILURE); + return (MS_FAILURE); } } else { msSetError(MS_IOERR, "Filename is undefined.", "msSaveMapContext()"); @@ -1325,133 +1262,139 @@ int msSaveMapContext(mapObj *map, char *filename) #endif } - - -int msWriteMapContext(mapObj *map, FILE *stream) -{ +int msWriteMapContext(mapObj *map, FILE *stream) { #if defined(USE_WMS_LYR) - const char * version; + const char *version; char *pszEPSG; - char * tabspace=NULL, *pszChar,*pszSLD=NULL,*pszSLD2=NULL; + char *tabspace = NULL, *pszChar, *pszSLD = NULL, *pszSLD2 = NULL; char *pszStyleItem, *pszSLDBody; char *pszEncodedVal; - int i, nValue, nVersion=OWS_VERSION_NOTSET; + int i, nValue, nVersion = OWS_VERSION_NOTSET; /* Dimension element */ char *pszDimension; - const char *pszDimUserValue=NULL, *pszDimUnits=NULL, *pszDimDefault=NULL; - const char *pszDimNearValue=NULL, *pszDimUnitSymbol=NULL; - const char *pszDimMultiValue=NULL; + const char *pszDimUserValue = NULL, *pszDimUnits = NULL, + *pszDimDefault = NULL; + const char *pszDimNearValue = NULL, *pszDimUnitSymbol = NULL; + const char *pszDimMultiValue = NULL; int bDimensionList = 0; /* Decide which version we're going to return... */ version = msLookupHashTable(&(map->web.metadata), "wms_context_version"); - if(version == NULL) + if (version == NULL) version = "1.1.0"; nVersion = msOWSParseVersionString(version); if (nVersion == OWS_VERSION_BADFORMAT) - return MS_FAILURE; /* msSetError() already called. */ + return MS_FAILURE; /* msSetError() already called. */ /* Make sure this is a supported version */ /* Note that we don't write 0.1.2 even if we read it. */ switch (nVersion) { - case OWS_0_1_4: - case OWS_0_1_7: - case OWS_1_0_0: - case OWS_1_1_0: - /* All is good, this is a supported version. */ - break; - default: - /* Not a supported version */ - msSetError(MS_MAPCONTEXTERR, - "This version of Map Context is not supported (%s).", - "msSaveMapContext()", version); - return MS_FAILURE; + case OWS_0_1_4: + case OWS_0_1_7: + case OWS_1_0_0: + case OWS_1_1_0: + /* All is good, this is a supported version. */ + break; + default: + /* Not a supported version */ + msSetError(MS_MAPCONTEXTERR, + "This version of Map Context is not supported (%s).", + "msSaveMapContext()", version); + return MS_FAILURE; } /* file header */ - msIO_fprintf( stream, "\n"); + msIO_fprintf(stream, + "\n"); /* set the WMS_Viewer_Context information */ pszEncodedVal = msEncodeHTMLEntities(version); - if(nVersion >= OWS_1_0_0) { - msIO_fprintf( stream, "= OWS_0_1_7) { - msIO_fprintf( stream, "= OWS_1_0_0) { + msIO_fprintf(stream, "= OWS_0_1_7) { + msIO_fprintf(stream, "= OWS_0_1_7 && nVersion < OWS_1_0_0 ) { + if (nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { msOWSPrintEncodeMetadata(stream, &(map->web.metadata), NULL, - "wms_context_fid", OWS_NOERR," fid=\"%s\"","0"); + "wms_context_fid", OWS_NOERR, " fid=\"%s\"", "0"); } - if ( nVersion >= OWS_1_0_0 ) + if (nVersion >= OWS_1_0_0) msOWSPrintEncodeParam(stream, "MAP.NAME", map->name, OWS_NOERR, " id=\"%s\"", NULL); - msIO_fprintf( stream, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); - msIO_fprintf( stream, " xmlns:ogc=\"http://www.opengis.net/ogc\""); + msIO_fprintf(stream, + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); + msIO_fprintf(stream, " xmlns:ogc=\"http://www.opengis.net/ogc\""); - if( nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0 ) { - msIO_fprintf( stream, " xmlns:gml=\"http://www.opengis.net/gml\""); + if (nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { + msIO_fprintf(stream, " xmlns:gml=\"http://www.opengis.net/gml\""); } - if( nVersion >= OWS_1_0_0 ) { - msIO_fprintf( stream, " xmlns:xlink=\"http://www.w3.org/1999/xlink\""); - msIO_fprintf( stream, " xmlns=\"http://www.opengis.net/context\""); - msIO_fprintf( stream, " xmlns:sld=\"http://www.opengis.net/sld\""); + if (nVersion >= OWS_1_0_0) { + msIO_fprintf(stream, " xmlns:xlink=\"http://www.w3.org/1999/xlink\""); + msIO_fprintf(stream, " xmlns=\"http://www.opengis.net/context\""); + msIO_fprintf(stream, " xmlns:sld=\"http://www.opengis.net/sld\""); pszEncodedVal = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); - if( nVersion >= OWS_1_1_0 ) - msIO_fprintf( stream, - " xsi:schemaLocation=\"http://www.opengis.net/context %s/context/1.1.0/context.xsd\">\n", - pszEncodedVal); + if (nVersion >= OWS_1_1_0) + msIO_fprintf(stream, + " xsi:schemaLocation=\"http://www.opengis.net/context " + "%s/context/1.1.0/context.xsd\">\n", + pszEncodedVal); else - msIO_fprintf( stream, - " xsi:schemaLocation=\"http://www.opengis.net/context %s/context/1.0.0/context.xsd\">\n", - pszEncodedVal); + msIO_fprintf(stream, + " xsi:schemaLocation=\"http://www.opengis.net/context " + "%s/context/1.0.0/context.xsd\">\n", + pszEncodedVal); msFree(pszEncodedVal); } else { - msIO_fprintf( stream, " xmlns:xlink=\"http://www.w3.org/TR/xlink\""); + msIO_fprintf(stream, " xmlns:xlink=\"http://www.w3.org/TR/xlink\""); pszEncodedVal = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); - msIO_fprintf( stream, " xsi:noNamespaceSchemaLocation=\"%s/contexts/", - pszEncodedVal ); + msIO_fprintf(stream, " xsi:noNamespaceSchemaLocation=\"%s/contexts/", + pszEncodedVal); msFree(pszEncodedVal); pszEncodedVal = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); - msIO_fprintf( stream, "%s/context.xsd\">\n", pszEncodedVal); + msIO_fprintf(stream, "%s/context.xsd\">\n", pszEncodedVal); msFree(pszEncodedVal); } /* set the General information */ - msIO_fprintf( stream, " \n" ); + msIO_fprintf(stream, " \n"); /* Window */ - if( map->width != -1 || map->height != -1 ) - msIO_fprintf( stream, " \n", - map->width, map->height ); + if (map->width != -1 || map->height != -1) + msIO_fprintf(stream, " \n", + map->width, map->height); /* Bounding box corners and spatial reference system */ - if(tabspace) + if (tabspace) free(tabspace); tabspace = msStrdup(" "); - msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "MO", MS_TRUE, &pszEPSG); - msIO_fprintf( stream, - "%s\n", - tabspace ); - if(!pszEPSG || (strcasecmp(pszEPSG, "(null)") == 0)) - msIO_fprintf(stream, "\n"); + msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "MO", MS_TRUE, + &pszEPSG); + msIO_fprintf(stream, + "%s\n", + tabspace); + if (!pszEPSG || (strcasecmp(pszEPSG, "(null)") == 0)) + msIO_fprintf(stream, "\n"); pszEncodedVal = msEncodeHTMLEntities(pszEPSG); - msIO_fprintf( stream, "%s\n", - tabspace, pszEncodedVal, map->extent.minx, map->extent.miny, - map->extent.maxx, map->extent.maxy ); + msIO_fprintf(stream, + "%s\n", + tabspace, pszEncodedVal, map->extent.minx, map->extent.miny, + map->extent.maxx, map->extent.maxy); msFree(pszEncodedVal); msFree(pszEPSG); /* Title, name */ - if( nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0 ) { + if (nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { msOWSPrintEncodeParam(stream, "MAP.NAME", map->name, OWS_NOERR, " %s\n", NULL); } else { @@ -1459,90 +1402,91 @@ int msWriteMapContext(mapObj *map, FILE *stream) msOWSPrintEncodeParam(stream, "MAP.NAME", map->name, OWS_NOERR, " %s\n", NULL); - msIO_fprintf( stream, "%s\n", tabspace ); - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), - NULL, "wms_title", OWS_WARN, - " %s\n", map->name); + msIO_fprintf(stream, "%s\n", tabspace); + msOWSPrintEncodeMetadata(stream, &(map->web.metadata), NULL, "wms_title", + OWS_WARN, " %s\n", map->name); } /* keyword */ if (nVersion >= OWS_1_0_0) { - if (msLookupHashTable(&(map->web.metadata),"wms_keywordlist")!=NULL) { + if (msLookupHashTable(&(map->web.metadata), "wms_keywordlist") != NULL) { char **papszKeywords; int nKeywords, iKey; - const char* pszValue = msLookupHashTable(&(map->web.metadata), - "wms_keywordlist"); + const char *pszValue = + msLookupHashTable(&(map->web.metadata), "wms_keywordlist"); papszKeywords = msStringSplit(pszValue, ',', &nKeywords); - if(nKeywords > 0 && papszKeywords) { - msIO_fprintf( stream, " \n"); - for(iKey=0; iKey 0 && papszKeywords) { + msIO_fprintf(stream, " \n"); + for (iKey = 0; iKey < nKeywords; iKey++) { pszEncodedVal = msEncodeHTMLEntities(papszKeywords[iKey]); - msIO_fprintf( stream, " %s\n", - pszEncodedVal); + msIO_fprintf(stream, " %s\n", pszEncodedVal); msFree(pszEncodedVal); } - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, " \n"); } } } else msOWSPrintEncodeMetadataList(stream, &(map->web.metadata), NULL, - "wms_keywordlist", - " \n", " \n", - " %s\n", NULL); + "wms_keywordlist", " \n", + " \n", " %s\n", NULL); /* abstract */ - if( nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0 ) { - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), - NULL, "wms_abstract", OWS_NOERR, - " %s\n", NULL); + if (nVersion >= OWS_0_1_7 && nVersion < OWS_1_0_0) { + msOWSPrintEncodeMetadata( + stream, &(map->web.metadata), NULL, "wms_abstract", OWS_NOERR, + " %s\n", NULL); } else { - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), - NULL, "wms_abstract", OWS_NOERR, - " %s\n", NULL); + msOWSPrintEncodeMetadata(stream, &(map->web.metadata), NULL, "wms_abstract", + OWS_NOERR, " %s\n", NULL); } /* LogoURL */ /* The LogoURL have a width, height, format and an URL */ - msOWSPrintURLType(stream, &(map->web.metadata), "MO", "logourl", - OWS_NOERR, NULL, "LogoURL", NULL, " width=\"%s\"", - " height=\"%s\""," format=\"%s\"", - " \n", - MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, - NULL, NULL, NULL, NULL, NULL, " "); + msOWSPrintURLType( + stream, &(map->web.metadata), "MO", "logourl", OWS_NOERR, NULL, "LogoURL", + NULL, " width=\"%s\"", " height=\"%s\"", " format=\"%s\"", + " \n", + MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, NULL, NULL, NULL, NULL, + NULL, " "); /* DataURL */ - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), - NULL, "wms_dataurl", OWS_NOERR, - " \n \n \n", NULL); + msOWSPrintEncodeMetadata( + stream, &(map->web.metadata), NULL, "wms_dataurl", OWS_NOERR, + " \n \n \n", + NULL); /* DescriptionURL */ /* The DescriptionURL have a width, height, format and an URL */ /* The metadata is structured like this: "width height format url" */ - msOWSPrintURLType(stream, &(map->web.metadata), "MO", "descriptionurl", - OWS_NOERR, NULL, "DescriptionURL", NULL, " width=\"%s\"", - " height=\"%s\""," format=\"%s\"", - " \n", - MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, - NULL, NULL, NULL, NULL, NULL, " "); + msOWSPrintURLType( + stream, &(map->web.metadata), "MO", "descriptionurl", OWS_NOERR, NULL, + "DescriptionURL", NULL, " width=\"%s\"", " height=\"%s\"", + " format=\"%s\"", + " \n", + MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, NULL, NULL, NULL, NULL, + NULL, " "); /* Contact Info */ - msOWSPrintContactInfo( stream, tabspace, OWS_1_1_0, &(map->web.metadata), "MO" ); + msOWSPrintContactInfo(stream, tabspace, OWS_1_1_0, &(map->web.metadata), + "MO"); /* Close General */ - msIO_fprintf( stream, " \n" ); + msIO_fprintf(stream, " \n"); free(tabspace); /* Set the layer list */ msIO_fprintf(stream, " \n"); /* Loop on all layer */ - for(i=0; inumlayers; i++) { - if(GET_LAYER(map, i)->status != MS_DELETE && GET_LAYER(map, i)->connectiontype == MS_WMS) { - const char* pszValue; - char* pszValueMod; - const char* pszCurrent; - if(GET_LAYER(map, i)->status == MS_OFF) + for (i = 0; i < map->numlayers; i++) { + if (GET_LAYER(map, i)->status != MS_DELETE && + GET_LAYER(map, i)->connectiontype == MS_WMS) { + const char *pszValue; + char *pszValueMod; + const char *pszCurrent; + if (GET_LAYER(map, i)->status == MS_OFF) nValue = 1; else nValue = 0; @@ -1552,72 +1496,69 @@ int msWriteMapContext(mapObj *map, FILE *stream) /* */ /* Server definition */ /* */ - if(nVersion < OWS_1_0_0 ) - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_server_version", OWS_WARN, - " metadata), NULL, "wms_server_version", + OWS_WARN, " metadata), - NULL, "wms_server_version", OWS_WARN, - " metadata), "MO", "server_title")) - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_server_title", OWS_NOERR, + msOWSPrintEncodeMetadata( + stream, &(GET_LAYER(map, i)->metadata), NULL, "wms_server_version", + OWS_WARN, " metadata), "MO", + "server_title")) + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_server_title", OWS_NOERR, "title=\"%s\">\n", ""); - else if(GET_LAYER(map, i)->name) - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_title", OWS_NOERR, - "title=\"%s\">\n", GET_LAYER(map, i)->name); + else if (GET_LAYER(map, i)->name) + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_title", OWS_NOERR, "title=\"%s\">\n", + GET_LAYER(map, i)->name); else { - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_title", OWS_NOERR, - "title=\"%s\">\n", ""); + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_title", OWS_NOERR, "title=\"%s\">\n", ""); } /* Get base url of the online resource to be the default value */ - if(GET_LAYER(map, i)->connection) - pszValueMod = msStrdup( GET_LAYER(map, i)->connection ); + if (GET_LAYER(map, i)->connection) + pszValueMod = msStrdup(GET_LAYER(map, i)->connection); else - pszValueMod = msStrdup( "" ); + pszValueMod = msStrdup(""); pszChar = strchr(pszValueMod, '?'); - if( pszChar ) + if (pszChar) pszValueMod[pszChar - pszValueMod] = '\0'; - if(msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_onlineresource", OWS_WARN, - " \n", - pszValueMod) == OWS_WARN) + if (msOWSPrintEncodeMetadata( + stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_onlineresource", OWS_WARN, + " \n", + pszValueMod) == OWS_WARN) msIO_fprintf(stream, "\n"); + " , but probably not what you want -->\n"); msIO_fprintf(stream, " \n"); - if(pszValueMod) + if (pszValueMod) free(pszValueMod); /* */ /* Layer information */ /* */ - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_name", OWS_WARN, - " %s\n", - GET_LAYER(map, i)->name); - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_title", OWS_WARN, - " %s\n", + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_name", OWS_WARN, " %s\n", GET_LAYER(map, i)->name); - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_abstract", OWS_NOERR, - " %s\n", - NULL); + msOWSPrintEncodeMetadata( + stream, &(GET_LAYER(map, i)->metadata), NULL, "wms_title", OWS_WARN, + " %s\n", GET_LAYER(map, i)->name); + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_abstract", OWS_NOERR, + " %s\n", NULL); /* DataURL */ - if(nVersion <= OWS_0_1_4) { - msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), - NULL, "wms_dataurl", OWS_NOERR, - " %s\n", - NULL); + if (nVersion <= OWS_0_1_4) { + msOWSPrintEncodeMetadata(stream, &(GET_LAYER(map, i)->metadata), NULL, + "wms_dataurl", OWS_NOERR, + " %s\n", NULL); } else { /* The DataURL have a width, height, format and an URL */ /* The metadata will be structured like this: */ @@ -1627,12 +1568,11 @@ int msWriteMapContext(mapObj *map, FILE *stream) /* for consistency with the URLType. */ msOWSPrintURLType(stream, &(GET_LAYER(map, i)->metadata), "MO", "dataurl", OWS_NOERR, NULL, "DataURL", NULL, - " width=\"%s\"", " height=\"%s\"", - " format=\"%s\"", + " width=\"%s\"", " height=\"%s\"", " format=\"%s\"", " \n", - MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, - MS_TRUE, NULL, NULL, NULL,NULL,NULL, " "); + MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, NULL, + NULL, NULL, NULL, NULL, " "); } /* MetadataURL */ @@ -1640,28 +1580,30 @@ int msWriteMapContext(mapObj *map, FILE *stream) /* The metadata will be structured like this: */ /* "width height format url" */ msOWSPrintURLType(stream, &(GET_LAYER(map, i)->metadata), "MO", - "metadataurl", OWS_NOERR, NULL, "MetadataURL",NULL, - " width=\"%s\"", " height=\"%s\""," format=\"%s\"", + "metadataurl", OWS_NOERR, NULL, "MetadataURL", NULL, + " width=\"%s\"", " height=\"%s\"", " format=\"%s\"", " \n", - MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, - MS_TRUE, NULL, NULL, NULL, NULL, NULL, " "); + MS_FALSE, MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, NULL, + NULL, NULL, NULL, NULL, " "); /* MinScale && MaxScale */ - if(nVersion >= OWS_1_1_0 && GET_LAYER(map, i)->minscaledenom > 0) - msIO_fprintf(stream, - " %g\n", - GET_LAYER(map, i)->minscaledenom); - if(nVersion >= OWS_1_1_0 && GET_LAYER(map, i)->maxscaledenom > 0) - msIO_fprintf(stream, - " %g\n", - GET_LAYER(map, i)->maxscaledenom); + if (nVersion >= OWS_1_1_0 && GET_LAYER(map, i)->minscaledenom > 0) + msIO_fprintf( + stream, + " %g\n", + GET_LAYER(map, i)->minscaledenom); + if (nVersion >= OWS_1_1_0 && GET_LAYER(map, i)->maxscaledenom > 0) + msIO_fprintf( + stream, + " %g\n", + GET_LAYER(map, i)->maxscaledenom); /* Layer SRS */ msOWSGetEPSGProj(&(GET_LAYER(map, i)->projection), - &(GET_LAYER(map, i)->metadata), - "MO", MS_FALSE, &pszEPSG); - if(pszEPSG && (strcasecmp(pszEPSG, "(null)") != 0)) { + &(GET_LAYER(map, i)->metadata), "MO", MS_FALSE, + &pszEPSG); + if (pszEPSG && (strcasecmp(pszEPSG, "(null)") != 0)) { pszEncodedVal = msEncodeHTMLEntities(pszEPSG); msIO_fprintf(stream, " %s\n", pszEncodedVal); msFree(pszEncodedVal); @@ -1669,25 +1611,27 @@ int msWriteMapContext(mapObj *map, FILE *stream) msFree(pszEPSG); /* Format */ - if(msLookupHashTable(&(GET_LAYER(map, i)->metadata),"wms_formatlist")==NULL && - msLookupHashTable(&(GET_LAYER(map, i)->metadata),"wms_format")==NULL) { - char* pszURL; - if(GET_LAYER(map, i)->connection) - pszURL = msStrdup( GET_LAYER(map, i)->connection ); + if (msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_formatlist") == + NULL && + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_format") == + NULL) { + char *pszURL; + if (GET_LAYER(map, i)->connection) + pszURL = msStrdup(GET_LAYER(map, i)->connection); else - pszURL = msStrdup( "" ); + pszURL = msStrdup(""); - pszValueMod = strstr( pszURL, "FORMAT=" ); - if( pszValueMod ) { + pszValueMod = strstr(pszURL, "FORMAT="); + if (pszValueMod) { pszValueMod += 7; pszChar = strchr(pszValueMod, '&'); - if( pszChar ) + if (pszChar) pszValueMod[pszChar - pszValueMod] = '\0'; - if(strcasecmp(pszValueMod, "") != 0) { + if (strcasecmp(pszValueMod, "") != 0) { pszEncodedVal = msEncodeHTMLEntities(pszValueMod); - msIO_fprintf( stream, " \n"); - msIO_fprintf(stream," %s\n",pszValueMod); - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, " \n"); + msIO_fprintf(stream, " %s\n", pszValueMod); + msIO_fprintf(stream, " \n"); msFree(pszEncodedVal); } } @@ -1696,62 +1640,62 @@ int msWriteMapContext(mapObj *map, FILE *stream) char **papszFormats; int numFormats, nForm; - pszValue = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_formatlist"); - if(!pszValue) - pszValue = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_format"); - pszCurrent = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_format"); + pszValue = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_formatlist"); + if (!pszValue) + pszValue = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_format"); + pszCurrent = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_format"); papszFormats = msStringSplit(pszValue, ',', &numFormats); - if(numFormats > 0 && papszFormats) { - msIO_fprintf( stream, " \n"); - for(nForm=0; nForm%s\n", - pszEncodedVal); + if (numFormats > 0 && papszFormats) { + msIO_fprintf(stream, " \n"); + for (nForm = 0; nForm < numFormats; nForm++) { + pszEncodedVal = msEncodeHTMLEntities(papszFormats[nForm]); + if (pszCurrent && + (strcasecmp(papszFormats[nForm], pszCurrent) == 0)) + msIO_fprintf(stream, + " %s\n", + pszEncodedVal); else - msIO_fprintf( stream, " %s\n", - pszEncodedVal); + msIO_fprintf(stream, " %s\n", + pszEncodedVal); msFree(pszEncodedVal); } - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, " \n"); } - if(papszFormats) + if (papszFormats) msFreeCharArray(papszFormats, numFormats); } /* Style */ /* First check the stylelist */ - pszValue = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_stylelist"); - while( pszValue && *pszValue == ' ' ) - pszValue ++; - if(pszValue == NULL || strlen(pszValue) < 1) { + pszValue = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_stylelist"); + while (pszValue && *pszValue == ' ') + pszValue++; + if (pszValue == NULL || strlen(pszValue) < 1) { /* Check if the style is in the connection URL */ - char* pszURL; - if(GET_LAYER(map, i)->connection) - pszURL = msStrdup( GET_LAYER(map, i)->connection ); + char *pszURL; + if (GET_LAYER(map, i)->connection) + pszURL = msStrdup(GET_LAYER(map, i)->connection); else - pszURL = msStrdup( "" ); + pszURL = msStrdup(""); /* Grab the STYLES in the URL */ - pszValueMod = strstr( pszURL, "STYLES=" ); - if( pszValueMod ) { + pszValueMod = strstr(pszURL, "STYLES="); + if (pszValueMod) { pszValueMod += 7; pszChar = strchr(pszValueMod, '&'); - if( pszChar ) + if (pszChar) pszValueMod[pszChar - pszValueMod] = '\0'; /* Check the SLD string from the URL */ - if(GET_LAYER(map, i)->connection) + if (GET_LAYER(map, i)->connection) pszSLD2 = msStrdup(GET_LAYER(map, i)->connection); else - pszSLD2 = msStrdup( "" ); - if(pszSLD2) { + pszSLD2 = msStrdup(""); + if (pszSLD2) { pszSLD = strstr(pszSLD2, "SLD="); pszSLDBody = strstr(pszSLD2, "SLD_BODY="); } else { @@ -1759,106 +1703,104 @@ int msWriteMapContext(mapObj *map, FILE *stream) pszSLDBody = NULL; } /* Check SLD */ - if( pszSLD ) { + if (pszSLD) { pszChar = strchr(pszSLD, '&'); - if( pszChar ) + if (pszChar) pszSLD[pszChar - pszSLD] = '\0'; pszSLD += 4; } /* Check SLDBody */ - if( pszSLDBody ) { + if (pszSLDBody) { pszChar = strchr(pszSLDBody, '&'); - if( pszChar ) + if (pszChar) pszSLDBody[pszChar - pszSLDBody] = '\0'; pszSLDBody += 9; } - if( (pszValueMod && (strcasecmp(pszValueMod, "") != 0)) || + if ((pszValueMod && (strcasecmp(pszValueMod, "") != 0)) || (pszSLD && (strcasecmp(pszSLD, "") != 0)) || (pszSLDBody && (strcasecmp(pszSLDBody, "") != 0))) { /* Write Name and Title */ - msIO_fprintf( stream, " \n"); - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, " \n"); } - if(pszSLD2) { + if (pszSLD2) { free(pszSLD2); pszSLD2 = NULL; } } free(pszURL); } else { - const char* pszCurrent; + const char *pszCurrent; /* If the style information is not in the connection URL, */ /* read the metadata. */ - pszValue = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_stylelist"); - pszCurrent = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_style"); - msIO_fprintf( stream, " \n"); + pszValue = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_stylelist"); + pszCurrent = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_style"); + msIO_fprintf(stream, " \n"); /* Loop in each style in the style list */ - while(pszValue != NULL) { - char* pszStyle = msStrdup(pszValue); + while (pszValue != NULL) { + char *pszStyle = msStrdup(pszValue); pszChar = strchr(pszStyle, ','); - if(pszChar != NULL) + if (pszChar != NULL) pszStyle[pszChar - pszStyle] = '\0'; - if(pszStyle[0] == '\0') - { + if (pszStyle[0] == '\0') { msFree(pszStyle); continue; } - if(pszCurrent && (strcasecmp(pszStyle, pszCurrent) == 0)) - msIO_fprintf( stream," \n"); + msIO_fprintf(stream, " \n"); } /* Dimension element */; @@ -1914,75 +1851,72 @@ int msWriteMapContext(mapObj *map, FILE *stream) pszValue = msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_dimensionlist"); - pszCurrent = msLookupHashTable(&(GET_LAYER(map, i)->metadata), - "wms_dimension"); - while(pszValue != NULL) { + pszCurrent = + msLookupHashTable(&(GET_LAYER(map, i)->metadata), "wms_dimension"); + while (pszValue != NULL) { /* Extract the dimension name from the list */ pszDimension = msStrdup(pszValue); pszChar = strchr(pszDimension, ','); - if(pszChar != NULL) + if (pszChar != NULL) pszDimension[pszChar - pszDimension] = '\0'; - if(strcasecmp(pszDimension, "") == 0) { + if (strcasecmp(pszDimension, "") == 0) { free(pszDimension); pszValue = strchr(pszValue, ','); - if(pszValue) + if (pszValue) pszValue++; continue; } /* From the dimension list, extract the required dimension */ - msOWSGetDimensionInfo(GET_LAYER(map, i), pszDimension, - &pszDimUserValue, &pszDimUnits, - &pszDimDefault, &pszDimNearValue, + msOWSGetDimensionInfo(GET_LAYER(map, i), pszDimension, &pszDimUserValue, + &pszDimUnits, &pszDimDefault, &pszDimNearValue, &pszDimUnitSymbol, &pszDimMultiValue); - if(pszDimUserValue == NULL || pszDimUnits == NULL || + if (pszDimUserValue == NULL || pszDimUnits == NULL || pszDimUnitSymbol == NULL) { free(pszDimension); pszValue = strchr(pszValue, ','); - if(pszValue) + if (pszValue) pszValue++; continue; } - if(!bDimensionList) { + if (!bDimensionList) { bDimensionList = 1; - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, " \n"); } /* name */ - msIO_fprintf( stream, " \n"); + msIO_fprintf(stream, "/>\n"); free(pszDimension); pszValue = strchr(pszValue, ','); - if(pszValue) + if (pszValue) pszValue++; } - if(bDimensionList) { - msIO_fprintf( stream, " \n"); + if (bDimensionList) { + msIO_fprintf(stream, " \n"); bDimensionList = 0; } @@ -1994,9 +1928,9 @@ int msWriteMapContext(mapObj *map, FILE *stream) msIO_fprintf(stream, " \n"); /* Close Map Context */ - if(nVersion >= OWS_1_0_0) { + if (nVersion >= OWS_1_0_0) { msIO_fprintf(stream, "\n"); - } else if(nVersion >= OWS_0_1_7) { + } else if (nVersion >= OWS_0_1_7) { msIO_fprintf(stream, "\n"); } else { /* 0.1.4 */ msIO_fprintf(stream, "\n"); @@ -2010,5 +1944,3 @@ int msWriteMapContext(mapObj *map, FILE *stream) return MS_FAILURE; #endif } - - diff --git a/mapcontour.c b/mapcontour.c index dd6c752575..edccd3b4c1 100644 --- a/mapcontour.c +++ b/mapcontour.c @@ -42,7 +42,7 @@ #include "mapraster.h" #include "cpl_string.h" -#define GEO_TRANS(tr,x,y) ((tr)[0]+(tr)[1]*(x)+(tr)[2]*(y)) +#define GEO_TRANS(tr, x, y) ((tr)[0] + (tr)[1] * (x) + (tr)[2] * (y)) extern int InvGeoTransform(double *gt_in, double *gt_out); @@ -53,7 +53,7 @@ typedef struct { /* internal use */ GDALDatasetH hOrigDS; - GDALDatasetH hDS; + GDALDatasetH hDS; double *buffer; /* memory dataset buffer */ rectObj extent; /* original dataset extent */ OGRDataSourceH hOGRDS; @@ -61,10 +61,8 @@ typedef struct { } contourLayerInfo; - -static int msContourLayerInitItemInfo(layerObj *layer) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +static int msContourLayerInitItemInfo(layerObj *layer) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (clinfo == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", @@ -75,9 +73,8 @@ static int msContourLayerInitItemInfo(layerObj *layer) return msLayerInitItemInfo(&clinfo->ogrLayer); } -static void msContourLayerFreeItemInfo(layerObj *layer) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +static void msContourLayerFreeItemInfo(layerObj *layer) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (clinfo == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", @@ -88,28 +85,28 @@ static void msContourLayerFreeItemInfo(layerObj *layer) msLayerFreeItemInfo(&clinfo->ogrLayer); } -static void msContourLayerInfoInitialize(layerObj *layer) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +static void msContourLayerInfoInitialize(layerObj *layer) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (clinfo != NULL) return; - clinfo = (contourLayerInfo *) msSmallCalloc(1,sizeof(contourLayerInfo)); + clinfo = (contourLayerInfo *)msSmallCalloc(1, sizeof(contourLayerInfo)); layer->layerinfo = clinfo; - clinfo->hOrigDS = NULL; + clinfo->hOrigDS = NULL; clinfo->hDS = NULL; clinfo->extent.minx = -1.0; clinfo->extent.miny = -1.0; clinfo->extent.maxx = -1.0; clinfo->extent.maxy = -1.0; - + initLayer(&clinfo->ogrLayer, layer->map); clinfo->ogrLayer.type = layer->type; clinfo->ogrLayer.debug = layer->debug; clinfo->ogrLayer.connectiontype = MS_OGR; clinfo->ogrLayer.name = msStrdup(layer->name); - clinfo->ogrLayer.connection = (char*)msSmallMalloc(strlen(clinfo->ogrLayer.name)+13); + clinfo->ogrLayer.connection = + (char *)msSmallMalloc(strlen(clinfo->ogrLayer.name) + 13); sprintf(clinfo->ogrLayer.connection, "__%s_CONTOUR__", clinfo->ogrLayer.name); clinfo->ogrLayer.units = layer->units; @@ -117,21 +114,20 @@ static void msContourLayerInfoInitialize(layerObj *layer) msInsertHashTable(&(layer->metadata), "gml_ID_type", "Integer"); } { - const char* elevItem = CSLFetchNameValue(layer->processing,"CONTOUR_ITEM"); + const char *elevItem = CSLFetchNameValue(layer->processing, "CONTOUR_ITEM"); if (elevItem && strlen(elevItem) > 0) { - char szTmp[100]; - snprintf(szTmp, sizeof(szTmp), "%s_type", elevItem); - if (msOWSLookupMetadata(&(layer->metadata), "OFG", szTmp) == NULL) { - snprintf(szTmp, sizeof(szTmp), "gml_%s_type", elevItem); - msInsertHashTable(&(layer->metadata), szTmp, "Real"); - } + char szTmp[100]; + snprintf(szTmp, sizeof(szTmp), "%s_type", elevItem); + if (msOWSLookupMetadata(&(layer->metadata), "OFG", szTmp) == NULL) { + snprintf(szTmp, sizeof(szTmp), "gml_%s_type", elevItem); + msInsertHashTable(&(layer->metadata), szTmp, "Real"); + } } } } -static void msContourLayerInfoFree(layerObj *layer) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +static void msContourLayerInfoFree(layerObj *layer) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (clinfo == NULL) return; @@ -142,23 +138,22 @@ static void msContourLayerInfoFree(layerObj *layer) layer->layerinfo = NULL; } -static int msContourLayerReadRaster(layerObj *layer, rectObj rect) -{ - mapObj *map = layer->map; +static int msContourLayerReadRaster(layerObj *layer, rectObj rect) { + mapObj *map = layer->map; char **bands; char pointer[64], memDSPointer[128]; int band = 1; double adfGeoTransform[6], adfInvGeoTransform[6]; - double llx, lly, urx, ury; + double llx, lly, urx, ury; rectObj copyRect, mapRect; int dst_xsize, dst_ysize; int virtual_grid_step_x, virtual_grid_step_y; - int src_xoff, src_yoff, src_xsize, src_ysize; + int src_xoff, src_yoff, src_xsize, src_ysize; double map_cellsize_x, map_cellsize_y, dst_cellsize_x, dst_cellsize_y; GDALRasterBandH hBand = NULL; CPLErr eErr; - - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; + + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerReadRaster().\n"); @@ -166,18 +161,19 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) if (clinfo == NULL || clinfo->hOrigDS == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", "msContourLayerReadRaster()"); - return MS_FAILURE; + return MS_FAILURE; } bands = CSLTokenizeStringComplex( - CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE ); + CSLFetchNameValue(layer->processing, "BANDS"), " ,", FALSE, FALSE); if (CSLCount(bands) > 0) { band = atoi(bands[0]); if (band < 1 || band > GDALGetRasterCount(clinfo->hOrigDS)) { - msSetError( MS_IMGERR, - "BANDS PROCESSING directive includes illegal band '%d', should be from 1 to %d.", - "msContourLayerReadRaster()", - band, GDALGetRasterCount(clinfo->hOrigDS)); + msSetError(MS_IMGERR, + "BANDS PROCESSING directive includes illegal band '%d', " + "should be from 1 to %d.", + "msContourLayerReadRaster()", band, + GDALGetRasterCount(clinfo->hOrigDS)); CSLDestroy(bands); return MS_FAILURE; } @@ -185,10 +181,8 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) CSLDestroy(bands); hBand = GDALGetRasterBand(clinfo->hOrigDS, band); - if (hBand == NULL) - { - msSetError(MS_IMGERR, - "Band %d does not exist on dataset.", + if (hBand == NULL) { + msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerReadRaster()", band); return MS_FAILURE; } @@ -198,49 +192,48 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) const char *wkt; wkt = GDALGetProjectionRef(clinfo->hOrigDS); if (wkt != NULL && strlen(wkt) > 0) { - if (msOGCWKT2ProjectionObj(wkt, &(layer->projection), - layer->debug) != MS_SUCCESS) { - char msg[MESSAGELENGTH*2]; + if (msOGCWKT2ProjectionObj(wkt, &(layer->projection), layer->debug) != + MS_SUCCESS) { + char msg[MESSAGELENGTH * 2]; errorObj *ms_error = msGetErrorObj(); - snprintf( msg, sizeof(msg), - "%s\n" - "PROJECTION AUTO cannot be used for this " - "GDAL raster (`%s').", - ms_error->message, layer->data); - msg[MESSAGELENGTH-1] = '\0'; + snprintf(msg, sizeof(msg), + "%s\n" + "PROJECTION AUTO cannot be used for this " + "GDAL raster (`%s').", + ms_error->message, layer->data); + msg[MESSAGELENGTH - 1] = '\0'; - msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", - msg); + msSetError(MS_OGRERR, "%s", "msDrawRasterLayer()", msg); return MS_FAILURE; } } } - + /* * Compute the georeferenced window of overlap, and read the source data * downsampled to match output resolution, or at full resolution if * output resolution is lower than the source resolution. * - * A large portion of this overlap calculation code was borrowed from - * msDrawRasterLayerGDAL(). + * A large portion of this overlap calculation code was borrowed from + * msDrawRasterLayerGDAL(). * Would be possible to move some of this to a reusable function? * * Note: This code works only if no reprojection is involved. It would * need rework to support cases where output projection differs from source * data file projection. */ - + src_xsize = GDALGetRasterXSize(clinfo->hOrigDS); src_ysize = GDALGetRasterYSize(clinfo->hOrigDS); /* set the Dataset extent */ - msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform); + msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform); clinfo->extent.minx = adfGeoTransform[0]; clinfo->extent.maxy = adfGeoTransform[3]; clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1]; clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5]; - + if (layer->transform) { if (layer->debug) msDebug("msContourLayerReadRaster(): Entering transform.\n"); @@ -248,16 +241,17 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) InvGeoTransform(adfGeoTransform, adfInvGeoTransform); mapRect = rect; - if( map->cellsize == 0 ) - { - map->cellsize = msAdjustExtent(&mapRect,map->width,map->height); + if (map->cellsize == 0) { + map->cellsize = msAdjustExtent(&mapRect, map->width, map->height); } map_cellsize_x = map_cellsize_y = map->cellsize; /* if necessary, project the searchrect to source coords */ - if (msProjectionsDiffer( &(map->projection), &(layer->projection))) { - if ( msProjectRect(&map->projection, &layer->projection, &mapRect) - != MS_SUCCESS ) { - msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); + if (msProjectionsDiffer(&(map->projection), &(layer->projection))) { + if (msProjectRect(&map->projection, &layer->projection, &mapRect) != + MS_SUCCESS) { + msDebug("msContourLayerReadRaster(%s): unable to reproject map request " + "rectangle into layer projection, canceling.\n", + layer->name); return MS_FAILURE; } @@ -266,24 +260,26 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) /* if the projection failed to project the extent requested, we need to calculate the cellsize to preserve the initial map cellsize ratio */ - if ( (mapRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) || - (mapRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) || - (mapRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) || - (mapRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) ) { + if ((mapRect.minx < GEO_TRANS(adfGeoTransform, 0, src_ysize)) || + (mapRect.maxx > GEO_TRANS(adfGeoTransform, src_xsize, 0)) || + (mapRect.miny < GEO_TRANS(adfGeoTransform + 3, 0, src_ysize)) || + (mapRect.maxy > GEO_TRANS(adfGeoTransform + 3, src_xsize, 0))) { int src_unit, dst_unit; src_unit = GetMapserverUnitUsingProj(&map->projection); dst_unit = GetMapserverUnitUsingProj(&layer->projection); if (src_unit == -1 || dst_unit == -1) { - msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); + msDebug("msContourLayerReadRaster(%s): unable to reproject map " + "request rectangle into layer projection, canceling.\n", + layer->name); return MS_FAILURE; } - map_cellsize_x = MS_CONVERT_UNIT(src_unit, dst_unit, - MS_CELLSIZE(rect.minx, rect.maxx, map->width)); - map_cellsize_y = MS_CONVERT_UNIT(src_unit, dst_unit, - MS_CELLSIZE(rect.miny, rect.maxy, map->height)); - } + map_cellsize_x = MS_CONVERT_UNIT( + src_unit, dst_unit, MS_CELLSIZE(rect.minx, rect.maxx, map->width)); + map_cellsize_y = MS_CONVERT_UNIT( + src_unit, dst_unit, MS_CELLSIZE(rect.miny, rect.maxy, map->height)); + } } if (map_cellsize_x == 0 || map_cellsize_y == 0) { @@ -291,36 +287,39 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) msDebug("msContourLayerReadRaster(): Cellsize can't be 0.\n"); return MS_FAILURE; } - - /* Adjust MapServer pixel model to GDAL pixel model */ - mapRect.minx -= map_cellsize_x*0.5; - mapRect.maxx += map_cellsize_x*0.5; - mapRect.miny -= map_cellsize_y*0.5; - mapRect.maxy += map_cellsize_y*0.5; + /* Adjust MapServer pixel model to GDAL pixel model */ + mapRect.minx -= map_cellsize_x * 0.5; + mapRect.maxx += map_cellsize_x * 0.5; + mapRect.miny -= map_cellsize_y * 0.5; + mapRect.maxy += map_cellsize_y * 0.5; /* - * If raw data cellsize (from geotransform) is larger than output map_cellsize - * then we want to extract only enough data to match the output map resolution - * which means that GDAL will automatically sample the data on read. + * If raw data cellsize (from geotransform) is larger than output + * map_cellsize then we want to extract only enough data to match the output + * map resolution which means that GDAL will automatically sample the data + * on read. * - * To prevent bad contour effects on tile edges, we adjust the target cellsize - * to align the extracted window with a virtual grid based on the origin of the - * raw data and a virtual grid step size corresponding to an integer sampling step. + * To prevent bad contour effects on tile edges, we adjust the target + * cellsize to align the extracted window with a virtual grid based on the + * origin of the raw data and a virtual grid step size corresponding to an + * integer sampling step. * - * If source data has a greater cellsize (i.e. lower res) that requested ouptut map - * then we use the raw data cellsize as target cellsize since there is no point in - * interpolating the data for contours in this case. + * If source data has a greater cellsize (i.e. lower res) that requested + * ouptut map then we use the raw data cellsize as target cellsize since + * there is no point in interpolating the data for contours in this case. */ virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1])); if (virtual_grid_step_x < 1) - virtual_grid_step_x = 1; /* Do not interpolate data if grid sampling step < 1 */ + virtual_grid_step_x = + 1; /* Do not interpolate data if grid sampling step < 1 */ virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5])); if (virtual_grid_step_y < 1) - virtual_grid_step_y = 1; /* Do not interpolate data if grid sampling step < 1 */ - + virtual_grid_step_y = + 1; /* Do not interpolate data if grid sampling step < 1 */ + /* target cellsize is a multiple of raw data cellsize based on grid step*/ dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x; dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y; @@ -329,15 +328,15 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) copyRect = mapRect; - if (copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) - copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize); - if (copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) - copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0); - if (copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) - copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize); - if (copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) - copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0); - + if (copyRect.minx < GEO_TRANS(adfGeoTransform, 0, src_ysize)) + copyRect.minx = GEO_TRANS(adfGeoTransform, 0, src_ysize); + if (copyRect.maxx > GEO_TRANS(adfGeoTransform, src_xsize, 0)) + copyRect.maxx = GEO_TRANS(adfGeoTransform, src_xsize, 0); + if (copyRect.miny < GEO_TRANS(adfGeoTransform + 3, 0, src_ysize)) + copyRect.miny = GEO_TRANS(adfGeoTransform + 3, 0, src_ysize); + if (copyRect.maxy > GEO_TRANS(adfGeoTransform + 3, src_xsize, 0)) + copyRect.maxy = GEO_TRANS(adfGeoTransform + 3, src_xsize, 0); + if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) { if (layer->debug) msDebug("msContourLayerReadRaster(): No overlap.\n"); @@ -347,42 +346,46 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) /* * Convert extraction window to raster coordinates */ - llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny); - lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny); - urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy); - ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy); + llx = GEO_TRANS(adfInvGeoTransform + 0, copyRect.minx, copyRect.miny); + lly = GEO_TRANS(adfInvGeoTransform + 3, copyRect.minx, copyRect.miny); + urx = GEO_TRANS(adfInvGeoTransform + 0, copyRect.maxx, copyRect.maxy); + ury = GEO_TRANS(adfInvGeoTransform + 3, copyRect.maxx, copyRect.maxy); - /* - * Align extraction window with virtual grid + /* + * Align extraction window with virtual grid * (keep in mind raster coordinates origin is at upper-left) * We also add an extra buffer to fix tile boundarie issues when zoomed */ - llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - (virtual_grid_step_x*5); - urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + (virtual_grid_step_x*5); - ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - (virtual_grid_step_x*5); - lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + (virtual_grid_step_x*5); - - src_xoff = MS_MAX(0,(int) floor(llx+0.5)); - src_yoff = MS_MAX(0,(int) floor(ury+0.5)); - src_xsize = MS_MIN(MS_MAX(0,(int) (urx - llx + 0.5)), - GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff); - src_ysize = MS_MIN(MS_MAX(0,(int) (lly - ury + 0.5)), - GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff); + llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - + (virtual_grid_step_x * 5); + urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + + (virtual_grid_step_x * 5); + ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - + (virtual_grid_step_x * 5); + lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + + (virtual_grid_step_x * 5); + + src_xoff = MS_MAX(0, (int)floor(llx + 0.5)); + src_yoff = MS_MAX(0, (int)floor(ury + 0.5)); + src_xsize = MS_MIN(MS_MAX(0, (int)(urx - llx + 0.5)), + GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff); + src_ysize = MS_MIN(MS_MAX(0, (int)(lly - ury + 0.5)), + GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff); /* Update the geographic extent (buffer added) */ /* TODO: a better way to go the geo_trans */ - copyRect.minx = GEO_TRANS(adfGeoTransform+0,src_xoff,0); - copyRect.maxx = GEO_TRANS(adfGeoTransform+0,src_xoff+src_xsize,0); - copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_yoff+src_ysize); - copyRect.maxy = GEO_TRANS(adfGeoTransform+3,0,src_yoff); - - /* + copyRect.minx = GEO_TRANS(adfGeoTransform + 0, src_xoff, 0); + copyRect.maxx = GEO_TRANS(adfGeoTransform + 0, src_xoff + src_xsize, 0); + copyRect.miny = GEO_TRANS(adfGeoTransform + 3, 0, src_yoff + src_ysize); + copyRect.maxy = GEO_TRANS(adfGeoTransform + 3, 0, src_yoff); + + /* * If input window is to small then stop here */ - if (src_xsize < 2 || src_ysize < 2) - { + if (src_xsize < 2 || src_ysize < 2) { if (layer->debug) - msDebug("msContourLayerReadRaster(): input window too small, or no apparent overlap between map view and this window(1).\n"); + msDebug("msContourLayerReadRaster(): input window too small, or no " + "apparent overlap between map view and this window(1).\n"); return MS_SUCCESS; } @@ -392,19 +395,20 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) if (dst_xsize == 0 || dst_ysize == 0) { if (layer->debug) - msDebug("msContourLayerReadRaster(): no apparent overlap between map view and this window(2).\n"); + msDebug("msContourLayerReadRaster(): no apparent overlap between map " + "view and this window(2).\n"); return MS_SUCCESS; } if (layer->debug) - msDebug( "msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", - src_xoff, src_yoff, src_xsize, src_ysize, - 0, 0, dst_xsize, dst_ysize ); + msDebug("msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", + src_xoff, src_yoff, src_xsize, src_ysize, 0, 0, dst_xsize, + dst_ysize); } else { src_xoff = 0; src_yoff = 0; - dst_xsize = src_xsize = MS_MIN(map->width,src_xsize); - dst_ysize = src_ysize = MS_MIN(map->height,src_ysize); + dst_xsize = src_xsize = MS_MIN(map->width, src_xsize); + dst_ysize = src_ysize = MS_MIN(map->height, src_ysize); copyRect.minx = 0; copyRect.miny = 0; (void)copyRect.miny; @@ -418,46 +422,44 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) /* Allocate buffer, and read data into it. */ /* -------------------------------------------------------------------- */ - clinfo->buffer = (double *) malloc(sizeof(double) * dst_xsize * dst_ysize); + clinfo->buffer = (double *)malloc(sizeof(double) * dst_xsize * dst_ysize); if (clinfo->buffer == NULL) { - msSetError(MS_MEMERR, "Malloc(): Out of memory.", "msContourLayerReadRaster()"); + msSetError(MS_MEMERR, "Malloc(): Out of memory.", + "msContourLayerReadRaster()"); return MS_FAILURE; } - eErr = GDALRasterIO(hBand, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64, - 0, 0); + eErr = GDALRasterIO(hBand, GF_Read, src_xoff, src_yoff, src_xsize, src_ysize, + clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64, 0, 0); if (eErr != CE_None) { - msSetError( MS_IOERR, "GDALRasterIO() failed: %s", - "msContourLayerReadRaster()", CPLGetLastErrorMsg() ); + msSetError(MS_IOERR, "GDALRasterIO() failed: %s", + "msContourLayerReadRaster()", CPLGetLastErrorMsg()); free(clinfo->buffer); return MS_FAILURE; } memset(pointer, 0, sizeof(pointer)); CPLPrintPointer(pointer, clinfo->buffer, sizeof(pointer)); - sprintf(memDSPointer,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64", + sprintf(memDSPointer, + "MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64", pointer, dst_xsize, dst_ysize); - clinfo->hDS = GDALOpen(memDSPointer, GA_ReadOnly); + clinfo->hDS = GDALOpen(memDSPointer, GA_ReadOnly); if (clinfo->hDS == NULL) { - msSetError(MS_IMGERR, - "Unable to open GDAL Memory dataset.", + msSetError(MS_IMGERR, "Unable to open GDAL Memory dataset.", "msContourLayerReadRaster()"); free(clinfo->buffer); return MS_FAILURE; } { - // Copy nodata value from source dataset to memory dataset - int bHasNoData = FALSE; - double dfNoDataValue = GDALGetRasterNoDataValue(hBand, &bHasNoData); - if( bHasNoData ) - { - GDALSetRasterNoDataValue(GDALGetRasterBand(clinfo->hDS, 1), - dfNoDataValue); - } + // Copy nodata value from source dataset to memory dataset + int bHasNoData = FALSE; + double dfNoDataValue = GDALGetRasterNoDataValue(hBand, &bHasNoData); + if (bHasNoData) { + GDALSetRasterNoDataValue(GDALGetRasterBand(clinfo->hDS, 1), + dfNoDataValue); + } } adfGeoTransform[0] = copyRect.minx; @@ -473,14 +475,13 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) sprintf(buf, "%lf", clinfo->cellsize); msInsertHashTable(&layer->metadata, "__data_cellsize__", buf); } - + GDALSetGeoTransform(clinfo->hDS, adfGeoTransform); return MS_SUCCESS; } -static void msContourOGRCloseConnection(void *conn_handle) -{ - OGRDataSourceH hDS = (OGRDataSourceH) conn_handle; +static void msContourOGRCloseConnection(void *conn_handle) { + OGRDataSourceH hDS = (OGRDataSourceH)conn_handle; msAcquireLock(TLOCK_OGR); OGR_DS_Destroy(hDS); @@ -489,19 +490,18 @@ static void msContourOGRCloseConnection(void *conn_handle) /* Function that parses multiple options in the a list. It also supports min/maxscaledenom checks. ie. "CONTOUR_INTERVAL=0,3842942:10" */ -static char* msContourGetOption(layerObj *layer, const char *name) -{ +static char *msContourGetOption(layerObj *layer, const char *name) { int c, i, found = MS_FALSE; char **values, **tmp, **options; double maxscaledenom, minscaledenom; char *value = NULL; - + options = CSLFetchNameValueMultiple(layer->processing, name); c = CSLCount(options); /* First pass to find the value among options that have min/maxscaledenom */ /* specified */ - for (i=0; imap->scaledenom <= 0 || - (((maxscaledenom <= 0) || (layer->map->scaledenom <= maxscaledenom)) && - ((minscaledenom <= 0) || (layer->map->scaledenom > minscaledenom)))) { + (((maxscaledenom <= 0) || + (layer->map->scaledenom <= maxscaledenom)) && + ((minscaledenom <= 0) || + (layer->map->scaledenom > minscaledenom)))) { value = msStrdup(values[1]); found = MS_TRUE; } @@ -519,10 +521,10 @@ static char* msContourGetOption(layerObj *layer, const char *name) } CSLDestroy(values); } - + /* Second pass to find the value among options that do NOT have */ /* min/maxscaledenom specified */ - for (i=0; ilayerinfo; + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; OGRRegisterAll(); @@ -563,12 +564,10 @@ static int msContourLayerGenerateContour(layerObj *layer) if (!clinfo->hDS) { /* no overlap */ return MS_SUCCESS; } - + hBand = GDALGetRasterBand(clinfo->hDS, 1); - if (hBand == NULL) - { - msSetError(MS_IMGERR, - "Band %d does not exist on dataset.", + if (hBand == NULL) { + msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerGenerateContour()", 1); return MS_FAILURE; } @@ -576,22 +575,20 @@ static int msContourLayerGenerateContour(layerObj *layer) /* Create the OGR DataSource */ hDriver = OGRGetDriverByName("Memory"); if (hDriver == NULL) { - msSetError(MS_OGRERR, - "Unable to get OGR driver 'Memory'.", + msSetError(MS_OGRERR, "Unable to get OGR driver 'Memory'.", "msContourLayerCreateOGRDataSource()"); return MS_FAILURE; } clinfo->hOGRDS = OGR_Dr_CreateDataSource(hDriver, "", NULL); if (clinfo->hOGRDS == NULL) { - msSetError(MS_OGRERR, - "Unable to create OGR DataSource.", + msSetError(MS_OGRERR, "Unable to create OGR DataSource.", "msContourLayerCreateOGRDataSource()"); return MS_FAILURE; } hLayer = OGR_DS_CreateLayer(clinfo->hOGRDS, clinfo->ogrLayer.name, NULL, - wkbLineString, NULL ); + wkbLineString, NULL); hFld = OGR_Fld_Create("ID", OFTInteger); OGR_Fld_SetWidth(hFld, 8); @@ -599,15 +596,14 @@ static int msContourLayerGenerateContour(layerObj *layer) OGR_Fld_Destroy(hFld); /* Check if we have a coutour item specified */ - elevItem = CSLFetchNameValue(layer->processing,"CONTOUR_ITEM"); + elevItem = CSLFetchNameValue(layer->processing, "CONTOUR_ITEM"); if (elevItem && strlen(elevItem) > 0) { hFld = OGR_Fld_Create(elevItem, OFTReal); OGR_Fld_SetWidth(hFld, 12); OGR_Fld_SetPrecision(hFld, 3); OGR_L_CreateField(hLayer, hFld, FALSE); OGR_Fld_Destroy(hFld); - } - else { + } else { elevItem = NULL; } @@ -619,11 +615,11 @@ static int msContourLayerGenerateContour(layerObj *layer) option = msContourGetOption(layer, "CONTOUR_LEVELS"); if (option) { - int i,c; + int i, c; char **levelsTmp; levelsTmp = CSLTokenizeStringComplex(option, ",", FALSE, FALSE); c = CSLCount(levelsTmp); - for (i=0;iogrLayer, clinfo->hOGRDS, msContourOGRCloseConnection); - return MS_SUCCESS; + msConnPoolRegister(&clinfo->ogrLayer, clinfo->hOGRDS, + msContourOGRCloseConnection); + return MS_SUCCESS; } -int msContourLayerOpen(layerObj *layer) -{ +int msContourLayerOpen(layerObj *layer) { char *decrypted_path; char szPath[MS_MAXPATHLEN]; contourLayerInfo *clinfo; @@ -667,69 +660,59 @@ int msContourLayerOpen(layerObj *layer) if (layer->layerinfo == NULL) msContourLayerInfoInitialize(layer); - clinfo = (contourLayerInfo *) layer->layerinfo; - if (layer->data == NULL && layer->tileindex == NULL ) { - msSetError(MS_MISCERR, - "Layer %s has neither DATA nor TILEINDEX defined.", - "msContourLayerOpen()", - layer->name); + clinfo = (contourLayerInfo *)layer->layerinfo; + if (layer->data == NULL && layer->tileindex == NULL) { + msSetError(MS_MISCERR, "Layer %s has neither DATA nor TILEINDEX defined.", + "msContourLayerOpen()", layer->name); return MS_FAILURE; } - if( layer->tileindex != NULL ) - { - char szTilename[MS_MAXPATHLEN]; - int status; - int tilelayerindex, tileitemindex, tilesrsindex; - rectObj searchrect; - layerObj* tlp; - shapeObj tshp; - char tilesrsname[1]; - - msInitShape(&tshp); - searchrect = layer->map->extent; - - status = msDrawRasterSetupTileLayer(layer->map, layer, - &searchrect, MS_FALSE, - &tilelayerindex, - &tileitemindex, - &tilesrsindex, - &tlp); - if( status == MS_FAILURE ) - { - return MS_FAILURE; - } + if (layer->tileindex != NULL) { + char szTilename[MS_MAXPATHLEN]; + int status; + int tilelayerindex, tileitemindex, tilesrsindex; + rectObj searchrect; + layerObj *tlp; + shapeObj tshp; + char tilesrsname[1]; - status = msDrawRasterIterateTileIndex(layer, tlp, &tshp, - tileitemindex, -1, - szTilename, sizeof(szTilename), - tilesrsname, sizeof(tilesrsname)); - if( status == MS_FAILURE || status == MS_DONE ) { - if( status == MS_DONE ) - { - if (layer->debug) - msDebug("No raster matching filter.\n"); - } - msDrawRasterCleanupTileLayer(tlp, tilelayerindex); - return MS_FAILURE; - } + msInitShape(&tshp); + searchrect = layer->map->extent; + status = msDrawRasterSetupTileLayer(layer->map, layer, &searchrect, + MS_FALSE, &tilelayerindex, + &tileitemindex, &tilesrsindex, &tlp); + if (status == MS_FAILURE) { + return MS_FAILURE; + } + + status = msDrawRasterIterateTileIndex(layer, tlp, &tshp, tileitemindex, -1, + szTilename, sizeof(szTilename), + tilesrsname, sizeof(tilesrsname)); + if (status == MS_FAILURE || status == MS_DONE) { + if (status == MS_DONE) { + if (layer->debug) + msDebug("No raster matching filter.\n"); + } msDrawRasterCleanupTileLayer(tlp, tilelayerindex); + return MS_FAILURE; + } - msDrawRasterBuildRasterPath(layer->map, layer, szTilename, szPath); - decrypted_path = msStrdup(szPath); + msDrawRasterCleanupTileLayer(tlp, tilelayerindex); - /* Cancel the time filter that might have been set on ours in case of */ - /* a inline tileindex */ - msFreeExpression(&layer->filter); - msInitExpression(&layer->filter); - } - else - { - msTryBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, layer->data); - decrypted_path = msDecryptStringTokens(layer->map, szPath); + msDrawRasterBuildRasterPath(layer->map, layer, szTilename, szPath); + decrypted_path = msStrdup(szPath); + + /* Cancel the time filter that might have been set on ours in case of */ + /* a inline tileindex */ + msFreeExpression(&layer->filter); + msInitExpression(&layer->filter); + } else { + msTryBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, + layer->data); + decrypted_path = msDecryptStringTokens(layer->map, szPath); } - + GDALAllRegister(); /* Open the original Dataset */ @@ -744,12 +727,11 @@ int msContourLayerOpen(layerObj *layer) msReleaseLock(TLOCK_GDAL); if (clinfo->hOrigDS == NULL) { - msSetError(MS_IMGERR, - "Unable to open GDAL dataset.", + msSetError(MS_IMGERR, "Unable to open GDAL dataset.", "msContourLayerOpen()"); return MS_FAILURE; } - + /* Open the raster source */ if (msContourLayerReadRaster(layer, layer->map->extent) != MS_SUCCESS) return MS_FAILURE; @@ -760,27 +742,25 @@ int msContourLayerOpen(layerObj *layer) if (clinfo->hDS) { GDALClose(clinfo->hDS); - clinfo->hDS = NULL; + clinfo->hDS = NULL; free(clinfo->buffer); } /* Open our virtual ogr layer */ if (clinfo->hOGRDS && (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS)) return MS_FAILURE; - + return MS_SUCCESS; } -int msContourLayerIsOpen(layerObj *layer) -{ +int msContourLayerIsOpen(layerObj *layer) { if (layer->layerinfo) return MS_TRUE; return MS_FALSE; } - -int msContourLayerClose(layerObj *layer) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; + +int msContourLayerClose(layerObj *layer) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerClose().\n"); @@ -790,29 +770,27 @@ int msContourLayerClose(layerObj *layer) msConnPoolRelease(&clinfo->ogrLayer, clinfo->hOGRDS); msLayerClose(&clinfo->ogrLayer); - + if (clinfo->hDS) { GDALClose(clinfo->hDS); clinfo->hDS = NULL; - free(clinfo->buffer); + free(clinfo->buffer); } if (clinfo->hOrigDS) { GDALClose(clinfo->hOrigDS); - clinfo->hOrigDS = NULL; + clinfo->hOrigDS = NULL; } msContourLayerInfoFree(layer); - } - + return MS_SUCCESS; } -int msContourLayerGetItems(layerObj *layer) -{ - const char* elevItem; - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +int msContourLayerGetItems(layerObj *layer) { + const char *elevItem; + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (clinfo == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", @@ -821,10 +799,10 @@ int msContourLayerGetItems(layerObj *layer) } layer->numitems = 0; - layer->items = (char **) msSmallCalloc(sizeof(char *),2); + layer->items = (char **)msSmallCalloc(sizeof(char *), 2); layer->items[layer->numitems++] = msStrdup("ID"); - elevItem = CSLFetchNameValue(layer->processing,"CONTOUR_ITEM"); + elevItem = CSLFetchNameValue(layer->processing, "CONTOUR_ITEM"); if (elevItem && strlen(elevItem) > 0) { layer->items[layer->numitems++] = msStrdup(elevItem); } @@ -832,11 +810,10 @@ int msContourLayerGetItems(layerObj *layer) return msLayerGetItems(&clinfo->ogrLayer); } -int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { int i; rectObj newRect; - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerWhichShapes().\n"); @@ -847,18 +824,17 @@ int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) return MS_FAILURE; } - if( isQuery ) - { + if (isQuery) { newRect = layer->map->extent; - } - else - { + } else { newRect = rect; /* if necessary, project the searchrect to source coords */ - if (msProjectionsDiffer( &(layer->map->projection), &(layer->projection))) { - if (msProjectRect(&layer->projection, &layer->map->projection, &newRect) - != MS_SUCCESS ) { - msDebug("msContourLayerWhichShapes(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); + if (msProjectionsDiffer(&(layer->map->projection), &(layer->projection))) { + if (msProjectRect(&layer->projection, &layer->map->projection, + &newRect) != MS_SUCCESS) { + msDebug("msContourLayerWhichShapes(%s): unable to reproject map " + "request rectangle into layer projection, canceling.\n", + layer->name); return MS_FAILURE; } } @@ -867,9 +843,9 @@ int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) /* regenerate the raster io */ if (clinfo->hOGRDS) msConnPoolRelease(&clinfo->ogrLayer, clinfo->hOGRDS); - + msLayerClose(&clinfo->ogrLayer); - + /* Open the raster source */ if (msContourLayerReadRaster(layer, newRect) != MS_SUCCESS) return MS_FAILURE; @@ -883,26 +859,27 @@ int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) clinfo->hDS = NULL; free(clinfo->buffer); } - + if (!clinfo->hOGRDS) /* no overlap */ return MS_DONE; - + /* Open our virtual ogr layer */ if (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS) return MS_FAILURE; clinfo->ogrLayer.numitems = layer->numitems; - clinfo->ogrLayer.items = (char **) msSmallMalloc(sizeof(char *)*layer->numitems); - for (i=0; inumitems;++i) { + clinfo->ogrLayer.items = + (char **)msSmallMalloc(sizeof(char *) * layer->numitems); + for (i = 0; i < layer->numitems; ++i) { clinfo->ogrLayer.items[i] = msStrdup(layer->items[i]); } return msLayerWhichShapes(&clinfo->ogrLayer, rect, isQuery); } -int msContourLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +int msContourLayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerGetShape().\n"); @@ -916,9 +893,8 @@ int msContourLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) return msLayerGetShape(&clinfo->ogrLayer, shape, record); } -int msContourLayerNextShape(layerObj *layer, shapeObj *shape) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +int msContourLayerNextShape(layerObj *layer, shapeObj *shape) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerNextShape().\n"); @@ -937,9 +913,8 @@ int msContourLayerNextShape(layerObj *layer, shapeObj *shape) /* Simple copy of the maprasterquery.c file. might change in the future */ /************************************************************************/ -int msContourLayerGetExtent(layerObj *layer, rectObj *extent) -{ - contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; +int msContourLayerGetExtent(layerObj *layer, rectObj *extent) { + contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerGetExtent().\n"); @@ -970,8 +945,7 @@ int msContourLayerGetExtent(layerObj *layer, rectObj *extent) /************************************************************************/ int msContourLayerSetTimeFilter(layerObj *layer, const char *timestring, - const char *timefield) -{ + const char *timefield) { int tilelayerindex; if (layer->debug) @@ -980,11 +954,11 @@ int msContourLayerSetTimeFilter(layerObj *layer, const char *timestring, /* -------------------------------------------------------------------- */ /* If we don't have a tileindex the time filter has no effect. */ /* -------------------------------------------------------------------- */ - if( layer->tileindex == NULL ) - { - if (layer->debug) - msDebug("msContourLayerSetTimeFilter(): time filter without effect on layers without tileindex.\n"); - return MS_SUCCESS; + if (layer->tileindex == NULL) { + if (layer->debug) + msDebug("msContourLayerSetTimeFilter(): time filter without effect on " + "layers without tileindex.\n"); + return MS_SUCCESS; } /* -------------------------------------------------------------------- */ @@ -997,25 +971,24 @@ int msContourLayerSetTimeFilter(layerObj *layer, const char *timestring, /* to say, the tileindex name is not of another layer), then we */ /* just install a backtics style filter on the current layer. */ /* -------------------------------------------------------------------- */ - if( tilelayerindex == -1 ) - return msLayerMakeBackticsTimeFilter( layer, timestring, timefield ); + if (tilelayerindex == -1) + return msLayerMakeBackticsTimeFilter(layer, timestring, timefield); /* -------------------------------------------------------------------- */ /* Otherwise we invoke the tileindex layers SetTimeFilter */ /* method. */ /* -------------------------------------------------------------------- */ - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; - return msLayerSetTimeFilter( layer->GET_LAYER(map,tilelayerindex), - timestring, timefield ); + return msLayerSetTimeFilter(layer->GET_LAYER(map, tilelayerindex), timestring, + timefield); } /************************************************************************/ /* msRASTERLayerInitializeVirtualTable() */ /************************************************************************/ -int msContourLayerInitializeVirtualTable(layerObj *layer) -{ +int msContourLayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); diff --git a/mapcopy.c b/mapcopy.c old mode 100755 new mode 100644 index 8a31fe6206..ee61a3f32e --- a/mapcopy.c +++ b/mapcopy.c @@ -53,8 +53,8 @@ * Copy a projectionObj while adding additional arguments * **********************************************************************/ -int msCopyProjectionExtended(projectionObj *dst, const projectionObj *src, char ** args, int num_args) -{ +int msCopyProjectionExtended(projectionObj *dst, const projectionObj *src, + char **args, int num_args) { MS_COPYSTELEM(numargs); MS_COPYSTELEM(gt); MS_COPYSTELEM(automatic); @@ -63,11 +63,10 @@ int msCopyProjectionExtended(projectionObj *dst, const projectionObj *src, char /* Our destination consists of unallocated pointers */ dst->args[i] = msStrdup(src->args[i]); } - if( args ) - { - for(int i=0 ; i< num_args; i++) { - dst->args[dst->numargs++] = msStrdup(args[i]); - } + if (args) { + for (int i = 0; i < num_args; i++) { + dst->args[dst->numargs++] = msStrdup(args[i]); + } } msProjectionInheritContextFrom(dst, src); if (dst->numargs != 0) { @@ -84,9 +83,8 @@ int msCopyProjectionExtended(projectionObj *dst, const projectionObj *src, char * Copy a projectionObj * **********************************************************************/ -int msCopyProjection(projectionObj *dst, const projectionObj *src) -{ - return msCopyProjectionExtended(dst,src,NULL,0); +int msCopyProjection(projectionObj *dst, const projectionObj *src) { + return msCopyProjectionExtended(dst, src, NULL, 0); } /*********************************************************************** @@ -94,8 +92,7 @@ int msCopyProjection(projectionObj *dst, const projectionObj *src) * * * Copy a lineObj, using msCopyPoint() * **********************************************************************/ -int msCopyLine(lineObj *dst, const lineObj *src) -{ +int msCopyLine(lineObj *dst, const lineObj *src) { int i; @@ -141,8 +138,7 @@ int msCopyShapeObj(shapeObj *dst, shapeObj *src) { * Copy an itemObj * **********************************************************************/ -int msCopyItem(itemObj *dst, const itemObj *src) -{ +int msCopyItem(itemObj *dst, const itemObj *src) { MS_COPYSTRING(dst->name, src->name); MS_COPYSTELEM(type); @@ -159,9 +155,8 @@ int msCopyItem(itemObj *dst, const itemObj *src) * Copy a hashTableObj, using msInsertHashTable() * **********************************************************************/ -int msCopyHashTable(hashTableObj *dst, const hashTableObj *src) -{ - const char *key=NULL; +int msCopyHashTable(hashTableObj *dst, const hashTableObj *src) { + const char *key = NULL; while (1) { key = msNextKeyFromHashTable(src, key); if (!key) @@ -178,8 +173,7 @@ int msCopyHashTable(hashTableObj *dst, const hashTableObj *src) * Copy a fontSetObj, using msCreateHashTable() and msCopyHashTable() * **********************************************************************/ -int msCopyFontSet(fontSetObj *dst, const fontSetObj *src, mapObj *map) -{ +int msCopyFontSet(fontSetObj *dst, const fontSetObj *src, mapObj *map) { MS_COPYSTRING(dst->filename, src->filename); MS_COPYSTELEM(numfonts); @@ -201,9 +195,9 @@ int msCopyFontSet(fontSetObj *dst, const fontSetObj *src, mapObj *map) * Copy an expressionObj, but only its string, type and flags * **********************************************************************/ -int msCopyExpression(expressionObj *dst, const expressionObj *src) -{ - if((dst->type == MS_REGEX) && dst->compiled) ms_regfree(&(dst->regex)); +int msCopyExpression(expressionObj *dst, const expressionObj *src) { + if ((dst->type == MS_REGEX) && dst->compiled) + ms_regfree(&(dst->regex)); dst->compiled = MS_FALSE; MS_COPYSTRING(dst->string, src->string); @@ -219,8 +213,7 @@ int msCopyExpression(expressionObj *dst, const expressionObj *src) * Copy a joinObj * **********************************************************************/ -int msCopyJoin(joinObj *dst, const joinObj *src) -{ +int msCopyJoin(joinObj *dst, const joinObj *src) { MS_COPYSTRING(dst->name, src->name); /* makes no sense to copy the items or values @@ -253,8 +246,7 @@ int msCopyJoin(joinObj *dst, const joinObj *src) * Copy a queryMapObj, using msCopyColor() * **********************************************************************/ -int msCopyQueryMap(queryMapObj *dst, const queryMapObj *src) -{ +int msCopyQueryMap(queryMapObj *dst, const queryMapObj *src) { MS_COPYSTELEM(height); MS_COPYSTELEM(width); MS_COPYSTELEM(status); @@ -264,15 +256,13 @@ int msCopyQueryMap(queryMapObj *dst, const queryMapObj *src) return MS_SUCCESS; } - /*********************************************************************** * msCopyLeader() * * * * Copy a labelLeaderObj, using msCopyStyle() * **********************************************************************/ -int msCopyLabelLeader(labelLeaderObj *dst, const labelLeaderObj *src) -{ +int msCopyLabelLeader(labelLeaderObj *dst, const labelLeaderObj *src) { int i; assert(dst && src); MS_COPYSTELEM(gridstep); @@ -282,9 +272,10 @@ int msCopyLabelLeader(labelLeaderObj *dst, const labelLeaderObj *src) */ /* free any previous styles on the dst label */ - for(i=0; inumstyles; i++) { /* each style */ - if (dst->styles[i]!=NULL) { - if( freeStyle(dst->styles[i]) == MS_SUCCESS ) msFree(dst->styles[i]); + for (i = 0; i < dst->numstyles; i++) { /* each style */ + if (dst->styles[i] != NULL) { + if (freeStyle(dst->styles[i]) == MS_SUCCESS) + msFree(dst->styles[i]); } } dst->numstyles = 0; @@ -311,13 +302,13 @@ int msCopyLabelLeader(labelLeaderObj *dst, const labelLeaderObj *src) * Copy a labelObj, using msCopyColor() and msCopyStyle() * **********************************************************************/ -int msCopyLabel(labelObj *dst, const labelObj *src) -{ +int msCopyLabel(labelObj *dst, const labelObj *src) { int i; - for(i=0; ibindings[i].item, src->bindings[i].item); - dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */ + dst->bindings[i].index = + src->bindings[i].index; /* no way to use the macros */ MS_COPYSTRING(dst->exprBindings[i].string, src->exprBindings[i].string); dst->exprBindings[i].type = src->exprBindings[i].type; } @@ -360,7 +351,6 @@ int msCopyLabel(labelObj *dst, const labelObj *src) MS_COPYSTELEM(repeatdistance); MS_COPYSTELEM(maxoverlapangle); - MS_COPYSTRING(dst->encoding, src->encoding); MS_COPYSTELEM(outlinewidth); @@ -381,9 +371,10 @@ int msCopyLabel(labelObj *dst, const labelObj *src) */ /* free any previous styles on the dst label */ - for(i=0; inumstyles; i++) { /* each style */ - if (dst->styles[i]!=NULL) { - if( freeStyle(dst->styles[i]) == MS_SUCCESS ) msFree(dst->styles[i]); + for (i = 0; i < dst->numstyles; i++) { /* each style */ + if (dst->styles[i] != NULL) { + if (freeStyle(dst->styles[i]) == MS_SUCCESS) + msFree(dst->styles[i]); } } dst->numstyles = 0; @@ -402,12 +393,12 @@ int msCopyLabel(labelObj *dst, const labelObj *src) dst->numstyles++; } - if(src->leader) { + if (src->leader) { dst->leader = msSmallMalloc(sizeof(labelLeaderObj)); initLeader(dst->leader); - msCopyLabelLeader(dst->leader,src->leader); + msCopyLabelLeader(dst->leader, src->leader); } else { - if(dst->leader) { + if (dst->leader) { freeLabelLeader(dst->leader); msFree(dst->leader); } @@ -427,8 +418,7 @@ int msCopyLabel(labelObj *dst, const labelObj *src) * msCopyHashTable() * **********************************************************************/ -int msCopyWeb(webObj *dst, const webObj *src, mapObj *map) -{ +int msCopyWeb(webObj *dst, const webObj *src, mapObj *map) { MS_COPYSTRING(dst->imagepath, src->imagepath); MS_COPYSTRING(dst->imageurl, src->imageurl); @@ -453,13 +443,13 @@ int msCopyWeb(webObj *dst, const webObj *src, mapObj *map) if (msCopyHashTable(&(dst->metadata), &(src->metadata)) != MS_SUCCESS) return MS_FAILURE; } - msCopyHashTable(&dst->validation,&src->validation); + msCopyHashTable(&dst->validation, &src->validation); MS_COPYSTRING(dst->queryformat, src->queryformat); MS_COPYSTRING(dst->legendformat, src->legendformat); MS_COPYSTRING(dst->browseformat, src->browseformat); - return MS_SUCCESS ; + return MS_SUCCESS; } /*********************************************************************** @@ -468,13 +458,13 @@ int msCopyWeb(webObj *dst, const webObj *src, mapObj *map) * Copy a styleObj, using msCopyColor() * **********************************************************************/ -int msCopyStyle(styleObj *dst, const styleObj *src) -{ +int msCopyStyle(styleObj *dst, const styleObj *src) { int i; - for(i=0; ibindings[i].item, src->bindings[i].item); - dst->bindings[i].index = src->bindings[i].index; /* no way to use the macros */ + dst->bindings[i].index = + src->bindings[i].index; /* no way to use the macros */ MS_COPYSTRING(dst->exprBindings[i].string, src->exprBindings[i].string); dst->exprBindings[i].type = src->exprBindings[i].type; } @@ -482,15 +472,15 @@ int msCopyStyle(styleObj *dst, const styleObj *src) MS_COPYSTELEM(nexprbindings); MS_COPYCOLOR(&(dst->color), &(src->color)); - MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor)); + MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor)); MS_COPYCOLOR(&(dst->mincolor), &(src->mincolor)); MS_COPYCOLOR(&(dst->maxcolor), &(src->maxcolor)); MS_COPYSTRING(dst->symbolname, src->symbolname); MS_COPYSTELEM(patternlength); - for(i=0; ipatternlength; i++) - dst->pattern[i]=src->pattern[i]; + for (i = 0; i < src->patternlength; i++) + dst->pattern[i] = src->pattern[i]; MS_COPYSTELEM(initialgap); MS_COPYSTELEM(gap); MS_COPYSTELEM(linejoin); @@ -533,12 +523,11 @@ int msCopyStyle(styleObj *dst, const styleObj *src) * msCopyLabel(), msCreateHashTable(), msCopyHashTable() * **********************************************************************/ -int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) -{ +int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) { int i, return_value; (void)layer_unused; - return_value = msCopyExpression(&(dst->expression),&(src->expression)); + return_value = msCopyExpression(&(dst->expression), &(src->expression)); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy expression.", "msCopyClass()"); return MS_FAILURE; @@ -548,9 +537,9 @@ int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) MS_COPYSTELEM(isfallback); /* free any previous styles on the dst layer */ - for(i=0; inumstyles; i++) { /* each style */ - if (dst->styles[i]!=NULL) { - if( freeStyle(dst->styles[i]) == MS_SUCCESS ) { + for (i = 0; i < dst->numstyles; i++) { /* each style */ + if (dst->styles[i] != NULL) { + if (freeStyle(dst->styles[i]) == MS_SUCCESS) { msFree(dst->styles[i]); } } @@ -572,7 +561,7 @@ int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) dst->numstyles++; } - for (i=0; inumlabels; i++) { + for (i = 0; i < src->numlabels; i++) { if (msGrowClassLabels(dst) == NULL) return MS_FAILURE; initLabel(dst->labels[i]); @@ -585,15 +574,15 @@ int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) } MS_COPYSTELEM(numlabels); - if(src->leader) { - if(dst->leader) { + if (src->leader) { + if (dst->leader) { freeLabelLeader(dst->leader); } - if(!dst->leader) { + if (!dst->leader) { dst->leader = msSmallMalloc(sizeof(labelLeaderObj)); initLeader(dst->leader); } - msCopyLabelLeader(dst->leader,src->leader); + msCopyLabelLeader(dst->leader, src->leader); } MS_COPYSTRING(dst->keyimage, src->keyimage); @@ -616,7 +605,7 @@ int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) /* dst->metadata = msCreateHashTable(); */ msCopyHashTable(&(dst->metadata), &(src->metadata)); } - msCopyHashTable(&dst->validation,&src->validation); + msCopyHashTable(&dst->validation, &src->validation); MS_COPYSTELEM(minscaledenom); MS_COPYSTELEM(maxscaledenom); @@ -629,21 +618,20 @@ int msCopyClass(classObj *dst, const classObj *src, layerObj *layer_unused) return MS_SUCCESS; } -int msCopyCluster(clusterObj *dst, const clusterObj *src) -{ +int msCopyCluster(clusterObj *dst, const clusterObj *src) { int return_value; MS_COPYSTELEM(maxdistance); MS_COPYSTELEM(buffer); MS_COPYSTRING(dst->region, src->region); - return_value = msCopyExpression(&(dst->group),&(src->group)); + return_value = msCopyExpression(&(dst->group), &(src->group)); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy cluster group.", "msCopyCluster()"); return MS_FAILURE; } - return_value = msCopyExpression(&(dst->filter),&(src->filter)); + return_value = msCopyExpression(&(dst->filter), &(src->filter)); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy cluster filter.", "msCopyCluster()"); return MS_FAILURE; @@ -656,8 +644,7 @@ int msCopyCluster(clusterObj *dst, const clusterObj *src) * msCopyGrid() * **********************************************************************/ -int msCopyGrid(graticuleObj *dst, const graticuleObj *src) -{ +int msCopyGrid(graticuleObj *dst, const graticuleObj *src) { MS_COPYSTELEM(dwhichlatitude); MS_COPYSTELEM(dwhichlongitude); MS_COPYSTELEM(dstartlatitude); @@ -678,7 +665,7 @@ int msCopyGrid(graticuleObj *dst, const graticuleObj *src) MS_COPYSTELEM(ilabeltype); MS_COPYRECT(&(dst->extent), &(src->extent)); MS_COPYSTRING(dst->labelformat, src->labelformat); - + return MS_SUCCESS; } @@ -693,8 +680,8 @@ int msCopyGrid(graticuleObj *dst, const graticuleObj *src) * make exact copies, this method might not get much use. * **********************************************************************/ -int msCopyLabelCacheMember(labelCacheMemberObj *dst, const labelCacheMemberObj *src) -{ +int msCopyLabelCacheMember(labelCacheMemberObj *dst, + const labelCacheMemberObj *src) { int i; MS_COPYSTELEM(featuresize); @@ -705,7 +692,7 @@ int msCopyLabelCacheMember(labelCacheMemberObj *dst, const labelCacheMemberObj * } MS_COPYSTELEM(numlabels); - dst->labels = (labelObj *) msSmallMalloc(sizeof(labelObj)*dst->numlabels); + dst->labels = (labelObj *)msSmallMalloc(sizeof(labelObj) * dst->numlabels); for (i = 0; i < dst->numlabels; i++) { msCopyLabel(&(dst->labels[i]), &(src->labels[i])); } @@ -728,8 +715,7 @@ int msCopyLabelCacheMember(labelCacheMemberObj *dst, const labelCacheMemberObj * **********************************************************************/ int msCopyMarkerCacheMember(markerCacheMemberObj *dst, - const markerCacheMemberObj *src) -{ + const markerCacheMemberObj *src) { MS_COPYSTELEM(id); /* msCopyShape(&(dst->poly), &(src->poly)); */ @@ -740,8 +726,7 @@ int msCopyMarkerCacheMember(markerCacheMemberObj *dst, * msCopyLabelCacheSlot() * **********************************************************************/ -int msCopyLabelCacheSlot(labelCacheSlotObj *dst, const labelCacheSlotObj *src) -{ +int msCopyLabelCacheSlot(labelCacheSlotObj *dst, const labelCacheSlotObj *src) { int i; for (i = 0; i < dst->numlabels; i++) { @@ -761,12 +746,11 @@ int msCopyLabelCacheSlot(labelCacheSlotObj *dst, const labelCacheSlotObj *src) * msCopyLabelCache() * **********************************************************************/ -int msCopyLabelCache(labelCacheObj *dst, const labelCacheObj *src) -{ +int msCopyLabelCache(labelCacheObj *dst, const labelCacheObj *src) { int p; MS_COPYSTELEM(numlabels); - for (p=0; pslots[p]), &(src->slots[p])); } @@ -779,8 +763,7 @@ int msCopyLabelCache(labelCacheObj *dst, const labelCacheObj *src) * msCopyResult() * **********************************************************************/ -int msCopyResult(resultObj *dst, const resultObj *src) -{ +int msCopyResult(resultObj *dst, const resultObj *src) { MS_COPYSTELEM(shapeindex); MS_COPYSTELEM(tileindex); MS_COPYSTELEM(classindex); @@ -793,8 +776,7 @@ int msCopyResult(resultObj *dst, const resultObj *src) * msCopyResultCache() * **********************************************************************/ -int msCopyResultCache(resultCacheObj *dst, const resultCacheObj *src) -{ +int msCopyResultCache(resultCacheObj *dst, const resultCacheObj *src) { int i; MS_COPYSTELEM(cachesize); MS_COPYSTELEM(numresults); @@ -814,8 +796,7 @@ int msCopyResultCache(resultCacheObj *dst, const resultCacheObj *src) **********************************************************************/ int msCopyReferenceMap(referenceMapObj *dst, const referenceMapObj *src, - mapObj *map) -{ + mapObj *map) { initReferenceMap(dst); @@ -824,9 +805,8 @@ int msCopyReferenceMap(referenceMapObj *dst, const referenceMapObj *src, MS_COPYSTELEM(height); MS_COPYSTELEM(width); - MS_COPYCOLOR(&(dst->color), &(src->color)); - MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor)); + MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor)); MS_COPYSTRING(dst->image, src->image); MS_COPYSTELEM(status); @@ -847,8 +827,7 @@ int msCopyReferenceMap(referenceMapObj *dst, const referenceMapObj *src, * and msCopyLabel() * **********************************************************************/ -int msCopyScalebar(scalebarObj *dst, const scalebarObj *src) -{ +int msCopyScalebar(scalebarObj *dst, const scalebarObj *src) { initScalebar(dst); @@ -859,7 +838,7 @@ int msCopyScalebar(scalebarObj *dst, const scalebarObj *src) MS_COPYSTELEM(intervals); if (msCopyLabel(&(dst->label), &(src->label)) != MS_SUCCESS) { - msSetError(MS_MEMERR, "Failed to copy label.","msCopyScalebar()"); + msSetError(MS_MEMERR, "Failed to copy label.", "msCopyScalebar()"); return MS_FAILURE; } @@ -884,16 +863,14 @@ int msCopyScalebar(scalebarObj *dst, const scalebarObj *src) * Copy a legendObj, using msCopyColor() * **********************************************************************/ -int msCopyLegend(legendObj *dst, const legendObj *src, mapObj *map) -{ +int msCopyLegend(legendObj *dst, const legendObj *src, mapObj *map) { int return_value; MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor)); return_value = msCopyLabel(&(dst->label), &(src->label)); if (return_value != MS_SUCCESS) { - msSetError(MS_MEMERR, "Failed to copy label.", - "msCopyLegend()"); + msSetError(MS_MEMERR, "Failed to copy label.", "msCopyLegend()"); return MS_FAILURE; } @@ -902,7 +879,7 @@ int msCopyLegend(legendObj *dst, const legendObj *src, mapObj *map) MS_COPYSTELEM(keyspacingx); MS_COPYSTELEM(keyspacingy); - MS_COPYCOLOR(&(dst->outlinecolor),&(src->outlinecolor)); + MS_COPYCOLOR(&(dst->outlinecolor), &(src->outlinecolor)); MS_COPYSTELEM(status); MS_COPYSTELEM(height); @@ -921,8 +898,9 @@ int msCopyLegend(legendObj *dst, const legendObj *src, mapObj *map) return MS_SUCCESS; } -int msCopyScaleTokenEntry(const scaleTokenEntryObj *src, scaleTokenEntryObj *dst) { - MS_COPYSTRING(dst->value,src->value); +int msCopyScaleTokenEntry(const scaleTokenEntryObj *src, + scaleTokenEntryObj *dst) { + MS_COPYSTRING(dst->value, src->value); MS_COPYSTELEM(minscale); MS_COPYSTELEM(maxscale); return MS_SUCCESS; @@ -930,23 +908,25 @@ int msCopyScaleTokenEntry(const scaleTokenEntryObj *src, scaleTokenEntryObj *dst int msCopyScaleToken(const scaleTokenObj *src, scaleTokenObj *dst) { int i; - MS_COPYSTRING(dst->name,src->name); + MS_COPYSTRING(dst->name, src->name); MS_COPYSTELEM(n_entries); - dst->tokens = (scaleTokenEntryObj*)msSmallCalloc(src->n_entries,sizeof(scaleTokenEntryObj)); - for(i=0;in_entries;i++) { - msCopyScaleTokenEntry(&src->tokens[i],&dst->tokens[i]); + dst->tokens = (scaleTokenEntryObj *)msSmallCalloc(src->n_entries, + sizeof(scaleTokenEntryObj)); + for (i = 0; i < src->n_entries; i++) { + msCopyScaleTokenEntry(&src->tokens[i], &dst->tokens[i]); } return MS_SUCCESS; } -int msCopyCompositingFilter(CompositingFilter **pdst, const CompositingFilter *src) { +int msCopyCompositingFilter(CompositingFilter **pdst, + const CompositingFilter *src) { CompositingFilter *dst = NULL; - if(!src) { + if (!src) { *pdst = NULL; return MS_SUCCESS; } - while(src) { - if(!dst) { + while (src) { + if (!dst) { dst = *pdst = msSmallMalloc(sizeof(CompositingFilter)); } else { dst->next = msSmallMalloc(sizeof(CompositingFilter)); @@ -961,13 +941,13 @@ int msCopyCompositingFilter(CompositingFilter **pdst, const CompositingFilter *s int msCopyCompositer(LayerCompositer **ldst, const LayerCompositer *src) { LayerCompositer *dst = NULL; - if(!src) { + if (!src) { *ldst = NULL; return MS_SUCCESS; } - while(src) { - if(!dst) { + while (src) { + if (!dst) { dst = *ldst = msSmallMalloc(sizeof(LayerCompositer)); } else { dst->next = msSmallMalloc(sizeof(LayerCompositer)); @@ -992,8 +972,7 @@ int msCopyCompositer(LayerCompositer **ldst, const LayerCompositer *src) { * As it stands, we are not copying a layer's resultcache * **********************************************************************/ -int msCopyLayer(layerObj *dst, const layerObj *src) -{ +int msCopyLayer(layerObj *dst, const layerObj *src) { int i, return_value; featureListNodeObjPtr current; @@ -1002,11 +981,11 @@ int msCopyLayer(layerObj *dst, const layerObj *src) MS_COPYSTELEM(classitemindex); - for(i = 0; i < src->numscaletokens; i++) { - if(msGrowLayerScaletokens(dst) == NULL) + for (i = 0; i < src->numscaletokens; i++) { + if (msGrowLayerScaletokens(dst) == NULL) return MS_FAILURE; initScaleToken(&dst->scaletokens[i]); - msCopyScaleToken(&src->scaletokens[i],&dst->scaletokens[i]); + msCopyScaleToken(&src->scaletokens[i], &dst->scaletokens[i]); dst->numscaletokens++; } @@ -1015,7 +994,7 @@ int msCopyLayer(layerObj *dst, const layerObj *src) return MS_FAILURE; #ifndef __cplusplus initClass(dst->class[i]); - return_value = msCopyClass(dst->class[i], src->class[i], dst); + return_value = msCopyClass(dst->class[i], src -> class[i], dst); #else initClass(dst->_class[i]); return_value = msCopyClass(dst->_class[i], src->_class[i], dst); @@ -1073,13 +1052,13 @@ int msCopyLayer(layerObj *dst, const layerObj *src) MS_COPYSTRING(dst->tileindex, src->tileindex); - return_value = msCopyProjection(&(dst->projection),&(src->projection)); + return_value = msCopyProjection(&(dst->projection), &(src->projection)); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyLayer()"); return MS_FAILURE; } - return_value = msCopyCluster(&(dst->cluster),&(src->cluster)); + return_value = msCopyCluster(&(dst->cluster), &(src->cluster)); if (return_value != MS_SUCCESS) { return MS_FAILURE; } @@ -1088,7 +1067,7 @@ int msCopyLayer(layerObj *dst, const layerObj *src) MS_COPYSTELEM(units); current = src->features; - while(current != NULL) { + while (current != NULL) { insertFeatureList(&(dst->features), &(current->shape)); current = current->next; } @@ -1120,8 +1099,8 @@ int msCopyLayer(layerObj *dst, const layerObj *src) if (&(src->metadata)) { msCopyHashTable(&(dst->metadata), &(src->metadata)); } - msCopyHashTable(&dst->validation,&src->validation); - msCopyHashTable(&dst->connectionoptions,&src->connectionoptions); + msCopyHashTable(&dst->validation, &src->validation); + msCopyHashTable(&dst->connectionoptions, &src->connectionoptions); MS_COPYSTELEM(debug); @@ -1150,13 +1129,13 @@ int msCopyLayer(layerObj *dst, const layerObj *src) freeGrid(dst->grid); msFree(dst->grid); } - dst->grid = (void *) malloc(sizeof(graticuleObj)); + dst->grid = (void *)malloc(sizeof(graticuleObj)); MS_CHECK_ALLOC(dst->grid, sizeof(graticuleObj), -1); initGrid(dst->grid); msCopyGrid(dst->grid, src->grid); } - if(src->compositer) { + if (src->compositer) { msCopyCompositer(&dst->compositer, src->compositer); } @@ -1172,8 +1151,7 @@ int msCopyLayer(layerObj *dst, const layerObj *src) * msCopyOutputFormat(), msCopyWeb(), msCopyReferenceMap() * **********************************************************************/ -int msCopyMap(mapObj *dst, const mapObj *src) -{ +int msCopyMap(mapObj *dst, const mapObj *src) { int i, return_value; outputFormatObj *format; @@ -1203,7 +1181,7 @@ int msCopyMap(mapObj *dst, const mapObj *src) } return_value = msCopySymbolSet(&(dst->symbolset), &(src->symbolset), dst); - if(return_value != MS_SUCCESS) { + if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy symbolset.", "msCopyMap()"); return MS_FAILURE; } @@ -1223,31 +1201,30 @@ int msCopyMap(mapObj *dst, const mapObj *src) MS_COPYCOLOR(&(dst->imagecolor), &(src->imagecolor)); /* clear existing destination format list */ - if( dst->outputformat && --dst->outputformat->refcount < 1 ) { - msFreeOutputFormat( dst->outputformat ); + if (dst->outputformat && --dst->outputformat->refcount < 1) { + msFreeOutputFormat(dst->outputformat); dst->outputformat = NULL; } - for(i=0; i < dst->numoutputformats; i++ ) { - if( --dst->outputformatlist[i]->refcount < 1 ) - msFreeOutputFormat( dst->outputformatlist[i] ); + for (i = 0; i < dst->numoutputformats; i++) { + if (--dst->outputformatlist[i]->refcount < 1) + msFreeOutputFormat(dst->outputformatlist[i]); } - if( dst->outputformatlist != NULL ) - msFree( dst->outputformatlist ); + if (dst->outputformatlist != NULL) + msFree(dst->outputformatlist); dst->outputformatlist = NULL; dst->outputformat = NULL; dst->numoutputformats = 0; for (i = 0; i < src->numoutputformats; i++) - msAppendOutputFormat( dst, - msCloneOutputFormat( src->outputformatlist[i]) ); + msAppendOutputFormat(dst, msCloneOutputFormat(src->outputformatlist[i])); /* set the active output format */ MS_COPYSTRING(dst->imagetype, src->imagetype); - format = msSelectOutputFormat( dst, dst->imagetype ); + format = msSelectOutputFormat(dst, dst->imagetype); msApplyOutputFormat(&(dst->outputformat), format, MS_NOOVERRIDE); - return_value = msCopyProjection(&(dst->projection),&(src->projection)); + return_value = msCopyProjection(&(dst->projection), &(src->projection)); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy projection.", "msCopyMap()"); return MS_FAILURE; @@ -1255,8 +1232,7 @@ int msCopyMap(mapObj *dst, const mapObj *src) /* No need to copy latlon projection */ - return_value = msCopyReferenceMap(&(dst->reference),&(src->reference), - dst); + return_value = msCopyReferenceMap(&(dst->reference), &(src->reference), dst); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy reference.", "msCopyMap()"); return MS_FAILURE; @@ -1268,7 +1244,7 @@ int msCopyMap(mapObj *dst, const mapObj *src) return MS_FAILURE; } - return_value = msCopyLegend(&(dst->legend), &(src->legend),dst); + return_value = msCopyLegend(&(dst->legend), &(src->legend), dst); if (return_value != MS_SUCCESS) { msSetError(MS_MEMERR, "Failed to copy legend.", "msCopyMap()"); return MS_FAILURE; @@ -1286,16 +1262,17 @@ int msCopyMap(mapObj *dst, const mapObj *src) return MS_FAILURE; } - if( src->layerorder ) { + if (src->layerorder) { for (i = 0; i < dst->numlayers; i++) { - MS_COPYSTELEM(layerorder[i]); + MS_COPYSTELEM(layerorder[i]); } } MS_COPYSTELEM(debug); MS_COPYSTRING(dst->datapattern, src->datapattern); MS_COPYSTRING(dst->templatepattern, src->templatepattern); - if( msCopyHashTable( &(dst->configoptions), &(src->configoptions) ) != MS_SUCCESS ) + if (msCopyHashTable(&(dst->configoptions), &(src->configoptions)) != + MS_SUCCESS) return MS_FAILURE; return MS_SUCCESS; @@ -1303,19 +1280,24 @@ int msCopyMap(mapObj *dst, const mapObj *src) int msCopyRasterBuffer(rasterBufferObj *dst, const rasterBufferObj *src) { *dst = *src; - if(src->type == MS_BUFFER_BYTE_RGBA) { + if (src->type == MS_BUFFER_BYTE_RGBA) { dst->data.rgba = src->data.rgba; - dst->data.rgba.pixels = msSmallMalloc(src->height * src->data.rgba.row_step); - memcpy(dst->data.rgba.pixels, src->data.rgba.pixels, src->data.rgba.row_step*src->height); - dst->data.rgba.r = dst->data.rgba.pixels + (src->data.rgba.r - src->data.rgba.pixels); - dst->data.rgba.g = dst->data.rgba.pixels + (src->data.rgba.g - src->data.rgba.pixels); - dst->data.rgba.b = dst->data.rgba.pixels + (src->data.rgba.b - src->data.rgba.pixels); - if(src->data.rgba.a) { - dst->data.rgba.a = dst->data.rgba.pixels + (src->data.rgba.a - src->data.rgba.pixels); + dst->data.rgba.pixels = + msSmallMalloc(src->height * src->data.rgba.row_step); + memcpy(dst->data.rgba.pixels, src->data.rgba.pixels, + src->data.rgba.row_step * src->height); + dst->data.rgba.r = + dst->data.rgba.pixels + (src->data.rgba.r - src->data.rgba.pixels); + dst->data.rgba.g = + dst->data.rgba.pixels + (src->data.rgba.g - src->data.rgba.pixels); + dst->data.rgba.b = + dst->data.rgba.pixels + (src->data.rgba.b - src->data.rgba.pixels); + if (src->data.rgba.a) { + dst->data.rgba.a = + dst->data.rgba.pixels + (src->data.rgba.a - src->data.rgba.pixels); } else { dst->data.rgba.a = NULL; } } return MS_SUCCESS; } - diff --git a/mapcopy.h b/mapcopy.h index cf91567812..1ed5990eda 100644 --- a/mapcopy.h +++ b/mapcopy.h @@ -32,42 +32,39 @@ /* Following works for GCC and MSVC. That's ~98% of our users, if Tyler * Mitchell's survey is correct */ -#define MS_COPYSTELEM(_name) (dst)->/**/_name = (src)->/**/_name +#define MS_COPYSTELEM(_name) (dst)->/**/ _name = (src)->/**/ _name -#define MS_MACROBEGIN do { -#define MS_MACROEND } while (0) +#define MS_MACROBEGIN do { +#define MS_MACROEND \ + } \ + while (0) -#define MS_COPYRECT(_dst, _src) \ - MS_MACROBEGIN \ - (_dst)->minx = (_src)->minx; \ - (_dst)->miny = (_src)->miny; \ - (_dst)->maxx = (_src)->maxx; \ - (_dst)->maxy = (_src)->maxy; \ - MS_MACROEND +#define MS_COPYRECT(_dst, _src) \ + MS_MACROBEGIN(_dst)->minx = (_src)->minx; \ + (_dst)->miny = (_src)->miny; \ + (_dst)->maxx = (_src)->maxx; \ + (_dst)->maxy = (_src)->maxy; \ + MS_MACROEND -#define MS_COPYPOINT(_dst, _src) \ - MS_MACROBEGIN \ - (_dst)->x = (_src)->x; \ - (_dst)->y = (_src)->y; \ - (_dst)->m = (_src)->m; \ - MS_MACROEND - -#define MS_COPYCOLOR(_dst, _src) \ - MS_MACROBEGIN \ - (_dst)->red = (_src)->red; \ - (_dst)->green = (_src)->green;\ - (_dst)->blue = (_src)->blue; \ - (_dst)->alpha = (_src)->alpha; \ - MS_MACROEND - -#define MS_COPYSTRING(_dst, _src) \ - MS_MACROBEGIN \ - if ((_dst) != NULL) \ - msFree((_dst)); \ - if ((_src)) \ - (_dst) = msStrdup((_src)); \ - else \ - (_dst) = NULL; \ - MS_MACROEND +#define MS_COPYPOINT(_dst, _src) \ + MS_MACROBEGIN(_dst)->x = (_src)->x; \ + (_dst)->y = (_src)->y; \ + (_dst)->m = (_src)->m; \ + MS_MACROEND +#define MS_COPYCOLOR(_dst, _src) \ + MS_MACROBEGIN(_dst)->red = (_src)->red; \ + (_dst)->green = (_src)->green; \ + (_dst)->blue = (_src)->blue; \ + (_dst)->alpha = (_src)->alpha; \ + MS_MACROEND +#define MS_COPYSTRING(_dst, _src) \ + MS_MACROBEGIN \ + if ((_dst) != NULL) \ + msFree((_dst)); \ + if ((_src)) \ + (_dst) = msStrdup((_src)); \ + else \ + (_dst) = NULL; \ + MS_MACROEND diff --git a/mapcpl.c b/mapcpl.c index 9a2854dc35..bad88c940d 100644 --- a/mapcpl.c +++ b/mapcpl.c @@ -41,27 +41,24 @@ #include #include "mapserver.h" - - /* should be size of largest possible filename */ #define MS_PATH_BUF_SIZE 2048 -static char szStaticResult[MS_PATH_BUF_SIZE]; - +static char szStaticResult[MS_PATH_BUF_SIZE]; /************************************************************************/ /* msFindFilenameStart() */ /************************************************************************/ -static int msFindFilenameStart( const char * pszFilename ) +static int msFindFilenameStart(const char *pszFilename) { - int iFileStart; + int iFileStart; - for( iFileStart = strlen(pszFilename); - iFileStart > 0 - && pszFilename[iFileStart-1] != '/' - && pszFilename[iFileStart-1] != '\\'; - iFileStart-- ) {} + for (iFileStart = strlen(pszFilename); + iFileStart > 0 && pszFilename[iFileStart - 1] != '/' && + pszFilename[iFileStart - 1] != '\\'; + iFileStart--) { + } return iFileStart; } @@ -90,24 +87,25 @@ static int msFindFilenameStart( const char * pszFilename ) * may be destroyed by the next ms filename handling call. */ -const char *msGetBasename( const char *pszFullFilename ) +const char *msGetBasename(const char *pszFullFilename) { - int iFileStart = msFindFilenameStart( pszFullFilename ); + int iFileStart = msFindFilenameStart(pszFullFilename); int iExtStart, nLength; - for( iExtStart = strlen(pszFullFilename); + for (iExtStart = strlen(pszFullFilename); iExtStart > iFileStart && pszFullFilename[iExtStart] != '.'; - iExtStart-- ) {} + iExtStart--) { + } - if( iExtStart == iFileStart ) + if (iExtStart == iFileStart) iExtStart = strlen(pszFullFilename); nLength = iExtStart - iFileStart; - assert( nLength < MS_PATH_BUF_SIZE ); + assert(nLength < MS_PATH_BUF_SIZE); - strlcpy( szStaticResult, pszFullFilename + iFileStart, nLength+1 ); + strlcpy(szStaticResult, pszFullFilename + iFileStart, nLength + 1); return szStaticResult; } @@ -159,45 +157,42 @@ const char *msGetBasename( const char *pszFullFilename ) * found, or the shared library can't be loaded. */ -void *msGetSymbol( const char * pszLibrary, const char * pszSymbolName ) -{ - void *pLibrary; - void *pSymbol; +void *msGetSymbol(const char *pszLibrary, const char *pszSymbolName) { + void *pLibrary; + void *pSymbol; pLibrary = dlopen(pszLibrary, RTLD_LAZY); - if( pLibrary == NULL ) { - msSetError(MS_MISCERR, - "Dynamic loading failed: %s", - "msGetSymbol()", dlerror()); + if (pLibrary == NULL) { + msSetError(MS_MISCERR, "Dynamic loading failed: %s", "msGetSymbol()", + dlerror()); return NULL; } - pSymbol = dlsym( pLibrary, pszSymbolName ); + pSymbol = dlsym(pLibrary, pszSymbolName); #if (defined(__APPLE__) && defined(__MACH__)) /* On mach-o systems, C symbols have a leading underscore and depending * on how dlcompat is configured it may or may not add the leading * underscore. So if dlsym() fails add an underscore and try again. */ - if( pSymbol == NULL ) { + if (pSymbol == NULL) { char withUnder[strlen(pszSymbolName) + 2]; withUnder[0] = '_'; withUnder[1] = 0; strcat(withUnder, pszSymbolName); - pSymbol = dlsym( pLibrary, withUnder ); + pSymbol = dlsym(pLibrary, withUnder); } #endif - if( pSymbol == NULL ) { - msSetError(MS_MISCERR, - "Dynamic loading failed: %s", - "msGetSymbol()", dlerror()); + if (pSymbol == NULL) { + msSetError(MS_MISCERR, "Dynamic loading failed: %s", "msGetSymbol()", + dlerror()); return NULL; } /* We accept leakage of pLibrary */ /* coverity[leaked_storage] */ - return( pSymbol ); + return (pSymbol); } #endif /* def __unix__ && defined(HAVE_DLFCN_H) */ @@ -215,29 +210,26 @@ void *msGetSymbol( const char * pszLibrary, const char * pszSymbolName ) /* msGetSymbol() */ /************************************************************************/ -void *msGetSymbol( const char * pszLibrary, const char * pszSymbolName ) -{ - void *pLibrary; - void *pSymbol; +void *msGetSymbol(const char *pszLibrary, const char *pszSymbolName) { + void *pLibrary; + void *pSymbol; pLibrary = LoadLibrary(pszLibrary); - if( pLibrary == NULL ) { - msSetError(MS_MISCERR, - "Can't load requested dynamic library: %s", + if (pLibrary == NULL) { + msSetError(MS_MISCERR, "Can't load requested dynamic library: %s", "msGetSymbol()", pszLibrary); return NULL; } - pSymbol = (void *) GetProcAddress( (HINSTANCE) pLibrary, pszSymbolName ); + pSymbol = (void *)GetProcAddress((HINSTANCE)pLibrary, pszSymbolName); - if( pSymbol == NULL ) { - msSetError(MS_MISCERR, - "Can't find requested entry point: %s in lib %s", + if (pSymbol == NULL) { + msSetError(MS_MISCERR, "Can't find requested entry point: %s in lib %s", "msGetSymbol()", pszSymbolName, pLibrary); return NULL; } - return( pSymbol ); + return (pSymbol); } #endif /* def _WIN32 */ @@ -254,11 +246,11 @@ void *msGetSymbol( const char * pszLibrary, const char * pszSymbolName ) /* Dummy implementation. */ /************************************************************************/ -void *msGetSymbol(const char *pszLibrary, const char *pszEntryPoint) -{ - msSetError(MS_MISCERR, - "msGetSymbol(%s,%s) called. Failed as this is stub implementation.", - "msGetSymbol()", pszLibrary, pszEntryPoint); +void *msGetSymbol(const char *pszLibrary, const char *pszEntryPoint) { + msSetError( + MS_MISCERR, + "msGetSymbol(%s,%s) called. Failed as this is stub implementation.", + "msGetSymbol()", pszLibrary, pszEntryPoint); return NULL; } #endif diff --git a/mapcrypto.c b/mapcrypto.c index 2f72da180e..91c14dfafd 100644 --- a/mapcrypto.c +++ b/mapcrypto.c @@ -28,15 +28,14 @@ ****************************************************************************/ #include -#include /* isxdigit() */ -#include /* rand() */ -#include /* time() */ +#include /* isxdigit() */ +#include /* rand() */ +#include /* time() */ #include "mapserver.h" #include "cpl_conv.h" - /********************************************************************** * encipher() and decipher() from the Tiny Encryption Algorithm (TEA) * website at: @@ -86,35 +85,34 @@ **********************************************************************/ static void encipher(const ms_uint32 *const v, ms_uint32 *const w, - const ms_uint32 *const k) -{ - register ms_uint32 y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=32; + const ms_uint32 *const k) { + register ms_uint32 y = v[0], z = v[1], sum = 0, delta = 0x9E3779B9, n = 32; - while(n-->0) { - y += ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum&3]); + while (n-- > 0) { + y += ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]); sum += delta; - z += ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum>>11 & 3]); + z += ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]); } - w[0]=y; - w[1]=z; + w[0] = y; + w[1] = z; } static void decipher(const ms_uint32 *const v, ms_uint32 *const w, - const ms_uint32 *const k) -{ - register ms_uint32 y=v[0],z=v[1],sum=0xC6EF3720, delta=0x9E3779B9,n=32; + const ms_uint32 *const k) { + register ms_uint32 y = v[0], z = v[1], sum = 0xC6EF3720, delta = 0x9E3779B9, + n = 32; /* sum = delta<<5, in general sum = delta * n */ - while(n-->0) { - z -= ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum>>11 & 3]); + while (n-- > 0) { + z -= ((y << 4 ^ y >> 5) + y) ^ (sum + k[sum >> 11 & 3]); sum -= delta; - y -= ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum&3]); + y -= ((z << 4 ^ z >> 5) + z) ^ (sum + k[sum & 3]); } - w[0]=y; - w[1]=z; + w[0] = y; + w[1] = z; } /********************************************************************** @@ -125,13 +123,12 @@ static void decipher(const ms_uint32 *const v, ms_uint32 *const w, * out[] should be preallocated by the caller to be at least 2*numbytes+1 * (+1 for the terminating '\0') **********************************************************************/ -void msHexEncode(const unsigned char *in, char *out, int numbytes) -{ +void msHexEncode(const unsigned char *in, char *out, int numbytes) { char *hex = "0123456789ABCDEF"; while (numbytes-- > 0) { - *out++ = hex[*in/16]; - *out++ = hex[*in%16]; + *out++ = hex[*in / 16]; + *out++ = hex[*in % 16]; in++; } *out = '\0'; @@ -151,20 +148,19 @@ void msHexEncode(const unsigned char *in, char *out, int numbytes) * Returns the number of bytes written to out[] which may be different from * numchars/2 if an error or a '\0' is encountered. **********************************************************************/ -int msHexDecode(const char *in, unsigned char *out, int numchars) -{ +int msHexDecode(const char *in, unsigned char *out, int numchars) { int numbytes_out = 0; /* Make sure numchars is even */ - numchars = (numchars/2) * 2; + numchars = (numchars / 2) * 2; if (numchars < 2) numchars = -1; /* Will result in this value being ignored in the loop*/ - while (*in != '\0' && *(in+1) != '\0' && numchars != 0) { - *out = 0x10 * (*in >= 'A' ? ((*in & 0xdf) - 'A')+10 : (*in - '0')); + while (*in != '\0' && *(in + 1) != '\0' && numchars != 0) { + *out = 0x10 * (*in >= 'A' ? ((*in & 0xdf) - 'A') + 10 : (*in - '0')); in++; - *out += (*in >= 'A' ? ((*in & 0xdf) - 'A')+10 : (*in - '0')); + *out += (*in >= 'A' ? ((*in & 0xdf) - 'A') + 10 : (*in - '0')); in++; out++; @@ -176,7 +172,6 @@ int msHexDecode(const char *in, unsigned char *out, int numchars) return numbytes_out; } - /********************************************************************** * msGenerateEncryptionKey() * @@ -185,15 +180,13 @@ int msHexDecode(const char *in, unsigned char *out, int numchars) * The output buffer should be at least MS_ENCRYPTION_KEY_SIZE bytes. **********************************************************************/ -int msGenerateEncryptionKey(unsigned char *k) -{ +int msGenerateEncryptionKey(unsigned char *k) { int i; /* Use current time as seed for rand() */ - srand( (unsigned int) time( NULL )); + srand((unsigned int)time(NULL)); - for(i=0; iencryption_key_loaded) - return MS_SUCCESS; /* Already loaded */ + return MS_SUCCESS; /* Already loaded */ keyfile = msGetConfigOption(map, "MS_ENCRYPTION_KEY"); - if(!keyfile) keyfile = CPLGetConfigOption("MS_ENCRYPTION_KEY", NULL); + if (!keyfile) + keyfile = CPLGetConfigOption("MS_ENCRYPTION_KEY", NULL); if (keyfile && - msReadEncryptionKeyFromFile(keyfile,map->encryption_key) == MS_SUCCESS) { + msReadEncryptionKeyFromFile(keyfile, map->encryption_key) == MS_SUCCESS) { map->encryption_key_loaded = MS_TRUE; } else { - msSetError(MS_MISCERR, "Failed reading encryption key. Make sure " + msSetError(MS_MISCERR, + "Failed reading encryption key. Make sure " "MS_ENCRYPTION_KEY is set and points to a valid key file.", "msLoadEncryptionKey()"); return MS_FAILURE; @@ -294,8 +288,8 @@ static int msLoadEncryptionKey(mapObj *map) * **********************************************************************/ -void msEncryptStringWithKey(const unsigned char *key, const char *in, char *out) -{ +void msEncryptStringWithKey(const unsigned char *key, const char *in, + char *out) { ms_uint32 v[4], w[4]; const ms_uint32 *k; int last_block = MS_FALSE; @@ -303,9 +297,9 @@ void msEncryptStringWithKey(const unsigned char *key, const char *in, char *out) /* Casting the key this way is safe only as long as longs are 4 bytes * on this platform */ assert(sizeof(ms_uint32) == 4); - k = (const ms_uint32 *) key; + k = (const ms_uint32 *)key; - while(!last_block) { + while (!last_block) { int i, j; /* encipher() takes v[2] (64 bits) as input. * Copy bytes from in[] to the v[2] input array (pair of 4 bytes) @@ -313,14 +307,14 @@ void msEncryptStringWithKey(const unsigned char *key, const char *in, char *out) */ v[0] = 0; v[1] = 0; - for(i=0; !last_block && i<2; i++) { - for(j=0; j<4; j++) { + for (i = 0; !last_block && i < 2; i++) { + for (j = 0; j < 4; j++) { if (*in == '\0') { last_block = MS_TRUE; break; } - v[i] |= *in << (j*8); + v[i] |= *in << (j * 8); in++; } } @@ -334,9 +328,8 @@ void msEncryptStringWithKey(const unsigned char *key, const char *in, char *out) /* Append hex-encoded bytes to output, 4 bytes at a time */ msHexEncode((unsigned char *)w, out, 4); out += 8; - msHexEncode((unsigned char *)(w+1), out, 4); + msHexEncode((unsigned char *)(w + 1), out, 4); out += 8; - } /* Make sure output is 0-terminated */ @@ -352,8 +345,8 @@ void msEncryptStringWithKey(const unsigned char *key, const char *in, char *out) * **********************************************************************/ -void msDecryptStringWithKey(const unsigned char *key, const char *in, char *out) -{ +void msDecryptStringWithKey(const unsigned char *key, const char *in, + char *out) { ms_uint32 v[4], w[4]; const ms_uint32 *k; int last_block = MS_FALSE; @@ -361,9 +354,9 @@ void msDecryptStringWithKey(const unsigned char *key, const char *in, char *out) /* Casting the key this way is safe only as long as longs are 4 bytes * on this platform */ assert(sizeof(ms_uint32) == 4); - k = (const ms_uint32 *) key; + k = (const ms_uint32 *)key; - while(!last_block) { + while (!last_block) { int i; /* decipher() takes v[2] (64 bits) as input. * Copy bytes from in[] to the v[2] input array (pair of 4 bytes) @@ -376,7 +369,7 @@ void msDecryptStringWithKey(const unsigned char *key, const char *in, char *out) last_block = MS_TRUE; else { in += 8; - if (msHexDecode(in, (unsigned char *)(v+1), 8) != 4) + if (msHexDecode(in, (unsigned char *)(v + 1), 8) != 4) last_block = MS_TRUE; else in += 8; @@ -386,7 +379,7 @@ void msDecryptStringWithKey(const unsigned char *key, const char *in, char *out) decipher(v, w, k); /* Copy the results to out[] */ - for(i=0; i<2; i++) { + for (i = 0; i < 2; i++) { *out++ = (w[i] & 0x000000ff); *out++ = (w[i] & 0x0000ff00) >> 8; *out++ = (w[i] & 0x00ff0000) >> 16; @@ -410,8 +403,7 @@ void msDecryptStringWithKey(const unsigned char *key, const char *in, char *out) * **********************************************************************/ -char *msDecryptStringTokens(mapObj *map, const char *in) -{ +char *msDecryptStringTokens(mapObj *map, const char *in) { char *outbuf, *out; if (map == NULL) { @@ -421,13 +413,13 @@ char *msDecryptStringTokens(mapObj *map, const char *in) /* Start with a copy of the string. Decryption can only result in * a string with the same or shorter length */ - if ((outbuf = (char *)malloc((strlen(in)+1)*sizeof(char))) == NULL) { + if ((outbuf = (char *)malloc((strlen(in) + 1) * sizeof(char))) == NULL) { msSetError(MS_MEMERR, NULL, "msDecryptStringTokens()"); return NULL; } out = outbuf; - while(*in != '\0') { + while (*in != '\0') { if (*in == '{') { /* Possibly beginning of a token, look for closing bracket ** and make sure all chars in between are valid hex encoding chars @@ -435,12 +427,11 @@ char *msDecryptStringTokens(mapObj *map, const char *in) const char *pszStart, *pszEnd; int valid_token = MS_FALSE; - pszStart = in+1; - if ( (pszEnd = strchr(pszStart, '}')) != NULL && - pszEnd - pszStart > 1) { + pszStart = in + 1; + if ((pszEnd = strchr(pszStart, '}')) != NULL && pszEnd - pszStart > 1) { const char *pszTmp; valid_token = MS_TRUE; - for(pszTmp = pszStart; pszTmp < pszEnd; pszTmp++) { + for (pszTmp = pszStart; pszTmp < pszEnd; pszTmp++) { if (!isxdigit(*pszTmp)) { valid_token = MS_FALSE; break; @@ -460,13 +451,13 @@ char *msDecryptStringTokens(mapObj *map, const char *in) if (msLoadEncryptionKey(map) != MS_SUCCESS) return NULL; - pszTmp = (char*)malloc( (pszEnd-pszStart+1)*sizeof(char)); - strlcpy(pszTmp, pszStart, (pszEnd-pszStart)+1); + pszTmp = (char *)malloc((pszEnd - pszStart + 1) * sizeof(char)); + strlcpy(pszTmp, pszStart, (pszEnd - pszStart) + 1); msDecryptStringWithKey(map->encryption_key, pszTmp, out); out += strlen(out); - in = pszEnd+1; + in = pszEnd + 1; free(pszTmp); } else { /* Not a valid token, just copy the '{' and keep going */ @@ -482,7 +473,6 @@ char *msDecryptStringTokens(mapObj *map, const char *in) return outbuf; } - #ifdef TEST_MAPCRYPTO /* Test for mapcrypto.c functions. To run these tests, use the following @@ -493,10 +483,9 @@ test_mapcrypto: $(LIBMAP_STATIC) mapcrypto.c ** */ -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { const unsigned char bytes_in[] = {0x12, 0x34, 0xff, 0x00, 0x44, 0x22}; - unsigned char bytes_out[8], encryption_key[MS_ENCRYPTION_KEY_SIZE*2+1]; + unsigned char bytes_out[8], encryption_key[MS_ENCRYPTION_KEY_SIZE * 2 + 1]; char string_buf[256], string_buf2[256]; int numbytes = 0; @@ -511,29 +500,30 @@ int main(int argc, char *argv[]) */ memset(bytes_out, 0, 8); numbytes = msHexDecode(string_buf, bytes_out, -1); - printf("msHexDecode(%s, -1) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", - string_buf, numbytes, - bytes_out[0], bytes_out[1], bytes_out[2], bytes_out[3], - bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); + printf( + "msHexDecode(%s, -1) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", + string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2], + bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); memset(bytes_out, 0, 8); numbytes = msHexDecode(string_buf, bytes_out, 4); - printf("msHexDecode(%s, 4) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", - string_buf, numbytes, - bytes_out[0], bytes_out[1], bytes_out[2], bytes_out[3], - bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); + printf( + "msHexDecode(%s, 4) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", + string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2], + bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); memset(bytes_out, 0, 8); numbytes = msHexDecode(string_buf, bytes_out, 20); - printf("msHexDecode(%s, 20) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", - string_buf, numbytes, - bytes_out[0], bytes_out[1], bytes_out[2], bytes_out[3], - bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); + printf( + "msHexDecode(%s, 20) = %d, bytes_out = %x, %x, %x, %x, %x, %x, %x, %x\n", + string_buf, numbytes, bytes_out[0], bytes_out[1], bytes_out[2], + bytes_out[3], bytes_out[4], bytes_out[5], bytes_out[6], bytes_out[7]); /* ** Test loading encryption key */ - if (msReadEncryptionKeyFromFile("/tmp/test.key", encryption_key) != MS_SUCCESS) { + if (msReadEncryptionKeyFromFile("/tmp/test.key", encryption_key) != + MS_SUCCESS) { printf("msReadEncryptionKeyFromFile() = MS_FAILURE\n"); printf("Aborting tests!\n"); msWriteError(stderr); @@ -552,21 +542,24 @@ int main(int argc, char *argv[]) printf("msEncryptStringWithKey('test1234') returned '%s'\n", string_buf); msDecryptStringWithKey(encryption_key, string_buf, string_buf2); - printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, string_buf2); + printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, + string_buf2); /* Next with an 1 byte input string */ msEncryptStringWithKey(encryption_key, "t", string_buf); printf("msEncryptStringWithKey('t') returned '%s'\n", string_buf); msDecryptStringWithKey(encryption_key, string_buf, string_buf2); - printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, string_buf2); + printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, + string_buf2); /* Next with an 12 bytes input string */ msEncryptStringWithKey(encryption_key, "test123456", string_buf); printf("msEncryptStringWithKey('test123456') returned '%s'\n", string_buf); msDecryptStringWithKey(encryption_key, string_buf, string_buf2); - printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, string_buf2); + printf("msDecryptStringWithKey('%s') returned '%s'\n", string_buf, + string_buf2); /* ** Test decryption with tokens @@ -586,8 +579,8 @@ int main(int argc, char *argv[]) msWriteError(stderr); return -1; } else { - printf("msDecryptStringTokens('%s') returned '%s'\n", - string_buf2, pszBuf); + printf("msDecryptStringTokens('%s') returned '%s'\n", string_buf2, + pszBuf); } msFree(pszBuf); msFreeMap(map); @@ -596,5 +589,4 @@ int main(int argc, char *argv[]) return 0; } - #endif /* TEST_MAPCRYPTO */ diff --git a/mapdebug.c b/mapdebug.c index 1ef0788b1f..d03cfdea7e 100644 --- a/mapdebug.c +++ b/mapdebug.c @@ -27,7 +27,6 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #include "mapserver.h" #include "maperror.h" #include "mapthread.h" @@ -50,16 +49,11 @@ #include /* OutputDebugStringA() */ #endif - - - #ifndef USE_THREAD -debugInfoObj *msGetDebugInfoObj() -{ - static debugInfoObj debuginfo = {MS_DEBUGLEVEL_ERRORSONLY, - MS_DEBUGMODE_OFF, NULL, NULL - }; +debugInfoObj *msGetDebugInfoObj() { + static debugInfoObj debuginfo = {MS_DEBUGLEVEL_ERRORSONLY, MS_DEBUGMODE_OFF, + NULL, NULL}; return &debuginfo; } @@ -67,32 +61,32 @@ debugInfoObj *msGetDebugInfoObj() static debugInfoObj *debuginfo_list = NULL; -debugInfoObj *msGetDebugInfoObj() -{ +debugInfoObj *msGetDebugInfoObj() { debugInfoObj *link; - void* thread_id; + void *thread_id; debugInfoObj *ret_obj; - msAcquireLock( TLOCK_DEBUGOBJ ); + msAcquireLock(TLOCK_DEBUGOBJ); thread_id = msGetThreadId(); /* find link for this thread */ - for( link = debuginfo_list; - link != NULL && link->thread_id != thread_id - && link->next != NULL && link->next->thread_id != thread_id; - link = link->next ) {} + for (link = debuginfo_list; + link != NULL && link->thread_id != thread_id && link->next != NULL && + link->next->thread_id != thread_id; + link = link->next) { + } /* If the target thread link is already at the head of the list were ok */ - if( debuginfo_list != NULL && debuginfo_list->thread_id == thread_id ) { + if (debuginfo_list != NULL && debuginfo_list->thread_id == thread_id) { } /* We don't have one ... initialize one. */ - else if( link == NULL || link->next == NULL ) { + else if (link == NULL || link->next == NULL) { debugInfoObj *new_link; - new_link = (debugInfoObj *) msSmallMalloc(sizeof(debugInfoObj)); + new_link = (debugInfoObj *)msSmallMalloc(sizeof(debugInfoObj)); new_link->next = debuginfo_list; new_link->thread_id = thread_id; new_link->global_debug_level = MS_DEBUGLEVEL_ERRORSONLY; @@ -113,13 +107,12 @@ debugInfoObj *msGetDebugInfoObj() ret_obj = debuginfo_list; - msReleaseLock( TLOCK_DEBUGOBJ ); + msReleaseLock(TLOCK_DEBUGOBJ); return ret_obj; } #endif - /* msSetErrorFile() ** ** Set output target, ready to write to it, open file if necessary @@ -130,8 +123,7 @@ debugInfoObj *msGetDebugInfoObj() ** ** Returns MS_SUCCESS/MS_FAILURE */ -int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath) -{ +int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath) { char extended_path[MS_MAXPATHLEN]; debugInfoObj *debuginfo = msGetDebugInfoObj(); @@ -139,7 +131,7 @@ int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath) strcmp(pszErrorFile, "stdout") != 0 && strcmp(pszErrorFile, "windowsdebug") != 0) { /* Try to make the path relative */ - if(msBuildPath(extended_path, pszRelToPath, pszErrorFile) == NULL) + if (msBuildPath(extended_path, pszRelToPath, pszErrorFile) == NULL) return MS_FAILURE; pszErrorFile = extended_path; } @@ -171,13 +163,17 @@ int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath) debuginfo->fp = NULL; debuginfo->debug_mode = MS_DEBUGMODE_WINDOWSDEBUG; #else - msSetError(MS_MISCERR, "'MS_ERRORFILE windowsdebug' is available only on Windows platforms.", "msSetErrorFile()"); + msSetError( + MS_MISCERR, + "'MS_ERRORFILE windowsdebug' is available only on Windows platforms.", + "msSetErrorFile()"); return MS_FAILURE; #endif } else { debuginfo->fp = fopen(pszErrorFile, "a"); if (debuginfo->fp == NULL) { - msSetError(MS_MISCERR, "Failed to open MS_ERRORFILE %s", "msSetErrorFile()", pszErrorFile); + msSetError(MS_MISCERR, "Failed to open MS_ERRORFILE %s", + "msSetErrorFile()", pszErrorFile); return MS_FAILURE; } debuginfo->errorfile = msStrdup(pszErrorFile); @@ -191,8 +187,7 @@ int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath) ** ** Close current output file (if one is open) and reset related members */ -void msCloseErrorFile() -{ +void msCloseErrorFile() { debugInfoObj *debuginfo = msGetDebugInfoObj(); if (debuginfo && debuginfo->debug_mode != MS_DEBUGMODE_OFF) { @@ -212,16 +207,13 @@ void msCloseErrorFile() } } - - /* msGetErrorFile() ** ** Returns name of current error file ** ** Returns NULL if not set. */ -const char *msGetErrorFile() -{ +const char *msGetErrorFile() { debugInfoObj *debuginfo = msGetDebugInfoObj(); if (debuginfo) @@ -235,16 +227,14 @@ const char *msGetErrorFile() ** the context of mapObj or layerObj. ** */ -void msSetGlobalDebugLevel(int level) -{ +void msSetGlobalDebugLevel(int level) { debugInfoObj *debuginfo = msGetDebugInfoObj(); if (debuginfo) debuginfo->global_debug_level = (debugLevel)level; } -debugLevel msGetGlobalDebugLevel() -{ +debugLevel msGetGlobalDebugLevel() { debugInfoObj *debuginfo = msGetDebugInfoObj(); if (debuginfo) @@ -253,67 +243,63 @@ debugLevel msGetGlobalDebugLevel() return MS_DEBUGLEVEL_ERRORSONLY; } - /* msDebugInitFromEnv() ** ** Init debug state from MS_ERRORFILE and MS_DEBUGLEVEL env vars if set ** ** Returns MS_SUCCESS/MS_FAILURE */ -int msDebugInitFromEnv() -{ +int msDebugInitFromEnv() { const char *val; - if( (val=CPLGetConfigOption("MS_ERRORFILE", NULL)) != NULL ) { - if ( msSetErrorFile(val, NULL) != MS_SUCCESS ) + if ((val = CPLGetConfigOption("MS_ERRORFILE", NULL)) != NULL) { + if (msSetErrorFile(val, NULL) != MS_SUCCESS) return MS_FAILURE; } - if( (val=CPLGetConfigOption("MS_DEBUGLEVEL", NULL)) != NULL ) + if ((val = CPLGetConfigOption("MS_DEBUGLEVEL", NULL)) != NULL) msSetGlobalDebugLevel(atoi(val)); return MS_SUCCESS; } - /* msDebugCleanup() ** ** Called by msCleanup to remove info related to this thread. */ -void msDebugCleanup() -{ +void msDebugCleanup() { /* make sure file is closed */ msCloseErrorFile(); #ifdef USE_THREAD { - void* thread_id = msGetThreadId(); + void *thread_id = msGetThreadId(); debugInfoObj *link; - msAcquireLock( TLOCK_DEBUGOBJ ); + msAcquireLock(TLOCK_DEBUGOBJ); /* find link for this thread */ - for( link = debuginfo_list; - link != NULL && link->thread_id != thread_id - && link->next != NULL && link->next->thread_id != thread_id; - link = link->next ) {} + for (link = debuginfo_list; + link != NULL && link->thread_id != thread_id && link->next != NULL && + link->next->thread_id != thread_id; + link = link->next) { + } - if( link->thread_id == thread_id ) { + if (link->thread_id == thread_id) { /* presumably link is at head of list. */ - if( debuginfo_list == link ) + if (debuginfo_list == link) debuginfo_list = link->next; - free( link ); - } else if( link->next != NULL && link->next->thread_id == thread_id ) { + free(link); + } else if (link->next != NULL && link->next->thread_id == thread_id) { debugInfoObj *next_link = link->next; link->next = link->next->next; - free( next_link ); + free(next_link); } - msReleaseLock( TLOCK_DEBUGOBJ ); + msReleaseLock(TLOCK_DEBUGOBJ); } #endif - } /* msDebug() @@ -322,19 +308,18 @@ void msDebugCleanup() ** (see msSetErrorFile()) ** */ -void msDebug( const char * pszFormat, ... ) -{ +void msDebug(const char *pszFormat, ...) { va_list args; debugInfoObj *debuginfo = msGetDebugInfoObj(); char szMessage[MESSAGELENGTH]; if (debuginfo == NULL || debuginfo->debug_mode == MS_DEBUGMODE_OFF) - return; /* Don't waste time here! */ + return; /* Don't waste time here! */ va_start(args, pszFormat); - vsnprintf( szMessage, MESSAGELENGTH, pszFormat, args ); + vsnprintf(szMessage, MESSAGELENGTH, pszFormat, args); va_end(args); - szMessage[MESSAGELENGTH-1] = '\0'; + szMessage[MESSAGELENGTH - 1] = '\0'; msRedactCredentials(szMessage); @@ -351,8 +336,8 @@ void msDebug( const char * pszFormat, ... ) time_t t; msGettimeofday(&tv, NULL); t = tv.tv_sec; - msIO_fprintf(debuginfo->fp, "[%s].%ld ", - msStringChop(ctime(&t)), (long)tv.tv_usec); + msIO_fprintf(debuginfo->fp, "[%s].%ld ", msStringChop(ctime(&t)), + (long)tv.tv_usec); } msIO_fprintf(debuginfo->fp, "%s", szMessage); @@ -363,16 +348,11 @@ void msDebug( const char * pszFormat, ... ) OutputDebugStringA(szMessage); } #endif - } - /* msDebug2() ** ** Variadic function with no operation ** */ -void msDebug2( int level, ... ) -{ - (void)level; -} +void msDebug2(int level, ...) { (void)level; } diff --git a/mapdraw.c b/mapdraw.c index 431816562d..4c66440d5c 100644 --- a/mapdraw.c +++ b/mapdraw.c @@ -35,7 +35,6 @@ #include "mapfile.h" #include "mapows.h" - /* msPrepareImage() * * Returns a new imageObj ready for rendering the current map. @@ -44,69 +43,76 @@ * msMapRestoreRealExtent() once they are done with the image. * This should be set to MS_TRUE only when called from msDrawMap(), see bug 945. */ -imageObj *msPrepareImage(mapObj *map, int allow_nonsquare) -{ +imageObj *msPrepareImage(mapObj *map, int allow_nonsquare) { int i, status; - imageObj *image=NULL; + imageObj *image = NULL; double geo_cellsize; - if(map->width == -1 || map->height == -1) { - msSetError(MS_MISCERR, "Image dimensions not specified.", "msPrepareImage()"); - return(NULL); + if (map->width == -1 || map->height == -1) { + msSetError(MS_MISCERR, "Image dimensions not specified.", + "msPrepareImage()"); + return (NULL); } msFreeLabelCache(&(map->labelcache)); - msInitLabelCache(&(map->labelcache)); /* this clears any previously allocated cache */ + msInitLabelCache( + &(map->labelcache)); /* this clears any previously allocated cache */ /* clear any previously created mask layer images */ - for(i=0; inumlayers; i++) { - if(GET_LAYER(map, i)->maskimage) { + for (i = 0; i < map->numlayers; i++) { + if (GET_LAYER(map, i)->maskimage) { msFreeImage(GET_LAYER(map, i)->maskimage); GET_LAYER(map, i)->maskimage = NULL; } } - status = msValidateContexts(map); /* make sure there are no recursive REQUIRES or LABELREQUIRES expressions */ - if(status != MS_SUCCESS) return NULL; + status = msValidateContexts(map); /* make sure there are no recursive REQUIRES + or LABELREQUIRES expressions */ + if (status != MS_SUCCESS) + return NULL; - if(!map->outputformat) { + if (!map->outputformat) { msSetError(MS_IMGERR, "Map outputformat not set!", "msPrepareImage()"); - return(NULL); + return (NULL); } else if (MS_RENDERER_PLUGIN(map->outputformat)) { rendererVTableObj *renderer = map->outputformat->vtable; colorObj *bg = &map->imagecolor; - map->imagecolor.alpha=255; + map->imagecolor.alpha = 255; - image = renderer->createImage(map->width, map->height, map->outputformat,bg); + image = + renderer->createImage(map->width, map->height, map->outputformat, bg); if (image == NULL) - return(NULL); + return (NULL); image->format = map->outputformat; image->format->refcount++; image->width = map->width; image->height = map->height; - + image->resolution = map->resolution; - image->resolutionfactor = map->resolution/map->defresolution; + image->resolutionfactor = map->resolution / map->defresolution; if (map->web.imagepath) image->imagepath = msStrdup(map->web.imagepath); if (map->web.imageurl) image->imageurl = msStrdup(map->web.imageurl); - } else if( MS_RENDERER_IMAGEMAP(map->outputformat) ) { + } else if (MS_RENDERER_IMAGEMAP(map->outputformat)) { image = msImageCreateIM(map->width, map->height, map->outputformat, - map->web.imagepath, map->web.imageurl, map->resolution, map->defresolution); - } else if( MS_RENDERER_RAWDATA(map->outputformat) ) { - image = msImageCreate(map->width, map->height, map->outputformat, - map->web.imagepath, map->web.imageurl, map->resolution, map->defresolution, &map->imagecolor); + map->web.imagepath, map->web.imageurl, + map->resolution, map->defresolution); + } else if (MS_RENDERER_RAWDATA(map->outputformat)) { + image = + msImageCreate(map->width, map->height, map->outputformat, + map->web.imagepath, map->web.imageurl, map->resolution, + map->defresolution, &map->imagecolor); } else { image = NULL; } - - if(!image) { + + if (!image) { msSetError(MS_IMGERR, "Unable to initialize image.", "msPrepareImage()"); - return(NULL); + return (NULL); } - + image->map = map; /* @@ -115,135 +121,151 @@ imageObj *msPrepareImage(mapObj *map, int allow_nonsquare) * * If allow_nonsquare is set to MS_TRUE then the caller should call * msMapRestoreRealExtent() once they are done with the image. - * This should be set to MS_TRUE only when called from msDrawMap(), see bug 945. + * This should be set to MS_TRUE only when called from msDrawMap(), see bug + * 945. */ - if( allow_nonsquare && msTestConfigOption( map, "MS_NONSQUARE", MS_FALSE ) ) { - double cellsize_x = (map->extent.maxx - map->extent.minx)/map->width; - double cellsize_y = (map->extent.maxy - map->extent.miny)/map->height; + if (allow_nonsquare && msTestConfigOption(map, "MS_NONSQUARE", MS_FALSE)) { + double cellsize_x = (map->extent.maxx - map->extent.minx) / map->width; + double cellsize_y = (map->extent.maxy - map->extent.miny) / map->height; - if( cellsize_y != 0.0 - && (fabs(cellsize_x/cellsize_y) > 1.00001 - || fabs(cellsize_x/cellsize_y) < 0.99999) ) { + if (cellsize_y != 0.0 && (fabs(cellsize_x / cellsize_y) > 1.00001 || + fabs(cellsize_x / cellsize_y) < 0.99999)) { map->gt.need_geotransform = MS_TRUE; if (map->debug) - msDebug( "msDrawMap(): kicking into non-square pixel preserving mode.\n" ); + msDebug( + "msDrawMap(): kicking into non-square pixel preserving mode.\n"); } - map->cellsize = (cellsize_x*0.5 + cellsize_y*0.5); + map->cellsize = (cellsize_x * 0.5 + cellsize_y * 0.5); } else - map->cellsize = msAdjustExtent(&(map->extent),map->width,map->height); + map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - status = msCalculateScale(map->extent,map->units,map->width,map->height, map->resolution, &map->scaledenom); - if(status != MS_SUCCESS) { + status = msCalculateScale(map->extent, map->units, map->width, map->height, + map->resolution, &map->scaledenom); + if (status != MS_SUCCESS) { msFreeImage(image); - return(NULL); + return (NULL); } /* update geotransform based on adjusted extent. */ - msMapComputeGeotransform( map ); + msMapComputeGeotransform(map); /* Do we need to fake out stuff for rotated support? */ - if( map->gt.need_geotransform ) - msMapSetFakedExtent( map ); + if (map->gt.need_geotransform) + msMapSetFakedExtent(map); /* We will need a cellsize that represents a real georeferenced */ /* coordinate cellsize here, so compute it from saved extents. */ geo_cellsize = map->cellsize; - if( map->gt.need_geotransform == MS_TRUE ) { - double cellsize_x = (map->saved_extent.maxx - map->saved_extent.minx) - / map->width; - double cellsize_y = (map->saved_extent.maxy - map->saved_extent.miny) - / map->height; - - geo_cellsize = sqrt(cellsize_x*cellsize_x + cellsize_y*cellsize_y) - / sqrt(2.0); + if (map->gt.need_geotransform == MS_TRUE) { + double cellsize_x = + (map->saved_extent.maxx - map->saved_extent.minx) / map->width; + double cellsize_y = + (map->saved_extent.maxy - map->saved_extent.miny) / map->height; + + geo_cellsize = + sqrt(cellsize_x * cellsize_x + cellsize_y * cellsize_y) / sqrt(2.0); } /* compute layer/class/style/label scale factors now */ - for(int lid=0; lidnumlayers; lid++) { - layerObj * layer = GET_LAYER(map, lid); - if(layer->sizeunits != MS_PIXELS) - layer->scalefactor = (msInchesPerUnit(layer->sizeunits,0)/msInchesPerUnit(map->units,0)) / geo_cellsize; - else if(layer->symbolscaledenom > 0 && map->scaledenom > 0) - layer->scalefactor = layer->symbolscaledenom/map->scaledenom*map->resolution/map->defresolution; + for (int lid = 0; lid < map->numlayers; lid++) { + layerObj *layer = GET_LAYER(map, lid); + if (layer->sizeunits != MS_PIXELS) + layer->scalefactor = (msInchesPerUnit(layer->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + geo_cellsize; + else if (layer->symbolscaledenom > 0 && map->scaledenom > 0) + layer->scalefactor = layer->symbolscaledenom / map->scaledenom * + map->resolution / map->defresolution; else - layer->scalefactor = map->resolution/map->defresolution; - for (int cid=0 ; cidnumclasses ; cid++) - { - classObj * class = GET_CLASS(map, lid, cid); + layer->scalefactor = map->resolution / map->defresolution; + for (int cid = 0; cid < layer->numclasses; cid++) { + classObj *class = GET_CLASS(map, lid, cid); if (class->sizeunits == MS_INHERIT) class->scalefactor = layer->scalefactor; else if (class->sizeunits != MS_PIXELS) - class->scalefactor = (msInchesPerUnit(class->sizeunits,0)/msInchesPerUnit(map->units,0)) / geo_cellsize; + class->scalefactor = (msInchesPerUnit(class->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + geo_cellsize; else if (layer->symbolscaledenom > 0 && map->scaledenom > 0) - class->scalefactor = layer->symbolscaledenom/map->scaledenom*map->resolution/map->defresolution; + class->scalefactor = layer->symbolscaledenom / map->scaledenom * + map->resolution / map->defresolution; else - class->scalefactor = map->resolution/map->defresolution; - for (int sid=0 ; sidnumstyles ; sid++) - { - styleObj * style = class->styles[sid]; + class->scalefactor = map->resolution / map->defresolution; + for (int sid = 0; sid < class->numstyles; sid++) { + styleObj *style = class->styles[sid]; if (style->sizeunits == MS_INHERIT) style->scalefactor = class->scalefactor; else if (style->sizeunits != MS_PIXELS) - style->scalefactor = (msInchesPerUnit(style->sizeunits,0)/msInchesPerUnit(map->units,0)) / geo_cellsize; + style->scalefactor = (msInchesPerUnit(style->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + geo_cellsize; else if (layer->symbolscaledenom > 0 && map->scaledenom > 0) - style->scalefactor = layer->symbolscaledenom/map->scaledenom*map->resolution/map->defresolution; + style->scalefactor = layer->symbolscaledenom / map->scaledenom * + map->resolution / map->defresolution; else - style->scalefactor = map->resolution/map->defresolution; + style->scalefactor = map->resolution / map->defresolution; } - for (int sid=0 ; sidnumlabels ; sid++) - { - labelObj * label = class->labels[sid]; + for (int sid = 0; sid < class->numlabels; sid++) { + labelObj *label = class->labels[sid]; if (label->sizeunits == MS_INHERIT) label->scalefactor = class->scalefactor; else if (label->sizeunits != MS_PIXELS) - label->scalefactor = (msInchesPerUnit(label->sizeunits,0)/msInchesPerUnit(map->units,0)) / geo_cellsize; + label->scalefactor = (msInchesPerUnit(label->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + geo_cellsize; else if (layer->symbolscaledenom > 0 && map->scaledenom > 0) - label->scalefactor = layer->symbolscaledenom/map->scaledenom*map->resolution/map->defresolution; + label->scalefactor = layer->symbolscaledenom / map->scaledenom * + map->resolution / map->defresolution; else - label->scalefactor = map->resolution/map->defresolution; - for (int lsid=0 ; lsidnumstyles ; lsid++) - { - styleObj * lstyle = label->styles[lsid]; + label->scalefactor = map->resolution / map->defresolution; + for (int lsid = 0; lsid < label->numstyles; lsid++) { + styleObj *lstyle = label->styles[lsid]; if (lstyle->sizeunits == MS_INHERIT) lstyle->scalefactor = label->scalefactor; else if (lstyle->sizeunits != MS_PIXELS) - lstyle->scalefactor = (msInchesPerUnit(lstyle->sizeunits,0)/msInchesPerUnit(map->units,0)) / geo_cellsize; + lstyle->scalefactor = (msInchesPerUnit(lstyle->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + geo_cellsize; else if (layer->symbolscaledenom > 0 && map->scaledenom > 0) - lstyle->scalefactor = layer->symbolscaledenom/map->scaledenom*map->resolution/map->defresolution; + lstyle->scalefactor = layer->symbolscaledenom / map->scaledenom * + map->resolution / map->defresolution; else - lstyle->scalefactor = map->resolution/map->defresolution; + lstyle->scalefactor = map->resolution / map->defresolution; } } } } - image->refpt.x = MS_MAP2IMAGE_X_IC_DBL(0, map->extent.minx, 1.0/map->cellsize); - image->refpt.y = MS_MAP2IMAGE_Y_IC_DBL(0, map->extent.maxy, 1.0/map->cellsize); + image->refpt.x = + MS_MAP2IMAGE_X_IC_DBL(0, map->extent.minx, 1.0 / map->cellsize); + image->refpt.y = + MS_MAP2IMAGE_Y_IC_DBL(0, map->extent.maxy, 1.0 / map->cellsize); return image; - } -static int msCompositeRasterBuffer(mapObj *map, imageObj *img, rasterBufferObj *rb, LayerCompositer *comp) { +static int msCompositeRasterBuffer(mapObj *map, imageObj *img, + rasterBufferObj *rb, LayerCompositer *comp) { int ret = MS_SUCCESS; - if(MS_IMAGE_RENDERER(img)->compositeRasterBuffer) { - while(comp && ret == MS_SUCCESS) { + if (MS_IMAGE_RENDERER(img)->compositeRasterBuffer) { + while (comp && ret == MS_SUCCESS) { rasterBufferObj *rb_ptr = rb; CompositingFilter *filter = comp->filter; - if(filter && comp->next) { - /* if we have another compositor to apply, then we need to copy the rasterBufferObj. Otherwise - * we can work on it directly */ - rb_ptr = (rasterBufferObj*)msSmallCalloc(sizeof(rasterBufferObj),1); - msCopyRasterBuffer(rb_ptr,rb); - } - while(filter && ret == MS_SUCCESS) { - ret = msApplyCompositingFilter(map,rb_ptr,filter); + if (filter && comp->next) { + /* if we have another compositor to apply, then we need to copy the + * rasterBufferObj. Otherwise we can work on it directly */ + rb_ptr = (rasterBufferObj *)msSmallCalloc(sizeof(rasterBufferObj), 1); + msCopyRasterBuffer(rb_ptr, rb); + } + while (filter && ret == MS_SUCCESS) { + ret = msApplyCompositingFilter(map, rb_ptr, filter); filter = filter->next; } - if(ret == MS_SUCCESS) - ret = MS_IMAGE_RENDERER(img)->compositeRasterBuffer(img,rb_ptr,comp->comp_op, comp->opacity); - if(rb_ptr != rb) { + if (ret == MS_SUCCESS) + ret = MS_IMAGE_RENDERER(img)->compositeRasterBuffer( + img, rb_ptr, comp->comp_op, comp->opacity); + if (rb_ptr != rb) { msFreeRasterBuffer(rb_ptr); msFree(rb_ptr); } @@ -257,15 +279,15 @@ static int msCompositeRasterBuffer(mapObj *map, imageObj *img, rasterBufferObj * /* * Generic function to render the map file. - * The type of the image created is based on the imagetype parameter in the map file. + * The type of the image created is based on the imagetype parameter in the map + * file. * * mapObj *map - map object loaded in MapScript or via a mapfile to use * int querymap - is this map the result of a query operation, MS_TRUE|MS_FALSE -*/ -imageObj *msDrawMap(mapObj *map, int querymap) -{ + */ +imageObj *msDrawMap(mapObj *map, int querymap) { int i; - layerObj *lp=NULL; + layerObj *lp = NULL; int status = MS_FAILURE; imageObj *image = NULL; struct mstimeval mapstarttime = {0}, mapendtime = {0}; @@ -273,85 +295,92 @@ imageObj *msDrawMap(mapObj *map, int querymap) #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) enum MS_CONNECTION_TYPE lastconnectiontype; - httpRequestObj *pasOWSReqInfo=NULL; - int numOWSLayers=0; - int numOWSRequests=0; + httpRequestObj *pasOWSReqInfo = NULL; + int numOWSLayers = 0; + int numOWSRequests = 0; wmsParamsObj sLastWMSParams; #endif - if(map->debug >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&mapstarttime, NULL); + if (map->debug >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&mapstarttime, NULL); - if(querymap) { /* use queryMapObj image dimensions */ - if(map->querymap.width > 0 && map->querymap.width <= map->maxsize) map->width = map->querymap.width; - if(map->querymap.height > 0 && map->querymap.height <= map->maxsize) map->height = map->querymap.height; + if (querymap) { /* use queryMapObj image dimensions */ + if (map->querymap.width > 0 && map->querymap.width <= map->maxsize) + map->width = map->querymap.width; + if (map->querymap.height > 0 && map->querymap.height <= map->maxsize) + map->height = map->querymap.height; } msApplyMapConfigOptions(map); image = msPrepareImage(map, MS_TRUE); - if(!image) { + if (!image) { msSetError(MS_IMGERR, "Unable to initialize image.", "msDrawMap()"); - return(NULL); + return (NULL); } - if( map->debug >= MS_DEBUGLEVEL_DEBUG ) - msDebug( "msDrawMap(): rendering using outputformat named %s (%s).\n", - map->outputformat->name, - map->outputformat->driver ); + if (map->debug >= MS_DEBUGLEVEL_DEBUG) + msDebug("msDrawMap(): rendering using outputformat named %s (%s).\n", + map->outputformat->name, map->outputformat->driver); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Time the OWS query phase */ - if(map->debug >= MS_DEBUGLEVEL_TUNING ) msGettimeofday(&starttime, NULL); + if (map->debug >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&starttime, NULL); /* How many OWS (WMS/WFS) layers do we have to draw? * Note: numOWSLayers is the number of actual layers and numOWSRequests is * the number of HTTP requests which could be lower if multiple layers * are merged into the same request. */ - numOWSLayers=0; - for(i=0; inumlayers; i++) { - if(map->layerorder[i] == -1 ) - continue; + numOWSLayers = 0; + for (i = 0; i < map->numlayers; i++) { + if (map->layerorder[i] == -1) + continue; - lp = GET_LAYER(map,map->layerorder[i]); - if( lp->connectiontype != MS_WMS && - lp->connectiontype != MS_WFS ) { - continue; - } - numOWSLayers++; + lp = GET_LAYER(map, map->layerorder[i]); + if (lp->connectiontype != MS_WMS && lp->connectiontype != MS_WFS) { + continue; + } + numOWSLayers++; } if (numOWSLayers > 0) { /* Alloc and init pasOWSReqInfo... */ - pasOWSReqInfo = (httpRequestObj *)malloc(numOWSLayers*sizeof(httpRequestObj)); + pasOWSReqInfo = + (httpRequestObj *)malloc(numOWSLayers * sizeof(httpRequestObj)); if (pasOWSReqInfo == NULL) { - msSetError(MS_MEMERR, "Allocation of httpRequestObj failed.", "msDrawMap()"); + msSetError(MS_MEMERR, "Allocation of httpRequestObj failed.", + "msDrawMap()"); return NULL; } msHTTPInitRequestObj(pasOWSReqInfo, numOWSLayers); msInitWmsParamsObj(&sLastWMSParams); - /* Pre-download all WMS/WFS layers in parallel before starting to draw map */ + /* Pre-download all WMS/WFS layers in parallel before starting to draw map + */ lastconnectiontype = MS_SHAPEFILE; - for(i=0; inumlayers; i++) { - if(map->layerorder[i] == -1 ) + for (i = 0; i < map->numlayers; i++) { + if (map->layerorder[i] == -1) continue; - lp = GET_LAYER(map,map->layerorder[i]); - if( lp->connectiontype != MS_WMS && - lp->connectiontype != MS_WFS ) { + lp = GET_LAYER(map, map->layerorder[i]); + if (lp->connectiontype != MS_WMS && lp->connectiontype != MS_WFS) { continue; } - if( !msLayerIsVisible(map, lp) ) + if (!msLayerIsVisible(map, lp)) continue; #ifdef USE_WMS_LYR - if(lp->connectiontype == MS_WMS) { - if(msPrepareWMSLayerRequest(map->layerorder[i], map, lp, 1, lastconnectiontype, &sLastWMSParams, 0, 0, 0, NULL, pasOWSReqInfo, &numOWSRequests) == MS_FAILURE) { + if (lp->connectiontype == MS_WMS) { + if (msPrepareWMSLayerRequest(map->layerorder[i], map, lp, 1, + lastconnectiontype, &sLastWMSParams, 0, 0, + 0, NULL, pasOWSReqInfo, + &numOWSRequests) == MS_FAILURE) { msFreeWmsParamsObj(&sLastWMSParams); msFreeImage(image); msFree(pasOWSReqInfo); @@ -361,8 +390,9 @@ imageObj *msDrawMap(mapObj *map, int querymap) #endif #ifdef USE_WFS_LYR - if(lp->connectiontype == MS_WFS) { - if(msPrepareWFSLayerRequest(map->layerorder[i], map, lp, pasOWSReqInfo, &numOWSRequests) == MS_FAILURE) { + if (lp->connectiontype == MS_WFS) { + if (msPrepareWFSLayerRequest(map->layerorder[i], map, lp, pasOWSReqInfo, + &numOWSRequests) == MS_FAILURE) { msFreeWmsParamsObj(&sLastWMSParams); msFreeImage(image); msFree(pasOWSReqInfo); @@ -377,73 +407,86 @@ imageObj *msDrawMap(mapObj *map, int querymap) msFreeWmsParamsObj(&sLastWMSParams); } /* if numOWSLayers > 0 */ - if(numOWSRequests && msOWSExecuteRequests(pasOWSReqInfo, numOWSRequests, map, MS_TRUE) == MS_FAILURE) { + if (numOWSRequests && msOWSExecuteRequests(pasOWSReqInfo, numOWSRequests, map, + MS_TRUE) == MS_FAILURE) { msFreeImage(image); msFree(pasOWSReqInfo); return NULL; } - if(map->debug >= MS_DEBUGLEVEL_TUNING) { + if (map->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&endtime, NULL); msDebug("msDrawMap(): WMS/WFS set-up and query, %.3fs\n", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } #endif /* USE_WMS_LYR || USE_WFS_LYR */ /* OK, now we can start drawing */ - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { - if(map->layerorder[i] != -1) { + if (map->layerorder[i] != -1) { const char *force_draw_label_cache = NULL; - lp = (GET_LAYER(map, map->layerorder[i])); + lp = (GET_LAYER(map, map->layerorder[i])); - if(lp->postlabelcache) /* wait to draw */ + if (lp->postlabelcache) /* wait to draw */ continue; - if(map->debug >= MS_DEBUGLEVEL_TUNING || lp->debug >= MS_DEBUGLEVEL_TUNING ) msGettimeofday(&starttime, NULL); + if (map->debug >= MS_DEBUGLEVEL_TUNING || + lp->debug >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&starttime, NULL); - if(!msLayerIsVisible(map, lp)) continue; + if (!msLayerIsVisible(map, lp)) + continue; - if(lp->connectiontype == MS_WMS) { + if (lp->connectiontype == MS_WMS) { #ifdef USE_WMS_LYR - if(MS_RENDERER_PLUGIN(image->format) || MS_RENDERER_RAWDATA(image->format)) { + if (MS_RENDERER_PLUGIN(image->format) || + MS_RENDERER_RAWDATA(image->format)) { assert(pasOWSReqInfo); - status = msDrawWMSLayerLow(map->layerorder[i], pasOWSReqInfo, numOWSRequests, map, lp, image); - } - else { - msSetError(MS_WMSCONNERR, "Output format '%s' doesn't support WMS layers.", "msDrawMap()", image->format->name); + status = msDrawWMSLayerLow(map->layerorder[i], pasOWSReqInfo, + numOWSRequests, map, lp, image); + } else { + msSetError(MS_WMSCONNERR, + "Output format '%s' doesn't support WMS layers.", + "msDrawMap()", image->format->name); status = MS_FAILURE; } - if(status == MS_FAILURE) { + if (status == MS_FAILURE) { msSetError(MS_WMSCONNERR, - "Failed to draw WMS layer named '%s'. This most likely happened because " - "the remote WMS server returned an invalid image, and XML exception " - "or another unexpected result in response to the GetMap request. Also check " + "Failed to draw WMS layer named '%s'. This most likely " + "happened because " + "the remote WMS server returned an invalid image, and XML " + "exception " + "or another unexpected result in response to the GetMap " + "request. Also check " "and make sure that the layer's connection URL is valid.", "msDrawMap()", lp->name); msFreeImage(image); msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); msFree(pasOWSReqInfo); - return(NULL); + return (NULL); } - #else /* ndef USE_WMS_LYR */ - msSetError(MS_WMSCONNERR, "MapServer not built with WMS Client support, unable to render layer '%s'.", "msDrawMap()", lp->name); + msSetError(MS_WMSCONNERR, + "MapServer not built with WMS Client support, unable to " + "render layer '%s'.", + "msDrawMap()", lp->name); msFreeImage(image); - return(NULL); + return (NULL); #endif } else { /* Default case: anything but WMS layers */ - if(querymap) + if (querymap) status = msDrawQueryLayer(map, lp, image); else status = msDrawLayer(map, lp, image); - if(status == MS_FAILURE) { - msSetError(MS_IMGERR, "Failed to draw layer named '%s'.", "msDrawMap()", lp->name); + if (status == MS_FAILURE) { + msSetError(MS_IMGERR, "Failed to draw layer named '%s'.", + "msDrawMap()", lp->name); msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) if (pasOWSReqInfo) { @@ -451,80 +494,81 @@ imageObj *msDrawMap(mapObj *map, int querymap) msFree(pasOWSReqInfo); } #endif /* USE_WMS_LYR || USE_WFS_LYR */ - return(NULL); + return (NULL); } } - if(map->debug >= MS_DEBUGLEVEL_TUNING || lp->debug >= MS_DEBUGLEVEL_TUNING) { + if (map->debug >= MS_DEBUGLEVEL_TUNING || + lp->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&endtime, NULL); - msDebug("msDrawMap(): Layer %d (%s), %.3fs\n", - map->layerorder[i], lp->name?lp->name:"(null)", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + msDebug("msDrawMap(): Layer %d (%s), %.3fs\n", map->layerorder[i], + lp->name ? lp->name : "(null)", + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } - /* Flush layer cache in-between layers if requested by PROCESSING directive*/ - force_draw_label_cache = msLayerGetProcessingKey(lp, "FORCE_DRAW_LABEL_CACHE"); + /* Flush layer cache in-between layers if requested by PROCESSING + * directive*/ + force_draw_label_cache = + msLayerGetProcessingKey(lp, "FORCE_DRAW_LABEL_CACHE"); if (force_draw_label_cache && - strncasecmp(force_draw_label_cache,"FLUSH",5)==0) { - if(map->debug >= MS_DEBUGLEVEL_V) - msDebug("msDrawMap(): PROCESSING FORCE_DRAW_LABEL_CACHE=FLUSH found.\n"); - if(msDrawLabelCache(map, image) != MS_SUCCESS) { - msFreeImage(image); + strncasecmp(force_draw_label_cache, "FLUSH", 5) == 0) { + if (map->debug >= MS_DEBUGLEVEL_V) + msDebug( + "msDrawMap(): PROCESSING FORCE_DRAW_LABEL_CACHE=FLUSH found.\n"); + if (msDrawLabelCache(map, image) != MS_SUCCESS) { + msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) - if (pasOWSReqInfo) { - msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); - msFree(pasOWSReqInfo); - } + if (pasOWSReqInfo) { + msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); + msFree(pasOWSReqInfo); + } #endif /* USE_WMS_LYR || USE_WFS_LYR */ - return(NULL); - } - msFreeLabelCache(&(map->labelcache)); - msInitLabelCache(&(map->labelcache)); + return (NULL); + } + msFreeLabelCache(&(map->labelcache)); + msInitLabelCache(&(map->labelcache)); } /* PROCESSING FORCE_DRAW_LABEL_CACHE */ - } } - if(map->scalebar.status == MS_EMBED && !map->scalebar.postlabelcache) { + if (map->scalebar.status == MS_EMBED && !map->scalebar.postlabelcache) { /* We need to temporarily restore the original extent for drawing */ /* the scalebar as it uses the extent to recompute cellsize. */ - if(map->gt.need_geotransform) + if (map->gt.need_geotransform) msMapRestoreRealExtent(map); - - if(MS_SUCCESS != msEmbedScalebar(map, image)) { - msFreeImage( image ); + if (MS_SUCCESS != msEmbedScalebar(map, image)) { + msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Cleanup WMS/WFS Request stuff */ if (pasOWSReqInfo) { - msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); - msFree(pasOWSReqInfo); + msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); + msFree(pasOWSReqInfo); } #endif return NULL; } - - if(map->gt.need_geotransform) + if (map->gt.need_geotransform) msMapSetFakedExtent(map); } - if(map->legend.status == MS_EMBED && !map->legend.postlabelcache) { - if( msEmbedLegend(map, image) != MS_SUCCESS ) { - msFreeImage( image ); + if (map->legend.status == MS_EMBED && !map->legend.postlabelcache) { + if (msEmbedLegend(map, image) != MS_SUCCESS) { + msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Cleanup WMS/WFS Request stuff */ if (pasOWSReqInfo) { - msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); - msFree(pasOWSReqInfo); + msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); + msFree(pasOWSReqInfo); } #endif return NULL; } } - if(msDrawLabelCache(map, image) != MS_SUCCESS) { + if (msDrawLabelCache(map, image) != MS_SUCCESS) { msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) if (pasOWSReqInfo) { @@ -532,38 +576,42 @@ imageObj *msDrawMap(mapObj *map, int querymap) msFree(pasOWSReqInfo); } #endif /* USE_WMS_LYR || USE_WFS_LYR */ - return(NULL); + return (NULL); } - - for(i=0; inumlayers; i++) { /* for each layer, check for postlabelcache layers */ + for (i = 0; i < map->numlayers; + i++) { /* for each layer, check for postlabelcache layers */ lp = (GET_LAYER(map, map->layerorder[i])); - if(!lp->postlabelcache) continue; - if(!msLayerIsVisible(map, lp)) continue; + if (!lp->postlabelcache) + continue; + if (!msLayerIsVisible(map, lp)) + continue; - if(map->debug >= MS_DEBUGLEVEL_TUNING || lp->debug >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&starttime, NULL); + if (map->debug >= MS_DEBUGLEVEL_TUNING || lp->debug >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&starttime, NULL); - if(lp->connectiontype == MS_WMS) { + if (lp->connectiontype == MS_WMS) { #ifdef USE_WMS_LYR - if(MS_RENDERER_PLUGIN(image->format) || MS_RENDERER_RAWDATA(image->format)) - { + if (MS_RENDERER_PLUGIN(image->format) || + MS_RENDERER_RAWDATA(image->format)) { assert(pasOWSReqInfo); - status = msDrawWMSLayerLow(map->layerorder[i], pasOWSReqInfo, numOWSRequests, map, lp, image); + status = msDrawWMSLayerLow(map->layerorder[i], pasOWSReqInfo, + numOWSRequests, map, lp, image); } #else status = MS_FAILURE; #endif } else { - if(querymap) + if (querymap) status = msDrawQueryLayer(map, lp, image); else status = msDrawLayer(map, lp, image); } - if(status == MS_FAILURE) { + if (status == MS_FAILURE) { msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) if (pasOWSReqInfo) { @@ -571,27 +619,27 @@ imageObj *msDrawMap(mapObj *map, int querymap) msFree(pasOWSReqInfo); } #endif /* USE_WMS_LYR || USE_WFS_LYR */ - return(NULL); + return (NULL); } - if(map->debug >= MS_DEBUGLEVEL_TUNING || lp->debug >= MS_DEBUGLEVEL_TUNING) { + if (map->debug >= MS_DEBUGLEVEL_TUNING || + lp->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&endtime, NULL); - msDebug("msDrawMap(): Layer %d (%s), %.3fs\n", - map->layerorder[i], lp->name?lp->name:"(null)", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + msDebug("msDrawMap(): Layer %d (%s), %.3fs\n", map->layerorder[i], + lp->name ? lp->name : "(null)", + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } - } /* Do we need to fake out stuff for rotated support? */ /* This really needs to be done on every preceeding exit point too... */ - if(map->gt.need_geotransform) + if (map->gt.need_geotransform) msMapRestoreRealExtent(map); - if(map->legend.status == MS_EMBED && map->legend.postlabelcache) - if(MS_UNLIKELY(MS_FAILURE == msEmbedLegend(map, image))) { - msFreeImage( image ); + if (map->legend.status == MS_EMBED && map->legend.postlabelcache) + if (MS_UNLIKELY(MS_FAILURE == msEmbedLegend(map, image))) { + msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Cleanup WMS/WFS Request stuff */ if (pasOWSReqInfo) { @@ -602,27 +650,26 @@ imageObj *msDrawMap(mapObj *map, int querymap) return NULL; } - if(map->scalebar.status == MS_EMBED && map->scalebar.postlabelcache) { + if (map->scalebar.status == MS_EMBED && map->scalebar.postlabelcache) { /* We need to temporarily restore the original extent for drawing */ /* the scalebar as it uses the extent to recompute cellsize. */ - if(map->gt.need_geotransform) + if (map->gt.need_geotransform) msMapRestoreRealExtent(map); - if(MS_SUCCESS != msEmbedScalebar(map, image)) { - msFreeImage( image ); + if (MS_SUCCESS != msEmbedScalebar(map, image)) { + msFreeImage(image); #if defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Cleanup WMS/WFS Request stuff */ if (pasOWSReqInfo) { - msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); - msFree(pasOWSReqInfo); + msHTTPFreeRequestObj(pasOWSReqInfo, numOWSRequests); + msFree(pasOWSReqInfo); } #endif return NULL; } - - if(map->gt.need_geotransform) + if (map->gt.need_geotransform) msMapSetFakedExtent(map); } @@ -634,162 +681,195 @@ imageObj *msDrawMap(mapObj *map, int querymap) } #endif - if(map->debug >= MS_DEBUGLEVEL_TUNING) { + if (map->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&mapendtime, NULL); msDebug("msDrawMap() total time: %.3fs\n", - (mapendtime.tv_sec+mapendtime.tv_usec/1.0e6)- - (mapstarttime.tv_sec+mapstarttime.tv_usec/1.0e6) ); + (mapendtime.tv_sec + mapendtime.tv_usec / 1.0e6) - + (mapstarttime.tv_sec + mapstarttime.tv_usec / 1.0e6)); } - return(image); + return (image); } /* * Test whether a layer should be drawn or not in the current map view and * at the current scale. * Returns TRUE if layer is visible, FALSE if not. -*/ -int msLayerIsVisible(mapObj *map, layerObj *layer) -{ + */ +int msLayerIsVisible(mapObj *map, layerObj *layer) { int i; - if(!layer->data && !layer->tileindex && !layer->connection && !layer->features && !layer->grid) - return(MS_FALSE); /* no data associated with this layer, not an error since layer may be used as a template from MapScript */ + if (!layer->data && !layer->tileindex && !layer->connection && + !layer->features && !layer->grid) + return (MS_FALSE); /* no data associated with this layer, not an error since + layer may be used as a template from MapScript */ - if(layer->type == MS_LAYER_QUERY || layer->type == MS_LAYER_TILEINDEX) return(MS_FALSE); - if((layer->status != MS_ON) && (layer->status != MS_DEFAULT)) return(MS_FALSE); + if (layer->type == MS_LAYER_QUERY || layer->type == MS_LAYER_TILEINDEX) + return (MS_FALSE); + if ((layer->status != MS_ON) && (layer->status != MS_DEFAULT)) + return (MS_FALSE); /* Do comparisons of layer scale vs map scale now, since msExtentsOverlap() */ /* can be slow */ - if(map->scaledenom > 0) { + if (map->scaledenom > 0) { /* layer scale boundaries should be checked first */ - if((layer->maxscaledenom > 0) && (map->scaledenom > layer->maxscaledenom)) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER.MAXSCALE is too small for this MAP scale\n", layer->name); + if ((layer->maxscaledenom > 0) && + (map->scaledenom > layer->maxscaledenom)) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because " + "LAYER.MAXSCALE is too small for this MAP scale\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } - if(/*(layer->minscaledenom > 0) &&*/ (map->scaledenom <= layer->minscaledenom)) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER.MINSCALE is too large for this MAP scale\n", layer->name); + if (/*(layer->minscaledenom > 0) &&*/ (map->scaledenom <= + layer->minscaledenom)) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because " + "LAYER.MINSCALE is too large for this MAP scale\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } } - /* Only return MS_FALSE if it is definitely false. Sometimes it will return MS_UNKNOWN, which we - ** consider true, for this use case (it might be visible, try and draw it, see what happens). */ - if ( msExtentsOverlap(map, layer) == MS_FALSE ) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER.EXTENT does not intersect MAP.EXTENT\n", layer->name); + /* Only return MS_FALSE if it is definitely false. Sometimes it will return + *MS_UNKNOWN, which we + ** consider true, for this use case (it might be visible, try and draw it, + *see what happens). */ + if (msExtentsOverlap(map, layer) == MS_FALSE) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER.EXTENT " + "does not intersect MAP.EXTENT\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } - if(msEvalContext(map, layer, layer->requires) == MS_FALSE) return(MS_FALSE); + if (msEvalContext(map, layer, layer->requires) == MS_FALSE) + return (MS_FALSE); - if(map->scaledenom > 0) { + if (map->scaledenom > 0) { /* now check class scale boundaries (all layers *must* pass these tests) */ - if(layer->numclasses > 0) { - for(i=0; inumclasses; i++) { - if((layer->class[i]->maxscaledenom > 0) && (map->scaledenom > layer->class[i]->maxscaledenom)) + if (layer->numclasses > 0) { + for (i = 0; i < layer->numclasses; i++) { + if ((layer->class[i] -> maxscaledenom > 0) && + (map->scaledenom > layer->class[i] -> maxscaledenom)) continue; /* can skip this one, next class */ - if((layer->class[i]->minscaledenom > 0) && (map->scaledenom <= layer->class[i]->minscaledenom)) + if ((layer->class[i] -> minscaledenom > 0) && + (map->scaledenom <= layer->class[i] -> minscaledenom)) continue; /* can skip this one, next class */ break; /* can't skip this class (or layer for that matter) */ } - if(i == layer->numclasses) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because no CLASS in the layer is in-scale for this MAP scale\n", layer->name); + if (i == layer->numclasses) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because no CLASS in " + "the layer is in-scale for this MAP scale\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } } - } if (layer->maxscaledenom <= 0 && layer->minscaledenom <= 0) { - if((layer->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > layer->maxgeowidth)) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER width is much smaller than map width\n", layer->name); + if ((layer->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > layer->maxgeowidth)) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER width " + "is much smaller than map width\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } - if((layer->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < layer->mingeowidth)) { - if( layer->debug >= MS_DEBUGLEVEL_V ) { - msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER width is much larger than map width\n", layer->name); + if ((layer->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < layer->mingeowidth)) { + if (layer->debug >= MS_DEBUGLEVEL_V) { + msDebug("msLayerIsVisible(): Skipping layer (%s) because LAYER width " + "is much larger than map width\n", + layer->name); } - return(MS_FALSE); + return (MS_FALSE); } } - return MS_TRUE; /* All tests passed. Layer is visible. */ + return MS_TRUE; /* All tests passed. Layer is visible. */ } - -#define LAYER_NEEDS_COMPOSITING(layer) (((layer)->compositer != NULL) && ((layer)->compositer->next || (layer)->compositor->opacity < 100 || (layer)->compositor->compop != MS_COMPOP_SRC_OVER || (layer)->compositer->filter )) +#define LAYER_NEEDS_COMPOSITING(layer) \ + (((layer)->compositer != NULL) && \ + ((layer)->compositer->next || (layer)->compositor->opacity < 100 || \ + (layer)->compositor->compop != MS_COMPOP_SRC_OVER || \ + (layer)->compositer->filter)) /* * Generic function to render a layer object. -*/ -int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image) -{ + */ +int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image) { imageObj *image_draw = image; - outputFormatObj *altFormat=NULL; - int retcode=MS_SUCCESS; + outputFormatObj *altFormat = NULL; + int retcode = MS_SUCCESS; const char *alternativeFomatString = NULL; layerObj *maskLayer = NULL; - if(!msLayerIsVisible(map, layer)) + if (!msLayerIsVisible(map, layer)) return MS_SUCCESS; - if(layer->compositer && !layer->compositer->next && layer->compositer->opacity == 0) return MS_SUCCESS; /* layer is completely transparent, skip it */ - + if (layer->compositer && !layer->compositer->next && + layer->compositer->opacity == 0) + return MS_SUCCESS; /* layer is completely transparent, skip it */ /* conditions may have changed since this layer last drawn, so retest layer->project (Bug #673) */ - layer->project = msProjectionsDiffer(&(layer->projection),&(map->projection)); + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); - /* make sure labelcache setting is set correctly if postlabelcache is set. This is done by the parser but - may have been altered by a mapscript. see #5142 */ - if(layer->postlabelcache) { + /* make sure labelcache setting is set correctly if postlabelcache is set. + This is done by the parser but may have been altered by a mapscript. see + #5142 */ + if (layer->postlabelcache) { layer->labelcache = MS_FALSE; } - if(layer->mask) { + if (layer->mask) { int maskLayerIdx; /* render the mask layer in its own imageObj */ - if(!MS_IMAGE_RENDERER(image)->supports_pixel_buffer) { - msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msDrawLayer()", - layer->name); + if (!MS_IMAGE_RENDERER(image)->supports_pixel_buffer) { + msSetError(MS_MISCERR, + "Layer (%s) references references a mask layer, but the " + "selected renderer does not support them", + "msDrawLayer()", layer->name); return (MS_FAILURE); } - maskLayerIdx = msGetLayerIndex(map,layer->mask); - if(maskLayerIdx == -1) { - msSetError(MS_MISCERR, "Layer (%s) references unknown mask layer (%s)", "msDrawLayer()", - layer->name,layer->mask); + maskLayerIdx = msGetLayerIndex(map, layer->mask); + if (maskLayerIdx == -1) { + msSetError(MS_MISCERR, "Layer (%s) references unknown mask layer (%s)", + "msDrawLayer()", layer->name, layer->mask); return (MS_FAILURE); } maskLayer = GET_LAYER(map, maskLayerIdx); - if(!maskLayer->maskimage) { + if (!maskLayer->maskimage) { int i; int origstatus, origlabelcache; - altFormat = msSelectOutputFormat(map, "png24"); + altFormat = msSelectOutputFormat(map, "png24"); msInitializeRendererVTable(altFormat); - /* TODO: check the png24 format hasn't been tampered with, i.e. it's agg */ - maskLayer->maskimage= msImageCreate(image->width, image->height,altFormat, - image->imagepath, image->imageurl, map->resolution, map->defresolution, NULL); + /* TODO: check the png24 format hasn't been tampered with, i.e. it's agg + */ + maskLayer->maskimage = msImageCreate( + image->width, image->height, altFormat, image->imagepath, + image->imageurl, map->resolution, map->defresolution, NULL); if (!maskLayer->maskimage) { - msSetError(MS_MISCERR, "Unable to initialize mask image.", "msDrawLayer()"); + msSetError(MS_MISCERR, "Unable to initialize mask image.", + "msDrawLayer()"); return (MS_FAILURE); } /* - * force the masked layer to status on, and turn off the labelcache so that - * eventual labels are added to the temporary image instead of being added - * to the labelcache + * force the masked layer to status on, and turn off the labelcache so + * that eventual labels are added to the temporary image instead of being + * added to the labelcache */ origstatus = maskLayer->status; origlabelcache = maskLayer->labelcache; @@ -800,79 +880,85 @@ int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image) retcode = msDrawLayer(map, maskLayer, maskLayer->maskimage); maskLayer->status = origstatus; maskLayer->labelcache = origlabelcache; - if(retcode != MS_SUCCESS) { + if (retcode != MS_SUCCESS) { return MS_FAILURE; } /* - * hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain - * symbols that reference it. We want to remove those references before the altFormat is destroyed - * to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking - * it's for him. + * hack to work around bug #3834: if we have use an alternate renderer, + * the symbolset may contain symbols that reference it. We want to remove + * those references before the altFormat is destroyed to avoid a segfault + * and/or a leak, and so the the main renderer doesn't pick the cache up + * thinking it's for him. */ - for(i=0; isymbolset.numsymbols; i++) { - if (map->symbolset.symbol[i]!=NULL) { + for (i = 0; i < map->symbolset.numsymbols; i++) { + if (map->symbolset.symbol[i] != NULL) { symbolObj *s = map->symbolset.symbol[i]; - if(s->renderer == MS_IMAGE_RENDERER(maskLayer->maskimage)) { + if (s->renderer == MS_IMAGE_RENDERER(maskLayer->maskimage)) { MS_IMAGE_RENDERER(maskLayer->maskimage)->freeSymbol(s); s->renderer = NULL; } } } - /* set the imagetype from the original outputformat back (it was removed by msSelectOutputFormat() */ + /* set the imagetype from the original outputformat back (it was removed + * by msSelectOutputFormat() */ msFree(map->imagetype); map->imagetype = msStrdup(image->format->name); } - } altFormat = NULL; /* inform the rendering device that layer draw is starting. */ msImageStartLayer(map, layer, image); - /*check if an alternative renderer should be used for this layer*/ - alternativeFomatString = msLayerGetProcessingKey( layer, "RENDERER"); - if (MS_RENDERER_PLUGIN(image_draw->format) && alternativeFomatString!=NULL && - (altFormat= msSelectOutputFormat(map, alternativeFomatString))) { - rendererVTableObj *renderer=NULL; + alternativeFomatString = msLayerGetProcessingKey(layer, "RENDERER"); + if (MS_RENDERER_PLUGIN(image_draw->format) && + alternativeFomatString != NULL && + (altFormat = msSelectOutputFormat(map, alternativeFomatString))) { + rendererVTableObj *renderer = NULL; msInitializeRendererVTable(altFormat); - image_draw = msImageCreate(image->width, image->height, - altFormat, image->imagepath, image->imageurl, map->resolution, map->defresolution, &map->imagecolor); + image_draw = msImageCreate( + image->width, image->height, altFormat, image->imagepath, + image->imageurl, map->resolution, map->defresolution, &map->imagecolor); renderer = MS_IMAGE_RENDERER(image_draw); - renderer->startLayer(image_draw,map,layer); + renderer->startLayer(image_draw, map, layer); } else if (MS_RENDERER_PLUGIN(image_draw->format)) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image_draw); - if ((layer->mask && layer->connectiontype!=MS_WMS && layer->type != MS_LAYER_RASTER) || layer->compositer) { - /* masking occurs at the pixel/layer level for raster images, so we don't need to create a temporary image - in these cases + if ((layer->mask && layer->connectiontype != MS_WMS && + layer->type != MS_LAYER_RASTER) || + layer->compositer) { + /* masking occurs at the pixel/layer level for raster images, so we don't + need to create a temporary image in these cases */ if (layer->mask || renderer->compositeRasterBuffer) { - image_draw = msImageCreate(image->width, image->height, - image->format, image->imagepath, image->imageurl, map->resolution, map->defresolution, NULL); + image_draw = msImageCreate(image->width, image->height, image->format, + image->imagepath, image->imageurl, + map->resolution, map->defresolution, NULL); if (!image_draw) { - msSetError(MS_MISCERR, "Unable to initialize temporary transparent image.", + msSetError(MS_MISCERR, + "Unable to initialize temporary transparent image.", "msDrawLayer()"); return (MS_FAILURE); } image_draw->map = map; - renderer->startLayer(image_draw,map,layer); + renderer->startLayer(image_draw, map, layer); } } } /* ** redirect procesing of some layer types. */ - if(layer->connectiontype == MS_WMS) { + if (layer->connectiontype == MS_WMS) { #ifdef USE_WMS_LYR retcode = msDrawWMSLayer(map, layer, image_draw); #else retcode = MS_FAILURE; #endif - } else if(layer->type == MS_LAYER_RASTER) { + } else if (layer->type == MS_LAYER_RASTER) { retcode = msDrawRasterLayer(map, layer, image_draw); - } else if(layer->type == MS_LAYER_CHART) { + } else if (layer->type == MS_LAYER_CHART) { retcode = msDrawChartLayer(map, layer, image_draw); - } else { /* must be a Vector layer */ + } else { /* must be a Vector layer */ retcode = msDrawVectorLayer(map, layer, image_draw); } @@ -881,226 +967,230 @@ int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image) rendererVTableObj *altrenderer = MS_IMAGE_RENDERER(image_draw); rasterBufferObj rb; int i; - memset(&rb,0,sizeof(rasterBufferObj)); + memset(&rb, 0, sizeof(rasterBufferObj)); - altrenderer->endLayer(image_draw,map,layer); + altrenderer->endLayer(image_draw, map, layer); - retcode = altrenderer->getRasterBufferHandle(image_draw,&rb); - if(MS_UNLIKELY(retcode == MS_FAILURE)) { + retcode = altrenderer->getRasterBufferHandle(image_draw, &rb); + if (MS_UNLIKELY(retcode == MS_FAILURE)) { goto altformat_cleanup; } - retcode = renderer->mergeRasterBuffer(image,&rb,((layer->compositer)?(layer->compositer->opacity*0.01):(1.0)),0,0,0,0,rb.width,rb.height); - if(MS_UNLIKELY(retcode == MS_FAILURE)) { + retcode = renderer->mergeRasterBuffer( + image, &rb, + ((layer->compositer) ? (layer->compositer->opacity * 0.01) : (1.0)), 0, + 0, 0, 0, rb.width, rb.height); + if (MS_UNLIKELY(retcode == MS_FAILURE)) { goto altformat_cleanup; } -altformat_cleanup: + altformat_cleanup: /* - * hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain - * symbols that reference it. We want to remove those references before the altFormat is destroyed - * to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking + * hack to work around bug #3834: if we have use an alternate renderer, the + * symbolset may contain symbols that reference it. We want to remove those + * references before the altFormat is destroyed to avoid a segfault and/or a + * leak, and so the the main renderer doesn't pick the cache up thinking * it's for him. */ - for(i=0; isymbolset.numsymbols; i++) { - if (map->symbolset.symbol[i]!=NULL) { + for (i = 0; i < map->symbolset.numsymbols; i++) { + if (map->symbolset.symbol[i] != NULL) { symbolObj *s = map->symbolset.symbol[i]; - if(s->renderer == altrenderer) { + if (s->renderer == altrenderer) { altrenderer->freeSymbol(s); s->renderer = NULL; } } } msFreeImage(image_draw); - /* set the imagetype from the original outputformat back (it was removed by msSelectOutputFormat() */ + /* set the imagetype from the original outputformat back (it was removed by + * msSelectOutputFormat() */ msFree(map->imagetype); map->imagetype = msStrdup(image->format->name); - } else if( image != image_draw) { + } else if (image != image_draw) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image_draw); rasterBufferObj rb; - memset(&rb,0,sizeof(rasterBufferObj)); + memset(&rb, 0, sizeof(rasterBufferObj)); - renderer->endLayer(image_draw,map,layer); + renderer->endLayer(image_draw, map, layer); - retcode = renderer->getRasterBufferHandle(image_draw,&rb); - if(MS_UNLIKELY(retcode == MS_FAILURE)) { + retcode = renderer->getRasterBufferHandle(image_draw, &rb); + if (MS_UNLIKELY(retcode == MS_FAILURE)) { goto imagedraw_cleanup; } - if(maskLayer && maskLayer->maskimage) { + if (maskLayer && maskLayer->maskimage) { rasterBufferObj mask; - unsigned int row,col; - memset(&mask,0,sizeof(rasterBufferObj)); - retcode = MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,&mask); - if(MS_UNLIKELY(retcode == MS_FAILURE)) { + unsigned int row, col; + memset(&mask, 0, sizeof(rasterBufferObj)); + retcode = MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, &mask); + if (MS_UNLIKELY(retcode == MS_FAILURE)) { goto imagedraw_cleanup; } /* modify the pixels of the overlay */ - if(rb.type == MS_BUFFER_BYTE_RGBA) { - for(row=0; rowcompositer) { - /*we have a mask layer with no composition configured, do a nomral blend */ - retcode = renderer->mergeRasterBuffer(image,&rb,1.0,0,0,0,0,rb.width,rb.height); + if (!layer->compositer) { + /*we have a mask layer with no composition configured, do a nomral blend + */ + retcode = renderer->mergeRasterBuffer(image, &rb, 1.0, 0, 0, 0, 0, + rb.width, rb.height); } else { - retcode = msCompositeRasterBuffer(map,image,&rb,layer->compositer); + retcode = msCompositeRasterBuffer(map, image, &rb, layer->compositer); } - if(MS_UNLIKELY(retcode == MS_FAILURE)) { + if (MS_UNLIKELY(retcode == MS_FAILURE)) { goto imagedraw_cleanup; } -imagedraw_cleanup: + imagedraw_cleanup: msFreeImage(image_draw); } - msImageEndLayer(map,layer,image); - return(retcode); + msImageEndLayer(map, layer, image); + return (retcode); } -int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) -{ - int status, retcode=MS_SUCCESS; - int drawmode=MS_DRAWMODE_FEATURES; - char annotate=MS_TRUE; - shapeObj shape; - shapeObj savedShape; - rectObj searchrect; - char cache=MS_FALSE; - int maxnumstyles=1; - featureListNodeObjPtr shpcache=NULL, current=NULL; +int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) { + int status, retcode = MS_SUCCESS; + int drawmode = MS_DRAWMODE_FEATURES; + char annotate = MS_TRUE; + shapeObj shape; + shapeObj savedShape; + rectObj searchrect; + char cache = MS_FALSE; + int maxnumstyles = 1; + featureListNodeObjPtr shpcache = NULL, current = NULL; int nclasses = 0; int *classgroup = NULL; double minfeaturesize = -1; - int maxfeatures=-1; - int featuresdrawn=0; + int maxfeatures = -1; + int featuresdrawn = 0; if (image) - maxfeatures=msLayerGetMaxFeaturesToDraw(layer, image->format); + maxfeatures = msLayerGetMaxFeaturesToDraw(layer, image->format); /* TODO TBT: draw as raster layer in vector renderers */ annotate = msEvalContext(map, layer, layer->labelrequires); - if(map->scaledenom > 0) { - if((layer->labelmaxscaledenom != -1) && (map->scaledenom >= layer->labelmaxscaledenom)) annotate = MS_FALSE; - if((layer->labelminscaledenom != -1) && (map->scaledenom < layer->labelminscaledenom)) annotate = MS_FALSE; + if (map->scaledenom > 0) { + if ((layer->labelmaxscaledenom != -1) && + (map->scaledenom >= layer->labelmaxscaledenom)) + annotate = MS_FALSE; + if ((layer->labelminscaledenom != -1) && + (map->scaledenom < layer->labelminscaledenom)) + annotate = MS_FALSE; } /* open this layer */ status = msLayerOpen(layer); - if(status != MS_SUCCESS) return MS_FAILURE; + if (status != MS_SUCCESS) + return MS_FAILURE; /* build item list. STYLEITEM javascript needs the shape attributes */ - if (layer->styleitem && (strncasecmp(layer->styleitem, "javascript://", 13) == 0)) { + if (layer->styleitem && + (strncasecmp(layer->styleitem, "javascript://", 13) == 0)) { status = msLayerWhichItems(layer, MS_TRUE, NULL); } else { status = msLayerWhichItems(layer, MS_FALSE, NULL); } - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msLayerClose(layer); return MS_FAILURE; } /* identify target shapes */ - if(layer->transform == MS_TRUE) { + if (layer->transform == MS_TRUE) { searchrect = map->extent; - if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) { + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0)) { int bDone = MS_FALSE; - if( layer->connectiontype == MS_UVRASTER ) - { - /* Nasty hack to make msUVRASTERLayerWhichShapes() aware that the */ - /* original area of interest is (map->extent, map->projection)... */ - /* Useful when dealin with UVRASTER that extend beyond 180 deg */ - msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes( layer, map ); + if (layer->connectiontype == MS_UVRASTER) { + /* Nasty hack to make msUVRASTERLayerWhichShapes() aware that the */ + /* original area of interest is (map->extent, map->projection)... */ + /* Useful when dealin with UVRASTER that extend beyond 180 deg */ + msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes(layer, map); - searchrect = msUVRASTERGetSearchRect( layer, map ); - bDone = MS_TRUE; + searchrect = msUVRASTERGetSearchRect(layer, map); + bDone = MS_TRUE; } - if( !bDone ) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ + if (!bDone) + msProjectRect( + &map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ } } else { searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; } status = msLayerWhichShapes(layer, searchrect, MS_FALSE); - if( layer->connectiontype == MS_UVRASTER ) - { - msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes( layer, NULL ); + if (layer->connectiontype == MS_UVRASTER) { + msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes(layer, NULL); } - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(layer); return MS_SUCCESS; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(layer); return MS_FAILURE; } nclasses = 0; classgroup = NULL; - if(layer->classgroup && layer->numclasses > 0) + if (layer->classgroup && layer->numclasses > 0) classgroup = msAllocateValidClassGroups(layer, &nclasses); - if(layer->minfeaturesize > 0) + if (layer->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, layer, layer->minfeaturesize); // Select how to render classes // MS_FIRST_MATCHING_CLASS: Default and historic MapServer behavior // MS_ALL_MATCHING_CLASSES: SLD behavior int ref_rendermode; - const char * rendermodestr = msLayerGetProcessingKey(layer, "RENDERMODE"); - if (layer->rendermode == MS_ALL_MATCHING_CLASSES) - { + const char *rendermodestr = msLayerGetProcessingKey(layer, "RENDERMODE"); + if (layer->rendermode == MS_ALL_MATCHING_CLASSES) { // SLD takes precedence ref_rendermode = MS_ALL_MATCHING_CLASSES; - } - else if (!rendermodestr) - { + } else if (!rendermodestr) { // Default Mapfile ref_rendermode = MS_FIRST_MATCHING_CLASS; - } - else if (!strcmp(rendermodestr,"FIRST_MATCHING_CLASS")) - { + } else if (!strcmp(rendermodestr, "FIRST_MATCHING_CLASS")) { // Explicit default Mapfile ref_rendermode = MS_FIRST_MATCHING_CLASS; - } - else if (!strcmp(rendermodestr,"ALL_MATCHING_CLASSES")) - { + } else if (!strcmp(rendermodestr, "ALL_MATCHING_CLASSES")) { // SLD-like Mapfile ref_rendermode = MS_ALL_MATCHING_CLASSES; - } - else - { + } else { msLayerClose(layer); msSetError(MS_MISCERR, - "Unknown RENDERMODE: %s, should be one of: FIRST_MATCHING_CLASS, ALL_MATCHING_CLASSES.", - "msDrawVectorLayer()", - rendermodestr); + "Unknown RENDERMODE: %s, should be one of: " + "FIRST_MATCHING_CLASS, ALL_MATCHING_CLASSES.", + "msDrawVectorLayer()", rendermodestr); return MS_FAILURE; } @@ -1118,63 +1208,78 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) } /* Check if the shape size is ok to be drawn */ - if((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) && (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)) { - if(layer->debug >= MS_DEBUGLEVEL_V) - msDebug("msDrawVectorLayer(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0) && + (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE)) { + if (layer->debug >= MS_DEBUGLEVEL_V) + msDebug("msDrawVectorLayer(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); continue; } classcount = 0; } - classindex = msShapeGetNextClass(classindex, layer, map, &shape, classgroup, nclasses); - if((classindex == -1) || (layer->class[classindex]->status == MS_OFF)) { + classindex = msShapeGetNextClass(classindex, layer, map, &shape, classgroup, + nclasses); + if ((classindex == -1) || (layer->class[classindex] -> status == MS_OFF)) { continue; } shape.classindex = classindex; - // When only one class is applicable, rendering mode is forced to its default, - // i.e. only the first applicable class is actually applied. As a consequence, - // cache can be enabled when relevant. + // When only one class is applicable, rendering mode is forced to its + // default, i.e. only the first applicable class is actually applied. As a + // consequence, cache can be enabled when relevant. classcount++; rendermode = ref_rendermode; - if ((classcount == 1) && (msShapeGetNextClass(classindex, layer, map, &shape, classgroup, nclasses) == -1)) - { + if ((classcount == 1) && + (msShapeGetNextClass(classindex, layer, map, &shape, classgroup, + nclasses) == -1)) { rendermode = MS_FIRST_MATCHING_CLASS; } - if (rendermode == MS_FIRST_MATCHING_CLASS) - { + if (rendermode == MS_FIRST_MATCHING_CLASS) { classindex = -1; } - if(maxfeatures >=0 && featuresdrawn >= maxfeatures) { + if (maxfeatures >= 0 && featuresdrawn >= maxfeatures) { status = MS_DONE; break; } featuresdrawn++; cache = MS_FALSE; - if(layer->type == MS_LAYER_LINE && (layer->class[shape.classindex]->numstyles > 1 || (layer->class[shape.classindex]->numstyles == 1 && layer->class[shape.classindex]->styles[0]->outlinewidth > 0))) { + if (layer->type == MS_LAYER_LINE && + (layer->class[shape.classindex] + -> numstyles > 1 || + (layer->class[shape.classindex] -> numstyles == 1 && layer + -> class[shape.classindex] -> styles[0] -> outlinewidth > + 0))) { int i; - cache = MS_TRUE; /* only line layers with multiple styles need be cached (I don't think POLYLINE layers need caching - SDL) */ - - /* we can't handle caching with attribute binding other than for the first style (#3976) */ - for(i=1; iclass[shape.classindex]->numstyles; i++) { - if(layer->class[shape.classindex]->styles[i]->numbindings > 0) cache = MS_FALSE; + cache = MS_TRUE; /* only line layers with multiple styles need be cached + (I don't think POLYLINE layers need caching - SDL) */ + + /* we can't handle caching with attribute binding other than for the first + * style (#3976) */ + for (i = 1; i < layer->class[shape.classindex] -> numstyles; i++) { + if (layer->class[shape.classindex] -> styles[i] -> numbindings > 0) + cache = MS_FALSE; } } /* With 'STYLEITEM AUTO', we will have the datasource fill the class' */ /* style parameters for this shape. */ - if(layer->styleitem) { - if(strcasecmp(layer->styleitem, "AUTO") == 0) { - if(msLayerGetAutoStyle(map, layer, layer->class[shape.classindex], &shape) != MS_SUCCESS) { + if (layer->styleitem) { + if (strcasecmp(layer->styleitem, "AUTO") == 0) { + if (msLayerGetAutoStyle(map, layer, layer->class[shape.classindex], + &shape) != MS_SUCCESS) { retcode = MS_FAILURE; break; } } else { /* Generic feature style handling as per RFC-61 */ - if(msLayerGetFeatureStyle(map, layer, layer->class[shape.classindex], &shape) != MS_SUCCESS) { + if (msLayerGetFeatureStyle(map, layer, layer->class[shape.classindex], + &shape) != MS_SUCCESS) { retcode = MS_FAILURE; break; } @@ -1184,31 +1289,31 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) cache = MS_FALSE; } - if (rendermode == MS_ALL_MATCHING_CLASSES) - { + if (rendermode == MS_ALL_MATCHING_CLASSES) { // Cache is designed to handle only one class. Therefore it is // disabled when using SLD "painters model" rendering mode. cache = MS_FALSE; } - /* RFC77 TODO: check return value, may need a more sophisticated if-then test. */ - if(annotate && layer->class[shape.classindex]->numlabels > 0) { + /* RFC77 TODO: check return value, may need a more sophisticated if-then + * test. */ + if (annotate && layer->class[shape.classindex] -> numlabels > 0) { drawmode |= MS_DRAWMODE_LABELS; if (msLayerGetProcessingKey(layer, "LABEL_NO_CLIP")) { drawmode |= MS_DRAWMODE_UNCLIPPEDLABELS; } } - if (layer->type == MS_LAYER_LINE && msLayerGetProcessingKey(layer, "POLYLINE_NO_CLIP")) { + if (layer->type == MS_LAYER_LINE && + msLayerGetProcessingKey(layer, "POLYLINE_NO_CLIP")) { drawmode |= MS_DRAWMODE_UNCLIPPEDLINES; } - if (rendermode == MS_ALL_MATCHING_CLASSES) - { - // In SLD "painters model" rendering mode, all applicable classes are actually applied. - // Coordinates stored in the shape must keep their original values for - // the shape to be drawn multiple times. - // Here the original shape is saved. + if (rendermode == MS_ALL_MATCHING_CLASSES) { + // In SLD "painters model" rendering mode, all applicable classes are + // actually applied. Coordinates stored in the shape must keep their + // original values for the shape to be drawn multiple times. Here the + // original shape is saved. msInitShape(&savedShape); msCopyShape(&shape, &savedShape); } @@ -1224,86 +1329,95 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) * - draw the shape (the outline) in the first pass of the * caching mechanism */ - msOutlineRenderingPrepareStyle(pStyle, map, layer, image); + msOutlineRenderingPrepareStyle(pStyle, map, layer, image); } - status = msDrawShape(map, layer, &shape, image, 0, drawmode|MS_DRAWMODE_SINGLESTYLE); /* draw a single style */ + status = msDrawShape( + map, layer, &shape, image, 0, + drawmode | MS_DRAWMODE_SINGLESTYLE); /* draw a single style */ if (pStyle->outlinewidth > 0) { /* * RFC 49 implementation: switch back the styleobj to its * original state, so the line fill will be drawn in the * second pass of the caching mechanism */ - msOutlineRenderingRestoreStyle(pStyle, map, layer, image); + msOutlineRenderingRestoreStyle(pStyle, map, layer, image); } } else - status = msDrawShape(map, layer, &shape, image, -1, drawmode); /* all styles */ - - if (rendermode == MS_ALL_MATCHING_CLASSES) - { - // In SLD "painters model" rendering mode, all applicable classes are actually applied. - // Coordinates stored in the shape must keep their original values for - // the shape to be drawn multiple times. - // Here the original shape is restored. + status = + msDrawShape(map, layer, &shape, image, -1, drawmode); /* all styles */ + + if (rendermode == MS_ALL_MATCHING_CLASSES) { + // In SLD "painters model" rendering mode, all applicable classes are + // actually applied. Coordinates stored in the shape must keep their + // original values for the shape to be drawn multiple times. Here the + // original shape is restored. msFreeShape(&shape); msCopyShape(&savedShape, &shape); msFreeShape(&savedShape); } - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { retcode = MS_FAILURE; break; } - - if(shape.numlines == 0) { /* once clipped the shape didn't need to be drawn */ + + if (shape.numlines == + 0) { /* once clipped the shape didn't need to be drawn */ continue; } - if(cache) { - if(insertFeatureList(&shpcache, &shape) == NULL) { + if (cache) { + if (insertFeatureList(&shpcache, &shape) == NULL) { retcode = MS_FAILURE; /* problem adding to the cache */ break; } } - maxnumstyles = MS_MAX(maxnumstyles, layer->class[shape.classindex]->numstyles); - + maxnumstyles = + MS_MAX(maxnumstyles, layer->class[shape.classindex] -> numstyles); } msFreeShape(&shape); if (classgroup) msFree(classgroup); - if(status != MS_DONE || retcode == MS_FAILURE) { + if (status != MS_DONE || retcode == MS_FAILURE) { msLayerClose(layer); - if(shpcache) { + if (shpcache) { freeFeatureList(shpcache); shpcache = NULL; } return MS_FAILURE; } - if(shpcache && MS_DRAW_FEATURES(drawmode)) { + if (shpcache && MS_DRAW_FEATURES(drawmode)) { int s; - for(s=0; snext) { - if(layer->class[current->shape.classindex]->numstyles > s) { + for (s = 0; s < maxnumstyles; s++) { + for (current = shpcache; current; current = current->next) { + if (layer->class[current->shape.classindex] -> numstyles > s) { styleObj *pStyle = layer->class[current->shape.classindex]->styles[s]; - if(pStyle->_geomtransform.type != MS_GEOMTRANSFORM_NONE) + if (pStyle->_geomtransform.type != MS_GEOMTRANSFORM_NONE) continue; /*skip this as it has already been rendered*/ - if(map->scaledenom > 0) { - if((pStyle->maxscaledenom != -1) && (map->scaledenom >= pStyle->maxscaledenom)) + if (map->scaledenom > 0) { + if ((pStyle->maxscaledenom != -1) && + (map->scaledenom >= pStyle->maxscaledenom)) continue; - if((pStyle->minscaledenom != -1) && (map->scaledenom < pStyle->minscaledenom)) + if ((pStyle->minscaledenom != -1) && + (map->scaledenom < pStyle->minscaledenom)) continue; } - if(s==0 && pStyle->outlinewidth>0 && MS_VALID_COLOR(pStyle->color)) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) { + if (s == 0 && pStyle->outlinewidth > 0 && + MS_VALID_COLOR(pStyle->color)) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) { return MS_FAILURE; } - } else if(s>0) { - if (pStyle->outlinewidth > 0 && MS_VALID_COLOR(pStyle->outlinecolor)) { + } else if (s > 0) { + if (pStyle->outlinewidth > 0 && + MS_VALID_COLOR(pStyle->outlinecolor)) { /* * RFC 49 implementation * if an outlinewidth is used: @@ -1312,8 +1426,10 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) * - draw the shape (the outline) in the first pass of the * caching mechanism */ - msOutlineRenderingPrepareStyle(pStyle, map, layer, image); - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) { + msOutlineRenderingPrepareStyle(pStyle, map, layer, image); + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) { return MS_FAILURE; } /* @@ -1321,19 +1437,19 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) * original state, so the line fill will be drawn in the * second pass of the caching mechanism */ - msOutlineRenderingRestoreStyle(pStyle, map, layer, image); + msOutlineRenderingRestoreStyle(pStyle, map, layer, image); } - /* draw a valid line, i.e. one with a color defined or of type pixmap*/ - if(MS_VALID_COLOR(pStyle->color) || - ( - pStyle->symbolsymbolset.numsymbols && - ( - map->symbolset.symbol[pStyle->symbol]->type == MS_SYMBOL_PIXMAP || - map->symbolset.symbol[pStyle->symbol]->type == MS_SYMBOL_SVG - ) - ) - ) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) + /* draw a valid line, i.e. one with a color defined or of type + * pixmap*/ + if (MS_VALID_COLOR(pStyle->color) || + (pStyle->symbol < map->symbolset.numsymbols && + (map->symbolset.symbol[pStyle->symbol]->type == + MS_SYMBOL_PIXMAP || + map->symbolset.symbol[pStyle->symbol]->type == + MS_SYMBOL_SVG))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) return MS_FAILURE; } } @@ -1347,52 +1463,60 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) msLayerClose(layer); return MS_SUCCESS; - } /* -** Function to draw a layer IF it already has a result cache associated with it. Called by msDrawMap and via MapScript. +** Function to draw a layer IF it already has a result cache associated with it. +*Called by msDrawMap and via MapScript. */ -int msDrawQueryLayer(mapObj *map, layerObj *layer, imageObj *image) -{ +int msDrawQueryLayer(mapObj *map, layerObj *layer, imageObj *image) { int i, status; - char annotate=MS_TRUE, cache=MS_FALSE; + char annotate = MS_TRUE, cache = MS_FALSE; int drawmode = MS_DRAWMODE_FEATURES; shapeObj shape; - int maxnumstyles=1; + int maxnumstyles = 1; - featureListNodeObjPtr shpcache=NULL, current=NULL; + featureListNodeObjPtr shpcache = NULL, current = NULL; colorObj *colorbuffer = NULL; int *mindistancebuffer = NULL; - if(!layer->resultcache) return(msDrawLayer(map, layer, image)); + if (!layer->resultcache) + return (msDrawLayer(map, layer, image)); - if(!msLayerIsVisible(map, layer)) return(MS_SUCCESS); /* not an error, just nothing to do */ + if (!msLayerIsVisible(map, layer)) + return (MS_SUCCESS); /* not an error, just nothing to do */ /* conditions may have changed since this layer last drawn, so reset layer->project to recheck projection needs (Bug #673) */ - layer->project = msProjectionsDiffer(&(layer->projection),&(map->projection)); + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); /* set annotation status */ annotate = msEvalContext(map, layer, layer->labelrequires); - if(map->scaledenom > 0) { - if((layer->labelmaxscaledenom != -1) && (map->scaledenom >= layer->labelmaxscaledenom)) annotate = MS_FALSE; - if((layer->labelminscaledenom != -1) && (map->scaledenom < layer->labelminscaledenom)) annotate = MS_FALSE; + if (map->scaledenom > 0) { + if ((layer->labelmaxscaledenom != -1) && + (map->scaledenom >= layer->labelmaxscaledenom)) + annotate = MS_FALSE; + if ((layer->labelminscaledenom != -1) && + (map->scaledenom < layer->labelminscaledenom)) + annotate = MS_FALSE; } /* - ** Certain query map styles require us to render all features only (MS_NORMAL) or first (MS_HILITE). With - ** single-pass queries we have to make a copy of the layer and work from it instead. + ** Certain query map styles require us to render all features only (MS_NORMAL) + *or first (MS_HILITE). With + ** single-pass queries we have to make a copy of the layer and work from it + *instead. */ - if(map->querymap.style == MS_NORMAL || map->querymap.style == MS_HILITE) { + if (map->querymap.style == MS_NORMAL || map->querymap.style == MS_HILITE) { layerObj tmp_layer; - if(initLayer(&tmp_layer, map) == -1) - return(MS_FAILURE); + if (initLayer(&tmp_layer, map) == -1) + return (MS_FAILURE); if (msCopyLayer(&tmp_layer, layer) != MS_SUCCESS) - return(MS_FAILURE); + return (MS_FAILURE); /* disable the connection pool for this layer */ msLayerSetProcessingKey(&tmp_layer, "CLOSE_CONNECTION", "ALWAYS"); @@ -1401,72 +1525,113 @@ int msDrawQueryLayer(mapObj *map, layerObj *layer, imageObj *image) freeLayer(&tmp_layer); - if(map->querymap.style == MS_NORMAL || status != MS_SUCCESS) return(status); + if (map->querymap.style == MS_NORMAL || status != MS_SUCCESS) + return (status); } - /* if MS_HILITE, alter the one style (always at least 1 style), and set a MINDISTANCE for the labelObj to avoid duplicates */ - if(map->querymap.style == MS_HILITE) { + /* if MS_HILITE, alter the one style (always at least 1 style), and set a + * MINDISTANCE for the labelObj to avoid duplicates */ + if (map->querymap.style == MS_HILITE) { drawmode |= MS_DRAWMODE_QUERY; if (layer->numclasses > 0) { - colorbuffer = (colorObj*)msSmallMalloc(layer->numclasses*sizeof(colorObj)); - mindistancebuffer = (int*)msSmallMalloc(layer->numclasses*sizeof(int)); + colorbuffer = + (colorObj *)msSmallMalloc(layer->numclasses * sizeof(colorObj)); + mindistancebuffer = (int *)msSmallMalloc(layer->numclasses * sizeof(int)); } - for(i=0; inumclasses; i++) { - if(layer->type == MS_LAYER_POLYGON && layer->class[i]->numstyles > 0) { /* alter BOTTOM style since that's almost always the fill */ - if (layer->class[i]->styles == NULL) { - msSetError(MS_MISCERR, "Don't know how to draw class %s of layer %s without a style definition.", "msDrawQueryLayer()", layer->class[i]->name, layer->name); + for (i = 0; i < layer->numclasses; i++) { + if (layer->type == MS_LAYER_POLYGON && + layer->class[i] -> numstyles > + 0) { /* alter BOTTOM style since that's + almost always the fill */ + if (layer->class[i] -> styles == NULL) { + msSetError(MS_MISCERR, + "Don't know how to draw class %s of layer %s without a " + "style definition.", + "msDrawQueryLayer()", layer->class[i] -> name, + layer -> name); msFree(colorbuffer); msFree(mindistancebuffer); - return(MS_FAILURE); + return (MS_FAILURE); } - if(MS_VALID_COLOR(layer->class[i]->styles[0]->color)) { - colorbuffer[i] = layer->class[i]->styles[0]->color; /* save the color from the BOTTOM style */ + if (MS_VALID_COLOR(layer->class[i] -> styles[0] -> color)) { + colorbuffer[i] = + layer->class[i] + ->styles[0] + ->color; /* save the color from the BOTTOM style */ layer->class[i]->styles[0]->color = map->querymap.color; - } else if(MS_VALID_COLOR(layer->class[i]->styles[0]->outlinecolor)) { - colorbuffer[i] = layer->class[i]->styles[0]->outlinecolor; /* if no color, save the outlinecolor from the BOTTOM style */ + } else if (MS_VALID_COLOR( + layer->class[i] -> styles[0] -> outlinecolor)) { + colorbuffer[i] = + layer->class[i] + ->styles[0] + ->outlinecolor; /* if no color, save the outlinecolor from the + BOTTOM style */ layer->class[i]->styles[0]->outlinecolor = map->querymap.color; } - } else if (layer->type == MS_LAYER_LINE && layer->class[i]->numstyles > 0 && layer->class[i]->styles[0]->outlinewidth > 0) { /* alter BOTTOM style for lines with outlines */ - if(MS_VALID_COLOR(layer->class[i]->styles[0]->color)) { - colorbuffer[i] = layer->class[i]->styles[0]->color; /* save the color from the BOTTOM style */ + } else if (layer->type == MS_LAYER_LINE && + layer->class[i] -> numstyles > 0 && + layer -> class[i] -> styles[0] + -> outlinewidth > + 0) { /* alter BOTTOM style for lines with outlines */ + if (MS_VALID_COLOR(layer->class[i] -> styles[0] -> color)) { + colorbuffer[i] = + layer->class[i] + ->styles[0] + ->color; /* save the color from the BOTTOM style */ layer->class[i]->styles[0]->color = map->querymap.color; } /* else ??? */ - } else if (layer->class[i]->numstyles > 0) { - if(MS_VALID_COLOR(layer->class[i]->styles[layer->class[i]->numstyles-1]->color)) { - colorbuffer[i] = layer->class[i]->styles[layer->class[i]->numstyles-1]->color; /* save the color from the TOP style */ - layer->class[i]->styles[layer->class[i]->numstyles-1]->color = map->querymap.color; - } else if(MS_VALID_COLOR(layer->class[i]->styles[layer->class[i]->numstyles-1]->outlinecolor)) { - colorbuffer[i] = layer->class[i]->styles[layer->class[i]->numstyles-1]->outlinecolor; /* if no color, save the outlinecolor from the TOP style */ - layer->class[i]->styles[layer->class[i]->numstyles-1]->outlinecolor = map->querymap.color; + } else if (layer->class[i] -> numstyles > 0) { + if (MS_VALID_COLOR( + layer->class[i] -> styles[layer->class[i] -> numstyles - 1] + -> color)) { + colorbuffer[i] = layer->class[i] + ->styles[layer->class[i] -> numstyles - 1] + ->color; /* save the color from the TOP style */ + layer->class[i]->styles[layer->class[i] -> numstyles - 1]->color = + map->querymap.color; + } else if (MS_VALID_COLOR(layer->class[i] + -> styles[layer->class[i] -> numstyles - 1] + -> outlinecolor)) { + colorbuffer[i] = + layer->class[i] + ->styles[layer->class[i] -> numstyles - 1] + ->outlinecolor; /* if no color, save the outlinecolor from the + TOP style */ + layer->class[i] + ->styles[layer->class[i] -> numstyles - 1] + ->outlinecolor = map->querymap.color; } - } else if (layer->class[i]->numlabels > 0) { - colorbuffer[i] = layer->class[i]->labels[0]->color; - layer->class[i]->labels[0]->color = map->querymap.color; + } else if (layer->class[i] -> numlabels > 0) { + colorbuffer[i] = layer->class[i]->labels[0]->color; + layer->class[i]->labels[0]->color = map->querymap.color; } /* else ??? */ - mindistancebuffer[i] = -1; /* RFC77 TODO: only using the first label, is that cool? */ - if(layer->class[i]->numlabels > 0) { + mindistancebuffer[i] = + -1; /* RFC77 TODO: only using the first label, is that cool? */ + if (layer->class[i] -> numlabels > 0) { mindistancebuffer[i] = layer->class[i]->labels[0]->mindistance; - layer->class[i]->labels[0]->mindistance = MS_MAX(0, layer->class[i]->labels[0]->mindistance); + layer->class[i]->labels[0]->mindistance = + MS_MAX(0, layer->class[i] -> labels[0] -> mindistance); } } } /* - ** Layer was opened as part of the query process, msLayerWhichItems() has also been run, shapes have been classified - start processing! + ** Layer was opened as part of the query process, msLayerWhichItems() has also + *been run, shapes have been classified - start processing! */ msInitShape(&shape); - for(i=0; iresultcache->numresults; i++) { + for (i = 0; i < layer->resultcache->numresults; i++) { status = msLayerGetShape(layer, &shape, &(layer->resultcache->results[i])); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msFree(colorbuffer); msFree(mindistancebuffer); - return(MS_FAILURE); + return (MS_FAILURE); } shape.classindex = layer->resultcache->results[i].classindex; @@ -1477,89 +1642,119 @@ int msDrawQueryLayer(mapObj *map, layerObj *layer, imageObj *image) * FrankW: classindex is also sometimes 0 even if there are no classes, so * we are careful not to use out of range class values as an index. */ - if(shape.classindex==-1 - || shape.classindex >= layer->numclasses - || layer->class[shape.classindex]->status == MS_OFF) { + if (shape.classindex == -1 || shape.classindex >= layer->numclasses || + layer->class[shape.classindex] -> status == MS_OFF) { msFreeShape(&shape); continue; } cache = MS_FALSE; - if(layer->type == MS_LAYER_LINE && (layer->class[shape.classindex]->numstyles > 1 || (layer->class[shape.classindex]->numstyles == 1 && layer->class[shape.classindex]->styles[0]->outlinewidth > 0))) { + if (layer->type == MS_LAYER_LINE && + (layer->class[shape.classindex] + -> numstyles > 1 || + (layer->class[shape.classindex] -> numstyles == 1 && layer + -> class[shape.classindex] -> styles[0] -> outlinewidth > + 0))) { int i; - cache = MS_TRUE; /* only line layers with multiple styles need be cached (I don't think POLYLINE layers need caching - SDL) */ - - /* we can't handle caching with attribute binding other than for the first style (#3976) */ - for(i=1; iclass[shape.classindex]->numstyles; i++) { - if(layer->class[shape.classindex]->styles[i]->numbindings > 0) cache = MS_FALSE; + cache = MS_TRUE; /* only line layers with multiple styles need be cached + (I don't think POLYLINE layers need caching - SDL) */ + + /* we can't handle caching with attribute binding other than for the first + * style (#3976) */ + for (i = 1; i < layer->class[shape.classindex] -> numstyles; i++) { + if (layer->class[shape.classindex] -> styles[i] -> numbindings > 0) + cache = MS_FALSE; } } - if(annotate && layer->class[shape.classindex]->numlabels > 0) { + if (annotate && layer->class[shape.classindex] -> numlabels > 0) { drawmode |= MS_DRAWMODE_LABELS; } - if(cache) { + if (cache) { styleObj *pStyle = layer->class[shape.classindex]->styles[0]; - if (pStyle->outlinewidth > 0) msOutlineRenderingPrepareStyle(pStyle, map, layer, image); - status = msDrawShape(map, layer, &shape, image, 0, drawmode|MS_DRAWMODE_SINGLESTYLE); /* draw only the first style */ - if (pStyle->outlinewidth > 0) msOutlineRenderingRestoreStyle(pStyle, map, layer, image); + if (pStyle->outlinewidth > 0) + msOutlineRenderingPrepareStyle(pStyle, map, layer, image); + status = msDrawShape( + map, layer, &shape, image, 0, + drawmode | MS_DRAWMODE_SINGLESTYLE); /* draw only the first style */ + if (pStyle->outlinewidth > 0) + msOutlineRenderingRestoreStyle(pStyle, map, layer, image); } else { - status = msDrawShape(map, layer, &shape, image, -1, drawmode); /* all styles */ + status = + msDrawShape(map, layer, &shape, image, -1, drawmode); /* all styles */ } - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msLayerClose(layer); msFree(colorbuffer); msFree(mindistancebuffer); - return(MS_FAILURE); + return (MS_FAILURE); } - if(shape.numlines == 0) { /* once clipped the shape didn't need to be drawn */ + if (shape.numlines == + 0) { /* once clipped the shape didn't need to be drawn */ msFreeShape(&shape); continue; } - if(cache) { - if(insertFeatureList(&shpcache, &shape) == NULL) { + if (cache) { + if (insertFeatureList(&shpcache, &shape) == NULL) { msFree(colorbuffer); msFree(mindistancebuffer); - return(MS_FAILURE); /* problem adding to the cache */ + return (MS_FAILURE); /* problem adding to the cache */ } } - maxnumstyles = MS_MAX(maxnumstyles, layer->class[shape.classindex]->numstyles); + maxnumstyles = + MS_MAX(maxnumstyles, layer->class[shape.classindex] -> numstyles); msFreeShape(&shape); } - if(shpcache) { + if (shpcache) { int s; - for(s=0; snext) { - if(layer->class[current->shape.classindex]->numstyles > s) { + for (s = 0; s < maxnumstyles; s++) { + for (current = shpcache; current; current = current->next) { + if (layer->class[current->shape.classindex] -> numstyles > s) { styleObj *pStyle = layer->class[current->shape.classindex]->styles[s]; - if(pStyle->_geomtransform.type != MS_GEOMTRANSFORM_NONE) + if (pStyle->_geomtransform.type != MS_GEOMTRANSFORM_NONE) continue; /* skip this as it has already been rendered */ - if(map->scaledenom > 0) { - if((pStyle->maxscaledenom != -1) && (map->scaledenom >= pStyle->maxscaledenom)) + if (map->scaledenom > 0) { + if ((pStyle->maxscaledenom != -1) && + (map->scaledenom >= pStyle->maxscaledenom)) continue; - if((pStyle->minscaledenom != -1) && (map->scaledenom < pStyle->minscaledenom)) + if ((pStyle->minscaledenom != -1) && + (map->scaledenom < pStyle->minscaledenom)) continue; } - if(s==0 && pStyle->outlinewidth>0 && MS_VALID_COLOR(pStyle->color)) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) { + if (s == 0 && pStyle->outlinewidth > 0 && + MS_VALID_COLOR(pStyle->color)) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) { return MS_FAILURE; } - } else if(s>0) { - if (pStyle->outlinewidth > 0 && MS_VALID_COLOR(pStyle->outlinecolor)) { + } else if (s > 0) { + if (pStyle->outlinewidth > 0 && + MS_VALID_COLOR(pStyle->outlinecolor)) { msOutlineRenderingPrepareStyle(pStyle, map, layer, image); - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) { return MS_FAILURE; } msOutlineRenderingRestoreStyle(pStyle, map, layer, image); } - /* draw a valid line, i.e. one with a color defined or of type pixmap */ - if(MS_VALID_COLOR(pStyle->color) || (pStyle->symbolsymbolset.numsymbols && (map->symbolset.symbol[pStyle->symbol]->type == MS_SYMBOL_PIXMAP || map->symbolset.symbol[pStyle->symbol]->type == MS_SYMBOL_SVG))) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, ¤t->shape, pStyle, pStyle->scalefactor))) + /* draw a valid line, i.e. one with a color defined or of type + * pixmap */ + if (MS_VALID_COLOR(pStyle->color) || + (pStyle->symbol < map->symbolset.numsymbols && + (map->symbolset.symbol[pStyle->symbol]->type == + MS_SYMBOL_PIXMAP || + map->symbolset.symbol[pStyle->symbol]->type == + MS_SYMBOL_SVG))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, ¤t->shape, + pStyle, pStyle->scalefactor))) return MS_FAILURE; } } @@ -1572,72 +1767,99 @@ int msDrawQueryLayer(mapObj *map, layerObj *layer, imageObj *image) } /* if MS_HILITE, restore color and mindistance values */ - if(map->querymap.style == MS_HILITE) { - for(i=0; inumclasses; i++) { - if(layer->type == MS_LAYER_POLYGON && layer->class[i]->numstyles > 0) { - if(MS_VALID_COLOR(layer->class[i]->styles[0]->color)) + if (map->querymap.style == MS_HILITE) { + for (i = 0; i < layer->numclasses; i++) { + if (layer->type == MS_LAYER_POLYGON && layer->class[i] -> numstyles > 0) { + if (MS_VALID_COLOR(layer->class[i] -> styles[0] -> color)) + layer->class[i]->styles[0]->color = colorbuffer[i]; + else if (MS_VALID_COLOR(layer->class[i] -> styles[0] -> outlinecolor)) + layer->class[i]->styles[0]->outlinecolor = + colorbuffer[i]; /* if no color, restore outlinecolor for the + BOTTOM style */ + } else if (layer->type == MS_LAYER_LINE && + layer->class[i] -> numstyles > 0 && layer -> class[i] + -> styles[0] -> outlinewidth > 0) { + if (MS_VALID_COLOR(layer->class[i] -> styles[0] -> color)) layer->class[i]->styles[0]->color = colorbuffer[i]; - else if(MS_VALID_COLOR(layer->class[i]->styles[0]->outlinecolor)) - layer->class[i]->styles[0]->outlinecolor = colorbuffer[i]; /* if no color, restore outlinecolor for the BOTTOM style */ - } else if (layer->type == MS_LAYER_LINE && layer->class[i]->numstyles > 0 && layer->class[i]->styles[0]->outlinewidth > 0) { - if(MS_VALID_COLOR(layer->class[i]->styles[0]->color)) - layer->class[i]->styles[0]->color = colorbuffer[i]; - } else if (layer->class[i]->numstyles > 0) { - if(MS_VALID_COLOR(layer->class[i]->styles[layer->class[i]->numstyles-1]->color)) - layer->class[i]->styles[layer->class[i]->numstyles-1]->color = colorbuffer[i]; - else if(MS_VALID_COLOR(layer->class[i]->styles[layer->class[i]->numstyles-1]->outlinecolor)) - layer->class[i]->styles[layer->class[i]->numstyles-1]->outlinecolor = colorbuffer[i]; /* if no color, restore outlinecolor for the TOP style */ - } else if (layer->class[i]->numlabels > 0) { - if(MS_VALID_COLOR(layer->class[i]->labels[0]->color)) + } else if (layer->class[i] -> numstyles > 0) { + if (MS_VALID_COLOR( + layer->class[i] -> styles[layer->class[i] -> numstyles - 1] + -> color)) + layer->class[i]->styles[layer->class[i] -> numstyles - 1]->color = + colorbuffer[i]; + else if (MS_VALID_COLOR( + layer->class[i] -> styles[layer->class[i] -> numstyles - 1] + -> outlinecolor)) + layer->class[i] + ->styles[layer->class[i] -> numstyles - 1] + ->outlinecolor = + colorbuffer[i]; /* if no color, restore outlinecolor for the TOP + style */ + } else if (layer->class[i] -> numlabels > 0) { + if (MS_VALID_COLOR(layer->class[i] -> labels[0] -> color)) layer->class[i]->labels[0]->color = colorbuffer[i]; } - if(layer->class[i]->numlabels > 0) - layer->class[i]->labels[0]->mindistance = mindistancebuffer[i]; /* RFC77 TODO: again, only using the first label, is that cool? */ + if (layer->class[i] -> numlabels > 0) + layer->class[i]->labels[0]->mindistance = + mindistancebuffer[i]; /* RFC77 TODO: again, only using the first + label, is that cool? */ } msFree(colorbuffer); msFree(mindistancebuffer); } - return(MS_SUCCESS); + return (MS_SUCCESS); } /** * msDrawRasterLayerPlugin() */ -static int -msDrawRasterLayerPlugin( mapObj *map, layerObj *layer, imageObj *image) +static int msDrawRasterLayerPlugin(mapObj *map, layerObj *layer, + imageObj *image) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image); - rasterBufferObj *rb = msSmallCalloc(1,sizeof(rasterBufferObj)); + rasterBufferObj *rb = msSmallCalloc(1, sizeof(rasterBufferObj)); int ret; - if( renderer->supports_pixel_buffer ) { - if (MS_SUCCESS != renderer->getRasterBufferHandle( image, rb )) { - msSetError(MS_MISCERR,"renderer failed to extract raster buffer","msDrawRasterLayer()"); + if (renderer->supports_pixel_buffer) { + if (MS_SUCCESS != renderer->getRasterBufferHandle(image, rb)) { + msSetError(MS_MISCERR, "renderer failed to extract raster buffer", + "msDrawRasterLayer()"); return MS_FAILURE; } - ret = msDrawRasterLayerLow( map, layer, image, rb ); + ret = msDrawRasterLayerLow(map, layer, image, rb); } else { - if (MS_SUCCESS != renderer->initializeRasterBuffer( rb, image->width, image->height, MS_IMAGEMODE_RGBA )) { - msSetError(MS_MISCERR,"renderer failed to create raster buffer","msDrawRasterLayer()"); + if (MS_SUCCESS != renderer->initializeRasterBuffer( + rb, image->width, image->height, MS_IMAGEMODE_RGBA)) { + msSetError(MS_MISCERR, "renderer failed to create raster buffer", + "msDrawRasterLayer()"); return MS_FAILURE; } - ret = msDrawRasterLayerLow( map, layer, image, rb ); + ret = msDrawRasterLayerLow(map, layer, image, rb); - if( ret == 0 ) { - ret = renderer->mergeRasterBuffer( image, rb, 1.0, 0, 0, 0, 0, rb->width, rb->height ); + if (ret == 0) { + ret = renderer->mergeRasterBuffer(image, rb, 1.0, 0, 0, 0, 0, rb->width, + rb->height); } msFreeRasterBuffer(rb); } -#define RB_GET_R(rb,x,y) *((rb)->data.rgba.r + (x) * (rb)->data.rgba.pixel_step + (y) * (rb)->data.rgba.row_step) -#define RB_GET_G(rb,x,y) *((rb)->data.rgba.g + (x) * (rb)->data.rgba.pixel_step + (y) * (rb)->data.rgba.row_step) -#define RB_GET_B(rb,x,y) *((rb)->data.rgba.b + (x) * (rb)->data.rgba.pixel_step + (y) * (rb)->data.rgba.row_step) -#define RB_GET_A(rb,x,y) *((rb)->data.rgba.a + (x) * (rb)->data.rgba.pixel_step + (y) * (rb)->data.rgba.row_step) +#define RB_GET_R(rb, x, y) \ + *((rb)->data.rgba.r + (x) * (rb)->data.rgba.pixel_step + \ + (y) * (rb)->data.rgba.row_step) +#define RB_GET_G(rb, x, y) \ + *((rb)->data.rgba.g + (x) * (rb)->data.rgba.pixel_step + \ + (y) * (rb)->data.rgba.row_step) +#define RB_GET_B(rb, x, y) \ + *((rb)->data.rgba.b + (x) * (rb)->data.rgba.pixel_step + \ + (y) * (rb)->data.rgba.row_step) +#define RB_GET_A(rb, x, y) \ + *((rb)->data.rgba.a + (x) * (rb)->data.rgba.pixel_step + \ + (y) * (rb)->data.rgba.row_step) free(rb); @@ -1647,20 +1869,21 @@ msDrawRasterLayerPlugin( mapObj *map, layerObj *layer, imageObj *image) /** * Generic function to render raster layers. */ -int msDrawRasterLayer(mapObj *map, layerObj *layer, imageObj *image) -{ - +int msDrawRasterLayer(mapObj *map, layerObj *layer, imageObj *image) { + int rv = MS_FAILURE; if (!image || !map || !layer) { return rv; } /* RFC-86 Scale dependant token replacements*/ - rv = msLayerApplyScaletokens(layer,(layer->map)?layer->map->scaledenom:-1); - if (rv != MS_SUCCESS) return rv; - if( MS_RENDERER_PLUGIN(image->format) ) + rv = msLayerApplyScaletokens(layer, + (layer->map) ? layer->map->scaledenom : -1); + if (rv != MS_SUCCESS) + return rv; + if (MS_RENDERER_PLUGIN(image->format)) rv = msDrawRasterLayerPlugin(map, layer, image); - else if( MS_RENDERER_RAWDATA(image->format) ) + else if (MS_RENDERER_RAWDATA(image->format)) rv = msDrawRasterLayerLow(map, layer, image, NULL); msLayerRestoreFromScaletokens(layer); return rv; @@ -1675,8 +1898,7 @@ int msDrawRasterLayer(mapObj *map, layerObj *layer, imageObj *image) */ #ifdef USE_WMS_LYR -int msDrawWMSLayer(mapObj *map, layerObj *layer, imageObj *image) -{ +int msDrawWMSLayer(mapObj *map, layerObj *layer, imageObj *image) { int nStatus = MS_FAILURE; if (image && map && layer) { @@ -1688,22 +1910,19 @@ int msDrawWMSLayer(mapObj *map, layerObj *layer, imageObj *image) msHTTPInitRequestObj(asReqInfo, 2); - if ( msPrepareWMSLayerRequest(1, map, layer, 1, - 0, NULL, 0, 0, 0, NULL, - asReqInfo, &numReq) == MS_FAILURE || - msOWSExecuteRequests(asReqInfo, numReq, map, MS_TRUE) == MS_FAILURE ) { + if (msPrepareWMSLayerRequest(1, map, layer, 1, 0, NULL, 0, 0, 0, NULL, + asReqInfo, &numReq) == MS_FAILURE || + msOWSExecuteRequests(asReqInfo, numReq, map, MS_TRUE) == MS_FAILURE) { return MS_FAILURE; } /* ------------------------------------------------------------------ * Then draw layer based on output format * ------------------------------------------------------------------ */ - if( MS_RENDERER_PLUGIN(image->format) ) - nStatus = msDrawWMSLayerLow(1, asReqInfo, numReq, - map, layer, image) ; - else if( MS_RENDERER_RAWDATA(image->format) ) - nStatus = msDrawWMSLayerLow(1, asReqInfo, numReq, - map, layer, image) ; + if (MS_RENDERER_PLUGIN(image->format)) + nStatus = msDrawWMSLayerLow(1, asReqInfo, numReq, map, layer, image); + else if (MS_RENDERER_RAWDATA(image->format)) + nStatus = msDrawWMSLayerLow(1, asReqInfo, numReq, map, layer, image); else { msSetError(MS_WMSCONNERR, @@ -1719,15 +1938,17 @@ int msDrawWMSLayer(mapObj *map, layerObj *layer, imageObj *image) } #endif -int circleLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape) -{ +int circleLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, + shapeObj *shape) { pointObj center; double r; int s; int c = shape->classindex; - if (shape->numlines != 1) return (MS_SUCCESS); /* invalid shape */ - if (shape->line[0].numpoints != 2) return (MS_SUCCESS); /* invalid shape */ + if (shape->numlines != 1) + return (MS_SUCCESS); /* invalid shape */ + if (shape->line[0].numpoints != 2) + return (MS_SUCCESS); /* invalid shape */ center.x = (shape->line[0].point[0].x + shape->line[0].point[1].x) / 2.0; center.y = (shape->line[0].point[0].y + shape->line[0].point[1].y) / 2.0; @@ -1748,12 +1969,14 @@ int circleLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj } else msOffsetPointRelativeTo(¢er, layer); - for (s = 0; s < layer->class[c]->numstyles; s++) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { if (msScaleInBounds(map->scaledenom, - layer->class[c]->styles[s]->minscaledenom, - layer->class[c]->styles[s]->maxscaledenom)) - if(MS_UNLIKELY(MS_FAILURE == msCircleDrawShadeSymbol(map, image, ¢er, r, - layer->class[c]->styles[s], layer->class[c]->styles[s]->scalefactor))) { + layer->class[c] -> styles[s] -> minscaledenom, + layer -> class[c] -> styles[s] -> maxscaledenom)) + if (MS_UNLIKELY(MS_FAILURE == + msCircleDrawShadeSymbol( + map, image, ¢er, r, layer->class[c] -> styles[s], + layer -> class[c] -> styles[s] -> scalefactor))) { return MS_FAILURE; } } @@ -1761,37 +1984,31 @@ int circleLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj /* TODO: need to handle circle annotation */ } -static -int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape, int drawmode) -{ +static int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, + shapeObj *shape, int drawmode) { int l, c = shape->classindex, j, i, s; pointObj *point; int ret = MS_FAILURE; - if (layer->project && layer->transform == MS_TRUE) - { - reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, map); - if( reprojector == NULL ) - { - return MS_FAILURE; - } - msProjectShapeEx(reprojector, shape); + if (layer->project && layer->transform == MS_TRUE) { + reprojectionObj *reprojector = msLayerGetReprojectorToMap(layer, map); + if (reprojector == NULL) { + return MS_FAILURE; + } + msProjectShapeEx(reprojector, shape); } // Only take into account map rotation if the label and style angles are // non-zero. - if( map->gt.rotation_angle ) - { - for (l = 0; l < layer->class[c]->numlabels; l++) - { - if( layer->class[c]->labels[l]->angle != 0 ) - layer->class[c]->labels[l]->angle -= map->gt.rotation_angle; + if (map->gt.rotation_angle) { + for (l = 0; l < layer->class[c] -> numlabels; l++) { + if (layer->class[c] -> labels[l] -> angle != 0) + layer->class[c]->labels[l]->angle -= map->gt.rotation_angle; } - for (s = 0; s < layer->class[c]->numstyles; s++) - { - if( layer->class[c]->styles[s]->angle != 0 ) - layer->class[c]->styles[s]->angle -= map->gt.rotation_angle; + for (s = 0; s < layer->class[c] -> numstyles; s++) { + if (layer->class[c] -> styles[s] -> angle != 0) + layer->class[c]->styles[s]->angle -= map->gt.rotation_angle; } } @@ -1799,29 +2016,42 @@ int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj for (i = 0; i < shape->line[j].numpoints; i++) { point = &(shape->line[j].point[i]); if (layer->transform == MS_TRUE) { - if (!msPointInRect(point, &map->extent)) continue; /* next point */ + if (!msPointInRect(point, &map->extent)) + continue; /* next point */ msTransformPoint(point, &map->extent, map->cellsize, image); } else msOffsetPointRelativeTo(point, layer); - if(MS_DRAW_FEATURES(drawmode)) { - for (s = 0; s < layer->class[c]->numstyles; s++) { + if (MS_DRAW_FEATURES(drawmode)) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { if (msScaleInBounds(map->scaledenom, - layer->class[c]->styles[s]->minscaledenom, - layer->class[c]->styles[s]->maxscaledenom)) - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, point, layer->class[c]->styles[s], layer->class[c]->styles[s]->scalefactor))) { + layer->class[c] -> styles[s] -> minscaledenom, + layer -> class[c] -> styles[s] -> maxscaledenom)) + if (MS_UNLIKELY( + MS_FAILURE == + msDrawMarkerSymbol( + map, image, point, layer->class[c] -> styles[s], + layer -> class[c] -> styles[s] -> scalefactor))) { goto end; } } } - if(MS_DRAW_LABELS(drawmode)) { + if (MS_DRAW_LABELS(drawmode)) { if (layer->labelcache) { - if (msAddLabelGroup(map, image, layer, c, shape, point, -1) != MS_SUCCESS) goto end; + if (msAddLabelGroup(map, image, layer, c, shape, point, -1) != + MS_SUCCESS) + goto end; } else { - for (l = 0; l < layer->class[c]->numlabels; l++) - if(msGetLabelStatus(map,layer,shape,layer->class[c]->labels[l]) == MS_ON) { - char *annotext = msShapeGetLabelAnnotation(layer,shape,layer->class[c]->labels[l]); - if(MS_UNLIKELY(MS_FAILURE == msDrawLabel(map, image, *point, annotext, layer->class[c]->labels[l], layer->class[c]->labels[l]->scalefactor))) { + for (l = 0; l < layer->class[c] -> numlabels; l++) + if (msGetLabelStatus(map, layer, shape, + layer->class[c] -> labels[l]) == MS_ON) { + char *annotext = msShapeGetLabelAnnotation( + layer, shape, layer->class[c] -> labels[l]); + if (MS_UNLIKELY(MS_FAILURE == + msDrawLabel(map, image, *point, annotext, + layer->class[c] -> labels[l], + layer -> class[c] -> labels[l] + -> scalefactor))) { goto end; } } @@ -1832,92 +2062,103 @@ int pointLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj ret = MS_SUCCESS; end: - if( map->gt.rotation_angle ) - { - for (l = 0; l < layer->class[c]->numlabels; l++) - { - if( layer->class[c]->labels[l]->angle != 0 ) - layer->class[c]->labels[l]->angle += map->gt.rotation_angle; + if (map->gt.rotation_angle) { + for (l = 0; l < layer->class[c] -> numlabels; l++) { + if (layer->class[c] -> labels[l] -> angle != 0) + layer->class[c]->labels[l]->angle += map->gt.rotation_angle; } - for (s = 0; s < layer->class[c]->numstyles; s++) - { - if( layer->class[c]->styles[s]->angle != 0 ) - layer->class[c]->styles[s]->angle += map->gt.rotation_angle; + for (s = 0; s < layer->class[c] -> numstyles; s++) { + if (layer->class[c] -> styles[s] -> angle != 0) + layer->class[c]->styles[s]->angle += map->gt.rotation_angle; } } return ret; } -int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj *shape, - shapeObj *anno_shape, shapeObj *unclipped_shape, int style, int drawmode) -{ +int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, + shapeObj *shape, shapeObj *anno_shape, + shapeObj *unclipped_shape, int style, int drawmode) { int c = shape->classindex; int ret = MS_SUCCESS; /* RFC48: loop through the styles, and pass off to the type-specific function if the style has an appropriate type */ - if(MS_DRAW_FEATURES(drawmode)) { - for (int s = 0; s < layer->class[c]->numstyles; s++) { + if (MS_DRAW_FEATURES(drawmode)) { + for (int s = 0; s < layer->class[c] -> numstyles; s++) { if (msScaleInBounds(map->scaledenom, - layer->class[c]->styles[s]->minscaledenom, - layer->class[c]->styles[s]->maxscaledenom)) { - if (layer->class[c]->styles[s]->_geomtransform.type != MS_GEOMTRANSFORM_NONE) { - if(MS_UNLIKELY(MS_FAILURE == msDrawTransformedShape(map, image, unclipped_shape, layer->class[c]->styles[s], layer->class[c]->styles[s]->scalefactor))) { + layer->class[c] -> styles[s] -> minscaledenom, + layer -> class[c] -> styles[s] -> maxscaledenom)) { + if (layer->class[c] -> styles[s] -> _geomtransform.type != + MS_GEOMTRANSFORM_NONE) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawTransformedShape( + map, image, unclipped_shape, + layer->class[c] -> styles[s], + layer -> class[c] -> styles[s] -> scalefactor))) { return MS_FAILURE; } - } - else if (!MS_DRAW_SINGLESTYLE(drawmode) || s == style) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map, image, shape, layer->class[c]->styles[s], layer->class[c]->styles[s]->scalefactor))) { + } else if (!MS_DRAW_SINGLESTYLE(drawmode) || s == style) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol( + map, image, shape, layer->class[c] -> styles[s], + layer -> class[c] -> styles[s] -> scalefactor))) { return MS_FAILURE; } } } } } - - if(MS_DRAW_LABELS(drawmode)) { - for (int l = 0; l < layer->class[c]->numlabels; l++) { + + if (MS_DRAW_LABELS(drawmode)) { + for (int l = 0; l < layer->class[c] -> numlabels; l++) { labelObj *label = layer->class[c]->labels[l]; textSymbolObj ts; char *annotext; - if(!msGetLabelStatus(map,layer,shape,label)) { + if (!msGetLabelStatus(map, layer, shape, label)) { continue; } - annotext = msShapeGetLabelAnnotation(layer,anno_shape,label); - if(!annotext) continue; + annotext = msShapeGetLabelAnnotation(layer, anno_shape, label); + if (!annotext) + continue; initTextSymbol(&ts); - msPopulateTextSymbolForLabelAndString(&ts,label,annotext,label->scalefactor,image->resolutionfactor, layer->labelcache); - - + msPopulateTextSymbolForLabelAndString( + &ts, label, annotext, label->scalefactor, image->resolutionfactor, + layer->labelcache); + if (label->anglemode == MS_FOLLOW) { /* bug #1620 implementation */ struct label_follow_result lfr; - + if (!layer->labelcache) { - msSetError(MS_MISCERR, "Angle mode 'FOLLOW' is supported only with labelcache on", "msDrawShape()"); + msSetError(MS_MISCERR, + "Angle mode 'FOLLOW' is supported only with labelcache on", + "msDrawShape()"); ret = MS_FAILURE; goto line_cleanup; } - - memset(&lfr,0,sizeof(lfr)); + + memset(&lfr, 0, sizeof(lfr)); msPolylineLabelPath(map, image, anno_shape, &ts, label, &lfr); for (int i = 0; i < lfr.num_follow_labels; i++) { - if (msAddLabel(map, image, label, layer->index, c, anno_shape, NULL, -1, lfr.follow_labels[i]) != MS_SUCCESS) { + if (msAddLabel(map, image, label, layer->index, c, anno_shape, NULL, + -1, lfr.follow_labels[i]) != MS_SUCCESS) { ret = MS_FAILURE; goto line_cleanup; } } free(lfr.follow_labels); - for(int i=0; irotation = lfr.lar.angles[i]; { - if (msAddLabel(map, image, label, layer->index, c, anno_shape, &lfr.lar.label_points[i], -1, ts_auto) != MS_SUCCESS) { + if (msAddLabel(map, image, label, layer->index, c, anno_shape, + &lfr.lar.label_points[i], -1, + ts_auto) != MS_SUCCESS) { ret = MS_FAILURE; free(lfr.lar.angles); free(lfr.lar.label_points); @@ -1929,20 +2170,23 @@ int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj * free(lfr.lar.label_points); } else { struct label_auto_result lar; - memset(&lar,0,sizeof(struct label_auto_result)); - ret = msPolylineLabelPoint(map, anno_shape, &ts, label, &lar, image->resolutionfactor); - if(MS_UNLIKELY(MS_FAILURE == ret)) goto line_cleanup; + memset(&lar, 0, sizeof(struct label_auto_result)); + ret = msPolylineLabelPoint(map, anno_shape, &ts, label, &lar, + image->resolutionfactor); + if (MS_UNLIKELY(MS_FAILURE == ret)) + goto line_cleanup; if (label->angle != 0) label->angle -= map->gt.rotation_angle; /* apply rotation angle */ - for(int i=0; irotation = lar.angles[i]; if (layer->labelcache) { - if (msAddLabel(map, image, label, layer->index, c, anno_shape, &lar.label_points[i], -1, ts_auto) != MS_SUCCESS) { + if (msAddLabel(map, image, label, layer->index, c, anno_shape, + &lar.label_points[i], -1, ts_auto) != MS_SUCCESS) { ret = MS_FAILURE; free(lar.angles); free(lar.label_points); @@ -1951,8 +2195,8 @@ int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj * goto line_cleanup; } } else { - if(!ts_auto->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts_auto))) { + if (!ts_auto->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts_auto))) { ret = MS_FAILURE; free(lar.angles); free(lar.label_points); @@ -1961,21 +2205,23 @@ int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj * goto line_cleanup; } } - ret = msDrawTextSymbol(map,image,lar.label_points[i],ts_auto); + ret = msDrawTextSymbol(map, image, lar.label_points[i], ts_auto); freeTextSymbol(ts_auto); - free(ts_auto); /* TODO RFC98: could we not re-use the original ts instead of duplicating into ts_auto ? - * we cannot for now, as the rendering code will modify the glyph positions to apply - * the labelpoint and rotation offsets */ + free(ts_auto); /* TODO RFC98: could we not re-use the original ts + * instead of duplicating into ts_auto ? we cannot + * for now, as the rendering code will modify the + * glyph positions to apply the labelpoint and + * rotation offsets */ ts_auto = NULL; - if(MS_UNLIKELY(MS_FAILURE == ret)) goto line_cleanup; + if (MS_UNLIKELY(MS_FAILURE == ret)) + goto line_cleanup; } - } free(lar.angles); free(lar.label_points); } -line_cleanup: + line_cleanup: /* clean up and reset */ if (ret == MS_FAILURE) { break; /* from the label looping */ @@ -1985,29 +2231,35 @@ int lineLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, shapeObj * } return ret; - } int polygonLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, - shapeObj *shape, shapeObj *anno_shape, shapeObj *unclipped_shape, int drawmode) -{ + shapeObj *shape, shapeObj *anno_shape, + shapeObj *unclipped_shape, int drawmode) { int c = shape->classindex; pointObj annopnt = {0}; // initialize int i; - if(MS_DRAW_FEATURES(drawmode)) { - for (i = 0; i < layer->class[c]->numstyles; i++) { - if (msScaleInBounds(map->scaledenom, layer->class[c]->styles[i]->minscaledenom, - layer->class[c]->styles[i]->maxscaledenom)) { - if (layer->class[c]->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) { - if(MS_UNLIKELY(MS_FAILURE == msDrawShadeSymbol(map, image, shape, layer->class[c]->styles[i], layer->class[c]->styles[i]->scalefactor))) { + if (MS_DRAW_FEATURES(drawmode)) { + for (i = 0; i < layer->class[c] -> numstyles; i++) { + if (msScaleInBounds(map->scaledenom, + layer->class[c] -> styles[i] -> minscaledenom, + layer -> class[c] -> styles[i] -> maxscaledenom)) { + if (layer->class[c] -> styles[i] -> _geomtransform.type == + MS_GEOMTRANSFORM_NONE) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawShadeSymbol( + map, image, shape, layer->class[c] -> styles[i], + layer -> class[c] -> styles[i] -> scalefactor))) { return MS_FAILURE; } - } - else { - if(MS_UNLIKELY(MS_FAILURE == msDrawTransformedShape(map, image, unclipped_shape, - layer->class[c]->styles[i], layer->class[c]->styles[i]->scalefactor))) { + } else { + if (MS_UNLIKELY(MS_FAILURE == + msDrawTransformedShape( + map, image, unclipped_shape, + layer->class[c] -> styles[i], + layer -> class[c] -> styles[i] -> scalefactor))) { return MS_FAILURE; } } @@ -2015,22 +2267,37 @@ int polygonLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, } } - if(MS_DRAW_LABELS(drawmode)) { - if (layer->class[c]->numlabels > 0) { - double minfeaturesize = layer->class[c]->labels[0]->minfeaturesize * image->resolutionfactor; - if (msPolygonLabelPoint(anno_shape, &annopnt, minfeaturesize) == MS_SUCCESS) { - for (i = 0; i < layer->class[c]->numlabels; i++) - if (layer->class[c]->labels[i]->angle != 0) layer->class[c]->labels[i]->angle -= map->gt.rotation_angle; /* TODO: is this correct ??? */ + if (MS_DRAW_LABELS(drawmode)) { + if (layer->class[c] -> numlabels > 0) { + double minfeaturesize = + layer->class[c]->labels[0]->minfeaturesize * image->resolutionfactor; + if (msPolygonLabelPoint(anno_shape, &annopnt, minfeaturesize) == + MS_SUCCESS) { + for (i = 0; i < layer->class[c] -> numlabels; i++) + if (layer->class[c] -> labels[i] -> angle != 0) + layer->class[c]->labels[i]->angle -= + map->gt.rotation_angle; /* TODO: is this correct ??? */ if (layer->labelcache) { if (msAddLabelGroup(map, image, layer, c, anno_shape, &annopnt, - MS_MIN(shape->bounds.maxx - shape->bounds.minx, shape->bounds.maxy - shape->bounds.miny)) != MS_SUCCESS) { + MS_MIN(shape->bounds.maxx - shape->bounds.minx, + shape->bounds.maxy - + shape->bounds.miny)) != MS_SUCCESS) { return MS_FAILURE; } } else { - for (i = 0; i < layer->class[c]->numlabels; i++) - if(msGetLabelStatus(map,layer,shape,layer->class[c]->labels[i]) == MS_ON) { - char *annotext = msShapeGetLabelAnnotation(layer,shape,layer->class[c]->labels[i]); /*ownership taken by msDrawLabel, no need to free */ - if(MS_UNLIKELY(MS_FAILURE == msDrawLabel(map, image, annopnt, annotext, layer->class[c]->labels[i], layer->class[c]->labels[i]->scalefactor))) { + for (i = 0; i < layer->class[c] -> numlabels; i++) + if (msGetLabelStatus(map, layer, shape, + layer->class[c] -> labels[i]) == MS_ON) { + char *annotext = msShapeGetLabelAnnotation( + layer, shape, + layer->class[c] + -> labels[i]); /*ownership taken by msDrawLabel, no need to + free */ + if (MS_UNLIKELY(MS_FAILURE == + msDrawLabel(map, image, annopnt, annotext, + layer->class[c] -> labels[i], + layer -> class[c] -> labels[i] + -> scalefactor))) { return MS_FAILURE; } } @@ -2042,70 +2309,81 @@ int polygonLayerDrawShape(mapObj *map, imageObj *image, layerObj *layer, } /* -** Function to render an individual shape, the style variable enables/disables the drawing of a single style -** versus a single style. This is necessary when drawing entire layers as proper overlay can only be achived -** through caching. "querymapMode" parameter is used to tell msBindLayerToShape to not override the +** Function to render an individual shape, the style variable enables/disables +*the drawing of a single style +** versus a single style. This is necessary when drawing entire layers as proper +*overlay can only be achived +** through caching. "querymapMode" parameter is used to tell msBindLayerToShape +*to not override the ** QUERYMAP HILITE color. */ -int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, int style, int drawmode) -{ - int c,s,ret=MS_SUCCESS; +int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, + int style, int drawmode) { + int c, s, ret = MS_SUCCESS; shapeObj *anno_shape, *unclipped_shape = shape; int bNeedUnclippedShape = MS_FALSE; int bNeedUnclippedAnnoShape = MS_FALSE; int bShapeNeedsClipping = MS_TRUE; - if(shape->numlines == 0 || shape->type == MS_SHAPE_NULL) return MS_SUCCESS; + if (shape->numlines == 0 || shape->type == MS_SHAPE_NULL) + return MS_SUCCESS; c = shape->classindex; /* Before we do anything else, we will check for a rangeitem. If its there, we need to change the style's color to map the range to the shape */ - for(s=0; sclass[c]->numstyles; s++) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { styleObj *style = layer->class[c]->styles[s]; - if(style->rangeitem != NULL) - msShapeToRange((layer->class[c]->styles[s]), shape); + if (style->rangeitem != NULL) + msShapeToRange((layer->class[c] -> styles[s]), shape); } /* circle and point layers go through their own treatment */ - if(layer->type == MS_LAYER_CIRCLE) { - if(msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) return MS_FAILURE; + if (layer->type == MS_LAYER_CIRCLE) { + if (msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) + return MS_FAILURE; msDrawStartShape(map, layer, image, shape); - ret = circleLayerDrawShape(map,image,layer,shape); - msDrawEndShape(map,layer,image,shape); + ret = circleLayerDrawShape(map, image, layer, shape); + msDrawEndShape(map, layer, image, shape); return ret; - } else if(layer->type == MS_LAYER_POINT || layer->type == MS_LAYER_RASTER) { - if(msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) return MS_FAILURE; + } else if (layer->type == MS_LAYER_POINT || layer->type == MS_LAYER_RASTER) { + if (msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) + return MS_FAILURE; msDrawStartShape(map, layer, image, shape); - ret = pointLayerDrawShape(map,image,layer,shape,drawmode); - msDrawEndShape(map,layer,image,shape); + ret = pointLayerDrawShape(map, image, layer, shape, drawmode); + msDrawEndShape(map, layer, image, shape); return ret; } if (layer->type == MS_LAYER_POLYGON && shape->type != MS_SHAPE_POLYGON) { - msSetError(MS_MISCERR, "Only polygon shapes can be drawn using a polygon layer definition.", "polygonLayerDrawShape()"); + msSetError( + MS_MISCERR, + "Only polygon shapes can be drawn using a polygon layer definition.", + "polygonLayerDrawShape()"); return (MS_FAILURE); } - if (layer->type == MS_LAYER_LINE && shape->type != MS_SHAPE_POLYGON && shape->type != MS_SHAPE_LINE) { - msSetError(MS_MISCERR, "Only polygon or line shapes can be drawn using a line layer definition.", "msDrawShape()"); + if (layer->type == MS_LAYER_LINE && shape->type != MS_SHAPE_POLYGON && + shape->type != MS_SHAPE_LINE) { + msSetError(MS_MISCERR, + "Only polygon or line shapes can be drawn using a line layer " + "definition.", + "msDrawShape()"); return (MS_FAILURE); } - if (layer->project && layer->transform == MS_TRUE) - { - reprojectionObj* reprojector = msLayerGetReprojectorToMap(layer, map); - if( reprojector == NULL ) - { - return MS_FAILURE; - } - msProjectShapeEx(reprojector, shape); + if (layer->project && layer->transform == MS_TRUE) { + reprojectionObj *reprojector = msLayerGetReprojectorToMap(layer, map); + if (reprojector == NULL) { + return MS_FAILURE; + } + msProjectShapeEx(reprojector, shape); } /* check if we'll need the unclipped shape */ if (shape->type != MS_SHAPE_POINT) { - if(MS_DRAW_FEATURES(drawmode)) { - for (s = 0; s < layer->class[c]->numstyles; s++) { + if (MS_DRAW_FEATURES(drawmode)) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { styleObj *style = layer->class[c]->styles[s]; if (style->_geomtransform.type != MS_GEOMTRANSFORM_NONE) bNeedUnclippedShape = MS_TRUE; @@ -2118,31 +2396,33 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, shape->bounds.maxy > map->extent.maxy) { bShapeNeedsClipping = MS_TRUE; } - - if(MS_DRAW_LABELS(drawmode) && MS_DRAW_UNCLIPPED_LABELS(drawmode)) { + + if (MS_DRAW_LABELS(drawmode) && MS_DRAW_UNCLIPPED_LABELS(drawmode)) { bNeedUnclippedAnnoShape = MS_TRUE; bNeedUnclippedShape = MS_TRUE; } - if(MS_DRAW_UNCLIPPED_LINES(drawmode)) { + if (MS_DRAW_UNCLIPPED_LINES(drawmode)) { bShapeNeedsClipping = MS_FALSE; } } else { bShapeNeedsClipping = MS_FALSE; } - if(layer->transform == MS_TRUE && bShapeNeedsClipping) { - /* compute the size of the clipping buffer, in pixels. This buffer must account - for the size of symbols drawn to avoid artifacts around the image edges */ + if (layer->transform == MS_TRUE && bShapeNeedsClipping) { + /* compute the size of the clipping buffer, in pixels. This buffer must + account for the size of symbols drawn to avoid artifacts around the image + edges */ int clip_buf = 0; int s; rectObj cliprect; - for (s=0;sclass[c]->numstyles;s++) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { double maxsize, maxunscaledsize; symbolObj *symbol; styleObj *style = layer->class[c]->styles[s]; if (!MS_IS_VALID_ARRAY_INDEX(style->symbol, map->symbolset.numsymbols)) { - msSetError(MS_SYMERR, "Invalid symbol index: %d", "msDrawShape()", style->symbol); + msSetError(MS_SYMERR, "Invalid symbol index: %d", "msDrawShape()", + style->symbol); return MS_FAILURE; } symbol = map->symbolset.symbol[style->symbol]; @@ -2154,68 +2434,77 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, if (MS_SUCCESS != msPreloadSVGSymbol(symbol)) return MS_FAILURE; #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawShape()"); + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "msDrawShape()"); return MS_FAILURE; #endif } - maxsize = MS_MAX(msSymbolGetDefaultSize(symbol), MS_MAX(style->size, style->width)); - maxunscaledsize = MS_MAX(style->minsize*image->resolutionfactor, style->minwidth*image->resolutionfactor); - if(shape->type == MS_SHAPE_POLYGON && !IS_PARALLEL_OFFSET(style->offsety)) { - maxsize += MS_MAX(fabs(style->offsety),fabs(style->offsetx)); + maxsize = MS_MAX(msSymbolGetDefaultSize(symbol), + MS_MAX(style->size, style->width)); + maxunscaledsize = MS_MAX(style->minsize * image->resolutionfactor, + style->minwidth * image->resolutionfactor); + if (shape->type == MS_SHAPE_POLYGON && + !IS_PARALLEL_OFFSET(style->offsety)) { + maxsize += MS_MAX(fabs(style->offsety), fabs(style->offsetx)); } - clip_buf = MS_MAX(clip_buf,MS_NINT(MS_MAX(maxsize * style->scalefactor, maxunscaledsize) + 1)); + clip_buf = MS_MAX( + clip_buf, + MS_NINT(MS_MAX(maxsize * style->scalefactor, maxunscaledsize) + 1)); } - - /* if we need a copy of the unclipped shape, transform first, then clip to avoid transforming twice */ - if(bNeedUnclippedShape) { + /* if we need a copy of the unclipped shape, transform first, then clip to + * avoid transforming twice */ + if (bNeedUnclippedShape) { msTransformShape(shape, map->extent, map->cellsize, image); - if(shape->numlines == 0) return MS_SUCCESS; + if (shape->numlines == 0) + return MS_SUCCESS; msComputeBounds(shape); /* TODO: there's an optimization here that can be implemented: - no need to allocate unclipped_shape for each call to this function - - the calls to msClipXXXRect will discard the original lineObjs, whereas - we have just copied them because they where needed. These two functions - could be changed so they are instructed not to free the original lineObjs. */ - unclipped_shape = (shapeObj *) msSmallMalloc(sizeof (shapeObj)); + - the calls to msClipXXXRect will discard the original lineObjs, + whereas we have just copied them because they where needed. These two + functions could be changed so they are instructed not to free the + original lineObjs. */ + unclipped_shape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(unclipped_shape); msCopyShape(shape, unclipped_shape); - if(shape->type == MS_SHAPE_POLYGON) { - /* #179: additional buffer for polygons */ - clip_buf += 2; + if (shape->type == MS_SHAPE_POLYGON) { + /* #179: additional buffer for polygons */ + clip_buf += 2; } cliprect.minx = cliprect.miny = -clip_buf; cliprect.maxx = image->width + clip_buf; cliprect.maxy = image->height + clip_buf; - if(shape->type == MS_SHAPE_POLYGON) { + if (shape->type == MS_SHAPE_POLYGON) { msClipPolygonRect(shape, cliprect); } else { assert(shape->type == MS_SHAPE_LINE); msClipPolylineRect(shape, cliprect); } - if(bNeedUnclippedAnnoShape) { + if (bNeedUnclippedAnnoShape) { anno_shape = unclipped_shape; } else { anno_shape = shape; } } else { - /* clip first, then transform. This means we are clipping in geographical space */ + /* clip first, then transform. This means we are clipping in geographical + * space */ double clip_buf_d; - if(shape->type == MS_SHAPE_POLYGON) { - /* - * add a small buffer around the cliping rectangle to - * avoid lines around the edges : #179 - */ - clip_buf += 2; + if (shape->type == MS_SHAPE_POLYGON) { + /* + * add a small buffer around the cliping rectangle to + * avoid lines around the edges : #179 + */ + clip_buf += 2; } clip_buf_d = clip_buf * map->cellsize; cliprect.minx = map->extent.minx - clip_buf_d; cliprect.miny = map->extent.miny - clip_buf_d; cliprect.maxx = map->extent.maxx + clip_buf_d; cliprect.maxy = map->extent.maxy + clip_buf_d; - if(shape->type == MS_SHAPE_POLYGON) { + if (shape->type == MS_SHAPE_POLYGON) { msClipPolygonRect(shape, cliprect); } else { assert(shape->type == MS_SHAPE_LINE); @@ -2228,7 +2517,8 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, } else { /* the shape is fully in the map extent, - * or is a point type layer where out of bounds points are treated differently*/ + * or is a point type layer where out of bounds points are treated + * differently*/ if (layer->transform == MS_TRUE) { msTransformShape(shape, map->extent, map->cellsize, image); msComputeBounds(shape); @@ -2237,36 +2527,38 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, } anno_shape = shape; } - if(shape->numlines == 0) { + if (shape->numlines == 0) { ret = MS_SUCCESS; /* error message is set in msBindLayerToShape() */ goto draw_shape_cleanup; } - if(msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) { + if (msBindLayerToShape(layer, shape, drawmode) != MS_SUCCESS) { ret = MS_FAILURE; /* error message is set in msBindLayerToShape() */ goto draw_shape_cleanup; } - switch(layer->type) { - case MS_LAYER_LINE: - msDrawStartShape(map, layer, image, shape); - ret = lineLayerDrawShape(map, image, layer, shape, anno_shape, unclipped_shape, style, drawmode); - break; - case MS_LAYER_POLYGON: - msDrawStartShape(map, layer, image, shape); - ret = polygonLayerDrawShape(map, image, layer, shape, anno_shape, unclipped_shape, drawmode); - break; - case MS_LAYER_POINT: - case MS_LAYER_RASTER: - assert(0); //bug ! - default: - msSetError(MS_MISCERR, "Unknown layer type.", "msDrawShape()"); - ret = MS_FAILURE; + switch (layer->type) { + case MS_LAYER_LINE: + msDrawStartShape(map, layer, image, shape); + ret = lineLayerDrawShape(map, image, layer, shape, anno_shape, + unclipped_shape, style, drawmode); + break; + case MS_LAYER_POLYGON: + msDrawStartShape(map, layer, image, shape); + ret = polygonLayerDrawShape(map, image, layer, shape, anno_shape, + unclipped_shape, drawmode); + break; + case MS_LAYER_POINT: + case MS_LAYER_RASTER: + assert(0); // bug ! + default: + msSetError(MS_MISCERR, "Unknown layer type.", "msDrawShape()"); + ret = MS_FAILURE; } draw_shape_cleanup: - msDrawEndShape(map,layer,image,shape); - if(unclipped_shape != shape) { + msDrawEndShape(map, layer, image, shape); + if (unclipped_shape != shape) { msFreeShape(unclipped_shape); msFree(unclipped_shape); } @@ -2274,93 +2566,107 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image, } /* -** Function to render an individual point, used as a helper function for mapscript only. Since a point +** Function to render an individual point, used as a helper function for +*mapscript only. Since a point ** can't carry attributes you can't do attribute based font size or angle. */ -int msDrawPoint(mapObj *map, layerObj *layer, pointObj *point, imageObj *image, int classindex, char *labeltext) -{ - int s,ret; - classObj *theclass=NULL; - labelObj *label=NULL; - - if(layer->transform == MS_TRUE && layer->project && msProjectionsDiffer(&(layer->projection), &(map->projection))) { +int msDrawPoint(mapObj *map, layerObj *layer, pointObj *point, imageObj *image, + int classindex, char *labeltext) { + int s, ret; + classObj *theclass = NULL; + labelObj *label = NULL; + + if (layer->transform == MS_TRUE && layer->project && + msProjectionsDiffer(&(layer->projection), &(map->projection))) { msProjectPoint(&(layer->projection), &(map->projection), point); } - - if(classindex > layer->numclasses) { - msSetError(MS_MISCERR, "Invalid classindex (%d)", "msDrawPoint()", classindex); - return MS_FAILURE; + + if (classindex > layer->numclasses) { + msSetError(MS_MISCERR, "Invalid classindex (%d)", "msDrawPoint()", + classindex); + return MS_FAILURE; } theclass = layer->class[classindex]; - - if(labeltext && theclass->numlabels > 0) { + + if (labeltext && theclass->numlabels > 0) { label = theclass->labels[0]; } - - switch(layer->type) { - case MS_LAYER_POINT: - if(layer->transform == MS_TRUE) { - if(!msPointInRect(point, &map->extent)) return(0); - point->x = MS_MAP2IMAGE_X(point->x, map->extent.minx, map->cellsize); - point->y = MS_MAP2IMAGE_Y(point->y, map->extent.maxy, map->cellsize); - } else - msOffsetPointRelativeTo(point, layer); - for(s=0; snumstyles; s++) { - if(msScaleInBounds(map->scaledenom, theclass->styles[s]->minscaledenom, theclass->styles[s]->maxscaledenom)) - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, point, theclass->styles[s], theclass->styles[s]->scalefactor))) { - return MS_FAILURE; - } - } - if(label && labeltext && *labeltext) { - textSymbolObj *ts = msSmallMalloc(sizeof(textSymbolObj)); - initTextSymbol(ts); - msPopulateTextSymbolForLabelAndString(ts, label, msStrdup(labeltext), label->scalefactor, image->resolutionfactor, layer->labelcache); - if(layer->labelcache) { - if(msAddLabel(map, image, label, layer->index, classindex, NULL, point, -1, ts) != MS_SUCCESS) { - return(MS_FAILURE); - } - } else { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) { - freeTextSymbol(ts); - free(ts); - return MS_FAILURE; - } - ret = msDrawTextSymbol(map,image,*point,ts); + switch (layer->type) { + case MS_LAYER_POINT: + if (layer->transform == MS_TRUE) { + if (!msPointInRect(point, &map->extent)) + return (0); + point->x = MS_MAP2IMAGE_X(point->x, map->extent.minx, map->cellsize); + point->y = MS_MAP2IMAGE_Y(point->y, map->extent.maxy, map->cellsize); + } else + msOffsetPointRelativeTo(point, layer); + + for (s = 0; s < theclass->numstyles; s++) { + if (msScaleInBounds(map->scaledenom, theclass->styles[s]->minscaledenom, + theclass->styles[s]->maxscaledenom)) + if (MS_UNLIKELY(MS_FAILURE == + msDrawMarkerSymbol(map, image, point, + theclass->styles[s], + theclass->styles[s]->scalefactor))) { + return MS_FAILURE; + } + } + if (label && labeltext && *labeltext) { + textSymbolObj *ts = msSmallMalloc(sizeof(textSymbolObj)); + initTextSymbol(ts); + msPopulateTextSymbolForLabelAndString( + ts, label, msStrdup(labeltext), label->scalefactor, + image->resolutionfactor, layer->labelcache); + if (layer->labelcache) { + if (msAddLabel(map, image, label, layer->index, classindex, NULL, point, + -1, ts) != MS_SUCCESS) { + return (MS_FAILURE); + } + } else { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) { freeTextSymbol(ts); - free(ts); - if(MS_UNLIKELY(ret == MS_FAILURE)) return MS_FAILURE; + free(ts); + return MS_FAILURE; } + ret = msDrawTextSymbol(map, image, *point, ts); + freeTextSymbol(ts); + free(ts); + if (MS_UNLIKELY(ret == MS_FAILURE)) + return MS_FAILURE; } - break; - default: - break; /* don't do anything with layer of other types */ + } + break; + default: + break; /* don't do anything with layer of other types */ } - return(MS_SUCCESS); /* all done, no cleanup */ + return (MS_SUCCESS); /* all done, no cleanup */ } /* -** Draws a single label independently of the label cache. No collision avoidance is performed. +** Draws a single label independently of the label cache. No collision avoidance +*is performed. */ -int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, labelObj *label, double scalefactor) -{ +int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, + labelObj *label, double scalefactor) { shapeObj labelPoly; label_bounds lbounds = {0}; lineObj labelPolyLine; pointObj labelPolyPoints[5]; textSymbolObj ts = {0}; - int needLabelPoly=MS_TRUE; - int needLabelPoint=MS_TRUE; - int haveLabelText=MS_TRUE; + int needLabelPoly = MS_TRUE; + int needLabelPoint = MS_TRUE; + int haveLabelText = MS_TRUE; - if(!string || !*string) + if (!string || !*string) haveLabelText = MS_FALSE; - if(haveLabelText) { + if (haveLabelText) { initTextSymbol(&ts); - msPopulateTextSymbolForLabelAndString(&ts, label, string, scalefactor, image->resolutionfactor, 0); - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,&ts))) { + msPopulateTextSymbolForLabelAndString(&ts, label, string, scalefactor, + image->resolutionfactor, 0); + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, &ts))) { freeTextSymbol(&ts); return MS_FAILURE; } @@ -2372,24 +2678,33 @@ int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, l labelPoly.line->point = labelPolyPoints; labelPoly.line->numpoints = 5; - if(label->position != MS_XY) { + if (label->position != MS_XY) { pointObj p = {0}; - if(label->numstyles > 0) { + if (label->numstyles > 0) { int i; - for(i=0; inumstyles; i++) { - if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT || label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) { - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &labelPnt, label->styles[i], scalefactor))) { - if(haveLabelText) + for (i = 0; i < label->numstyles; i++) { + if (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT || + label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawMarkerSymbol(map, image, &labelPnt, + label->styles[i], scalefactor))) { + if (haveLabelText) freeTextSymbol(&ts); return MS_FAILURE; } - } else if(haveLabelText && (label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY || label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER)) { - if(needLabelPoly) { - p = get_metrics(&labelPnt, label->position, ts.textpath, label->offsetx * ts.scalefactor, - label->offsety * ts.scalefactor, ts.rotation, 1, &lbounds); - if(!lbounds.poly) { + } else if (haveLabelText && (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY || + label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER)) { + if (needLabelPoly) { + p = get_metrics(&labelPnt, label->position, ts.textpath, + label->offsetx * ts.scalefactor, + label->offsety * ts.scalefactor, ts.rotation, 1, + &lbounds); + if (!lbounds.poly) { /* we need the full shape to draw the label background */ labelPolyPoints[0].x = labelPolyPoints[4].x = lbounds.bbox.minx; labelPolyPoints[0].y = labelPolyPoints[4].y = lbounds.bbox.miny; @@ -2403,36 +2718,45 @@ int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, l needLabelPoint = MS_FALSE; /* don't re-compute */ needLabelPoly = MS_FALSE; } - if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - if(MS_UNLIKELY(MS_FAILURE == msDrawShadeSymbol(map, image, &labelPoly, label->styles[i], ts.scalefactor))) { + if (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + if (MS_UNLIKELY(MS_FAILURE == msDrawShadeSymbol(map, image, + &labelPoly, + label->styles[i], + ts.scalefactor))) { freeTextSymbol(&ts); return MS_FAILURE; } } else { pointObj labelCenter; - labelCenter.x = (lbounds.bbox.maxx + lbounds.bbox.minx)/2; - labelCenter.y = (lbounds.bbox.maxy + lbounds.bbox.miny)/2; - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &labelCenter, label->styles[i], scalefactor))) { + labelCenter.x = (lbounds.bbox.maxx + lbounds.bbox.minx) / 2; + labelCenter.y = (lbounds.bbox.maxy + lbounds.bbox.miny) / 2; + if (MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol( + map, image, &labelCenter, + label->styles[i], scalefactor))) { freeTextSymbol(&ts); return MS_FAILURE; } } } else { - msSetError(MS_MISCERR,"Unknown label geomtransform %s", "msDrawLabel()",label->styles[i]->_geomtransform.string); - if(haveLabelText) + msSetError(MS_MISCERR, "Unknown label geomtransform %s", + "msDrawLabel()", label->styles[i]->_geomtransform.string); + if (haveLabelText) freeTextSymbol(&ts); return MS_FAILURE; } } } - if(haveLabelText) { - if(needLabelPoint) - p = get_metrics(&labelPnt, label->position, ts.textpath, label->offsetx * ts.scalefactor, - label->offsety * ts.scalefactor, ts.rotation, 0, &lbounds); + if (haveLabelText) { + if (needLabelPoint) + p = get_metrics(&labelPnt, label->position, ts.textpath, + label->offsetx * ts.scalefactor, + label->offsety * ts.scalefactor, ts.rotation, 0, + &lbounds); /* draw the label text */ - if(MS_UNLIKELY(MS_FAILURE == msDrawTextSymbol(map,image,p,&ts))) { + if (MS_UNLIKELY(MS_FAILURE == msDrawTextSymbol(map, image, p, &ts))) { freeTextSymbol(&ts); return MS_FAILURE; } @@ -2441,22 +2765,30 @@ int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, l labelPnt.x += label->offsetx * ts.scalefactor; labelPnt.y += label->offsety * ts.scalefactor; - if(label->numstyles > 0) { + if (label->numstyles > 0) { int i; - for(i=0; inumstyles; i++) { - if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT || - label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) { - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &labelPnt, label->styles[i], scalefactor))) { + for (i = 0; i < label->numstyles; i++) { + if (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT || + label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawMarkerSymbol(map, image, &labelPnt, + label->styles[i], scalefactor))) { freeTextSymbol(&ts); return MS_FAILURE; } - } else if(haveLabelText && (label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY || label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER)) { - if(needLabelPoly) { - get_metrics(&labelPnt, label->position, ts.textpath, label->offsetx * ts.scalefactor, - label->offsety * ts.scalefactor, ts.rotation, 1, &lbounds); + } else if (haveLabelText && (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY || + label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER)) { + if (needLabelPoly) { + get_metrics(&labelPnt, label->position, ts.textpath, + label->offsetx * ts.scalefactor, + label->offsety * ts.scalefactor, ts.rotation, 1, + &lbounds); needLabelPoly = MS_FALSE; /* don't re-compute */ - if(!lbounds.poly) { + if (!lbounds.poly) { /* we need the full shape to draw the label background */ labelPolyPoints[0].x = labelPolyPoints[4].x = lbounds.bbox.minx; labelPolyPoints[0].y = labelPolyPoints[4].y = lbounds.bbox.miny; @@ -2468,54 +2800,63 @@ int msDrawLabel(mapObj *map, imageObj *image, pointObj labelPnt, char *string, l labelPolyPoints[3].y = lbounds.bbox.miny; } } - if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - if(MS_UNLIKELY(MS_FAILURE == msDrawShadeSymbol(map, image, &labelPoly, label->styles[i], scalefactor))) { + if (label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawShadeSymbol(map, image, &labelPoly, + label->styles[i], scalefactor))) { freeTextSymbol(&ts); return MS_FAILURE; } } else { - pointObj labelCenter; - labelCenter.x = (lbounds.bbox.maxx + lbounds.bbox.minx)/2; - labelCenter.y = (lbounds.bbox.maxy + lbounds.bbox.miny)/2; - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &labelCenter, label->styles[i], scalefactor))) { + pointObj labelCenter; + labelCenter.x = (lbounds.bbox.maxx + lbounds.bbox.minx) / 2; + labelCenter.y = (lbounds.bbox.maxy + lbounds.bbox.miny) / 2; + if (MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol( + map, image, &labelCenter, + label->styles[i], scalefactor))) { freeTextSymbol(&ts); return MS_FAILURE; } } } else { - msSetError(MS_MISCERR,"Unknown label geomtransform %s", "msDrawLabel()",label->styles[i]->_geomtransform.string); - if(haveLabelText) + msSetError(MS_MISCERR, "Unknown label geomtransform %s", + "msDrawLabel()", label->styles[i]->_geomtransform.string); + if (haveLabelText) freeTextSymbol(&ts); return MS_FAILURE; } } } - if(haveLabelText) { + if (haveLabelText) { /* draw the label text */ - if(MS_UNLIKELY(MS_FAILURE == msDrawTextSymbol(map,image,labelPnt,&ts))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawTextSymbol(map, image, labelPnt, &ts))) { freeTextSymbol(&ts); return MS_FAILURE; } } } - if(haveLabelText) + if (haveLabelText) freeTextSymbol(&ts); return MS_SUCCESS; } -static inline void offset_bbox(const rectObj *from, rectObj *to, double ox, double oy) { +static inline void offset_bbox(const rectObj *from, rectObj *to, double ox, + double oy) { to->minx = from->minx + ox; to->miny = from->miny + oy; to->maxx = from->maxx + ox; to->maxy = from->maxy + oy; } -static inline void offset_label_bounds(const label_bounds *from, label_bounds *to, double ox, double oy) { - if(from->poly) { +static inline void offset_label_bounds(const label_bounds *from, + label_bounds *to, double ox, double oy) { + if (from->poly) { int i; - for(i=0; ipoly->numpoints; i++) { + for (i = 0; i < from->poly->numpoints; i++) { to->poly->point[i].x = from->poly->point[i].x + ox; to->poly->point[i].y = from->poly->point[i].y + oy; } @@ -2527,30 +2868,33 @@ static inline void offset_label_bounds(const label_bounds *from, label_bounds *t } /* private shortcut function to try a leader offsetted label - * the caller must ensure that scratch->poly->points has been sufficiently allocated - * to hold the points from the cachePtr's label_bounds */ -void offsetAndTest(mapObj *map, labelCacheMemberObj *cachePtr, double ox, double oy, - int priority, int label_idx, label_bounds *scratch) -{ - int i,j,status; + * the caller must ensure that scratch->poly->points has been sufficiently + * allocated to hold the points from the cachePtr's label_bounds */ +void offsetAndTest(mapObj *map, labelCacheMemberObj *cachePtr, double ox, + double oy, int priority, int label_idx, + label_bounds *scratch) { + int i, j, status; pointObj leaderpt; lineObj *scratch_line = scratch->poly; - for(i=0; inumtextsymbols; i++) { + for (i = 0; i < cachePtr->numtextsymbols; i++) { textSymbolObj *ts = cachePtr->textsymbols[i]; - if(ts->textpath) { + if (ts->textpath) { offset_label_bounds(&ts->textpath->bounds, scratch, ox, oy); - status = msTestLabelCacheCollisions(map, cachePtr, scratch, priority, label_idx); - if(!status) { + status = msTestLabelCacheCollisions(map, cachePtr, scratch, priority, + label_idx); + if (!status) { return; } } - for(j=0; jlabel->numstyles; j++) { - if(ts->label->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { + for (j = 0; j < ts->label->numstyles; j++) { + if (ts->label->styles[j]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { scratch->poly = scratch_line; offset_label_bounds(ts->style_bounds[j], scratch, ox, oy); - status = msTestLabelCacheCollisions(map, cachePtr, scratch, priority, label_idx); - if(!status) { + status = msTestLabelCacheCollisions(map, cachePtr, scratch, priority, + label_idx); + if (!status) { return; } } @@ -2561,11 +2905,10 @@ void offsetAndTest(mapObj *map, labelCacheMemberObj *cachePtr, double ox, double leaderpt.y = cachePtr->point.y + oy; status = msTestLabelCacheLeaderCollision(map, &cachePtr->point, &leaderpt); - if(!status) { + if (!status) { return; } - /* the current offset is ok */ cachePtr->leaderbbox = msSmallMalloc(sizeof(rectObj)); cachePtr->leaderline = msSmallMalloc(sizeof(lineObj)); @@ -2573,32 +2916,31 @@ void offsetAndTest(mapObj *map, labelCacheMemberObj *cachePtr, double ox, double cachePtr->leaderline->numpoints = 2; cachePtr->leaderline->point[0] = cachePtr->point; cachePtr->leaderline->point[1] = leaderpt; - cachePtr->leaderbbox->minx = MS_MIN(leaderpt.x,cachePtr->point.x); - cachePtr->leaderbbox->maxx = MS_MAX(leaderpt.x,cachePtr->point.x); - cachePtr->leaderbbox->miny = MS_MIN(leaderpt.y,cachePtr->point.y); - cachePtr->leaderbbox->maxy = MS_MAX(leaderpt.y,cachePtr->point.y); + cachePtr->leaderbbox->minx = MS_MIN(leaderpt.x, cachePtr->point.x); + cachePtr->leaderbbox->maxx = MS_MAX(leaderpt.x, cachePtr->point.x); + cachePtr->leaderbbox->miny = MS_MIN(leaderpt.y, cachePtr->point.y); + cachePtr->leaderbbox->maxy = MS_MAX(leaderpt.y, cachePtr->point.y); cachePtr->status = MS_ON; - offset_bbox(&cachePtr->bbox,&cachePtr->bbox,ox,oy); + offset_bbox(&cachePtr->bbox, &cachePtr->bbox, ox, oy); - for(i=0; inumtextsymbols; i++) { + for (i = 0; i < cachePtr->numtextsymbols; i++) { textSymbolObj *ts = cachePtr->textsymbols[i]; - if(ts->textpath) { + if (ts->textpath) { offset_label_bounds(&ts->textpath->bounds, &ts->textpath->bounds, ox, oy); ts->annopoint.x += ox; ts->annopoint.y += oy; } - if(ts->style_bounds) { - for(j=0; jlabel->numstyles; j++) { - if(ts->label->styles[j]->_geomtransform.type != MS_GEOMTRANSFORM_NONE) + if (ts->style_bounds) { + for (j = 0; j < ts->label->numstyles; j++) { + if (ts->label->styles[j]->_geomtransform.type != MS_GEOMTRANSFORM_NONE) offset_label_bounds(ts->style_bounds[j], ts->style_bounds[j], ox, oy); } } } } -int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) -{ +int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) { int retval = MS_SUCCESS; int l; labelCacheObj *labelcache = &(map->labelcache); @@ -2612,68 +2954,75 @@ int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) cacheslot = &(labelcache->slots[priority]); scratch.poly = &scratch_line; - for(l=cacheslot->numlabels-1; l>=0; l--) { - cachePtr = &(cacheslot->labels[l]); /* point to right spot in the label cache */ - if(cachePtr->status == MS_OFF) { + for (l = cacheslot->numlabels - 1; l >= 0; l--) { + cachePtr = + &(cacheslot->labels[l]); /* point to right spot in the label cache */ + if (cachePtr->status == MS_OFF) { /* only test regular labels that have had their bounding box computed and that haven't been rendered */ - classObj *classPtr = (GET_CLASS(map,cachePtr->layerindex,cachePtr->classindex)); - layerObj *layerPtr = (GET_LAYER(map,cachePtr->layerindex)); - int steps,i,num_scratch_points_to_allocate = 0; + classObj *classPtr = + (GET_CLASS(map, cachePtr->layerindex, cachePtr->classindex)); + layerObj *layerPtr = (GET_LAYER(map, cachePtr->layerindex)); + int steps, i, num_scratch_points_to_allocate = 0; - assert(classPtr->leader); /* cachePtrs that don't need to be tested have been marked as status on or delete */ + assert(classPtr->leader); /* cachePtrs that don't need to be tested have + been marked as status on or delete */ - if(cachePtr->point.x < labelcache->gutter || + if (cachePtr->point.x < labelcache->gutter || cachePtr->point.y < labelcache->gutter || cachePtr->point.x >= image->width - labelcache->gutter || cachePtr->point.y >= image->height - labelcache->gutter) { - /* don't look for leaders if point is in edge buffer as the leader line would end up chopped off */ + /* don't look for leaders if point is in edge buffer as the leader line + * would end up chopped off */ continue; } - for(i=0; inumtextsymbols; i++) { + for (i = 0; i < cachePtr->numtextsymbols; i++) { int j; textSymbolObj *ts = cachePtr->textsymbols[i]; - if(ts->textpath && ts->textpath->bounds.poly) { - num_scratch_points_to_allocate = MS_MAX(num_scratch_points_to_allocate, ts->textpath->bounds.poly->numpoints); + if (ts->textpath && ts->textpath->bounds.poly) { + num_scratch_points_to_allocate = + MS_MAX(num_scratch_points_to_allocate, + ts->textpath->bounds.poly->numpoints); } - if(ts->style_bounds) { - for(j=0;jlabel->numstyles; j++) { - if(ts->label->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT && + if (ts->style_bounds) { + for (j = 0; j < ts->label->numstyles; j++) { + if (ts->label->styles[j]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT && ts->style_bounds[j]->poly) { - num_scratch_points_to_allocate = MS_MAX(num_scratch_points_to_allocate, ts->style_bounds[j]->poly->numpoints); + num_scratch_points_to_allocate = + MS_MAX(num_scratch_points_to_allocate, + ts->style_bounds[j]->poly->numpoints); } } } } - if(num_scratch_points_to_allocate > num_allocated_scratch_points) { - scratch_points = msSmallRealloc(scratch_points, num_scratch_points_to_allocate * sizeof(pointObj)); + if (num_scratch_points_to_allocate > num_allocated_scratch_points) { + scratch_points = msSmallRealloc( + scratch_points, num_scratch_points_to_allocate * sizeof(pointObj)); num_allocated_scratch_points = num_scratch_points_to_allocate; } - steps = classPtr->leader->maxdistance / classPtr->leader->gridstep; #define x0 (cachePtr->point.x) #define y0 (cachePtr->point.y) #define gridstepsc (classPtr->leader->gridstep) - -#define otest(ox,oy) if((x0+(ox)) >= labelcache->gutter &&\ - (y0+(oy)) >= labelcache->gutter &&\ - (x0+(ox)) < image->width - labelcache->gutter &&\ - (y0+(oy)) < image->height - labelcache->gutter) {\ - scratch_line.point = scratch_points;\ - scratch.poly = &scratch_line; \ - offsetAndTest(map,cachePtr,(ox),(oy),priority,l,&scratch); \ - if(cachePtr->status == MS_ON) break;\ - } +#define otest(ox, oy) \ + if ((x0 + (ox)) >= labelcache->gutter && \ + (y0 + (oy)) >= labelcache->gutter && \ + (x0 + (ox)) < image->width - labelcache->gutter && \ + (y0 + (oy)) < image->height - labelcache->gutter) { \ + scratch_line.point = scratch_points; \ + scratch.poly = &scratch_line; \ + offsetAndTest(map, cachePtr, (ox), (oy), priority, l, &scratch); \ + if (cachePtr->status == MS_ON) \ + break; \ + } /* loop through possible offsetted positions */ - for(i=1; i<=steps; i++) { - - - + for (i = 1; i <= steps; i++) { /* test the intermediate points on the ring */ @@ -2688,27 +3037,27 @@ int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) X00X00X */ int j; - for(j=1; jstatus == MS_ON) { + if (cachePtr->status == MS_ON) { int ll; - shapeObj labelLeader; /* label polygon (bounding box, possibly rotated) */ - labelLeader.line = cachePtr->leaderline; /* setup the label polygon structure */ + shapeObj + labelLeader; /* label polygon (bounding box, possibly rotated) */ + labelLeader.line = + cachePtr->leaderline; /* setup the label polygon structure */ labelLeader.numlines = 1; insertRenderedLabelMember(map, cachePtr); - for(ll=0; llleader->numstyles; ll++) { - retval = msDrawLineSymbol(map, image,&labelLeader , classPtr->leader->styles[ll], layerPtr->scalefactor); - if(MS_UNLIKELY(retval == MS_FAILURE)) { + for (ll = 0; ll < classPtr->leader->numstyles; ll++) { + retval = msDrawLineSymbol(map, image, &labelLeader, + classPtr->leader->styles[ll], + layerPtr->scalefactor); + if (MS_UNLIKELY(retval == MS_FAILURE)) { goto offset_cleanup; } } - for(ll=0; llnumtextsymbols; ll++) { + for (ll = 0; ll < cachePtr->numtextsymbols; ll++) { textSymbolObj *ts = cachePtr->textsymbols[ll]; - if(ts->style_bounds) { + if (ts->style_bounds) { /* here's where we draw the label styles */ - for(i=0; ilabel->numstyles; i++) { - if(ts->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - retval = msDrawMarkerSymbol(map, image, &(labelLeader.line->point[1]), ts->label->styles[i], layerPtr->scalefactor); - if(MS_UNLIKELY(retval == MS_FAILURE)) { + for (i = 0; i < ts->label->numstyles; i++) { + if (ts->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + retval = msDrawMarkerSymbol( + map, image, &(labelLeader.line->point[1]), + ts->label->styles[i], layerPtr->scalefactor); + if (MS_UNLIKELY(retval == MS_FAILURE)) { goto offset_cleanup; } - } else if(ts->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - retval = msDrawLabelBounds(map,image,ts->style_bounds[i],ts->label->styles[i], ts->scalefactor); - if(MS_UNLIKELY(retval == MS_FAILURE)) { + } else if (ts->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + retval = + msDrawLabelBounds(map, image, ts->style_bounds[i], + ts->label->styles[i], ts->scalefactor); + if (MS_UNLIKELY(retval == MS_FAILURE)) { goto offset_cleanup; } - } else if(ts->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER) { + } else if (ts->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER) { pointObj labelCenter; - labelCenter.x = (ts->style_bounds[i]->bbox.maxx + ts->style_bounds[i]->bbox.minx)/2; - labelCenter.y = (ts->style_bounds[i]->bbox.maxy + ts->style_bounds[i]->bbox.miny)/2; - retval = msDrawMarkerSymbol(map, image, &labelCenter, ts->label->styles[i], layerPtr->scalefactor); - if(MS_UNLIKELY(retval == MS_FAILURE)) { + labelCenter.x = (ts->style_bounds[i]->bbox.maxx + + ts->style_bounds[i]->bbox.minx) / + 2; + labelCenter.y = (ts->style_bounds[i]->bbox.maxy + + ts->style_bounds[i]->bbox.miny) / + 2; + retval = msDrawMarkerSymbol(map, image, &labelCenter, + ts->label->styles[i], + layerPtr->scalefactor); + if (MS_UNLIKELY(retval == MS_FAILURE)) { goto offset_cleanup; } } else { - msSetError(MS_MISCERR,"Labels only support LABELPNT, LABELPOLY and LABELCENTER GEOMTRANSFORMS", "msDrawOffsettedLabels()"); + msSetError(MS_MISCERR, + "Labels only support LABELPNT, LABELPOLY and " + "LABELCENTER GEOMTRANSFORMS", + "msDrawOffsettedLabels()"); retval = MS_FAILURE; } } } - if(ts->annotext) { - retval = msDrawTextSymbol(map,image,ts->annopoint,ts); - if(MS_UNLIKELY(retval == MS_FAILURE)) { + if (ts->annotext) { + retval = msDrawTextSymbol(map, image, ts->annopoint, ts); + if (MS_UNLIKELY(retval == MS_FAILURE)) { goto offset_cleanup; } } @@ -2831,9 +3200,9 @@ int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) tstyle.color.red = random()%255; tstyle.color.green = random()%255; tstyle.color.blue =random()%255; - msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, layerPtr->scalefactor); + msDrawLineSymbol(&map->symbolset, image, cachePtr->poly, &tstyle, + layerPtr->scalefactor); */ - } } } @@ -2842,18 +3211,15 @@ int msDrawOffsettedLabels(imageObj *image, mapObj *map, int priority) free(scratch_points); - return retval; } -void fastComputeBounds(lineObj *line, rectObj *bounds) -{ +void fastComputeBounds(lineObj *line, rectObj *bounds) { int j; bounds->minx = bounds->maxx = line->point[0].x; bounds->miny = bounds->maxy = line->point[0].y; - - for( j=0; jnumpoints; j++ ) { + for (j = 0; j < line->numpoints; j++) { bounds->minx = MS_MIN(bounds->minx, line->point[j].x); bounds->maxx = MS_MAX(bounds->maxx, line->point[j].x); bounds->miny = MS_MIN(bounds->miny, line->point[j].y); @@ -2861,35 +3227,36 @@ void fastComputeBounds(lineObj *line, rectObj *bounds) } } -int computeMarkerBounds(mapObj *map, pointObj *annopoint, textSymbolObj *ts, label_bounds *poly) -{ +int computeMarkerBounds(mapObj *map, pointObj *annopoint, textSymbolObj *ts, + label_bounds *poly) { int i; - for (i=0; ilabel->numstyles; i++) { + for (i = 0; i < ts->label->numstyles; i++) { styleObj *style = ts->label->styles[i]; - if(style->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT && + if (style->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT && style->symbol < map->symbolset.numsymbols && style->symbol >= 0) { - double sx,sy; + double sx, sy; int p; - double aox,aoy; + double aox, aoy; symbolObj *symbol = map->symbolset.symbol[style->symbol]; - if(msGetMarkerSize(map, style, &sx, &sy, ts->scalefactor) != MS_SUCCESS) - return -1; /* real error, different from MS_FALSE, return -1 so we can trap it */ - if(style->angle) { + if (msGetMarkerSize(map, style, &sx, &sy, ts->scalefactor) != MS_SUCCESS) + return -1; /* real error, different from MS_FALSE, return -1 so we can + trap it */ + if (style->angle) { pointObj *point = poly->poly->point; point[0].x = sx / 2.0; point[0].y = sy / 2.0; - point[1].x = point[0].x; + point[1].x = point[0].x; point[1].y = -point[0].y; point[2].x = -point[0].x; point[2].y = -point[0].y; point[3].x = -point[0].x; - point[3].y = point[0].y; - point[4].x = point[0].x; - point[4].y = point[0].y; - if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { + point[3].y = point[0].y; + point[4].x = point[0].x; + point[4].y = point[0].y; + if (symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { aox = (0.5 - symbol->anchorpoint_x) * sx; aoy = (0.5 - symbol->anchorpoint_y) * sy; - for(p=0; p<5; p++) { + for (p = 0; p < 5; p++) { point[p].x += aox; point[p].y += aoy; } @@ -2898,7 +3265,7 @@ int computeMarkerBounds(mapObj *map, pointObj *annopoint, textSymbolObj *ts, lab double rot = -style->angle * MS_DEG_TO_RAD; double sina = sin(rot); double cosa = cos(rot); - for(p=0; p<5; p++) { + for (p = 0; p < 5; p++) { double tmpx = point[p].x; point[p].x = point[p].x * cosa - point[p].y * sina; point[p].y = tmpx * sina + point[p].y * cosa; @@ -2906,35 +3273,35 @@ int computeMarkerBounds(mapObj *map, pointObj *annopoint, textSymbolObj *ts, lab } aox = annopoint->x + style->offsetx * ts->scalefactor; aoy = annopoint->y + style->offsety * ts->scalefactor; - for(p=0; p<5; p++) { + for (p = 0; p < 5; p++) { point[p].x += aox; point[p].y += aoy; } - fastComputeBounds(poly->poly,&poly->bbox); + fastComputeBounds(poly->poly, &poly->bbox); } else { - double aox = (0.5 - symbol->anchorpoint_x)*sx + annopoint->x + style->offsetx * ts->scalefactor; - double aoy = (0.5 - symbol->anchorpoint_y)*sy + annopoint->y + style->offsety * ts->scalefactor; + double aox = (0.5 - symbol->anchorpoint_x) * sx + annopoint->x + + style->offsetx * ts->scalefactor; + double aoy = (0.5 - symbol->anchorpoint_y) * sy + annopoint->y + + style->offsety * ts->scalefactor; poly->poly = NULL; - poly->bbox.maxx = sx/2.0 + aox; - poly->bbox.minx = -sx/2.0 + aox; - poly->bbox.maxy = sy/2.0 + aoy; - poly->bbox.miny = -sy/2.0 + aoy; + poly->bbox.maxx = sx / 2.0 + aox; + poly->bbox.minx = -sx / 2.0 + aox; + poly->bbox.maxy = sy / 2.0 + aoy; + poly->bbox.miny = -sy / 2.0 + aoy; } break; } } - if(i == ts->label->numstyles) + if (i == ts->label->numstyles) return MS_FALSE; /* the label has no marker styles */ else return MS_TRUE; } +/* check that the current entry does not fall close to a label with identical + * text, if configured so. Currently only checks the first label/text */ -/* check that the current entry does not fall close to a label with identical text, if configured so. - * Currently only checks the first label/text */ - -int msCheckLabelMinDistance(mapObj *map, labelCacheMemberObj *lc) -{ +int msCheckLabelMinDistance(mapObj *map, labelCacheMemberObj *lc) { int i; textSymbolObj *s; /* shortcut */ textSymbolObj *ts; @@ -2943,13 +3310,14 @@ int msCheckLabelMinDistance(mapObj *map, labelCacheMemberObj *lc) return MS_FALSE; /* no label with text */ s = lc->textsymbols[0]; - if (!s->annotext || s->label->mindistance <= 0.0 || s->label->force == MS_TRUE) + if (!s->annotext || s->label->mindistance <= 0.0 || + s->label->force == MS_TRUE) return MS_FALSE; /* min distance is not checked */ /* we buffer the label and check for intersection instead of calculating - the distance of two textpaths. we also buffer only the bbox of lc for + the distance of two textpaths. we also buffer only the bbox of lc for faster computation (it is still compared to the full textpath - of the label cache members). + of the label cache members). */ buffered = lc->bbox; buffered.minx -= s->label->mindistance * s->resolutionfactor; @@ -2960,7 +3328,7 @@ int msCheckLabelMinDistance(mapObj *map, labelCacheMemberObj *lc) for (i = 0; i < map->labelcache.num_rendered_members; i++) { labelCacheMemberObj *ilc = map->labelcache.rendered_text_symbols[i]; if (ilc->numtextsymbols == 0 || !ilc->textsymbols[0]->annotext) - continue; + continue; ts = ilc->textsymbols[0]; if (strcmp(s->annotext, ts->annotext) != 0) { @@ -2972,66 +3340,74 @@ int msCheckLabelMinDistance(mapObj *map, labelCacheMemberObj *lc) return MS_TRUE; } - if(ts->textpath && ts->textpath->absolute) { - if (intersectLabelPolygons(ts->textpath->bounds.poly, &ilc->bbox, NULL, &buffered) == MS_TRUE) { + if (ts->textpath && ts->textpath->absolute) { + if (intersectLabelPolygons(ts->textpath->bounds.poly, &ilc->bbox, NULL, + &buffered) == MS_TRUE) { return MS_TRUE; } continue; } - if (intersectLabelPolygons(NULL, &ilc->bbox, NULL, &buffered) == MS_TRUE) { - return MS_TRUE; + return MS_TRUE; } - } return MS_FALSE; } void copyLabelBounds(label_bounds *dst, label_bounds *src) { *dst = *src; - if(src->poly) { + if (src->poly) { int i; dst->poly = msSmallMalloc(sizeof(lineObj)); dst->poly->numpoints = src->poly->numpoints; dst->poly->point = msSmallMalloc(dst->poly->numpoints * sizeof(pointObj)); - for(i=0; ipoly->numpoints; i++) { + for (i = 0; i < dst->poly->numpoints; i++) { dst->poly->point[i] = src->poly->point[i]; } } } static int getLabelPositionFromString(char *pszString) { - if (strcasecmp(pszString, "UL")==0) return MS_UL; - else if (strcasecmp(pszString, "LR")==0) return MS_LR; - else if (strcasecmp(pszString, "UR")==0) return MS_UR; - else if (strcasecmp(pszString, "LL")==0) return MS_LL; - else if (strcasecmp(pszString, "CR")==0) return MS_CR; - else if (strcasecmp(pszString, "CL")==0) return MS_CL; - else if (strcasecmp(pszString, "UC")==0) return MS_UC; - else if (strcasecmp(pszString, "LC")==0) return MS_LC; - else return MS_CC; + if (strcasecmp(pszString, "UL") == 0) + return MS_UL; + else if (strcasecmp(pszString, "LR") == 0) + return MS_LR; + else if (strcasecmp(pszString, "UR") == 0) + return MS_UR; + else if (strcasecmp(pszString, "LL") == 0) + return MS_LL; + else if (strcasecmp(pszString, "CR") == 0) + return MS_CR; + else if (strcasecmp(pszString, "CL") == 0) + return MS_CL; + else if (strcasecmp(pszString, "UC") == 0) + return MS_UC; + else if (strcasecmp(pszString, "LC") == 0) + return MS_LC; + else + return MS_CC; } -int msDrawLabelCache(mapObj *map, imageObj *image) -{ +int msDrawLabelCache(mapObj *map, imageObj *image) { int nReturnVal = MS_SUCCESS; - struct mstimeval starttime={0}, endtime={0}; + struct mstimeval starttime = {0}, endtime = {0}; - if(map->debug >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&starttime, NULL); + if (map->debug >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&starttime, NULL); - if(image) { - if(MS_RENDERER_PLUGIN(image->format)) { + if (image) { + if (MS_RENDERER_PLUGIN(image->format)) { int i, l, ll, priority, its; double marker_offset_x, marker_offset_y; int label_offset_x, label_offset_y; const char *value; - labelCacheMemberObj *cachePtr=NULL; - layerObj *layerPtr=NULL; - classObj *classPtr=NULL; - textSymbolObj *textSymbolPtr=NULL; + labelCacheMemberObj *cachePtr = NULL; + layerObj *layerPtr = NULL; + classObj *classPtr = NULL; + textSymbolObj *textSymbolPtr = NULL; /* * some statically allocated containers for storing label bounds before @@ -3041,7 +3417,7 @@ int msDrawLabelCache(mapObj *map, imageObj *image) lineObj labelpoly_line; pointObj labelpoly_points[5]; label_bounds labelpoly_bounds = {0}; - lineObj label_marker_line; + lineObj label_marker_line; pointObj label_marker_points[5]; label_bounds label_marker_bounds; lineObj metrics_line; @@ -3056,365 +3432,545 @@ int msDrawLabelCache(mapObj *map, imageObj *image) labelpoly_line.numpoints = 5; /* Look for labelcache_map_edge_buffer map metadata - * If set then the value defines a buffer (in pixels) along the edge of the - * map image where labels can't fall + * If set then the value defines a buffer (in pixels) along the edge of + * the map image where labels can't fall */ - if((value = msLookupHashTable(&(map->web.metadata), "labelcache_map_edge_buffer")) != NULL) { + if ((value = msLookupHashTable(&(map->web.metadata), + "labelcache_map_edge_buffer")) != NULL) { map->labelcache.gutter = MS_ABS(atoi(value)); - if(map->debug) msDebug("msDrawLabelCache(): labelcache_map_edge_buffer = %d\n", map->labelcache.gutter); + if (map->debug) + msDebug("msDrawLabelCache(): labelcache_map_edge_buffer = %d\n", + map->labelcache.gutter); } - for(priority=MS_MAX_LABEL_PRIORITY-1; priority>=0; priority--) { + for (priority = MS_MAX_LABEL_PRIORITY - 1; priority >= 0; priority--) { labelCacheSlotObj *cacheslot; cacheslot = &(map->labelcache.slots[priority]); - for(l=cacheslot->numlabels-1; l>=0; l--) { - cachePtr = &(cacheslot->labels[l]); /* point to right spot in the label cache */ + for (l = cacheslot->numlabels - 1; l >= 0; l--) { + cachePtr = + &(cacheslot + ->labels[l]); /* point to right spot in the label cache */ - layerPtr = (GET_LAYER(map, cachePtr->layerindex)); /* set a couple of other pointers, avoids nasty references */ - classPtr = (GET_CLASS(map, cachePtr->layerindex, cachePtr->classindex)); + layerPtr = (GET_LAYER( + map, cachePtr->layerindex)); /* set a couple of other pointers, + avoids nasty references */ + classPtr = + (GET_CLASS(map, cachePtr->layerindex, cachePtr->classindex)); - if(cachePtr->textsymbols[0]->textpath && cachePtr->textsymbols[0]->textpath->absolute) { + if (cachePtr->textsymbols[0]->textpath && + cachePtr->textsymbols[0]->textpath->absolute) { /* we have an angle follow label */ cachePtr->bbox = cachePtr->textsymbols[0]->textpath->bounds.bbox; /* before going any futher, check that mindistance is respected */ - if (cachePtr->numtextsymbols && cachePtr->textsymbols[0]->label->mindistance > 0.0 && cachePtr->textsymbols[0]->annotext) { + if (cachePtr->numtextsymbols && + cachePtr->textsymbols[0]->label->mindistance > 0.0 && + cachePtr->textsymbols[0]->annotext) { if (msCheckLabelMinDistance(map, cachePtr) == MS_TRUE) { cachePtr->status = MS_DELETE; MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, - "Skipping labelgroup %d \"%s\" in layer \"%s\": too close to an identical label (mindistance)\n", - l, cachePtr->textsymbols[0]->annotext, layerPtr->name); - continue; /* move on to next entry, this one is too close to an already placed one */ + "Skipping labelgroup %d \"%s\" in layer \"%s\": too " + "close to an identical label (mindistance)\n", + l, cachePtr->textsymbols[0]->annotext, layerPtr->name); + continue; /* move on to next entry, this one is too close to an + already placed one */ } } - if(!cachePtr->textsymbols[0]->label->force) - cachePtr->status = msTestLabelCacheCollisions(map,cachePtr,&cachePtr->textsymbols[0]->textpath->bounds, priority, l); + if (!cachePtr->textsymbols[0]->label->force) + cachePtr->status = msTestLabelCacheCollisions( + map, cachePtr, &cachePtr->textsymbols[0]->textpath->bounds, + priority, l); else cachePtr->status = MS_ON; - if(cachePtr->status) { - - - if (MS_UNLIKELY(MS_FAILURE == msDrawTextSymbol(map, image, cachePtr->textsymbols[0]->annopoint /*not used*/, cachePtr->textsymbols[0]))) - { + if (cachePtr->status) { + + if (MS_UNLIKELY( + MS_FAILURE == + msDrawTextSymbol( + map, image, + cachePtr->textsymbols[0]->annopoint /*not used*/, + cachePtr->textsymbols[0]))) { return MS_FAILURE; } insertRenderedLabelMember(map, cachePtr); } else { - MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG,map, - "Skipping follow labelgroup %d \"%s\" in layer \"%s\": text collided\n", - l, cachePtr->textsymbols[0]->annotext, layerPtr->name); + MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, + "Skipping follow labelgroup %d \"%s\" in layer \"%s\": " + "text collided\n", + l, cachePtr->textsymbols[0]->annotext, layerPtr->name); } - cachePtr->status = MS_DELETE; /* we're done with this label, it won't even have a second chance in the leader phase */ + cachePtr->status = + MS_DELETE; /* we're done with this label, it won't even have a + second chance in the leader phase */ } else { marker_offset_x = marker_offset_y = 0; /* assume no marker */ - - if (layerPtr->type == MS_LAYER_POINT && cachePtr->markerid!=-1) { /* there is a marker already in the image that we need to account for */ - markerCacheMemberObj *markerPtr = &(cacheslot->markers[cachePtr->markerid]); /* point to the right spot in the marker cache*/ - marker_offset_x = (markerPtr->bounds.maxx-markerPtr->bounds.minx)/2.0; - marker_offset_y = (markerPtr->bounds.maxy-markerPtr->bounds.miny)/2.0; - } + if (layerPtr->type == MS_LAYER_POINT && + cachePtr->markerid != + -1) { /* there is a marker already in the image that we need + to account for */ + markerCacheMemberObj *markerPtr = &( + cacheslot + ->markers[cachePtr->markerid]); /* point to the right spot + in the marker cache*/ + marker_offset_x = + (markerPtr->bounds.maxx - markerPtr->bounds.minx) / 2.0; + marker_offset_y = + (markerPtr->bounds.maxy - markerPtr->bounds.miny) / 2.0; + } /* ** all other cases *could* have multiple labels defined */ - cachePtr->status = MS_ON; /* assume this cache element can be placed */ - for(ll=0; llnumtextsymbols; ll++) { /* RFC 77 TODO: Still may want to step through backwards... */ - int label_marker_status = MS_ON, have_label_marker, metrics_status = MS_ON; + cachePtr->status = + MS_ON; /* assume this cache element can be placed */ + for (ll = 0; ll < cachePtr->numtextsymbols; + ll++) { /* RFC 77 TODO: Still may want to step through + backwards... */ + int label_marker_status = MS_ON, have_label_marker, + metrics_status = MS_ON; int need_labelpoly = 0; - - /* reset the lineObj which may have been unset by a previous call to get_metrics() */ + + /* reset the lineObj which may have been unset by a previous call + * to get_metrics() */ label_marker_bounds.poly = &label_marker_line; labelpoly_bounds.poly = &labelpoly_line; textSymbolPtr = cachePtr->textsymbols[ll]; - for(i=0; ilabel->numstyles; i++) { - if(textSymbolPtr->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY || - textSymbolPtr->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER) { + for (i = 0; i < textSymbolPtr->label->numstyles; i++) { + if (textSymbolPtr->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY || + textSymbolPtr->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER) { need_labelpoly = 1; break; } } /* compute the poly of the label styles */ - if((have_label_marker = computeMarkerBounds(map,&cachePtr->point,textSymbolPtr, &label_marker_bounds)) == MS_TRUE) { - if(cachePtr->numtextsymbols > 1) { /* FIXME this test doesn't seem right, should probably check if we have an annotation layer with a regular style defined */ - marker_offset_x = (label_marker_bounds.bbox.maxx-label_marker_bounds.bbox.minx)/2.0; - marker_offset_y = (label_marker_bounds.bbox.maxy-label_marker_bounds.bbox.miny)/2.0; + if ((have_label_marker = + computeMarkerBounds(map, &cachePtr->point, textSymbolPtr, + &label_marker_bounds)) == MS_TRUE) { + if (cachePtr->numtextsymbols > + 1) { /* FIXME this test doesn't seem right, should probably + check if we have an annotation layer with a regular + style defined */ + marker_offset_x = (label_marker_bounds.bbox.maxx - + label_marker_bounds.bbox.minx) / + 2.0; + marker_offset_y = (label_marker_bounds.bbox.maxy - + label_marker_bounds.bbox.miny) / + 2.0; } else { /* we might be using an old style behavior with a markerPtr */ - marker_offset_x = MS_MAX(marker_offset_x,(label_marker_bounds.bbox.maxx-label_marker_bounds.bbox.minx)/2.0); - marker_offset_y = MS_MAX(marker_offset_y,(label_marker_bounds.bbox.maxy-label_marker_bounds.bbox.miny)/2.0); + marker_offset_x = + MS_MAX(marker_offset_x, (label_marker_bounds.bbox.maxx - + label_marker_bounds.bbox.minx) / + 2.0); + marker_offset_y = + MS_MAX(marker_offset_y, (label_marker_bounds.bbox.maxy - + label_marker_bounds.bbox.miny) / + 2.0); } /* add marker to cachePtr->poly */ - if(textSymbolPtr->label->force != MS_TRUE) { - label_marker_status = msTestLabelCacheCollisions(map, cachePtr, &label_marker_bounds ,priority, l); + if (textSymbolPtr->label->force != MS_TRUE) { + label_marker_status = msTestLabelCacheCollisions( + map, cachePtr, &label_marker_bounds, priority, l); } - if(label_marker_status == MS_OFF && - !(textSymbolPtr->label->force==MS_ON || classPtr->leader)) { + if (label_marker_status == MS_OFF && + !(textSymbolPtr->label->force == MS_ON || + classPtr->leader)) { cachePtr->status = MS_DELETE; MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, - "Skipping label %d of labelgroup %d of class %d in layer \"%s\": marker collided\n", - ll, l, cachePtr->classindex, layerPtr->name); + "Skipping label %d of labelgroup %d of class %d in " + "layer \"%s\": marker collided\n", + ll, l, cachePtr->classindex, layerPtr->name); break; /* the marker collided, break from multi-label loop */ } } - if(have_label_marker == -1) return MS_FAILURE; /* error occured (symbol not found, etc...) */ + if (have_label_marker == -1) + return MS_FAILURE; /* error occured (symbol not found, etc...) + */ - if(textSymbolPtr->annotext) { + if (textSymbolPtr->annotext) { /* - * if we don't have an offset defined, first check that the labelpoint itself does not collide - * this helps speed things up in dense labelling, as if the labelpoint collides there's - * no use in computing the labeltext bounds (i.e. going into shaping+freetype). - * We do however skip collision testing against the marker cache, as we want to allow rendering - * a label for points that overlap each other: this is done by setting priority to MAX_PRIORITY - * in the call to msTestLabelCacheCollisions (which is a hack!!) + * if we don't have an offset defined, first check that the + * labelpoint itself does not collide this helps speed things up + * in dense labelling, as if the labelpoint collides there's no + * use in computing the labeltext bounds (i.e. going into + * shaping+freetype). We do however skip collision testing + * against the marker cache, as we want to allow rendering a + * label for points that overlap each other: this is done by + * setting priority to MAX_PRIORITY in the call to + * msTestLabelCacheCollisions (which is a hack!!) */ - if(!have_label_marker && textSymbolPtr->label->force != MS_TRUE && !classPtr->leader && - !textSymbolPtr->label->offsetx && !textSymbolPtr->label->offsety) { + if (!have_label_marker && + textSymbolPtr->label->force != MS_TRUE && + !classPtr->leader && !textSymbolPtr->label->offsetx && + !textSymbolPtr->label->offsety) { label_bounds labelpoint_bounds; labelpoint_bounds.poly = NULL; labelpoint_bounds.bbox.minx = cachePtr->point.x - 0.1; labelpoint_bounds.bbox.maxx = cachePtr->point.x + 0.1; labelpoint_bounds.bbox.miny = cachePtr->point.y - 0.1; labelpoint_bounds.bbox.maxy = cachePtr->point.y + 0.1; - if(MS_OFF == msTestLabelCacheCollisions(map, cachePtr, &labelpoint_bounds, MS_MAX_LABEL_PRIORITY, l)) { - cachePtr->status = MS_DELETE; /* we won't check for leader offseted positions, as the anchor point colided */ + if (MS_OFF == msTestLabelCacheCollisions( + map, cachePtr, &labelpoint_bounds, + MS_MAX_LABEL_PRIORITY, l)) { + cachePtr->status = + MS_DELETE; /* we won't check for leader offseted + positions, as the anchor point colided */ MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, - "Skipping label %d \"%s\" of labelgroup %d of class %d in layer \"%s\": labelpoint collided\n", - ll, textSymbolPtr->annotext, l, cachePtr->classindex, layerPtr->name); + "Skipping label %d \"%s\" of labelgroup %d of " + "class %d in layer \"%s\": labelpoint collided\n", + ll, textSymbolPtr->annotext, l, + cachePtr->classindex, layerPtr->name); break; } } /* compute label size */ - if(!textSymbolPtr->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,textSymbolPtr))) { + if (!textSymbolPtr->textpath) { + if (MS_UNLIKELY(MS_FAILURE == + msComputeTextPath(map, textSymbolPtr))) { return MS_FAILURE; } } - /* if our label has an outline, adjust the marker offset so the outlinecolor does - * not bleed into the marker */ - if(marker_offset_x && MS_VALID_COLOR(textSymbolPtr->label->outlinecolor)) { - marker_offset_x += textSymbolPtr->label->outlinewidth/2.0 * textSymbolPtr->scalefactor; - marker_offset_y += textSymbolPtr->label->outlinewidth/2.0 * textSymbolPtr->scalefactor; + /* if our label has an outline, adjust the marker offset so the + * outlinecolor does not bleed into the marker */ + if (marker_offset_x && + MS_VALID_COLOR(textSymbolPtr->label->outlinecolor)) { + marker_offset_x += textSymbolPtr->label->outlinewidth / 2.0 * + textSymbolPtr->scalefactor; + marker_offset_y += textSymbolPtr->label->outlinewidth / 2.0 * + textSymbolPtr->scalefactor; } - + /* apply offset and buffer settings */ - if(textSymbolPtr->label->anglemode != MS_FOLLOW) { - label_offset_x = textSymbolPtr->label->offsetx * textSymbolPtr->scalefactor; - label_offset_y = textSymbolPtr->label->offsety * textSymbolPtr-> scalefactor; + if (textSymbolPtr->label->anglemode != MS_FOLLOW) { + label_offset_x = textSymbolPtr->label->offsetx * + textSymbolPtr->scalefactor; + label_offset_y = textSymbolPtr->label->offsety * + textSymbolPtr->scalefactor; } else { label_offset_x = 0; label_offset_y = 0; } - if(textSymbolPtr->label->position == MS_AUTO) { - /* no point in using auto positionning if the marker cannot be placed */ - int positions[MS_POSITIONS_LENGTH], npositions=0; - + if (textSymbolPtr->label->position == MS_AUTO) { + /* no point in using auto positionning if the marker cannot be + * placed */ + int positions[MS_POSITIONS_LENGTH], npositions = 0; + /* ** (Note: might be able to re-order this for more speed.) */ - if(msLayerGetProcessingKey(layerPtr, "LABEL_POSITIONS")) { - int p, ncustom_positions=0; - char **custom_positions = msStringSplitComplex(msLayerGetProcessingKey(layerPtr, "LABEL_POSITIONS"), ",", &ncustom_positions, MS_STRIPLEADSPACES|MS_STRIPENDSPACES); - for(p=0; ptype == MS_LAYER_POLYGON && marker_offset_x==0 ) { - positions[0]=MS_CC; - positions[1]=MS_UC; - positions[2]=MS_LC; - positions[3]=MS_CL; - positions[4]=MS_CR; + } else if (layerPtr->type == MS_LAYER_POLYGON && + marker_offset_x == 0) { + positions[0] = MS_CC; + positions[1] = MS_UC; + positions[2] = MS_LC; + positions[3] = MS_CL; + positions[4] = MS_CR; npositions = 5; - } else if(layerPtr->type == MS_LAYER_LINE && marker_offset_x == 0) { - positions[0]=MS_UC; - positions[1]=MS_LC; - positions[2]=MS_CC; + } else if (layerPtr->type == MS_LAYER_LINE && + marker_offset_x == 0) { + positions[0] = MS_UC; + positions[1] = MS_LC; + positions[2] = MS_CC; npositions = 3; } else { - positions[0]=MS_UL; - positions[1]=MS_LR; - positions[2]=MS_UR; - positions[3]=MS_LL; - positions[4]=MS_CR; - positions[5]=MS_CL; - positions[6]=MS_UC; - positions[7]=MS_LC; + positions[0] = MS_UL; + positions[1] = MS_LR; + positions[2] = MS_UR; + positions[3] = MS_LL; + positions[4] = MS_CR; + positions[5] = MS_CL; + positions[6] = MS_UC; + positions[7] = MS_LC; npositions = 8; } - for(i=0; iannopoint = get_metrics(&(cachePtr->point), positions[i], textSymbolPtr->textpath, - marker_offset_x + label_offset_x, marker_offset_y + label_offset_y, - textSymbolPtr->rotation, textSymbolPtr->label->buffer * textSymbolPtr->scalefactor, &metrics_bounds); - if(textSymbolPtr->label->force == MS_OFF) { - for(its=0;itsannopoint = + get_metrics(&(cachePtr->point), positions[i], + textSymbolPtr->textpath, + marker_offset_x + label_offset_x, + marker_offset_y + label_offset_y, + textSymbolPtr->rotation, + textSymbolPtr->label->buffer * + textSymbolPtr->scalefactor, + &metrics_bounds); + if (textSymbolPtr->label->force == MS_OFF) { + for (its = 0; its < ll; its++) { /* check for collisions inside the label group */ - if(intersectTextSymbol(cachePtr->textsymbols[its],&metrics_bounds) == MS_TRUE) { + if (intersectTextSymbol(cachePtr->textsymbols[its], + &metrics_bounds) == MS_TRUE) { /* there was a self intersection */ - break; /* next position, will break out to next position in containing loop*/ + break; /* next position, will break out to next + position in containing loop*/ } - if(its != ll) - continue; /* goto next position, this one had an intersection with our own label group */ + if (its != ll) + continue; /* goto next position, this one had an + intersection with our own label group */ } } - metrics_status = msTestLabelCacheCollisions(map, cachePtr,&metrics_bounds, priority, l); + metrics_status = msTestLabelCacheCollisions( + map, cachePtr, &metrics_bounds, priority, l); /* found a suitable place for this label */ - if(metrics_status == MS_TRUE || (i==(npositions-1) && textSymbolPtr->label->force == MS_ON)) { - metrics_status = MS_TRUE; /* set to true in case we are forcing it */ + if (metrics_status == MS_TRUE || + (i == (npositions - 1) && + textSymbolPtr->label->force == MS_ON)) { + metrics_status = + MS_TRUE; /* set to true in case we are forcing it */ /* compute anno poly for label background if needed */ - if(need_labelpoly) get_metrics(&(cachePtr->point), positions[i], textSymbolPtr->textpath, - marker_offset_x + label_offset_x, marker_offset_y + label_offset_y, - textSymbolPtr->rotation, 1, &labelpoly_bounds); + if (need_labelpoly) + get_metrics(&(cachePtr->point), positions[i], + textSymbolPtr->textpath, + marker_offset_x + label_offset_x, + marker_offset_y + label_offset_y, + textSymbolPtr->rotation, 1, + &labelpoly_bounds); break; /* ...out of position loop */ } } /* next position */ - /* if position auto didn't manage to find a position, but we have leader configured - * for the class, then we want to compute the label poly anyway, placed as MS_CC */ - if(classPtr->leader && metrics_status == MS_FALSE) { + /* if position auto didn't manage to find a position, but we + * have leader configured for the class, then we want to + * compute the label poly anyway, placed as MS_CC */ + if (classPtr->leader && metrics_status == MS_FALSE) { metrics_bounds.poly = &metrics_line; - textSymbolPtr->annopoint = get_metrics(&(cachePtr->point), MS_CC, textSymbolPtr->textpath, label_offset_x, label_offset_y, - textSymbolPtr->rotation, textSymbolPtr->label->buffer * textSymbolPtr->scalefactor, - &metrics_bounds); - if(need_labelpoly) get_metrics(&(cachePtr->point), MS_CC, textSymbolPtr->textpath, - label_offset_x, label_offset_y, - textSymbolPtr->rotation, 1, &labelpoly_bounds); + textSymbolPtr->annopoint = get_metrics( + &(cachePtr->point), MS_CC, textSymbolPtr->textpath, + label_offset_x, label_offset_y, textSymbolPtr->rotation, + textSymbolPtr->label->buffer * + textSymbolPtr->scalefactor, + &metrics_bounds); + if (need_labelpoly) + get_metrics(&(cachePtr->point), MS_CC, + textSymbolPtr->textpath, label_offset_x, + label_offset_y, textSymbolPtr->rotation, 1, + &labelpoly_bounds); } } else { /* explicit position */ - if(textSymbolPtr->label->position == MS_CC) { /* don't need the marker_offset */ + if (textSymbolPtr->label->position == + MS_CC) { /* don't need the marker_offset */ metrics_bounds.poly = &metrics_line; - textSymbolPtr->annopoint = get_metrics(&(cachePtr->point), MS_CC, textSymbolPtr->textpath, label_offset_x, label_offset_y, - textSymbolPtr->rotation, textSymbolPtr->label->buffer * textSymbolPtr->scalefactor, &metrics_bounds); - if(need_labelpoly) get_metrics(&(cachePtr->point), MS_CC, textSymbolPtr->textpath, - label_offset_x, label_offset_y, textSymbolPtr->rotation, 1, &labelpoly_bounds); + textSymbolPtr->annopoint = get_metrics( + &(cachePtr->point), MS_CC, textSymbolPtr->textpath, + label_offset_x, label_offset_y, textSymbolPtr->rotation, + textSymbolPtr->label->buffer * + textSymbolPtr->scalefactor, + &metrics_bounds); + if (need_labelpoly) + get_metrics(&(cachePtr->point), MS_CC, + textSymbolPtr->textpath, label_offset_x, + label_offset_y, textSymbolPtr->rotation, 1, + &labelpoly_bounds); } else { metrics_bounds.poly = &metrics_line; - textSymbolPtr->annopoint = get_metrics(&(cachePtr->point), textSymbolPtr->label->position, textSymbolPtr->textpath, - marker_offset_x + label_offset_x, marker_offset_y + label_offset_y, - textSymbolPtr->rotation, textSymbolPtr->label->buffer * textSymbolPtr->scalefactor, - &metrics_bounds); - if(need_labelpoly) get_metrics(&(cachePtr->point), textSymbolPtr->label->position, textSymbolPtr->textpath, - marker_offset_x + label_offset_x, marker_offset_y + label_offset_y, textSymbolPtr->rotation, 1, &labelpoly_bounds); + textSymbolPtr->annopoint = get_metrics( + &(cachePtr->point), textSymbolPtr->label->position, + textSymbolPtr->textpath, + marker_offset_x + label_offset_x, + marker_offset_y + label_offset_y, + textSymbolPtr->rotation, + textSymbolPtr->label->buffer * + textSymbolPtr->scalefactor, + &metrics_bounds); + if (need_labelpoly) + get_metrics( + &(cachePtr->point), textSymbolPtr->label->position, + textSymbolPtr->textpath, + marker_offset_x + label_offset_x, + marker_offset_y + label_offset_y, + textSymbolPtr->rotation, 1, &labelpoly_bounds); } - if(textSymbolPtr->label->force == MS_ON) { + if (textSymbolPtr->label->force == MS_ON) { metrics_status = MS_ON; } else { - if(textSymbolPtr->label->force == MS_OFF) { - /* check for collisions inside the label group unless the label is FORCE GROUP */ - for(its=0;itslabel->force == MS_OFF) { + /* check for collisions inside the label group unless the + * label is FORCE GROUP */ + for (its = 0; its < ll; its++) { /* check for collisions inside the label group */ - if(intersectTextSymbol(cachePtr->textsymbols[its],&metrics_bounds) == MS_TRUE) { + if (intersectTextSymbol(cachePtr->textsymbols[its], + &metrics_bounds) == MS_TRUE) { /* there was a self intersection */ - break; /* will break out to next position in containing loop*/ + break; /* will break out to next position in + containing loop*/ } - if(its != ll) { - cachePtr->status = MS_DELETE; /* TODO RFC98: check if this is correct */ - MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG,map, - "Skipping label %d (\"%s\") of labelgroup %d of class %d in layer \"%s\": intercollision with label text inside labelgroup\n", - ll, textSymbolPtr->annotext, l,cachePtr->classindex, layerPtr->name); - break; /* collision within the group, break out of textSymbol loop */ + if (its != ll) { + cachePtr->status = MS_DELETE; /* TODO RFC98: check if + this is correct */ + MS_DEBUG( + MS_DEBUGLEVEL_DEVDEBUG, map, + "Skipping label %d (\"%s\") of labelgroup %d of " + "class %d in layer \"%s\": intercollision with " + "label text inside labelgroup\n", + ll, textSymbolPtr->annotext, l, + cachePtr->classindex, layerPtr->name); + break; /* collision within the group, break out of + textSymbol loop */ } } } - /* TODO: in case we have leader lines and multiple labels, there's no use in testing for labelcache collisions - * once a first collision has been found. we only need to know that the label group has collided, and the - * poly of the whole label group: if(label_group) testLabelCacheCollisions */ - metrics_status = msTestLabelCacheCollisions(map, cachePtr,&metrics_bounds, priority, l); + /* TODO: in case we have leader lines and multiple labels, + * there's no use in testing for labelcache collisions once + * a first collision has been found. we only need to know + * that the label group has collided, and the poly of the + * whole label group: if(label_group) + * testLabelCacheCollisions */ + metrics_status = msTestLabelCacheCollisions( + map, cachePtr, &metrics_bounds, priority, l); } } /* end POSITION AUTO vs Fixed POSITION */ - if(!metrics_status && classPtr->leader == 0) { + if (!metrics_status && classPtr->leader == 0) { cachePtr->status = MS_DELETE; - MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG,map, - "Skipping label %d \"%s\" of labelgroup %d of class %d in layer \"%s\": text collided\n", - ll, textSymbolPtr->annotext, l, cachePtr->classindex, layerPtr->name); - break; /* no point looking at more labels, unless their is a leader defined */ + MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, + "Skipping label %d \"%s\" of labelgroup %d of class " + "%d in layer \"%s\": text collided\n", + ll, textSymbolPtr->annotext, l, cachePtr->classindex, + layerPtr->name); + break; /* no point looking at more labels, unless their is a + leader defined */ } } - /* if we're here, we can either fit the label directly, or we need to put it in the leader queue */ - assert((metrics_status && label_marker_status) || classPtr->leader); + /* if we're here, we can either fit the label directly, or we need + * to put it in the leader queue */ + assert((metrics_status && label_marker_status) || + classPtr->leader); - if(textSymbolPtr->annotext) { - copyLabelBounds(&textSymbolPtr->textpath->bounds, &metrics_bounds); + if (textSymbolPtr->annotext) { + copyLabelBounds(&textSymbolPtr->textpath->bounds, + &metrics_bounds); } - if(have_label_marker) { - if(!textSymbolPtr->style_bounds) - textSymbolPtr->style_bounds = msSmallCalloc(textSymbolPtr->label->numstyles, sizeof(label_bounds*)); - for(its=0;itslabel->numstyles; its++) { - if(textSymbolPtr->label->styles[its]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - textSymbolPtr->style_bounds[its] = msSmallMalloc(sizeof(label_bounds)); - copyLabelBounds(textSymbolPtr->style_bounds[its], &label_marker_bounds); + if (have_label_marker) { + if (!textSymbolPtr->style_bounds) + textSymbolPtr->style_bounds = msSmallCalloc( + textSymbolPtr->label->numstyles, sizeof(label_bounds *)); + for (its = 0; its < textSymbolPtr->label->numstyles; its++) { + if (textSymbolPtr->label->styles[its]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + textSymbolPtr->style_bounds[its] = + msSmallMalloc(sizeof(label_bounds)); + copyLabelBounds(textSymbolPtr->style_bounds[its], + &label_marker_bounds); } } } - if(!label_marker_status || ! metrics_status) { + if (!label_marker_status || !metrics_status) { MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, - "Putting label %d of labelgroup %d of class %d , layer \"%s\" in leader queue\n", - ll, l, cachePtr->classindex, layerPtr->name); - cachePtr->status = MS_OFF; /* we have a collision, but this entry is a candidate for leader testing */ + "Putting label %d of labelgroup %d of class %d , " + "layer \"%s\" in leader queue\n", + ll, l, cachePtr->classindex, layerPtr->name); + cachePtr->status = + MS_OFF; /* we have a collision, but this entry is a + candidate for leader testing */ } - /* do we need to copy the labelpoly, or can we use the static one ?*/ - if(cachePtr->numtextsymbols > 1 || (cachePtr->status == MS_OFF && classPtr->leader)) { + /* do we need to copy the labelpoly, or can we use the static one + * ?*/ + if (cachePtr->numtextsymbols > 1 || + (cachePtr->status == MS_OFF && classPtr->leader)) { /* - * if we have more than one label, or if we have a single one which didn't fit but needs - * to go through leader offset testing + * if we have more than one label, or if we have a single one + * which didn't fit but needs to go through leader offset + * testing */ - if(!textSymbolPtr->style_bounds) - textSymbolPtr->style_bounds = msSmallCalloc(textSymbolPtr->label->numstyles, sizeof(label_bounds*)); - for(its=0;itslabel->numstyles; its++) { - if(textSymbolPtr->label->styles[its]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY || - textSymbolPtr->label->styles[its]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER) { - textSymbolPtr->style_bounds[its] = msSmallMalloc(sizeof(label_bounds)); - copyLabelBounds(textSymbolPtr->style_bounds[its], &labelpoly_bounds); + if (!textSymbolPtr->style_bounds) + textSymbolPtr->style_bounds = msSmallCalloc( + textSymbolPtr->label->numstyles, sizeof(label_bounds *)); + for (its = 0; its < textSymbolPtr->label->numstyles; its++) { + if (textSymbolPtr->label->styles[its]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY || + textSymbolPtr->label->styles[its]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER) { + textSymbolPtr->style_bounds[its] = + msSmallMalloc(sizeof(label_bounds)); + copyLabelBounds(textSymbolPtr->style_bounds[its], + &labelpoly_bounds); } } } /* else: we'll use labelpoly_bounds directly below */ - } /* next label in the group */ + } /* next label in the group */ - if(cachePtr->status != MS_DELETE) { + if (cachePtr->status != MS_DELETE) { /* compute the global label bbox */ - int inited = 0,s; - for(its=0;itsnumtextsymbols;its++) { - if(cachePtr->textsymbols[its]->annotext) { - if(inited == 0) { - cachePtr->bbox = cachePtr->textsymbols[its]->textpath->bounds.bbox; + int inited = 0, s; + for (its = 0; its < cachePtr->numtextsymbols; its++) { + if (cachePtr->textsymbols[its]->annotext) { + if (inited == 0) { + cachePtr->bbox = + cachePtr->textsymbols[its]->textpath->bounds.bbox; inited = 1; } else { - cachePtr->bbox.minx = MS_MIN(cachePtr->bbox.minx, cachePtr->textsymbols[its]->textpath->bounds.bbox.minx); - cachePtr->bbox.miny = MS_MIN(cachePtr->bbox.miny, cachePtr->textsymbols[its]->textpath->bounds.bbox.miny); - cachePtr->bbox.maxx = MS_MAX(cachePtr->bbox.maxx, cachePtr->textsymbols[its]->textpath->bounds.bbox.maxx); - cachePtr->bbox.maxy = MS_MAX(cachePtr->bbox.maxy, cachePtr->textsymbols[its]->textpath->bounds.bbox.maxy); + cachePtr->bbox.minx = MS_MIN( + cachePtr->bbox.minx, + cachePtr->textsymbols[its]->textpath->bounds.bbox.minx); + cachePtr->bbox.miny = MS_MIN( + cachePtr->bbox.miny, + cachePtr->textsymbols[its]->textpath->bounds.bbox.miny); + cachePtr->bbox.maxx = MS_MAX( + cachePtr->bbox.maxx, + cachePtr->textsymbols[its]->textpath->bounds.bbox.maxx); + cachePtr->bbox.maxy = MS_MAX( + cachePtr->bbox.maxy, + cachePtr->textsymbols[its]->textpath->bounds.bbox.maxy); } } - for(s=0; stextsymbols[its]->label->numstyles; s++) { - if(cachePtr->textsymbols[its]->label->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - if(inited == 0) { - cachePtr->bbox = cachePtr->textsymbols[its]->style_bounds[s]->bbox; + for (s = 0; s < cachePtr->textsymbols[its]->label->numstyles; + s++) { + if (cachePtr->textsymbols[its] + ->label->styles[s] + ->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + if (inited == 0) { + cachePtr->bbox = + cachePtr->textsymbols[its]->style_bounds[s]->bbox; inited = 1; break; } else { - cachePtr->bbox.minx = MS_MIN(cachePtr->bbox.minx, cachePtr->textsymbols[its]->style_bounds[s]->bbox.minx); - cachePtr->bbox.miny = MS_MIN(cachePtr->bbox.miny, cachePtr->textsymbols[its]->style_bounds[s]->bbox.miny); - cachePtr->bbox.maxx = MS_MAX(cachePtr->bbox.maxx, cachePtr->textsymbols[its]->style_bounds[s]->bbox.maxx); - cachePtr->bbox.maxy = MS_MAX(cachePtr->bbox.maxy, cachePtr->textsymbols[its]->style_bounds[s]->bbox.maxy); - break; + cachePtr->bbox.minx = + MS_MIN(cachePtr->bbox.minx, cachePtr->textsymbols[its] + ->style_bounds[s] + ->bbox.minx); + cachePtr->bbox.miny = + MS_MIN(cachePtr->bbox.miny, cachePtr->textsymbols[its] + ->style_bounds[s] + ->bbox.miny); + cachePtr->bbox.maxx = + MS_MAX(cachePtr->bbox.maxx, cachePtr->textsymbols[its] + ->style_bounds[s] + ->bbox.maxx); + cachePtr->bbox.maxy = + MS_MAX(cachePtr->bbox.maxy, cachePtr->textsymbols[its] + ->style_bounds[s] + ->bbox.maxy); + break; } } } @@ -3422,72 +3978,122 @@ int msDrawLabelCache(mapObj *map, imageObj *image) } /* check that mindistance is respected */ - if (cachePtr->numtextsymbols && cachePtr->textsymbols[0]->label->mindistance > 0.0 && cachePtr->textsymbols[0]->annotext) { + if (cachePtr->numtextsymbols && + cachePtr->textsymbols[0]->label->mindistance > 0.0 && + cachePtr->textsymbols[0]->annotext) { if (msCheckLabelMinDistance(map, cachePtr) == MS_TRUE) { cachePtr->status = MS_DELETE; MS_DEBUG(MS_DEBUGLEVEL_DEVDEBUG, map, - "Skipping labelgroup %d \"%s\" in layer \"%s\": too close to an identical label (mindistance)\n", + "Skipping labelgroup %d \"%s\" in layer \"%s\": too " + "close to an identical label (mindistance)\n", l, cachePtr->textsymbols[0]->annotext, layerPtr->name); } } - if(cachePtr->status == MS_OFF || cachePtr->status == MS_DELETE) + if (cachePtr->status == MS_OFF || cachePtr->status == MS_DELETE) continue; /* next labelCacheMemberObj, as we had a collision */ /* insert the rendered label */ insertRenderedLabelMember(map, cachePtr); - for(ll=0; llnumtextsymbols; ll++) { + for (ll = 0; ll < cachePtr->numtextsymbols; ll++) { textSymbolPtr = cachePtr->textsymbols[ll]; /* here's where we draw the label styles */ - for(i=0; ilabel->numstyles; i++) { - if(textSymbolPtr->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &(cachePtr->point), textSymbolPtr->label->styles[i], textSymbolPtr->scalefactor))) { + for (i = 0; i < textSymbolPtr->label->numstyles; i++) { + if (textSymbolPtr->label->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + if (MS_UNLIKELY( + MS_FAILURE == + msDrawMarkerSymbol(map, image, &(cachePtr->point), + textSymbolPtr->label->styles[i], + textSymbolPtr->scalefactor))) { + return MS_FAILURE; + } + } else if (textSymbolPtr->annotext && + textSymbolPtr->label->styles[i] + ->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + if (textSymbolPtr->style_bounds && + textSymbolPtr->style_bounds[i]) { + if (MS_UNLIKELY( + MS_FAILURE == + msDrawLabelBounds(map, image, + textSymbolPtr->style_bounds[i], + textSymbolPtr->label->styles[i], + textSymbolPtr->scalefactor))) { return MS_FAILURE; } - } else if(textSymbolPtr->annotext && textSymbolPtr->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - if(textSymbolPtr->style_bounds && textSymbolPtr->style_bounds[i]) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLabelBounds(map,image,textSymbolPtr->style_bounds[i],textSymbolPtr->label->styles[i], textSymbolPtr->scalefactor))) { - return MS_FAILURE; - } - } else { - if(MS_UNLIKELY(MS_FAILURE == msDrawLabelBounds(map,image,&labelpoly_bounds,textSymbolPtr->label->styles[i], textSymbolPtr->scalefactor))) { - return MS_FAILURE; - } + } else { + if (MS_UNLIKELY( + MS_FAILURE == + msDrawLabelBounds(map, image, &labelpoly_bounds, + textSymbolPtr->label->styles[i], + textSymbolPtr->scalefactor))) { + return MS_FAILURE; } - } else if(textSymbolPtr->annotext && textSymbolPtr->label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELCENTER) { - pointObj labelCenter; - - if(textSymbolPtr->style_bounds && textSymbolPtr->style_bounds[i]) { - labelCenter.x = (textSymbolPtr->style_bounds[i]->bbox.maxx + textSymbolPtr->style_bounds[i]->bbox.minx)/2; - labelCenter.y = (textSymbolPtr->style_bounds[i]->bbox.maxy + textSymbolPtr->style_bounds[i]->bbox.miny)/2; - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map,image,&labelCenter,textSymbolPtr->label->styles[i], textSymbolPtr->scalefactor))) { - return MS_FAILURE; - } - } else { - labelCenter.x = (labelpoly_bounds.bbox.maxx + labelpoly_bounds.bbox.minx)/2; - labelCenter.y = (labelpoly_bounds.bbox.maxy + labelpoly_bounds.bbox.miny)/2; - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map,image,&labelCenter,textSymbolPtr->label->styles[i], textSymbolPtr->scalefactor))) { - return MS_FAILURE; - } + } + } else if (textSymbolPtr->annotext && + textSymbolPtr->label->styles[i] + ->_geomtransform.type == + MS_GEOMTRANSFORM_LABELCENTER) { + pointObj labelCenter; + + if (textSymbolPtr->style_bounds && + textSymbolPtr->style_bounds[i]) { + labelCenter.x = + (textSymbolPtr->style_bounds[i]->bbox.maxx + + textSymbolPtr->style_bounds[i]->bbox.minx) / + 2; + labelCenter.y = + (textSymbolPtr->style_bounds[i]->bbox.maxy + + textSymbolPtr->style_bounds[i]->bbox.miny) / + 2; + if (MS_UNLIKELY( + MS_FAILURE == + msDrawMarkerSymbol(map, image, &labelCenter, + textSymbolPtr->label->styles[i], + textSymbolPtr->scalefactor))) { + return MS_FAILURE; } - } else { - msSetError(MS_MISCERR,"Labels only support LABELPNT, LABELPOLY and LABELCENTER GEOMTRANSFORMS", "msDrawLabelCache()"); - return MS_FAILURE; + labelCenter.x = (labelpoly_bounds.bbox.maxx + + labelpoly_bounds.bbox.minx) / + 2; + labelCenter.y = (labelpoly_bounds.bbox.maxy + + labelpoly_bounds.bbox.miny) / + 2; + if (MS_UNLIKELY( + MS_FAILURE == + msDrawMarkerSymbol(map, image, &labelCenter, + textSymbolPtr->label->styles[i], + textSymbolPtr->scalefactor))) { + return MS_FAILURE; + } } + + } else { + msSetError(MS_MISCERR, + "Labels only support LABELPNT, LABELPOLY and " + "LABELCENTER GEOMTRANSFORMS", + "msDrawLabelCache()"); + return MS_FAILURE; } - - if(textSymbolPtr->annotext) { - if(MS_UNLIKELY(MS_FAILURE == msDrawTextSymbol(map,image,textSymbolPtr->annopoint,textSymbolPtr))) { + } + + if (textSymbolPtr->annotext) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawTextSymbol(map, image, + textSymbolPtr->annopoint, + textSymbolPtr))) { return MS_FAILURE; } } } } } /* next label(group) from cacheslot */ - if(MS_UNLIKELY(MS_FAILURE == msDrawOffsettedLabels(image, map, priority))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawOffsettedLabels(image, map, priority))) { return MS_FAILURE; } } /* next priority */ @@ -3499,18 +4105,21 @@ int msDrawLabelCache(mapObj *map, imageObj *image) tstyle.color.red = 255; tstyle.color.green = 0; tstyle.color.blue = 0; - for(priority=MS_MAX_LABEL_PRIORITY-1; priority>=0; priority--) { + for (priority = MS_MAX_LABEL_PRIORITY - 1; priority >= 0; priority--) { labelCacheSlotObj *cacheslot; cacheslot = &(map->labelcache.slots[priority]); - for(l=cacheslot->numlabels-1; l>=0; l--) { - cachePtr = &(cacheslot->labels[l]); /* point to right spot in the label cache */ + for (l = cacheslot->numlabels - 1; l >= 0; l--) { + cachePtr = + &(cacheslot + ->labels[l]); /* point to right spot in the label cache */ /* assert((cachePtr->poly == NULL && cachePtr->status == MS_OFF) || (cachePtr->poly && (cachePtr->status == MS_ON)); */ - if(cachePtr->status) { - msDrawLineSymbol(map, image, cachePtr->poly, &tstyle, layerPtr->scalefactor); + if (cachePtr->status) { + msDrawLineSymbol(map, image, cachePtr->poly, &tstyle, + layerPtr->scalefactor); } } } @@ -3520,60 +4129,60 @@ int msDrawLabelCache(mapObj *map, imageObj *image) } } - if(map->debug >= MS_DEBUGLEVEL_TUNING) { + if (map->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&endtime, NULL); msDebug("msDrawMap(): Drawing Label Cache, %.3fs\n", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } return nReturnVal; } - /** * Generic function to tell the underline device that layer * drawing is stating */ -void msImageStartLayer(mapObj *map, layerObj *layer, imageObj *image) -{ +void msImageStartLayer(mapObj *map, layerObj *layer, imageObj *image) { if (image) { - if( MS_RENDERER_PLUGIN(image->format) ) { - const char *approximation_scale = msLayerGetProcessingKey( layer, "APPROXIMATION_SCALE" ); - if(approximation_scale) { - if(!strncasecmp(approximation_scale,"ROUND",5)) { + if (MS_RENDERER_PLUGIN(image->format)) { + const char *approximation_scale = + msLayerGetProcessingKey(layer, "APPROXIMATION_SCALE"); + if (approximation_scale) { + if (!strncasecmp(approximation_scale, "ROUND", 5)) { MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_ROUND; - } else if(!strncasecmp(approximation_scale,"FULL",4)) { - MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_FULLRESOLUTION; - } else if(!strncasecmp(approximation_scale,"SIMPLIFY",8)) { + } else if (!strncasecmp(approximation_scale, "FULL", 4)) { + MS_IMAGE_RENDERER(image)->transform_mode = + MS_TRANSFORM_FULLRESOLUTION; + } else if (!strncasecmp(approximation_scale, "SIMPLIFY", 8)) { MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_SIMPLIFY; } else { MS_IMAGE_RENDERER(image)->transform_mode = MS_TRANSFORM_SNAPTOGRID; - MS_IMAGE_RENDERER(image)->approximation_scale = atof(approximation_scale); + MS_IMAGE_RENDERER(image)->approximation_scale = + atof(approximation_scale); } } else { - MS_IMAGE_RENDERER(image)->transform_mode = MS_IMAGE_RENDERER(image)->default_transform_mode; - MS_IMAGE_RENDERER(image)->approximation_scale = MS_IMAGE_RENDERER(image)->default_approximation_scale; + MS_IMAGE_RENDERER(image)->transform_mode = + MS_IMAGE_RENDERER(image)->default_transform_mode; + MS_IMAGE_RENDERER(image)->approximation_scale = + MS_IMAGE_RENDERER(image)->default_approximation_scale; } MS_IMAGE_RENDERER(image)->startLayer(image, map, layer); - } else if( MS_RENDERER_IMAGEMAP(image->format) ) + } else if (MS_RENDERER_IMAGEMAP(image->format)) msImageStartLayerIM(map, layer, image); - } } - /** * Generic function to tell the underline device that layer * drawing is ending */ -void msImageEndLayer(mapObj *map, layerObj *layer, imageObj *image) -{ - if(image) { - if( MS_RENDERER_PLUGIN(image->format) ) { - MS_IMAGE_RENDERER(image)->endLayer(image,map,layer); +void msImageEndLayer(mapObj *map, layerObj *layer, imageObj *image) { + if (image) { + if (MS_RENDERER_PLUGIN(image->format)) { + MS_IMAGE_RENDERER(image)->endLayer(image, map, layer); } } } @@ -3584,32 +4193,27 @@ void msImageEndLayer(mapObj *map, layerObj *layer, imageObj *image) */ void msDrawStartShape(mapObj *map, layerObj *layer, imageObj *image, - shapeObj *shape) -{ + shapeObj *shape) { (void)map; (void)layer; if (image) { - if(MS_RENDERER_PLUGIN(image->format)) { + if (MS_RENDERER_PLUGIN(image->format)) { if (image->format->vtable->startShape) image->format->vtable->startShape(image, shape); } - - } } - /** * Generic function to tell the underline device that shape * drawing is ending */ void msDrawEndShape(mapObj *map, layerObj *layer, imageObj *image, - shapeObj *shape) -{ + shapeObj *shape) { (void)map; (void)layer; - if(MS_RENDERER_PLUGIN(image->format)) { + if (MS_RENDERER_PLUGIN(image->format)) { if (image->format->vtable->endShape) image->format->vtable->endShape(image, shape); } @@ -3618,11 +4222,10 @@ void msDrawEndShape(mapObj *map, layerObj *layer, imageObj *image, * take the value from the shape and use it to change the * color in the style to match the range map */ -int msShapeToRange(styleObj *style, shapeObj *shape) -{ +int msShapeToRange(styleObj *style, shapeObj *shape) { /*first, get the value of the rangeitem, which should*/ /*evaluate to a double*/ - const char* fieldStr = shape->values[style->rangeitemindex]; + const char *fieldStr = shape->values[style->rangeitemindex]; if (fieldStr == NULL) { /*if there's not value, bail*/ return MS_FAILURE; } @@ -3636,42 +4239,59 @@ int msShapeToRange(styleObj *style, shapeObj *shape) * Ranges. The styls passed in is updated to reflect the right color * based on the fieldVal */ -int msValueToRange(styleObj *style, double fieldVal, colorspace cs) -{ +int msValueToRange(styleObj *style, double fieldVal, colorspace cs) { double range; double scaledVal; range = style->maxvalue - style->minvalue; - scaledVal = (fieldVal - style->minvalue)/range; + scaledVal = (fieldVal - style->minvalue) / range; - if(cs == MS_COLORSPACE_RGB) { + if (cs == MS_COLORSPACE_RGB) { /*At this point, we know where on the range we need to be*/ /*However, we don't know how to map it yet, since RGB(A) can */ /*Go up or down*/ - style->color.red = (int)(MS_MAX(0,(MS_MIN(255, (style->mincolor.red + ((style->maxcolor.red - style->mincolor.red) * scaledVal)))))); - style->color.green = (int)(MS_MAX(0,(MS_MIN(255,(style->mincolor.green + ((style->maxcolor.green - style->mincolor.green) * scaledVal)))))); - style->color.blue = (int)(MS_MAX(0,(MS_MIN(255,(style->mincolor.blue + ((style->maxcolor.blue - style->mincolor.blue) * scaledVal)))))); - style->color.alpha = (int)(MS_MAX(0,(MS_MIN(255,(style->mincolor.alpha + ((style->maxcolor.alpha - style->mincolor.alpha) * scaledVal)))))); + style->color.red = (int)(MS_MAX( + 0, (MS_MIN(255, (style->mincolor.red + + ((style->maxcolor.red - style->mincolor.red) * + scaledVal)))))); + style->color.green = (int)(MS_MAX( + 0, (MS_MIN(255, (style->mincolor.green + + ((style->maxcolor.green - style->mincolor.green) * + scaledVal)))))); + style->color.blue = (int)(MS_MAX( + 0, (MS_MIN(255, (style->mincolor.blue + + ((style->maxcolor.blue - style->mincolor.blue) * + scaledVal)))))); + style->color.alpha = (int)(MS_MAX( + 0, (MS_MIN(255, (style->mincolor.alpha + + ((style->maxcolor.alpha - style->mincolor.alpha) * + scaledVal)))))); } else { /* HSL */ assert(cs == MS_COLORSPACE_HSL); - if(fieldVal <= style->minvalue) style->color = style->mincolor; - else if(fieldVal >= style->maxvalue) style->color = style->maxcolor; + if (fieldVal <= style->minvalue) + style->color = style->mincolor; + else if (fieldVal >= style->maxvalue) + style->color = style->maxcolor; else { - double mh,ms,ml,Mh,Ms,Ml; - msRGBtoHSL(&style->mincolor,&mh,&ms,&ml); - msRGBtoHSL(&style->maxcolor,&Mh,&Ms,&Ml); - mh+=(Mh-mh)*scaledVal; - ms+=(Ms-ms)*scaledVal; - ml+=(Ml-ml)*scaledVal; - msHSLtoRGB(mh,ms,ml,&style->color); - style->color.alpha = style->mincolor.alpha + (style->maxcolor.alpha - style->mincolor.alpha)*scaledVal; + double mh, ms, ml, Mh, Ms, Ml; + msRGBtoHSL(&style->mincolor, &mh, &ms, &ml); + msRGBtoHSL(&style->maxcolor, &Mh, &Ms, &Ml); + mh += (Mh - mh) * scaledVal; + ms += (Ms - ms) * scaledVal; + ml += (Ml - ml) * scaledVal; + msHSLtoRGB(mh, ms, ml, &style->color); + style->color.alpha = + style->mincolor.alpha + + (style->maxcolor.alpha - style->mincolor.alpha) * scaledVal; } } - /*( "msMapRange(): %i %i %i", style->color.red , style->color.green, style->color.blue);*/ + /*( "msMapRange(): %i %i %i", style->color.red , style->color.green, + * style->color.blue);*/ #if ALPHACOLOR_ENABLED - /*NO ALPHA RANGE YET style->color.alpha = style->mincolor.alpha + ((style->maxcolor.alpha - style->mincolor.alpha) * scaledVal);*/ + /*NO ALPHA RANGE YET style->color.alpha = style->mincolor.alpha + + * ((style->maxcolor.alpha - style->mincolor.alpha) * scaledVal);*/ #endif return MS_SUCCESS; diff --git a/mapdrawgdal.c b/mapdrawgdal.c index e97cbfeebd..b3b222e738 100644 --- a/mapdrawgdal.c +++ b/mapdrawgdal.c @@ -35,57 +35,50 @@ #include "mapthread.h" #include "maptime.h" - -extern int InvGeoTransform( double *gt_in, double *gt_out ); +extern int InvGeoTransform(double *gt_in, double *gt_out); #define MAXCOLORS 256 -#define GEO_TRANS(tr,x,y) ((tr)[0]+(tr)[1]*(x)+(tr)[2]*(y)) -#define SKIP_MASK(x,y) (mask_rb && !*(mask_rb->data.rgba.a+(y)*mask_rb->data.rgba.row_step+(x)*mask_rb->data.rgba.pixel_step)) +#define GEO_TRANS(tr, x, y) ((tr)[0] + (tr)[1] * (x) + (tr)[2] * (y)) +#define SKIP_MASK(x, y) \ + (mask_rb && !*(mask_rb->data.rgba.a + (y)*mask_rb->data.rgba.row_step + \ + (x)*mask_rb->data.rgba.pixel_step)) #include "gdal.h" #include "cpl_string.h" #include "gdal_alg.h" -static bool -IsNoData( double dfValue, double dfNoDataValue ); - -static int -LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, - layerObj *layer, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - GByte *pabyBuffer, - int dst_xsize, int dst_ysize, - int *pbHaveRGBNoData, - int *pnNoData1, int *pnNoData2, int *pnNoData3, - bool *pbScaled, double *pdfScaleMin, double *pdfScaleRatio, - bool **ppbIsNoDataBuffer ); -static int -msDrawRasterLayerGDAL_RawMode( - mapObj *map, layerObj *layer, imageObj *image, GDALDatasetH hDS, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - int dst_xoff, int dst_yoff, int dst_xsize, int dst_ysize ); - -static int -msDrawRasterLayerGDAL_16BitClassification( - mapObj *map, layerObj *layer, rasterBufferObj *rb, - GDALRasterBandH hBand, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - int dst_xoff, int dst_yoff, int dst_xsize, int dst_ysize ); - +static bool IsNoData(double dfValue, double dfNoDataValue); + +static int LoadGDALImages(GDALDatasetH hDS, int band_numbers[4], int band_count, + layerObj *layer, int src_xoff, int src_yoff, + int src_xsize, int src_ysize, GByte *pabyBuffer, + int dst_xsize, int dst_ysize, int *pbHaveRGBNoData, + int *pnNoData1, int *pnNoData2, int *pnNoData3, + bool *pbScaled, double *pdfScaleMin, + double *pdfScaleRatio, bool **ppbIsNoDataBuffer); +static int msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, + imageObj *image, GDALDatasetH hDS, + int src_xoff, int src_yoff, + int src_xsize, int src_ysize, + int dst_xoff, int dst_yoff, + int dst_xsize, int dst_ysize); + +static int msDrawRasterLayerGDAL_16BitClassification( + mapObj *map, layerObj *layer, rasterBufferObj *rb, GDALRasterBandH hBand, + int src_xoff, int src_yoff, int src_xsize, int src_ysize, int dst_xoff, + int dst_yoff, int dst_xsize, int dst_ysize); /* * rasterBufferObj setting macros. */ - - /************************************************************************/ /* msDrawRasterLayerGDAL() */ /************************************************************************/ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, - rasterBufferObj *rb, void *hDSVoid ) + rasterBufferObj *rb, void *hDSVoid) { int i; /* loop counters */ @@ -99,35 +92,37 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, int src_xoff, src_yoff, src_xsize, src_ysize; double llx, lly, urx, ury; rectObj copyRect, mapRect; - unsigned char *pabyRaw1=NULL, *pabyRaw2=NULL, *pabyRaw3=NULL, - *pabyRawAlpha = NULL; + unsigned char *pabyRaw1 = NULL, *pabyRaw2 = NULL, *pabyRaw3 = NULL, + *pabyRawAlpha = NULL; int classified = FALSE; - int red_band=0, green_band=0, blue_band=0, alpha_band=0; + int red_band = 0, green_band = 0, blue_band = 0, alpha_band = 0; int band_count, band_numbers[4]; GDALDatasetH hDS = hDSVoid; - GDALColorTableH hColorMap=NULL; - GDALRasterBandH hBand1=NULL, hBand2=NULL, hBand3=NULL, hBandAlpha=NULL; + GDALColorTableH hColorMap = NULL; + GDALRasterBandH hBand1 = NULL, hBand2 = NULL, hBand3 = NULL, + hBandAlpha = NULL; int bHaveRGBNoData = FALSE; - int nNoData1=-1,nNoData2=-1,nNoData3=-1; + int nNoData1 = -1, nNoData2 = -1, nNoData3 = -1; rasterBufferObj *mask_rb = NULL; rasterBufferObj s_mask_rb; - if(layer->mask) { + if (layer->mask) { int ret; - layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map,layer->mask)); + layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map, layer->mask)); mask_rb = &s_mask_rb; memset(mask_rb, 0, sizeof(s_mask_rb)); - ret = MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,mask_rb); - if(ret != MS_SUCCESS) + ret = MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, mask_rb); + if (ret != MS_SUCCESS) return -1; } /*only support rawdata and pluggable renderers*/ - assert(MS_RENDERER_RAWDATA(image->format) || (MS_RENDERER_PLUGIN(image->format) && rb)); + assert(MS_RENDERER_RAWDATA(image->format) || + (MS_RENDERER_PLUGIN(image->format) && rb)); - - memset( cmap, 0xff, MAXCOLORS * sizeof(int) ); - memset( rb_cmap, 0, sizeof(rb_cmap) ); + memset(cmap, 0xff, MAXCOLORS * sizeof(int)); + memset(rb_cmap, 0, sizeof(rb_cmap)); /* -------------------------------------------------------------------- */ /* Test the image format instead of the map format. */ @@ -137,9 +132,8 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, /* and then dumped into the SWF or the PDF file. */ /* -------------------------------------------------------------------- */ - - src_xsize = GDALGetRasterXSize( hDS ); - src_ysize = GDALGetRasterYSize( hDS ); + src_xsize = GDALGetRasterXSize(hDS); + src_ysize = GDALGetRasterYSize(hDS); /* * If the RAW_WINDOW attribute is set, use that to establish what to @@ -147,21 +141,19 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, * problems with rotated maps. */ - if( CSLFetchNameValue( layer->processing, "RAW_WINDOW" ) != NULL ) { + if (CSLFetchNameValue(layer->processing, "RAW_WINDOW") != NULL) { char **papszTokens = - CSLTokenizeString( - CSLFetchNameValue( layer->processing, "RAW_WINDOW" ) ); - - if( layer->debug ) - msDebug( "msDrawGDAL(%s): using RAW_WINDOW=%s, dst=0,0,%d,%d\n", - layer->name, - CSLFetchNameValue( layer->processing, "RAW_WINDOW" ), - image->width, image->height ); - - if( CSLCount(papszTokens) != 4 ) { - CSLDestroy( papszTokens ); - msSetError( MS_IMGERR, "RAW_WINDOW PROCESSING directive corrupt.", - "msDrawGDAL()" ); + CSLTokenizeString(CSLFetchNameValue(layer->processing, "RAW_WINDOW")); + + if (layer->debug) + msDebug("msDrawGDAL(%s): using RAW_WINDOW=%s, dst=0,0,%d,%d\n", + layer->name, CSLFetchNameValue(layer->processing, "RAW_WINDOW"), + image->width, image->height); + + if (CSLCount(papszTokens) != 4) { + CSLDestroy(papszTokens); + msSetError(MS_IMGERR, "RAW_WINDOW PROCESSING directive corrupt.", + "msDrawGDAL()"); return -1; } @@ -175,107 +167,109 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, dst_xsize = image->width; dst_ysize = image->height; - CSLDestroy( papszTokens ); + CSLDestroy(papszTokens); } /* * Compute the georeferenced window of overlap, and do nothing if there * is no overlap between the map extents, and the file we are operating on. */ - else if( layer->transform ) { + else if (layer->transform) { int dst_lrx, dst_lry; - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): Entering transform.\n" ); + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): Entering transform.\n"); - msGetGDALGeoTransform( hDS, map, layer, adfGeoTransform ); - InvGeoTransform( adfGeoTransform, adfInvGeoTransform ); + msGetGDALGeoTransform(hDS, map, layer, adfGeoTransform); + InvGeoTransform(adfGeoTransform, adfInvGeoTransform); mapRect = map->extent; - mapRect.minx -= map->cellsize*0.5; - mapRect.maxx += map->cellsize*0.5; - mapRect.miny -= map->cellsize*0.5; - mapRect.maxy += map->cellsize*0.5; + mapRect.minx -= map->cellsize * 0.5; + mapRect.maxx += map->cellsize * 0.5; + mapRect.miny -= map->cellsize * 0.5; + mapRect.maxy += map->cellsize * 0.5; copyRect = mapRect; - if( copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize) ) - copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize); - if( copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0) ) - copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0); + if (copyRect.minx < GEO_TRANS(adfGeoTransform, 0, src_ysize)) + copyRect.minx = GEO_TRANS(adfGeoTransform, 0, src_ysize); + if (copyRect.maxx > GEO_TRANS(adfGeoTransform, src_xsize, 0)) + copyRect.maxx = GEO_TRANS(adfGeoTransform, src_xsize, 0); - if( copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize) ) - copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize); - if( copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0) ) - copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0); + if (copyRect.miny < GEO_TRANS(adfGeoTransform + 3, 0, src_ysize)) + copyRect.miny = GEO_TRANS(adfGeoTransform + 3, 0, src_ysize); + if (copyRect.maxy > GEO_TRANS(adfGeoTransform + 3, src_xsize, 0)) + copyRect.maxy = GEO_TRANS(adfGeoTransform + 3, src_xsize, 0); - if( copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy ) { - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): Error in overlap calculation.\n" ); + if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) { + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): Error in overlap calculation.\n"); return 0; } /* * Copy the source and destination raster coordinates. */ - llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny); - lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny); - urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy); - ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy); - - src_xoff = MS_MAX(0,(int) floor(llx+0.5)); - src_yoff = MS_MAX(0,(int) floor(ury+0.5)); - src_xsize = MS_MIN(MS_MAX(0,(int) (urx - llx + 0.5)), - GDALGetRasterXSize(hDS) - src_xoff); - src_ysize = MS_MIN(MS_MAX(0,(int) (lly - ury + 0.5)), - GDALGetRasterYSize(hDS) - src_yoff); + llx = GEO_TRANS(adfInvGeoTransform + 0, copyRect.minx, copyRect.miny); + lly = GEO_TRANS(adfInvGeoTransform + 3, copyRect.minx, copyRect.miny); + urx = GEO_TRANS(adfInvGeoTransform + 0, copyRect.maxx, copyRect.maxy); + ury = GEO_TRANS(adfInvGeoTransform + 3, copyRect.maxx, copyRect.maxy); + + src_xoff = MS_MAX(0, (int)floor(llx + 0.5)); + src_yoff = MS_MAX(0, (int)floor(ury + 0.5)); + src_xsize = MS_MIN(MS_MAX(0, (int)(urx - llx + 0.5)), + GDALGetRasterXSize(hDS) - src_xoff); + src_ysize = MS_MIN(MS_MAX(0, (int)(lly - ury + 0.5)), + GDALGetRasterYSize(hDS) - src_yoff); /* We want very small windows to use at least one source pixel (#4172) */ - if( src_xsize == 0 && (urx - llx) > 0.0 ) { + if (src_xsize == 0 && (urx - llx) > 0.0) { src_xsize = 1; - src_xoff = MS_MIN(src_xoff,GDALGetRasterXSize(hDS)-1); + src_xoff = MS_MIN(src_xoff, GDALGetRasterXSize(hDS) - 1); } - if( src_ysize == 0 && (lly - ury) > 0.0 ) { + if (src_ysize == 0 && (lly - ury) > 0.0) { src_ysize = 1; - src_yoff = MS_MIN(src_yoff,GDALGetRasterYSize(hDS)-1); + src_yoff = MS_MIN(src_yoff, GDALGetRasterYSize(hDS) - 1); } - if( src_xsize == 0 || src_ysize == 0 ) { - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): no apparent overlap between map view and this window(1).\n" ); + if (src_xsize == 0 || src_ysize == 0) { + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): no apparent overlap between map view " + "and this window(1).\n"); return 0; } if (map->cellsize == 0) { - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): Cellsize can't be 0.\n" ); + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): Cellsize can't be 0.\n"); return 0; } - dst_xoff = (int) ((copyRect.minx - mapRect.minx) / map->cellsize); - dst_yoff = (int) ((mapRect.maxy - copyRect.maxy) / map->cellsize); + dst_xoff = (int)((copyRect.minx - mapRect.minx) / map->cellsize); + dst_yoff = (int)((mapRect.maxy - copyRect.maxy) / map->cellsize); - dst_lrx = (int) ((copyRect.maxx - mapRect.minx) / map->cellsize + 0.5); - dst_lry = (int) ((mapRect.maxy - copyRect.miny) / map->cellsize + 0.5); - dst_lrx = MS_MAX(0,MS_MIN(image->width,dst_lrx)); - dst_lry = MS_MAX(0,MS_MIN(image->height,dst_lry)); + dst_lrx = (int)((copyRect.maxx - mapRect.minx) / map->cellsize + 0.5); + dst_lry = (int)((mapRect.maxy - copyRect.miny) / map->cellsize + 0.5); + dst_lrx = MS_MAX(0, MS_MIN(image->width, dst_lrx)); + dst_lry = MS_MAX(0, MS_MIN(image->height, dst_lry)); - dst_xsize = MS_MAX(0,MS_MIN(image->width,dst_lrx - dst_xoff)); - dst_ysize = MS_MAX(0,MS_MIN(image->height,dst_lry - dst_yoff)); + dst_xsize = MS_MAX(0, MS_MIN(image->width, dst_lrx - dst_xoff)); + dst_ysize = MS_MAX(0, MS_MIN(image->height, dst_lry - dst_yoff)); - if( dst_xsize == 0 || dst_ysize == 0 ) { - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): no apparent overlap between map view and this window(2).\n" ); + if (dst_xsize == 0 || dst_ysize == 0) { + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): no apparent overlap between map view " + "and this window(2).\n"); return 0; } - if( layer->debug ) - msDebug( "msDrawRasterLayerGDAL(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", - src_xoff, src_yoff, src_xsize, src_ysize, - dst_xoff, dst_yoff, dst_xsize, dst_ysize ); + if (layer->debug) + msDebug("msDrawRasterLayerGDAL(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", + src_xoff, src_yoff, src_xsize, src_ysize, dst_xoff, dst_yoff, + dst_xsize, dst_ysize); #ifndef notdef - if( layer->debug ) { + if (layer->debug) { double d_src_xoff, d_src_yoff, geo_x, geo_y; geo_x = mapRect.minx + dst_xoff * map->cellsize; @@ -284,9 +278,9 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, d_src_xoff = (geo_x - adfGeoTransform[0]) / adfGeoTransform[1]; d_src_yoff = (geo_y - adfGeoTransform[3]) / adfGeoTransform[5]; - msDebug( "msDrawRasterLayerGDAL(): source raster PL (%.3f,%.3f) for dst PL (%d,%d).\n", - d_src_xoff, d_src_yoff, - dst_xoff, dst_yoff ); + msDebug("msDrawRasterLayerGDAL(): source raster PL (%.3f,%.3f) for dst " + "PL (%d,%d).\n", + d_src_xoff, d_src_yoff, dst_xoff, dst_yoff); } #endif } @@ -297,19 +291,18 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, else { dst_xoff = src_xoff = 0; dst_yoff = src_yoff = 0; - dst_xsize = src_xsize = MS_MIN(image->width,src_xsize); - dst_ysize = src_ysize = MS_MIN(image->height,src_ysize); + dst_xsize = src_xsize = MS_MIN(image->width, src_xsize); + dst_ysize = src_ysize = MS_MIN(image->height, src_ysize); } /* * In RAWDATA mode we don't fool with colors. Do the raw processing, * and return from the function early. */ - if( MS_RENDERER_RAWDATA( image->format ) ) { + if (MS_RENDERER_RAWDATA(image->format)) { return msDrawRasterLayerGDAL_RawMode( - map, layer, image, hDS, - src_xoff, src_yoff, src_xsize, src_ysize, - dst_xoff, dst_yoff, dst_xsize, dst_ysize ); + map, layer, image, hDS, src_xoff, src_yoff, src_xsize, src_ysize, + dst_xoff, dst_yoff, dst_xsize, dst_ysize); } /* @@ -318,19 +311,19 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, * to treat the raster as classified if there is just a bogus class here * to force inclusion in the legend. */ - for( i = 0; i < layer->numclasses; i++ ) { + for (i = 0; i < layer->numclasses; i++) { int s; /* change colour based on colour range? */ - for(s=0; sclass[i]->numstyles; s++) { - if( MS_VALID_COLOR(layer->class[i]->styles[s]->mincolor) - && MS_VALID_COLOR(layer->class[i]->styles[s]->maxcolor) ) { + for (s = 0; s < layer->class[i] -> numstyles; s++) { + if (MS_VALID_COLOR(layer->class[i] -> styles[s] -> mincolor) && + MS_VALID_COLOR(layer->class[i] -> styles[s] -> maxcolor)) { classified = TRUE; break; } } - if( layer->class[i]->expression.string != NULL ) { + if (layer->class[i] -> expression.string != NULL) { classified = TRUE; break; } @@ -342,35 +335,32 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, * red=1,green=2,blue=3 or red=1,green=2,blue=3,alpha>=4. */ - if( CSLFetchNameValue( layer->processing, "BANDS" ) == NULL ) { - const int gdal_band_count = GDALGetRasterCount( hDS ); + if (CSLFetchNameValue(layer->processing, "BANDS") == NULL) { + const int gdal_band_count = GDALGetRasterCount(hDS); red_band = 1; - if( gdal_band_count >= 4 ) - { - /* The alpha band is not necessarily the 4th one */ - for( i = 4; i <= gdal_band_count; i ++ ) { - if( GDALGetRasterColorInterpretation( - GDALGetRasterBand( hDS, i ) ) == GCI_AlphaBand ) { - alpha_band = i; - break; - } + if (gdal_band_count >= 4) { + /* The alpha band is not necessarily the 4th one */ + for (i = 4; i <= gdal_band_count; i++) { + if (GDALGetRasterColorInterpretation(GDALGetRasterBand(hDS, i)) == + GCI_AlphaBand) { + alpha_band = i; + break; } + } } - if( gdal_band_count >= 3 ) { + if (gdal_band_count >= 3) { green_band = 2; blue_band = 3; } - if( gdal_band_count == 2 - && GDALGetRasterColorInterpretation( - GDALGetRasterBand( hDS, 2 ) ) == GCI_AlphaBand ) + if (gdal_band_count == 2 && GDALGetRasterColorInterpretation( + GDALGetRasterBand(hDS, 2)) == GCI_AlphaBand) alpha_band = 2; - hBand1 = GDALGetRasterBand( hDS, red_band ); - if( classified - || GDALGetRasterColorTable( hBand1 ) != NULL ) { + hBand1 = GDALGetRasterBand(hDS, red_band); + if (classified || GDALGetRasterColorTable(hBand1) != NULL) { alpha_band = 0; green_band = 0; blue_band = 0; @@ -378,15 +368,15 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, } else { int *band_list; - band_list = msGetGDALBandList( layer, hDS, 4, &band_count ); - if( band_list == NULL ) + band_list = msGetGDALBandList(layer, hDS, 4, &band_count); + if (band_list == NULL) return -1; - if( band_count > 0 ) + if (band_count > 0) red_band = band_list[0]; else red_band = 0; - if( band_count > 2 ) { + if (band_count > 2) { green_band = band_list[1]; blue_band = band_list[2]; } else { @@ -394,12 +384,12 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, blue_band = 0; } - if( band_count > 3 ) + if (band_count > 3) alpha_band = band_list[3]; else alpha_band = 0; - free( band_list ); + free(band_list); } band_numbers[0] = red_band; @@ -407,53 +397,53 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, band_numbers[2] = blue_band; band_numbers[3] = 0; - if( blue_band != 0 && alpha_band != 0 ) { + if (blue_band != 0 && alpha_band != 0) { band_numbers[3] = alpha_band; band_count = 4; - } else if( blue_band != 0 && alpha_band == 0 ) + } else if (blue_band != 0 && alpha_band == 0) band_count = 3; - else if( alpha_band != 0 ) { + else if (alpha_band != 0) { band_numbers[1] = alpha_band; band_count = 2; } else band_count = 1; - if( layer->debug > 1 || (layer->debug > 0 && green_band != 0) ) { - msDebug( "msDrawRasterLayerGDAL(): red,green,blue,alpha bands = %d,%d,%d,%d\n", - red_band, green_band, blue_band, alpha_band ); + if (layer->debug > 1 || (layer->debug > 0 && green_band != 0)) { + msDebug( + "msDrawRasterLayerGDAL(): red,green,blue,alpha bands = %d,%d,%d,%d\n", + red_band, green_band, blue_band, alpha_band); } /* * Get band handles for PC256, RGB or RGBA cases. */ - hBand1 = GDALGetRasterBand( hDS, red_band ); - if( hBand1 == NULL ) + hBand1 = GDALGetRasterBand(hDS, red_band); + if (hBand1 == NULL) return -1; hBand2 = hBand3 = hBandAlpha = NULL; - if( green_band != 0 ) { - hBand1 = GDALGetRasterBand( hDS, red_band ); - hBand2 = GDALGetRasterBand( hDS, green_band ); - hBand3 = GDALGetRasterBand( hDS, blue_band ); - if( hBand1 == NULL || hBand2 == NULL || hBand3 == NULL ) + if (green_band != 0) { + hBand1 = GDALGetRasterBand(hDS, red_band); + hBand2 = GDALGetRasterBand(hDS, green_band); + hBand3 = GDALGetRasterBand(hDS, blue_band); + if (hBand1 == NULL || hBand2 == NULL || hBand3 == NULL) return -1; } - if( alpha_band != 0 ) - hBandAlpha = GDALGetRasterBand( hDS, alpha_band ); + if (alpha_band != 0) + hBandAlpha = GDALGetRasterBand(hDS, alpha_band); /* * The logic for a classification rendering of non-8bit raster bands * is sufficiently different than the normal mechanism of loading * into an 8bit buffer, that we isolate it into it's own subfunction. */ - if( classified - && hBand1 != NULL && GDALGetRasterDataType( hBand1 ) != GDT_Byte ) { + if (classified && hBand1 != NULL && + GDALGetRasterDataType(hBand1) != GDT_Byte) { return msDrawRasterLayerGDAL_16BitClassification( - map, layer, rb, hBand1, - src_xoff, src_yoff, src_xsize, src_ysize, - dst_xoff, dst_yoff, dst_xsize, dst_ysize ); + map, layer, rb, hBand1, src_xoff, src_yoff, src_xsize, src_ysize, + dst_xoff, dst_yoff, dst_xsize, dst_ysize); } /* @@ -462,17 +452,17 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, */ bool isDefaultGreyscale = false; - if( hBand2 != NULL ) + if (hBand2 != NULL) hColorMap = NULL; else { - hColorMap = GDALGetRasterColorTable( hBand1 ); - if( hColorMap != NULL ) - hColorMap = GDALCloneColorTable( hColorMap ); + hColorMap = GDALGetRasterColorTable(hBand1); + if (hColorMap != NULL) + hColorMap = GDALCloneColorTable(hColorMap); else { - hColorMap = GDALCreateColorTable( GPI_RGB ); + hColorMap = GDALCreateColorTable(GPI_RGB); isDefaultGreyscale = true; - for( i = 0; i < 256; i++ ) { + for (i = 0; i < 256; i++) { colorObj pixel; GDALColorEntry sEntry; @@ -480,7 +470,7 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, pixel.green = i; pixel.blue = i; - if(MS_COMPARE_COLORS(pixel, layer->offsite)) { + if (MS_COMPARE_COLORS(pixel, layer->offsite)) { sEntry.c1 = 0; sEntry.c2 = 0; sEntry.c3 = 0; @@ -492,7 +482,7 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, sEntry.c4 = 255; } - GDALSetColorEntry( hColorMap, i, &sEntry ); + GDALSetColorEntry(hColorMap, i, &sEntry); } } @@ -500,20 +490,18 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, ** If we have a known NODATA value, mark it now as transparent. */ { - int bGotNoData; - double dfNoDataValue = msGetGDALNoDataValue( layer, hBand1, - &bGotNoData); + int bGotNoData; + double dfNoDataValue = msGetGDALNoDataValue(layer, hBand1, &bGotNoData); - if( bGotNoData && dfNoDataValue >= 0 - && dfNoDataValue < GDALGetColorEntryCount( hColorMap ) ) { + if (bGotNoData && dfNoDataValue >= 0 && + dfNoDataValue < GDALGetColorEntryCount(hColorMap)) { GDALColorEntry sEntry; - memcpy( &sEntry, - GDALGetColorEntry( hColorMap, (int) dfNoDataValue ), - sizeof(GDALColorEntry) ); + memcpy(&sEntry, GDALGetColorEntry(hColorMap, (int)dfNoDataValue), + sizeof(GDALColorEntry)); sEntry.c4 = 0; - GDALSetColorEntry( hColorMap, (int) dfNoDataValue, &sEntry ); + GDALSetColorEntry(hColorMap, (int)dfNoDataValue, &sEntry); } } } @@ -521,20 +509,20 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, /* * Allocate imagery buffers. */ - pabyRaw1 = (unsigned char *) malloc(dst_xsize * dst_ysize * band_count); - if( pabyRaw1 == NULL ) { + pabyRaw1 = (unsigned char *)malloc(dst_xsize * dst_ysize * band_count); + if (pabyRaw1 == NULL) { msSetError(MS_MEMERR, "Allocating work image of size %dx%dx%d failed.", - "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize, band_count ); + "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize, band_count); return -1; } - if( hBand2 != NULL && hBand3 != NULL ) { + if (hBand2 != NULL && hBand3 != NULL) { pabyRaw2 = pabyRaw1 + dst_xsize * dst_ysize * 1; pabyRaw3 = pabyRaw1 + dst_xsize * dst_ysize * 2; } - if( hBandAlpha != NULL ) { - if( hBand2 != NULL ) + if (hBandAlpha != NULL) { + if (hBand2 != NULL) pabyRawAlpha = pabyRaw1 + dst_xsize * dst_ysize * 3; else pabyRawAlpha = pabyRaw1 + dst_xsize * dst_ysize * 1; @@ -546,16 +534,13 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, bool bScaled = false; double dfScaleMin = 0; double dfScaleRatio = 0; - bool* pbIsNoDataBuffer = NULL; - if( LoadGDALImages( hDS, band_numbers, band_count, layer, - src_xoff, src_yoff, src_xsize, src_ysize, - pabyRaw1, dst_xsize, dst_ysize, - &bHaveRGBNoData, - &nNoData1, &nNoData2, &nNoData3, - &bScaled, &dfScaleMin, &dfScaleRatio, - &pbIsNoDataBuffer ) == -1 ) { - free( pabyRaw1 ); - free( pbIsNoDataBuffer ); + bool *pbIsNoDataBuffer = NULL; + if (LoadGDALImages(hDS, band_numbers, band_count, layer, src_xoff, src_yoff, + src_xsize, src_ysize, pabyRaw1, dst_xsize, dst_ysize, + &bHaveRGBNoData, &nNoData1, &nNoData2, &nNoData3, &bScaled, + &dfScaleMin, &dfScaleRatio, &pbIsNoDataBuffer) == -1) { + free(pabyRaw1); + free(pbIsNoDataBuffer); return -1; } @@ -565,93 +550,105 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, * class colors are provided by the MAP file, or where we use the native * color table. */ - if( classified ) { + if (classified) { int c; - const char* pszRangeColorspace = msLayerGetProcessingKey( layer, "RANGE_COLORSPACE" ); + const char *pszRangeColorspace = + msLayerGetProcessingKey(layer, "RANGE_COLORSPACE"); colorspace iRangeColorspace; #ifndef NDEBUG cmap_set = TRUE; #endif - if( hColorMap == NULL ) { + if (hColorMap == NULL) { msSetError(MS_IOERR, "Attempt to classify 24bit image, this is unsupported.", "drawGDAL()"); - free( pabyRaw1 ); - free( pbIsNoDataBuffer ); + free(pabyRaw1); + free(pbIsNoDataBuffer); return -1; } - - if(!pszRangeColorspace || !strcasecmp(pszRangeColorspace, "RGB")) { + + if (!pszRangeColorspace || !strcasecmp(pszRangeColorspace, "RGB")) { iRangeColorspace = MS_COLORSPACE_RGB; - } else if(!strcasecmp(pszRangeColorspace, "HSL")) { + } else if (!strcasecmp(pszRangeColorspace, "HSL")) { iRangeColorspace = MS_COLORSPACE_HSL; } else { msSetError(MS_MISCERR, "Unknown RANGE_COLORSPACE \"%s\", expecting RGB or HSL", "drawGDAL()", pszRangeColorspace); - GDALDestroyColorTable( hColorMap ); - free( pabyRaw1 ); - free( pbIsNoDataBuffer ); + GDALDestroyColorTable(hColorMap); + free(pabyRaw1); + free(pbIsNoDataBuffer); return -1; } int color_count = GDALGetColorEntryCount(hColorMap); const bool bScaleColors = bScaled && !isDefaultGreyscale; - if( !bScaleColors && color_count > 256 ) + if (!bScaleColors && color_count > 256) color_count = 256; - for(i=0; i < color_count; i++) { + for (i = 0; i < color_count; i++) { colorObj pixel; int colormap_index; GDALColorEntry sEntry; - GDALGetColorEntryAsRGB( hColorMap, i, &sEntry ); + GDALGetColorEntryAsRGB(hColorMap, i, &sEntry); - const int j = bScaleColors ? MAX(0, MIN(255, (int) ((i-dfScaleMin)*dfScaleRatio))) : i; + const int j = + bScaleColors + ? MAX(0, MIN(255, (int)((i - dfScaleMin) * dfScaleRatio))) + : i; pixel.red = sEntry.c1; pixel.green = sEntry.c2; pixel.blue = sEntry.c3; colormap_index = i; - if(!MS_COMPARE_COLORS(pixel, layer->offsite)) { + if (!MS_COMPARE_COLORS(pixel, layer->offsite)) { c = msGetClass(layer, &pixel, colormap_index); - if(c != -1) { /* belongs to any class */ + if (c != -1) { /* belongs to any class */ int s; /* change colour based on colour range? Currently we only address the greyscale case properly. */ - if( MS_VALID_COLOR(layer->class[c]->styles[0]->mincolor) ) { - for(s=0; sclass[c]->numstyles; s++) { - if( MS_VALID_COLOR(layer->class[c]->styles[s]->mincolor) - && MS_VALID_COLOR(layer->class[c]->styles[s]->maxcolor)) { - if( sEntry.c1 >= layer->class[c]->styles[s]->minvalue - && sEntry.c1 <= layer->class[c]->styles[s]->maxvalue ) { - msValueToRange(layer->class[c]->styles[s], sEntry.c1, iRangeColorspace); - if(MS_VALID_COLOR(layer->class[c]->styles[s]->color)) { + if (MS_VALID_COLOR(layer->class[c] -> styles[0] -> mincolor)) { + for (s = 0; s < layer->class[c] -> numstyles; s++) { + if (MS_VALID_COLOR(layer->class[c] -> styles[s] -> mincolor) && + MS_VALID_COLOR(layer->class[c] -> styles[s] -> maxcolor)) { + if (sEntry.c1 >= layer->class[c] -> styles[s] + -> minvalue && + sEntry.c1 <= + layer->class[c] -> styles[s] -> maxvalue) { + msValueToRange(layer->class[c] -> styles[s], sEntry.c1, + iRangeColorspace); + if (MS_VALID_COLOR(layer->class[c] -> styles[s] -> color)) { rb_cmap[0][j] = layer->class[c]->styles[s]->color.red; rb_cmap[1][j] = layer->class[c]->styles[s]->color.green; rb_cmap[2][j] = layer->class[c]->styles[s]->color.blue; - rb_cmap[3][j] = (layer->class[c]->styles[s]->color.alpha != 255)?(layer->class[c]->styles[s]->color.alpha):(255*layer->class[c]->styles[0]->opacity / 100); + rb_cmap[3][j] = + (layer->class[c] -> styles[s] -> color.alpha != 255) + ? (layer->class[c] -> styles[s] -> color.alpha) + : (255 * layer->class[c] -> styles[0] -> opacity / + 100); break; } } } } - } - else if( MS_TRANSPARENT_COLOR(layer->class[c]->styles[0]->color)) + } else if (MS_TRANSPARENT_COLOR( + layer->class[c] -> styles[0] -> color)) /* leave it transparent */; - else if( MS_VALID_COLOR(layer->class[c]->styles[0]->color)) { + else if (MS_VALID_COLOR(layer->class[c] -> styles[0] -> color)) { rb_cmap[0][j] = layer->class[c]->styles[0]->color.red; rb_cmap[1][j] = layer->class[c]->styles[0]->color.green; rb_cmap[2][j] = layer->class[c]->styles[0]->color.blue; - rb_cmap[3][j] = (255*layer->class[c]->styles[0]->opacity / 100); + rb_cmap[3][j] = + (255 * layer->class[c] -> styles[0] -> opacity / 100); } else { /* Use raster color */ @@ -663,29 +660,32 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, } } } - } else if( hBand2 == NULL && hColorMap != NULL && rb->type == MS_BUFFER_BYTE_RGBA ) { + } else if (hBand2 == NULL && hColorMap != NULL && + rb->type == MS_BUFFER_BYTE_RGBA) { int color_count; #ifndef NDEBUG cmap_set = TRUE; #endif - color_count = MS_MIN(256,GDALGetColorEntryCount(hColorMap)); + color_count = MS_MIN(256, GDALGetColorEntryCount(hColorMap)); const bool bScaleColors = bScaled && !isDefaultGreyscale; - if( !bScaleColors && color_count > 256 ) + if (!bScaleColors && color_count > 256) color_count = 256; - for(i=0; i < color_count; i++) { + for (i = 0; i < color_count; i++) { GDALColorEntry sEntry; - GDALGetColorEntryAsRGB( hColorMap, i, &sEntry ); - const int j = bScaleColors ? MAX(0, MIN(255, (int) ((i-dfScaleMin)*dfScaleRatio))) : i; + GDALGetColorEntryAsRGB(hColorMap, i, &sEntry); + const int j = + bScaleColors + ? MAX(0, MIN(255, (int)((i - dfScaleMin) * dfScaleRatio))) + : i; - if( sEntry.c4 != 0 - && (!MS_VALID_COLOR( layer->offsite ) - || layer->offsite.red != sEntry.c1 - || layer->offsite.green != sEntry.c2 - || layer->offsite.blue != sEntry.c3 ) ) { + if (sEntry.c4 != 0 && + (!MS_VALID_COLOR(layer->offsite) || layer->offsite.red != sEntry.c1 || + layer->offsite.green != sEntry.c2 || + layer->offsite.blue != sEntry.c3)) { rb_cmap[0][j] = sEntry.c1; rb_cmap[1][j] = sEntry.c2; rb_cmap[2][j] = sEntry.c3; @@ -694,45 +694,43 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, } } - if( bHaveRGBNoData && layer->debug ) - msDebug( "msDrawGDAL(): using RGB nodata values from GDAL dataset.\n" ); + if (bHaveRGBNoData && layer->debug) + msDebug("msDrawGDAL(): using RGB nodata values from GDAL dataset.\n"); /* -------------------------------------------------------------------- */ /* If there was no alpha band, but we have a dataset level mask */ /* load it as massage it so it will function as our alpha for */ /* transparency purposes. */ /* -------------------------------------------------------------------- */ - if( hBandAlpha == NULL ) { + if (hBandAlpha == NULL) { int nMaskFlags = GDALGetMaskFlags(hBand1); - if( CSLTestBoolean(CSLFetchNameValueDef( layer->processing, "USE_MASK_BAND", "YES" )) && + if (CSLTestBoolean( + CSLFetchNameValueDef(layer->processing, "USE_MASK_BAND", "YES")) && (nMaskFlags & GMF_PER_DATASET) != 0 && - (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) { + (nMaskFlags & (GMF_NODATA | GMF_ALL_VALID)) == 0) { CPLErr eErr; - unsigned char * pabyOrig = pabyRaw1; + unsigned char *pabyOrig = pabyRaw1; - - if( layer->debug ) - msDebug( "msDrawGDAL(): using GDAL mask band for alpha.\n" ); + if (layer->debug) + msDebug("msDrawGDAL(): using GDAL mask band for alpha.\n"); band_count++; - pabyRaw1 = (unsigned char *) - realloc(pabyOrig,dst_xsize * dst_ysize * band_count); + pabyRaw1 = (unsigned char *)realloc(pabyOrig, + dst_xsize * dst_ysize * band_count); - if( pabyRaw1 == NULL ) { - msSetError(MS_MEMERR, - "Allocating work image of size %dx%dx%d failed.", - "msDrawRasterLayerGDAL()", - dst_xsize, dst_ysize, band_count ); + if (pabyRaw1 == NULL) { + msSetError(MS_MEMERR, "Allocating work image of size %dx%dx%d failed.", + "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize, band_count); free(pabyOrig); - if( hColorMap != NULL ) - GDALDestroyColorTable( hColorMap ); - free( pbIsNoDataBuffer ); + if (hColorMap != NULL) + GDALDestroyColorTable(hColorMap); + free(pbIsNoDataBuffer); return -1; } - if( hBand2 != NULL ) { + if (hBand2 != NULL) { pabyRaw2 = pabyRaw1 + dst_xsize * dst_ysize * 1; pabyRaw3 = pabyRaw1 + dst_xsize * dst_ysize * 2; pabyRawAlpha = pabyRaw1 + dst_xsize * dst_ysize * 3; @@ -742,147 +740,125 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, hBandAlpha = GDALGetMaskBand(hBand1); - eErr = GDALRasterIO( hBandAlpha, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - pabyRawAlpha, dst_xsize, dst_ysize, GDT_Byte, 0,0); - - if( eErr != CE_None ) { - msSetError( MS_IOERR, "GDALRasterIO() failed: %s", - "drawGDAL()", CPLGetLastErrorMsg() ); - if( hColorMap != NULL ) - GDALDestroyColorTable( hColorMap ); - free( pabyRaw1 ); - free( pbIsNoDataBuffer ); + eErr = GDALRasterIO(hBandAlpha, GF_Read, src_xoff, src_yoff, src_xsize, + src_ysize, pabyRawAlpha, dst_xsize, dst_ysize, + GDT_Byte, 0, 0); + + if (eErr != CE_None) { + msSetError(MS_IOERR, "GDALRasterIO() failed: %s", "drawGDAL()", + CPLGetLastErrorMsg()); + if (hColorMap != NULL) + GDALDestroyColorTable(hColorMap); + free(pabyRaw1); + free(pbIsNoDataBuffer); return -1; } /* In case the mask is not an alpha channel, expand values of 1 to 255, */ /* so we can deal as it was an alpha band afterwards */ if ((nMaskFlags & GMF_ALPHA) == 0) { - for(i=0; itype == MS_BUFFER_BYTE_RGBA && hBandAlpha != NULL ) { - assert( cmap_set ); - - int k = 0; - for( i = dst_yoff; i < dst_yoff + dst_ysize; i++ ) { - for( int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++ ) { - int src_pixel, src_alpha, cmap_alpha, merged_alpha; - if(SKIP_MASK(j,i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) - continue; + /* -------------------------------------------------------------------- */ + /* Single band plus colormap and alpha to truecolor. (RB) */ + /* -------------------------------------------------------------------- */ + if (hBand2 == NULL && rb->type == MS_BUFFER_BYTE_RGBA && hBandAlpha != NULL) { + assert(cmap_set); - src_pixel = pabyRaw1[k]; - src_alpha = pabyRawAlpha[k]; - cmap_alpha = rb_cmap[3][src_pixel]; - - merged_alpha = (src_alpha * cmap_alpha) / 255; - - if( merged_alpha < 2 ) - /* do nothing - transparent */; - else if( merged_alpha > 253 ) { - RB_SET_PIXEL( rb, j, i, - rb_cmap[0][src_pixel], - rb_cmap[1][src_pixel], - rb_cmap[2][src_pixel], - cmap_alpha ); - } else { - RB_MIX_PIXEL( rb, j, i, - rb_cmap[0][src_pixel], - rb_cmap[1][src_pixel], - rb_cmap[2][src_pixel], - merged_alpha ); - } + int k = 0; + for (i = dst_yoff; i < dst_yoff + dst_ysize; i++) { + for (int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++) { + int src_pixel, src_alpha, cmap_alpha, merged_alpha; + if (SKIP_MASK(j, i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) + continue; + + src_pixel = pabyRaw1[k]; + src_alpha = pabyRawAlpha[k]; + cmap_alpha = rb_cmap[3][src_pixel]; + + merged_alpha = (src_alpha * cmap_alpha) / 255; + + if (merged_alpha < 2) + /* do nothing - transparent */; + else if (merged_alpha > 253) { + RB_SET_PIXEL(rb, j, i, rb_cmap[0][src_pixel], rb_cmap[1][src_pixel], + rb_cmap[2][src_pixel], cmap_alpha); + } else { + RB_MIX_PIXEL(rb, j, i, rb_cmap[0][src_pixel], rb_cmap[1][src_pixel], + rb_cmap[2][src_pixel], merged_alpha); } } } + } /* -------------------------------------------------------------------- */ /* Single band plus colormap (no alpha) to truecolor (RB) */ /* -------------------------------------------------------------------- */ - else if( hBand2 == NULL && rb->type == MS_BUFFER_BYTE_RGBA ) { - assert( cmap_set ); + else if (hBand2 == NULL && rb->type == MS_BUFFER_BYTE_RGBA) { + assert(cmap_set); - int k = 0; - for( i = dst_yoff; i < dst_yoff + dst_ysize; i++ ) { - for( int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++ ) { - int src_pixel = pabyRaw1[k]; - if(SKIP_MASK(j,i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) - continue; + int k = 0; + for (i = dst_yoff; i < dst_yoff + dst_ysize; i++) { + for (int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++) { + int src_pixel = pabyRaw1[k]; + if (SKIP_MASK(j, i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) + continue; - if( rb_cmap[3][src_pixel] > 253 ) { - RB_SET_PIXEL( rb, j, i, - rb_cmap[0][src_pixel], - rb_cmap[1][src_pixel], - rb_cmap[2][src_pixel], - rb_cmap[3][src_pixel] ); - } else if( rb_cmap[3][src_pixel] > 1 ) { - RB_MIX_PIXEL( rb, j, i, - rb_cmap[0][src_pixel], - rb_cmap[1][src_pixel], - rb_cmap[2][src_pixel], - rb_cmap[3][src_pixel] ); - } + if (rb_cmap[3][src_pixel] > 253) { + RB_SET_PIXEL(rb, j, i, rb_cmap[0][src_pixel], rb_cmap[1][src_pixel], + rb_cmap[2][src_pixel], rb_cmap[3][src_pixel]); + } else if (rb_cmap[3][src_pixel] > 1) { + RB_MIX_PIXEL(rb, j, i, rb_cmap[0][src_pixel], rb_cmap[1][src_pixel], + rb_cmap[2][src_pixel], rb_cmap[3][src_pixel]); } } } + } /* -------------------------------------------------------------------- */ /* Input is 3 band RGB. Alpha blending is mixed into the loop */ /* since this case is less commonly used and has lots of other */ /* overhead. (RB) */ /* -------------------------------------------------------------------- */ - else if( hBand3 != NULL && rb->type == MS_BUFFER_BYTE_RGBA ) { - int k = 0; - for( i = dst_yoff; i < dst_yoff + dst_ysize; i++ ) { - for( int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++ ) { - if(SKIP_MASK(j,i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) - continue; - if( MS_VALID_COLOR( layer->offsite ) - && pabyRaw1[k] == layer->offsite.red - && pabyRaw2[k] == layer->offsite.green - && pabyRaw3[k] == layer->offsite.blue ) - continue; + else if (hBand3 != NULL && rb->type == MS_BUFFER_BYTE_RGBA) { + int k = 0; + for (i = dst_yoff; i < dst_yoff + dst_ysize; i++) { + for (int j = dst_xoff; j < dst_xoff + dst_xsize; j++, k++) { + if (SKIP_MASK(j, i) || (pbIsNoDataBuffer && pbIsNoDataBuffer[k])) + continue; + if (MS_VALID_COLOR(layer->offsite) && + pabyRaw1[k] == layer->offsite.red && + pabyRaw2[k] == layer->offsite.green && + pabyRaw3[k] == layer->offsite.blue) + continue; - if( bHaveRGBNoData - && pabyRaw1[k] == nNoData1 - && pabyRaw2[k] == nNoData2 - && pabyRaw3[k] == nNoData3 ) - continue; + if (bHaveRGBNoData && pabyRaw1[k] == nNoData1 && + pabyRaw2[k] == nNoData2 && pabyRaw3[k] == nNoData3) + continue; - if( pabyRawAlpha == NULL || pabyRawAlpha[k] == 255 ) { - RB_SET_PIXEL( rb, j, i, - pabyRaw1[k], - pabyRaw2[k], - pabyRaw3[k], - 255 ); - } else if( pabyRawAlpha[k] != 0 ) { - RB_MIX_PIXEL( rb, j, i, - pabyRaw1[k], - pabyRaw2[k], - pabyRaw3[k], - pabyRawAlpha[k] ); - } + if (pabyRawAlpha == NULL || pabyRawAlpha[k] == 255) { + RB_SET_PIXEL(rb, j, i, pabyRaw1[k], pabyRaw2[k], pabyRaw3[k], 255); + } else if (pabyRawAlpha[k] != 0) { + RB_MIX_PIXEL(rb, j, i, pabyRaw1[k], pabyRaw2[k], pabyRaw3[k], + pabyRawAlpha[k]); } } } - + } /* ** Cleanup */ - free( pabyRaw1 ); - free( pbIsNoDataBuffer ); + free(pabyRaw1); + free(pbIsNoDataBuffer); - if( hColorMap != NULL ) - GDALDestroyColorTable( hColorMap ); + if (hColorMap != NULL) + GDALDestroyColorTable(hColorMap); return 0; } @@ -891,27 +867,27 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, /* ParseDefaultLUT() */ /************************************************************************/ -static int ParseDefaultLUT( const char *lut_def, GByte *lut, int nMaxValIn ) +static int ParseDefaultLUT(const char *lut_def, GByte *lut, int nMaxValIn) { const char *lut_read; - int last_in=0, last_out=0, all_done=FALSE; + int last_in = 0, last_out = 0, all_done = FALSE; /* -------------------------------------------------------------------- */ /* Parse definition, applying to lut on the fly. */ /* -------------------------------------------------------------------- */ lut_read = lut_def; - while( !all_done ) { - int this_in=0, this_out=0; + while (!all_done) { + int this_in = 0, this_out = 0; int lut_i; - while( isspace(*lut_read) ) + while (isspace(*lut_read)) lut_read++; /* if we are at end, assume nMaxValIn:255 */ - if( *lut_read == '\0' ) { + if (*lut_read == '\0') { all_done = TRUE; - if ( last_in != nMaxValIn ) { + if (last_in != nMaxValIn) { this_in = nMaxValIn; this_out = 255; } @@ -920,35 +896,35 @@ static int ParseDefaultLUT( const char *lut_def, GByte *lut, int nMaxValIn ) /* otherwise read "in:out", and skip past */ else { this_in = atoi(lut_read); - while( *lut_read != ':' && *lut_read ) + while (*lut_read != ':' && *lut_read) lut_read++; - if( *lut_read == ':' ) + if (*lut_read == ':') lut_read++; - while( isspace(*lut_read) ) + while (isspace(*lut_read)) lut_read++; this_out = atoi(lut_read); - while( *lut_read && *lut_read != ',' && *lut_read != '\n' ) + while (*lut_read && *lut_read != ',' && *lut_read != '\n') lut_read++; - if( *lut_read == ',' || *lut_read == '\n' ) + if (*lut_read == ',' || *lut_read == '\n') lut_read++; - while( isspace(*lut_read) ) + while (isspace(*lut_read)) lut_read++; } - this_in = MS_MAX(0,MS_MIN(nMaxValIn,this_in)); - this_out = MS_MAX(0,MS_MIN(255,this_out)); + this_in = MS_MAX(0, MS_MIN(nMaxValIn, this_in)); + this_out = MS_MAX(0, MS_MIN(255, this_out)); /* apply linear values from last in:out to this in:out */ - for( lut_i = last_in; lut_i <= this_in; lut_i++ ) { + for (lut_i = last_in; lut_i <= this_in; lut_i++) { double ratio; - if( last_in == this_in ) + if (last_in == this_in) ratio = 1.0; else - ratio = (lut_i - last_in) / (double) (this_in - last_in); + ratio = (lut_i - last_in) / (double)(this_in - last_in); - lut[lut_i] = (int) - floor(((1.0 - ratio)*last_out + ratio*this_out) + 0.5); + lut[lut_i] = + (int)floor(((1.0 - ratio) * last_out + ratio * this_out) + 0.5); } last_in = this_in; @@ -962,46 +938,46 @@ static int ParseDefaultLUT( const char *lut_def, GByte *lut, int nMaxValIn ) /* LutFromGimpLine() */ /************************************************************************/ -static int LutFromGimpLine( char *lut_line, GByte *lut ) +static int LutFromGimpLine(char *lut_line, GByte *lut) { char wrkLUTDef[1000]; - int i, count = 0; + int i, count = 0; char **tokens; /* cleanup white space at end of line (DOS LF, etc) */ i = strlen(lut_line) - 1; - while( i > 0 && isspace(lut_line[i]) ) + while (i > 0 && isspace(lut_line[i])) lut_line[i--] = '\0'; - while( *lut_line == 10 || *lut_line == 13 ) + while (*lut_line == 10 || *lut_line == 13) lut_line++; /* tokenize line */ - tokens = CSLTokenizeString( lut_line ); - if( CSLCount(tokens) != 17 * 2 ) { - CSLDestroy( tokens ); - msSetError(MS_MISCERR, - "GIMP curve file appears corrupt.", - "LutFromGimpLine()" ); + tokens = CSLTokenizeString(lut_line); + if (CSLCount(tokens) != 17 * 2) { + CSLDestroy(tokens); + msSetError(MS_MISCERR, "GIMP curve file appears corrupt.", + "LutFromGimpLine()"); return -1; } /* Convert to our own format */ wrkLUTDef[0] = '\0'; - for( i = 0; i < 17; i++ ) { - if( atoi(tokens[i*2]) >= 0 ) { - if( count++ > 0 ) - strlcat( wrkLUTDef, ",", sizeof(wrkLUTDef)); - - snprintf( wrkLUTDef + strlen(wrkLUTDef), sizeof(wrkLUTDef)-strlen(wrkLUTDef), - "%s:%s", tokens[i*2], tokens[i*2+1] ); + for (i = 0; i < 17; i++) { + if (atoi(tokens[i * 2]) >= 0) { + if (count++ > 0) + strlcat(wrkLUTDef, ",", sizeof(wrkLUTDef)); + + snprintf(wrkLUTDef + strlen(wrkLUTDef), + sizeof(wrkLUTDef) - strlen(wrkLUTDef), "%s:%s", tokens[i * 2], + tokens[i * 2 + 1]); } } - CSLDestroy( tokens ); + CSLDestroy(tokens); - return ParseDefaultLUT( wrkLUTDef, lut, 255 ); + return ParseDefaultLUT(wrkLUTDef, lut, 255); } /************************************************************************/ @@ -1010,33 +986,30 @@ static int LutFromGimpLine( char *lut_line, GByte *lut ) /* Parse a Gimp style LUT. */ /************************************************************************/ -static int ParseGimpLUT( const char *lut_def, GByte *lut, int iColorIndex ) +static int ParseGimpLUT(const char *lut_def, GByte *lut, int iColorIndex) { int i; GByte lutValue[256]; GByte lutColorBand[256]; - char **lines = - CSLTokenizeStringComplex( lut_def, "\n", FALSE, FALSE ); - - if( !EQUALN(lines[0],"# GIMP Curves File",18) - || CSLCount(lines) < 6 ) { - msSetError(MS_MISCERR, - "GIMP curve file appears corrupt.", - "ParseGimpLUT()" ); - CSLDestroy( lines ); + char **lines = CSLTokenizeStringComplex(lut_def, "\n", FALSE, FALSE); + + if (!EQUALN(lines[0], "# GIMP Curves File", 18) || CSLCount(lines) < 6) { + msSetError(MS_MISCERR, "GIMP curve file appears corrupt.", + "ParseGimpLUT()"); + CSLDestroy(lines); return -1; } /* * Convert the overall curve, and the color band specific curve into LUTs. */ - if( LutFromGimpLine( lines[1], lutValue ) != 0 - || LutFromGimpLine( lines[iColorIndex + 1], lutColorBand ) != 0 ) { - CSLDestroy( lines ); + if (LutFromGimpLine(lines[1], lutValue) != 0 || + LutFromGimpLine(lines[iColorIndex + 1], lutColorBand) != 0) { + CSLDestroy(lines); return -1; } - CSLDestroy( lines ); + CSLDestroy(lines); /* * Compose the two luts as if the raw value passed through the color band @@ -1044,7 +1017,7 @@ static int ParseGimpLUT( const char *lut_def, GByte *lut, int iColorIndex ) * other will be the identity mapping, but not always. */ - for( i = 0; i < 256; i++ ) { + for (i = 0; i < 256; i++) { lut[i] = lutValue[lutColorBand[i]]; } @@ -1057,7 +1030,7 @@ static int ParseGimpLUT( const char *lut_def, GByte *lut, int iColorIndex ) /* Load a LUT according to RFC 21. */ /************************************************************************/ -static int LoadLUT( layerObj *layer, int iColorIndex, char** ppszLutDef ) +static int LoadLUT(layerObj *layer, int iColorIndex, char **ppszLutDef) { const char *lut_def; @@ -1069,37 +1042,35 @@ static int LoadLUT( layerObj *layer, int iColorIndex, char** ppszLutDef ) /* Get lut specifier from processing directives. Do nothing if */ /* none are found. */ /* -------------------------------------------------------------------- */ - sprintf( key, "LUT_%d", iColorIndex ); - lut_def = msLayerGetProcessingKey( layer, key ); - if( lut_def == NULL ) - lut_def = msLayerGetProcessingKey( layer, "LUT" ); - if( lut_def == NULL ) + sprintf(key, "LUT_%d", iColorIndex); + lut_def = msLayerGetProcessingKey(layer, key); + if (lut_def == NULL) + lut_def = msLayerGetProcessingKey(layer, "LUT"); + if (lut_def == NULL) return 0; /* -------------------------------------------------------------------- */ /* Does this look like a file? If so, read it into memory. */ /* -------------------------------------------------------------------- */ - if( strspn(lut_def,"0123456789:, ") != strlen(lut_def) ) { + if (strspn(lut_def, "0123456789:, ") != strlen(lut_def)) { FILE *fp; char path[MS_MAXPATHLEN]; int len; msBuildPath(path, layer->map->mappath, lut_def); - fp = fopen( path, "rb" ); - if( fp == NULL ) { - msSetError(MS_IOERR, - "Failed to open LUT file '%s'.", - "drawGDAL()", path ); + fp = fopen(path, "rb"); + if (fp == NULL) { + msSetError(MS_IOERR, "Failed to open LUT file '%s'.", "drawGDAL()", path); return -1; } - len = fread( lut_def_fromfile, 1, sizeof(lut_def_fromfile), fp ); - fclose( fp ); + len = fread(lut_def_fromfile, 1, sizeof(lut_def_fromfile), fp); + fclose(fp); - if( len == sizeof(lut_def_fromfile) ) { + if (len == sizeof(lut_def_fromfile)) { msSetError(MS_IOERR, - "LUT definition from file %s longer than maximum buffer size (%d bytes).", - "drawGDAL()", - path, (int)sizeof(lut_def_fromfile) ); + "LUT definition from file %s longer than maximum buffer size " + "(%d bytes).", + "drawGDAL()", path, (int)sizeof(lut_def_fromfile)); return -1; } @@ -1111,19 +1082,17 @@ static int LoadLUT( layerObj *layer, int iColorIndex, char** ppszLutDef ) *ppszLutDef = msStrdup(lut_def); return 0; - } /************************************************************************/ /* FreeLUTs() */ /************************************************************************/ -static void FreeLUTs(char** apszLUTs) -{ - int i; - for( i = 0; i < 4; i++ ) - msFree(apszLUTs[i]); - msFree(apszLUTs); +static void FreeLUTs(char **apszLUTs) { + int i; + for (i = 0; i < 4; i++) + msFree(apszLUTs[i]); + msFree(apszLUTs); } /************************************************************************/ @@ -1133,24 +1102,21 @@ static void FreeLUTs(char** apszLUTs) /* or NULL in case of failure. */ /************************************************************************/ -static char** LoadLUTs(layerObj *layer, int band_count) -{ - int i; - char** apszLUTs; - - assert(band_count <= 4); +static char **LoadLUTs(layerObj *layer, int band_count) { + int i; + char **apszLUTs; - apszLUTs = (char**) msSmallCalloc( 4, sizeof(char*) ); - for( i = 0; i < band_count; i++ ) - { - if( LoadLUT( layer, i+1, &apszLUTs[i] ) != 0 ) - { - FreeLUTs(apszLUTs); - return NULL; - } + assert(band_count <= 4); + + apszLUTs = (char **)msSmallCalloc(4, sizeof(char *)); + for (i = 0; i < band_count; i++) { + if (LoadLUT(layer, i + 1, &apszLUTs[i]) != 0) { + FreeLUTs(apszLUTs); + return NULL; } + } - return apszLUTs; + return apszLUTs; } /************************************************************************/ @@ -1161,105 +1127,88 @@ static char** LoadLUTs(layerObj *layer, int band_count) /* must be queries on 16-bits. */ /************************************************************************/ -static GDALDataType GetDataTypeAppropriateForLUTS(char** apszLUTs) -{ - GDALDataType eDT = GDT_Byte; - int i; - for( i = 0; i < 4; i++ ) - { - const char* pszLastTuple; - int nLastInValue; - if( apszLUTs[i] == NULL ) - continue; - if( EQUALN(apszLUTs[i],"# GIMP",6) ) - continue; - /* Find last in:out tuple in string */ - pszLastTuple = strrchr( apszLUTs[i], ',' ); - if( pszLastTuple == NULL ) - pszLastTuple = apszLUTs[i]; - else - pszLastTuple ++; - while( *pszLastTuple == ' ' ) - pszLastTuple ++; - nLastInValue = atoi(pszLastTuple); - if( nLastInValue > 255 ) - { - eDT = GDT_UInt16; - break; - } +static GDALDataType GetDataTypeAppropriateForLUTS(char **apszLUTs) { + GDALDataType eDT = GDT_Byte; + int i; + for (i = 0; i < 4; i++) { + const char *pszLastTuple; + int nLastInValue; + if (apszLUTs[i] == NULL) + continue; + if (EQUALN(apszLUTs[i], "# GIMP", 6)) + continue; + /* Find last in:out tuple in string */ + pszLastTuple = strrchr(apszLUTs[i], ','); + if (pszLastTuple == NULL) + pszLastTuple = apszLUTs[i]; + else + pszLastTuple++; + while (*pszLastTuple == ' ') + pszLastTuple++; + nLastInValue = atoi(pszLastTuple); + if (nLastInValue > 255) { + eDT = GDT_UInt16; + break; } - return eDT; + } + return eDT; } /************************************************************************/ /* ApplyLUT() */ /************************************************************************/ -static int ApplyLUT( int iColorIndex, const char* lut_def, - const void* pInBuffer, GDALDataType eDT, - GByte* pabyOutBuffer, - int nPixelCount ) -{ +static int ApplyLUT(int iColorIndex, const char *lut_def, const void *pInBuffer, + GDALDataType eDT, GByte *pabyOutBuffer, int nPixelCount) { int i, err; GByte byteLut[256]; - GByte* uint16Lut = NULL; - - assert( eDT == GDT_Byte || eDT == GDT_UInt16 ); - - if( lut_def == NULL ) - { - if( pInBuffer != pabyOutBuffer ) - { - GDALCopyWords( (void*)pInBuffer, eDT, GDALGetDataTypeSize(eDT) / 8, - pabyOutBuffer, GDT_Byte, 1, - nPixelCount ); - } - return 0; + GByte *uint16Lut = NULL; + + assert(eDT == GDT_Byte || eDT == GDT_UInt16); + + if (lut_def == NULL) { + if (pInBuffer != pabyOutBuffer) { + GDALCopyWords((void *)pInBuffer, eDT, GDALGetDataTypeSize(eDT) / 8, + pabyOutBuffer, GDT_Byte, 1, nPixelCount); + } + return 0; } /* -------------------------------------------------------------------- */ /* Parse the LUT description. */ /* -------------------------------------------------------------------- */ - if( EQUALN(lut_def,"# GIMP",6) ) { - if( eDT != GDT_Byte ) { - msSetError(MS_MISCERR, - "Cannot apply a GIMP LUT on a 16-bit buffer", + if (EQUALN(lut_def, "# GIMP", 6)) { + if (eDT != GDT_Byte) { + msSetError(MS_MISCERR, "Cannot apply a GIMP LUT on a 16-bit buffer", "ApplyLUT()"); return -1; } - err = ParseGimpLUT( lut_def, byteLut, iColorIndex ); + err = ParseGimpLUT(lut_def, byteLut, iColorIndex); } else { - if( eDT == GDT_Byte ) - err = ParseDefaultLUT( lut_def, byteLut, 255 ); - else - { - uint16Lut = (GByte*) malloc( 65536 ); - if( uint16Lut == NULL ) - { - msSetError(MS_MEMERR, - "Cannot allocate 16-bit LUT", - "ApplyLUT()" ); - return -1; - } - err = ParseDefaultLUT( lut_def, uint16Lut, 65535 ); + if (eDT == GDT_Byte) + err = ParseDefaultLUT(lut_def, byteLut, 255); + else { + uint16Lut = (GByte *)malloc(65536); + if (uint16Lut == NULL) { + msSetError(MS_MEMERR, "Cannot allocate 16-bit LUT", "ApplyLUT()"); + return -1; + } + err = ParseDefaultLUT(lut_def, uint16Lut, 65535); } } /* -------------------------------------------------------------------- */ /* Apply LUT. */ /* -------------------------------------------------------------------- */ - if( eDT == GDT_Byte ) - { - for( i = 0; i < nPixelCount; i++ ) - pabyOutBuffer[i] = byteLut[((GByte*)pInBuffer)[i]]; - } - else - { - for( i = 0; i < nPixelCount; i++ ) - pabyOutBuffer[i] = uint16Lut[((GUInt16*)pInBuffer)[i]]; - free(uint16Lut); + if (eDT == GDT_Byte) { + for (i = 0; i < nPixelCount; i++) + pabyOutBuffer[i] = byteLut[((GByte *)pInBuffer)[i]]; + } else { + for (i = 0; i < nPixelCount; i++) + pabyOutBuffer[i] = uint16Lut[((GUInt16 *)pInBuffer)[i]]; + free(uint16Lut); } - + return err; } @@ -1271,22 +1220,19 @@ static int ApplyLUT( int iColorIndex, const char* lut_def, /* buffer. The processing options include scaling. */ /************************************************************************/ -static int -LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, - layerObj *layer, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - GByte *pabyWholeBuffer, - int dst_xsize, int dst_ysize, - int *pbHaveRGBNoData, - int *pnNoData1, int *pnNoData2, int *pnNoData3, - bool *pbScaled, double *pdfScaleMin, double *pdfScaleRatio, - bool **ppbIsNoDataBuffer ) +static int LoadGDALImages(GDALDatasetH hDS, int band_numbers[4], int band_count, + layerObj *layer, int src_xoff, int src_yoff, + int src_xsize, int src_ysize, GByte *pabyWholeBuffer, + int dst_xsize, int dst_ysize, int *pbHaveRGBNoData, + int *pnNoData1, int *pnNoData2, int *pnNoData3, + bool *pbScaled, double *pdfScaleMin, + double *pdfScaleRatio, bool **ppbIsNoDataBuffer) { - int iColorIndex, result_code=0; + int iColorIndex, result_code = 0; CPLErr eErr; float *pafWholeRawData; - char** papszLUTs; + char **papszLUTs; *pbScaled = false; *pdfScaleMin = 0; @@ -1299,87 +1245,73 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, /* input band, then nodata will already have been adderssed as */ /* part of the real or manufactured color table. */ /* -------------------------------------------------------------------- */ - if( band_count == 3 ) { - *pnNoData1 = (int) - msGetGDALNoDataValue( layer, - GDALGetRasterBand(hDS,band_numbers[0]), - pbHaveRGBNoData); + if (band_count == 3) { + *pnNoData1 = (int)msGetGDALNoDataValue( + layer, GDALGetRasterBand(hDS, band_numbers[0]), pbHaveRGBNoData); - if( *pbHaveRGBNoData ) - *pnNoData2 = (int) - msGetGDALNoDataValue( layer, - GDALGetRasterBand(hDS,band_numbers[1]), - pbHaveRGBNoData); - if( *pbHaveRGBNoData ) - *pnNoData3 = (int) - msGetGDALNoDataValue( layer, - GDALGetRasterBand(hDS,band_numbers[2]), - pbHaveRGBNoData); + if (*pbHaveRGBNoData) + *pnNoData2 = (int)msGetGDALNoDataValue( + layer, GDALGetRasterBand(hDS, band_numbers[1]), pbHaveRGBNoData); + if (*pbHaveRGBNoData) + *pnNoData3 = (int)msGetGDALNoDataValue( + layer, GDALGetRasterBand(hDS, band_numbers[2]), pbHaveRGBNoData); } /* -------------------------------------------------------------------- */ /* Are we doing a simple, non-scaling case? If so, read directly */ /* and return. */ /* -------------------------------------------------------------------- */ - if( CSLFetchNameValue( layer->processing, "SCALE" ) == NULL - && CSLFetchNameValue( layer->processing, "SCALE_1" ) == NULL - && CSLFetchNameValue( layer->processing, "SCALE_2" ) == NULL - && CSLFetchNameValue( layer->processing, "SCALE_3" ) == NULL - && CSLFetchNameValue( layer->processing, "SCALE_4" ) == NULL ) { - + if (CSLFetchNameValue(layer->processing, "SCALE") == NULL && + CSLFetchNameValue(layer->processing, "SCALE_1") == NULL && + CSLFetchNameValue(layer->processing, "SCALE_2") == NULL && + CSLFetchNameValue(layer->processing, "SCALE_3") == NULL && + CSLFetchNameValue(layer->processing, "SCALE_4") == NULL) { + GDALDataType eDT; - GUInt16* panBuffer = NULL; - void* pBuffer; + GUInt16 *panBuffer = NULL; + void *pBuffer; papszLUTs = LoadLUTs(layer, band_count); - if( papszLUTs == NULL ) { - return -1; + if (papszLUTs == NULL) { + return -1; } eDT = GetDataTypeAppropriateForLUTS(papszLUTs); - if( eDT == GDT_UInt16 ) { - panBuffer = - (GUInt16 *) malloc(sizeof(GUInt16) * dst_xsize * dst_ysize * band_count ); - - if( panBuffer == NULL ) { - msSetError(MS_MEMERR, - "Allocating work uint16 image of size %dx%dx%d failed.", - "msDrawRasterLayerGDAL()", - dst_xsize, dst_ysize, band_count ); - FreeLUTs(papszLUTs); - return -1; - } - pBuffer = panBuffer; - } - else - pBuffer = pabyWholeBuffer; - - eErr = GDALDatasetRasterIO( hDS, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - pBuffer, - dst_xsize, dst_ysize, eDT, - band_count, band_numbers, - 0,0,0); - - if( eErr != CE_None ) { - msSetError( MS_IOERR, - "GDALDatasetRasterIO() failed: %s", - "drawGDAL()", - CPLGetLastErrorMsg() ); + if (eDT == GDT_UInt16) { + panBuffer = (GUInt16 *)malloc(sizeof(GUInt16) * dst_xsize * dst_ysize * + band_count); + + if (panBuffer == NULL) { + msSetError(MS_MEMERR, + "Allocating work uint16 image of size %dx%dx%d failed.", + "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize, band_count); + FreeLUTs(papszLUTs); + return -1; + } + pBuffer = panBuffer; + } else + pBuffer = pabyWholeBuffer; + + eErr = GDALDatasetRasterIO(hDS, GF_Read, src_xoff, src_yoff, src_xsize, + src_ysize, pBuffer, dst_xsize, dst_ysize, eDT, + band_count, band_numbers, 0, 0, 0); + + if (eErr != CE_None) { + msSetError(MS_IOERR, "GDALDatasetRasterIO() failed: %s", "drawGDAL()", + CPLGetLastErrorMsg()); FreeLUTs(papszLUTs); msFree(panBuffer); return -1; } - for( iColorIndex = 0; - iColorIndex < band_count && result_code == 0; iColorIndex++ ) { - result_code = ApplyLUT( iColorIndex+1, - papszLUTs[iColorIndex], - (GByte*)pBuffer - + dst_xsize*dst_ysize*iColorIndex*(GDALGetDataTypeSize(eDT)/8), - eDT, - pabyWholeBuffer + dst_xsize*dst_ysize*iColorIndex, - dst_xsize * dst_ysize ); + for (iColorIndex = 0; iColorIndex < band_count && result_code == 0; + iColorIndex++) { + result_code = + ApplyLUT(iColorIndex + 1, papszLUTs[iColorIndex], + (GByte *)pBuffer + dst_xsize * dst_ysize * iColorIndex * + (GDALGetDataTypeSize(eDT) / 8), + eDT, pabyWholeBuffer + dst_xsize * dst_ysize * iColorIndex, + dst_xsize * dst_ysize); } FreeLUTs(papszLUTs); @@ -1406,85 +1338,76 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, /* interleaved). */ /* -------------------------------------------------------------------- */ pafWholeRawData = - (float *) malloc(sizeof(float) * dst_xsize * dst_ysize * band_count ); + (float *)malloc(sizeof(float) * dst_xsize * dst_ysize * band_count); - if( pafWholeRawData == NULL ) { + if (pafWholeRawData == NULL) { msSetError(MS_MEMERR, "Allocating work float image of size %dx%dx%d failed.", - "msDrawRasterLayerGDAL()", - dst_xsize, dst_ysize, band_count ); + "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize, band_count); return -1; } - eErr = GDALDatasetRasterIO( - hDS, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - pafWholeRawData, dst_xsize, dst_ysize, GDT_Float32, - band_count, band_numbers, - 0, 0, 0 ); + eErr = GDALDatasetRasterIO(hDS, GF_Read, src_xoff, src_yoff, src_xsize, + src_ysize, pafWholeRawData, dst_xsize, dst_ysize, + GDT_Float32, band_count, band_numbers, 0, 0, 0); - if( eErr != CE_None ) { - msSetError( MS_IOERR, "GDALDatasetRasterIO() failed: %s", - "drawGDAL()", - CPLGetLastErrorMsg() ); + if (eErr != CE_None) { + msSetError(MS_IOERR, "GDALDatasetRasterIO() failed: %s", "drawGDAL()", + CPLGetLastErrorMsg()); - free( pafWholeRawData ); + free(pafWholeRawData); return -1; } papszLUTs = LoadLUTs(layer, band_count); - if( papszLUTs == NULL ) { - free( pafWholeRawData ); + if (papszLUTs == NULL) { + free(pafWholeRawData); return -1; } - if( GetDataTypeAppropriateForLUTS(papszLUTs) != GDT_Byte ) { - msDebug( "LoadGDALImage(%s): One of the LUT contains a input value > 255.\n" - "This is not properly supported in combination with SCALE\n", - layer->name ); + if (GetDataTypeAppropriateForLUTS(papszLUTs) != GDT_Byte) { + msDebug("LoadGDALImage(%s): One of the LUT contains a input value > 255.\n" + "This is not properly supported in combination with SCALE\n", + layer->name); } /* -------------------------------------------------------------------- */ /* Fetch the scale processing option. */ /* -------------------------------------------------------------------- */ - for( iColorIndex = 0; iColorIndex < band_count; iColorIndex++ ) { + for (iColorIndex = 0; iColorIndex < band_count; iColorIndex++) { unsigned char *pabyBuffer; - double dfScaleMin=0.0, dfScaleMax=255.0, dfScaleRatio, dfNoDataValue; + double dfScaleMin = 0.0, dfScaleMax = 255.0, dfScaleRatio, dfNoDataValue; const char *pszScaleInfo; float *pafRawData; - int nPixelCount = dst_xsize * dst_ysize, i, bGotNoData = FALSE; - GDALRasterBandH hBand =GDALGetRasterBand(hDS,band_numbers[iColorIndex]); - pszScaleInfo = CSLFetchNameValue( layer->processing, "SCALE" ); - if( pszScaleInfo == NULL ) { + int nPixelCount = dst_xsize * dst_ysize, i, bGotNoData = FALSE; + GDALRasterBandH hBand = GDALGetRasterBand(hDS, band_numbers[iColorIndex]); + pszScaleInfo = CSLFetchNameValue(layer->processing, "SCALE"); + if (pszScaleInfo == NULL) { char szBandScalingName[20]; - sprintf( szBandScalingName, "SCALE_%d", iColorIndex+1 ); - pszScaleInfo = CSLFetchNameValue( layer->processing, - szBandScalingName); + sprintf(szBandScalingName, "SCALE_%d", iColorIndex + 1); + pszScaleInfo = CSLFetchNameValue(layer->processing, szBandScalingName); } - if( pszScaleInfo != NULL ) { + if (pszScaleInfo != NULL) { char **papszTokens; - papszTokens = CSLTokenizeStringComplex( pszScaleInfo, " ,", - FALSE, FALSE ); - if( CSLCount(papszTokens) == 1 - && EQUAL(papszTokens[0],"AUTO") ) { + papszTokens = CSLTokenizeStringComplex(pszScaleInfo, " ,", FALSE, FALSE); + if (CSLCount(papszTokens) == 1 && EQUAL(papszTokens[0], "AUTO")) { dfScaleMin = dfScaleMax = 0.0; - } else if( CSLCount(papszTokens) != 2 ) { - free( pafWholeRawData ); - CSLDestroy( papszTokens ); - FreeLUTs( papszLUTs ); - msSetError( MS_MISCERR, - "SCALE PROCESSING option unparsable for layer %s.", - "msDrawGDAL()", - layer->name ); + } else if (CSLCount(papszTokens) != 2) { + free(pafWholeRawData); + CSLDestroy(papszTokens); + FreeLUTs(papszLUTs); + msSetError(MS_MISCERR, + "SCALE PROCESSING option unparsable for layer %s.", + "msDrawGDAL()", layer->name); return -1; } else { dfScaleMin = atof(papszTokens[0]); dfScaleMax = atof(papszTokens[1]); } - CSLDestroy( papszTokens ); + CSLDestroy(papszTokens); } /* -------------------------------------------------------------------- */ @@ -1494,42 +1417,42 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, /* -------------------------------------------------------------------- */ pafRawData = pafWholeRawData + iColorIndex * dst_xsize * dst_ysize; - dfNoDataValue = msGetGDALNoDataValue( layer, hBand, &bGotNoData ); + dfNoDataValue = msGetGDALNoDataValue(layer, hBand, &bGotNoData); /* we force assignment to a float rather than letting pafRawData[i] get promoted to double later to avoid float precision issues. */ - float fNoDataValue = (float) dfNoDataValue; + float fNoDataValue = (float)dfNoDataValue; - if( dfScaleMin == dfScaleMax ) { + if (dfScaleMin == dfScaleMax) { int bMinMaxSet = 0; /* we force assignment to a float rather than letting pafRawData[i] get promoted to double later to avoid float precision issues. */ - float fNoDataValue = (float) dfNoDataValue; + float fNoDataValue = (float)dfNoDataValue; - for( i = 0; i < nPixelCount; i++ ) { - if( bGotNoData && IsNoData(pafRawData[i], fNoDataValue) ) + for (i = 0; i < nPixelCount; i++) { + if (bGotNoData && IsNoData(pafRawData[i], fNoDataValue)) continue; - if( CPLIsNan(pafRawData[i]) ) + if (CPLIsNan(pafRawData[i])) continue; - if( !bMinMaxSet ) { + if (!bMinMaxSet) { dfScaleMin = dfScaleMax = pafRawData[i]; bMinMaxSet = TRUE; } - dfScaleMin = MS_MIN(dfScaleMin,pafRawData[i]); - dfScaleMax = MS_MAX(dfScaleMax,pafRawData[i]); + dfScaleMin = MS_MIN(dfScaleMin, pafRawData[i]); + dfScaleMax = MS_MAX(dfScaleMax, pafRawData[i]); } - if( dfScaleMin == dfScaleMax ) + if (dfScaleMin == dfScaleMax) dfScaleMax = dfScaleMin + 1.0; } - if( layer->debug > 0 ) - msDebug( "msDrawGDAL(%s): scaling to 8bit, src range=%g,%g\n", - layer->name, dfScaleMin, dfScaleMax ); + if (layer->debug > 0) + msDebug("msDrawGDAL(%s): scaling to 8bit, src range=%g,%g\n", layer->name, + dfScaleMin, dfScaleMax); /* -------------------------------------------------------------------- */ /* Now process the data. */ @@ -1537,29 +1460,29 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, dfScaleRatio = 256.0 / (dfScaleMax - dfScaleMin); pabyBuffer = pabyWholeBuffer + iColorIndex * nPixelCount; - if( iColorIndex == 0 && bGotNoData ) + if (iColorIndex == 0 && bGotNoData) *ppbIsNoDataBuffer = (bool *)calloc(nPixelCount, 1); - for( i = 0; i < nPixelCount; i++ ) { + for (i = 0; i < nPixelCount; i++) { float fScaledValue; - if( bGotNoData && IsNoData(pafRawData[i], fNoDataValue) ) { - if( iColorIndex == 0 ) + if (bGotNoData && IsNoData(pafRawData[i], fNoDataValue)) { + if (iColorIndex == 0) (*ppbIsNoDataBuffer)[i] = true; continue; } - fScaledValue = (float) ((pafRawData[i]-dfScaleMin)*dfScaleRatio); + fScaledValue = (float)((pafRawData[i] - dfScaleMin) * dfScaleRatio); - if( fScaledValue < 0.0 ) + if (fScaledValue < 0.0) pabyBuffer[i] = 0; - else if( fScaledValue > 255.0 ) + else if (fScaledValue > 255.0) pabyBuffer[i] = 255; else - pabyBuffer[i] = (int) fScaledValue; + pabyBuffer[i] = (int)fScaledValue; } - if( iColorIndex == 0 ) { + if (iColorIndex == 0) { *pbScaled = true; *pdfScaleMin = dfScaleMin; *pdfScaleRatio = dfScaleRatio; @@ -1570,36 +1493,33 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, /* unable to utilize it since we can't return any pixels marked */ /* as nodata from this function. Need to fix someday. */ /* -------------------------------------------------------------------- */ - if( bGotNoData ) - msDebug( "LoadGDALImage(%s): NODATA value %g in GDAL\n" - "file or PROCESSING directive largely ignored. Not yet fully supported for\n" - "unclassified scaled data. The NODATA value is excluded from auto-scaling\n" - "min/max computation, but will not be transparent.\n", - layer->name, dfNoDataValue ); + if (bGotNoData) + msDebug("LoadGDALImage(%s): NODATA value %g in GDAL\n" + "file or PROCESSING directive largely ignored. Not yet fully " + "supported for\n" + "unclassified scaled data. The NODATA value is excluded from " + "auto-scaling\n" + "min/max computation, but will not be transparent.\n", + layer->name, dfNoDataValue); /* -------------------------------------------------------------------- */ /* Apply LUT if there is one. */ /* -------------------------------------------------------------------- */ - result_code = ApplyLUT( iColorIndex+1, - papszLUTs[iColorIndex], - pabyBuffer, - GDT_Byte, - pabyBuffer, - dst_xsize * dst_ysize ); - if( result_code == -1 ) { - free( pafWholeRawData ); - FreeLUTs( papszLUTs ); + result_code = ApplyLUT(iColorIndex + 1, papszLUTs[iColorIndex], pabyBuffer, + GDT_Byte, pabyBuffer, dst_xsize * dst_ysize); + if (result_code == -1) { + free(pafWholeRawData); + FreeLUTs(papszLUTs); return result_code; } } - free( pafWholeRawData ); - FreeLUTs( papszLUTs ); + free(pafWholeRawData); + FreeLUTs(papszLUTs); return result_code; } - /************************************************************************/ /* msGetGDALGeoTransform() */ /* */ @@ -1608,8 +1528,8 @@ LoadGDALImages( GDALDatasetH hDS, int band_numbers[4], int band_count, /* before this function is called. */ /************************************************************************/ -int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, - double *padfGeoTransform ) +int msGetGDALGeoTransform(GDALDatasetH hDS, mapObj *map, layerObj *layer, + double *padfGeoTransform) { const char *extent_priority = NULL; @@ -1620,7 +1540,7 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, char szPath[MS_MAXPATHLEN]; int fullPathLen; int success = 0; - rectObj rect; + rectObj rect; /* -------------------------------------------------------------------- */ /* some GDAL drivers (ie. GIF) don't set geotransform on failure. */ @@ -1635,33 +1555,32 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, /* -------------------------------------------------------------------- */ /* Do we want to override GDAL with a worldfile if one is present? */ /* -------------------------------------------------------------------- */ - extent_priority = CSLFetchNameValue( layer->processing, - "EXTENT_PRIORITY" ); + extent_priority = CSLFetchNameValue(layer->processing, "EXTENT_PRIORITY"); - if( extent_priority != NULL - && EQUALN(extent_priority,"WORLD",5) ) { + if (extent_priority != NULL && EQUALN(extent_priority, "WORLD", 5)) { /* is there a user configured worldfile? */ - value = CSLFetchNameValue( layer->processing, "WORLDFILE" ); + value = CSLFetchNameValue(layer->processing, "WORLDFILE"); - if( value != NULL ) { + if (value != NULL) { /* at this point, fullPath may be a filePath or path only */ fullPath = msBuildPath(szPath, map->mappath, value); /* fullPath is a path only, so let's append the dataset filename */ - if( strrchr(szPath,'.') == NULL ) { + if (strrchr(szPath, '.') == NULL) { fullPathLen = strlen(fullPath); - gdalDesc = msStripPath((char*)GDALGetDescription(hDS)); + gdalDesc = msStripPath((char *)GDALGetDescription(hDS)); - if ( (fullPathLen + strlen(gdalDesc)) < MS_MAXPATHLEN ) { - strcpy((char*)(fullPath + fullPathLen), gdalDesc); + if ((fullPathLen + strlen(gdalDesc)) < MS_MAXPATHLEN) { + strcpy((char *)(fullPath + fullPathLen), gdalDesc); } else { - msDebug("Path length to alternative worldfile exceeds MS_MAXPATHLEN.\n"); + msDebug( + "Path length to alternative worldfile exceeds MS_MAXPATHLEN.\n"); fullPath = NULL; } } /* fullPath has a filename included, so get the extension */ else { - fileExtension = msStrdup(strrchr(szPath,'.') + 1); + fileExtension = msStrdup(strrchr(szPath, '.') + 1); } } /* common behaviour with worldfile generated from basename + .wld */ @@ -1670,18 +1589,18 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, fileExtension = msStrdup("wld"); } - if( fullPath ) + if (fullPath) success = GDALReadWorldFile(fullPath, fileExtension, padfGeoTransform); - if( success && layer->debug >= MS_DEBUGLEVEL_VVV ) { + if (success && layer->debug >= MS_DEBUGLEVEL_VVV) { msDebug("Worldfile location: %s.\n", fullPath); - } else if( layer->debug >= MS_DEBUGLEVEL_VVV ) { + } else if (layer->debug >= MS_DEBUGLEVEL_VVV) { msDebug("Failed using worldfile location: %s.\n", fullPath); } msFree(fileExtension); - if( success ) + if (success) return MS_SUCCESS; } @@ -1694,8 +1613,8 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, /* files with no coordinate system otherwise they break down in */ /* many ways. */ /* -------------------------------------------------------------------- */ - if (GDALGetGeoTransform( hDS, padfGeoTransform ) == CE_None ) { - if( padfGeoTransform[5] == 1.0 && padfGeoTransform[3] == 0.0 ) { + if (GDALGetGeoTransform(hDS, padfGeoTransform) == CE_None) { + if (padfGeoTransform[5] == 1.0 && padfGeoTransform[3] == 0.0) { padfGeoTransform[5] = -1.0; padfGeoTransform[3] = GDALGetRasterYSize(hDS); } @@ -1706,9 +1625,8 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, /* -------------------------------------------------------------------- */ /* Try worldfile. */ /* -------------------------------------------------------------------- */ - if( GDALGetDescription(hDS) != NULL - && GDALReadWorldFile(GDALGetDescription(hDS), "wld", - padfGeoTransform) ) { + if (GDALGetDescription(hDS) != NULL && + GDALReadWorldFile(GDALGetDescription(hDS), "wld", padfGeoTransform)) { return MS_SUCCESS; } @@ -1724,13 +1642,13 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, rect = layer->extent; padfGeoTransform[0] = rect.minx; - padfGeoTransform[1] = (rect.maxx - rect.minx) / - (double) GDALGetRasterXSize( hDS ); + padfGeoTransform[1] = + (rect.maxx - rect.minx) / (double)GDALGetRasterXSize(hDS); padfGeoTransform[2] = 0; padfGeoTransform[3] = rect.maxy; padfGeoTransform[4] = 0; - padfGeoTransform[5] = (rect.miny - rect.maxy) / - (double) GDALGetRasterYSize( hDS ); + padfGeoTransform[5] = + (rect.miny - rect.maxy) / (double)GDALGetRasterYSize(hDS); return MS_SUCCESS; } @@ -1757,47 +1675,48 @@ int msGetGDALGeoTransform( GDALDatasetH hDS, mapObj *map, layerObj *layer, /************************************************************************/ static int -msDrawRasterLayerGDAL_RawMode( - mapObj *map, layerObj *layer, imageObj *image, GDALDatasetH hDS, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - int dst_xoff, int dst_yoff, int dst_xsize, int dst_ysize ) +msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image, + GDALDatasetH hDS, int src_xoff, int src_yoff, + int src_xsize, int src_ysize, int dst_xoff, + int dst_yoff, int dst_xsize, int dst_ysize) { void *pBuffer; GDALDataType eDataType; int *band_list, band_count; - int i, j, k, band; + int i, j, k, band; CPLErr eErr; float *f_nodatas = NULL; unsigned char *b_nodatas = NULL; GInt16 *i_nodatas = NULL; - int got_nodata=FALSE; + int got_nodata = FALSE; rasterBufferObj *mask_rb = NULL; rasterBufferObj s_mask_rb; - if(layer->mask) { + if (layer->mask) { int ret; - layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map,layer->mask)); + layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map, layer->mask)); mask_rb = &s_mask_rb; memset(mask_rb, 0, sizeof(s_mask_rb)); - ret = MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,mask_rb); - if(ret != MS_SUCCESS) + ret = MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, mask_rb); + if (ret != MS_SUCCESS) return -1; } - if( image->format->bands > 256 ) { - msSetError( MS_IMGERR, "Too many bands (more than 256).", - "msDrawRasterLayerGDAL_RawMode()" ); + if (image->format->bands > 256) { + msSetError(MS_IMGERR, "Too many bands (more than 256).", + "msDrawRasterLayerGDAL_RawMode()"); return -1; } /* -------------------------------------------------------------------- */ /* What data type do we need? */ /* -------------------------------------------------------------------- */ - if( image->format->imagemode == MS_IMAGEMODE_INT16 ) + if (image->format->imagemode == MS_IMAGEMODE_INT16) eDataType = GDT_Int16; - else if( image->format->imagemode == MS_IMAGEMODE_FLOAT32 ) + else if (image->format->imagemode == MS_IMAGEMODE_FLOAT32) eDataType = GDT_Float32; - else if( image->format->imagemode == MS_IMAGEMODE_BYTE ) + else if (image->format->imagemode == MS_IMAGEMODE_BYTE) eDataType = GDT_Byte; else return -1; @@ -1805,90 +1724,89 @@ msDrawRasterLayerGDAL_RawMode( /* -------------------------------------------------------------------- */ /* Work out the band list. */ /* -------------------------------------------------------------------- */ - band_list = msGetGDALBandList( layer, hDS, image->format->bands, - &band_count ); - if( band_list == NULL ) + band_list = msGetGDALBandList(layer, hDS, image->format->bands, &band_count); + if (band_list == NULL) return -1; - if( band_count != image->format->bands ) { - free( band_list ); - msSetError( MS_IMGERR, "BANDS PROCESSING directive has wrong number of bands, expected %d, got %d.", - "msDrawRasterLayerGDAL_RawMode()", - image->format->bands, band_count ); + if (band_count != image->format->bands) { + free(band_list); + msSetError(MS_IMGERR, + "BANDS PROCESSING directive has wrong number of bands, expected " + "%d, got %d.", + "msDrawRasterLayerGDAL_RawMode()", image->format->bands, + band_count); return -1; } /* -------------------------------------------------------------------- */ /* Do we have nodata values? */ /* -------------------------------------------------------------------- */ - f_nodatas = (float *) calloc(sizeof(float),band_count); + f_nodatas = (float *)calloc(sizeof(float), band_count); if (f_nodatas == NULL) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawRasterLayerGDAL_RawMode()", - __FILE__, __LINE__, (unsigned int)(sizeof(float)*band_count)); - free( band_list ); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msDrawRasterLayerGDAL_RawMode()", __FILE__, __LINE__, + (unsigned int)(sizeof(float) * band_count)); + free(band_list); return -1; } - if( band_count <= 3 - && (layer->offsite.red != -1 - || layer->offsite.green != -1 - || layer->offsite.blue != -1) ) { - if( band_count > 0 ) + if (band_count <= 3 && + (layer->offsite.red != -1 || layer->offsite.green != -1 || + layer->offsite.blue != -1)) { + if (band_count > 0) f_nodatas[0] = layer->offsite.red; - if( band_count > 1 ) + if (band_count > 1) f_nodatas[1] = layer->offsite.green; - if( band_count > 2 ) + if (band_count > 2) f_nodatas[2] = layer->offsite.blue; got_nodata = TRUE; } - if( !got_nodata ) { + if (!got_nodata) { got_nodata = TRUE; - for( band = 0; band < band_count && got_nodata; band++ ) { + for (band = 0; band < band_count && got_nodata; band++) { f_nodatas[band] = msGetGDALNoDataValue( - layer, GDALGetRasterBand(hDS,band_list[band]), &got_nodata ); + layer, GDALGetRasterBand(hDS, band_list[band]), &got_nodata); } } - if( !got_nodata ) { - free( f_nodatas ); + if (!got_nodata) { + free(f_nodatas); f_nodatas = NULL; - } else if( eDataType == GDT_Byte ) { - b_nodatas = (unsigned char *) f_nodatas; - for( band = 0; band < band_count; band++ ) - b_nodatas[band] = (unsigned char) f_nodatas[band]; - } else if( eDataType == GDT_Int16 ) { - i_nodatas = (GInt16 *) f_nodatas; - for( band = 0; band < band_count; band++ ) - i_nodatas[band] = (GInt16) f_nodatas[band]; + } else if (eDataType == GDT_Byte) { + b_nodatas = (unsigned char *)f_nodatas; + for (band = 0; band < band_count; band++) + b_nodatas[band] = (unsigned char)f_nodatas[band]; + } else if (eDataType == GDT_Int16) { + i_nodatas = (GInt16 *)f_nodatas; + for (band = 0; band < band_count; band++) + i_nodatas[band] = (GInt16)f_nodatas[band]; } /* -------------------------------------------------------------------- */ /* Allocate buffer, and read data into it. */ /* -------------------------------------------------------------------- */ - pBuffer = malloc(dst_xsize * dst_ysize * image->format->bands - * (GDALGetDataTypeSize(eDataType)/8) ); - if( pBuffer == NULL ) { - msSetError(MS_MEMERR, - "Allocating work image of size %dx%d failed.", - "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize ); - free( band_list ); - free( f_nodatas ); + pBuffer = malloc(dst_xsize * dst_ysize * image->format->bands * + (GDALGetDataTypeSize(eDataType) / 8)); + if (pBuffer == NULL) { + msSetError(MS_MEMERR, "Allocating work image of size %dx%d failed.", + "msDrawRasterLayerGDAL()", dst_xsize, dst_ysize); + free(band_list); + free(f_nodatas); return -1; } - eErr = GDALDatasetRasterIO( hDS, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - pBuffer, dst_xsize, dst_ysize, eDataType, - image->format->bands, band_list, - 0, 0, 0 ); - free( band_list ); + eErr = + GDALDatasetRasterIO(hDS, GF_Read, src_xoff, src_yoff, src_xsize, + src_ysize, pBuffer, dst_xsize, dst_ysize, eDataType, + image->format->bands, band_list, 0, 0, 0); + free(band_list); - if( eErr != CE_None ) { - msSetError( MS_IOERR, "GDALRasterIO() failed: %s", - "msDrawRasterLayerGDAL_RawMode()", CPLGetLastErrorMsg() ); - free( pBuffer ); - free( f_nodatas ); + if (eErr != CE_None) { + msSetError(MS_IOERR, "GDALRasterIO() failed: %s", + "msDrawRasterLayerGDAL_RawMode()", CPLGetLastErrorMsg()); + free(pBuffer); + free(f_nodatas); return -1; } @@ -1896,59 +1814,56 @@ msDrawRasterLayerGDAL_RawMode( /* Transfer the data to the imageObj. */ /* -------------------------------------------------------------------- */ k = 0; - for( band = 0; band < image->format->bands; band++ ) { - for( i = dst_yoff; i < dst_yoff + dst_ysize; i++ ) { - if( image->format->imagemode == MS_IMAGEMODE_INT16 ) { - for( j = dst_xoff; j < dst_xoff + dst_xsize; j++ ) { - int off = j + i * image->width - + band*image->width*image->height; + for (band = 0; band < image->format->bands; band++) { + for (i = dst_yoff; i < dst_yoff + dst_ysize; i++) { + if (image->format->imagemode == MS_IMAGEMODE_INT16) { + for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) { + int off = j + i * image->width + band * image->width * image->height; int off_mask = j + i * image->width; - if( ( i_nodatas && ((GInt16 *) pBuffer)[k] == i_nodatas[band] ) - || SKIP_MASK(j,i)) { + if ((i_nodatas && ((GInt16 *)pBuffer)[k] == i_nodatas[band]) || + SKIP_MASK(j, i)) { k++; continue; } - image->img.raw_16bit[off] = ((GInt16 *) pBuffer)[k++]; - MS_SET_BIT(image->img_mask,off_mask); + image->img.raw_16bit[off] = ((GInt16 *)pBuffer)[k++]; + MS_SET_BIT(image->img_mask, off_mask); } - } else if( image->format->imagemode == MS_IMAGEMODE_FLOAT32 ) { - for( j = dst_xoff; j < dst_xoff + dst_xsize; j++ ) { - int off = j + i * image->width - + band*image->width*image->height; + } else if (image->format->imagemode == MS_IMAGEMODE_FLOAT32) { + for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) { + int off = j + i * image->width + band * image->width * image->height; int off_mask = j + i * image->width; - if( ( f_nodatas && ((float *) pBuffer)[k] == f_nodatas[band] ) - || SKIP_MASK(j,i)) { + if ((f_nodatas && ((float *)pBuffer)[k] == f_nodatas[band]) || + SKIP_MASK(j, i)) { k++; continue; } - image->img.raw_float[off] = ((float *) pBuffer)[k++]; - MS_SET_BIT(image->img_mask,off_mask); + image->img.raw_float[off] = ((float *)pBuffer)[k++]; + MS_SET_BIT(image->img_mask, off_mask); } - } else if( image->format->imagemode == MS_IMAGEMODE_BYTE ) { - for( j = dst_xoff; j < dst_xoff + dst_xsize; j++ ) { - int off = j + i * image->width - + band*image->width*image->height; + } else if (image->format->imagemode == MS_IMAGEMODE_BYTE) { + for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) { + int off = j + i * image->width + band * image->width * image->height; int off_mask = j + i * image->width; - if( ( b_nodatas && ((unsigned char *) pBuffer)[k] == b_nodatas[band] ) - || SKIP_MASK(j,i)) { + if ((b_nodatas && ((unsigned char *)pBuffer)[k] == b_nodatas[band]) || + SKIP_MASK(j, i)) { k++; continue; } - image->img.raw_byte[off] = ((unsigned char *) pBuffer)[k++]; - MS_SET_BIT(image->img_mask,off_mask); + image->img.raw_byte[off] = ((unsigned char *)pBuffer)[k++]; + MS_SET_BIT(image->img_mask, off_mask); } } } } - free( pBuffer ); - free( f_nodatas ); + free(pBuffer); + free(f_nodatas); return 0; } @@ -1965,129 +1880,123 @@ msDrawRasterLayerGDAL_RawMode( /* the 16bit cases at the cost of some complication. */ /************************************************************************/ -static int -msDrawRasterLayerGDAL_16BitClassification( - mapObj *map, layerObj *layer, rasterBufferObj *rb, - GDALRasterBandH hBand, - int src_xoff, int src_yoff, int src_xsize, int src_ysize, - int dst_xoff, int dst_yoff, int dst_xsize, int dst_ysize ) +static int msDrawRasterLayerGDAL_16BitClassification( + mapObj *map, layerObj *layer, rasterBufferObj *rb, GDALRasterBandH hBand, + int src_xoff, int src_yoff, int src_xsize, int src_ysize, int dst_xoff, + int dst_yoff, int dst_xsize, int dst_ysize) { float *pafRawData; - double dfScaleMin=0.0, dfScaleMax=0.0, dfScaleRatio; - int nPixelCount = dst_xsize * dst_ysize, i, nBucketCount=0; + double dfScaleMin = 0.0, dfScaleMax = 0.0, dfScaleRatio; + int nPixelCount = dst_xsize * dst_ysize, i, nBucketCount = 0; GDALDataType eDataType; - float fDataMin=0.0, fDataMax=255.0, fNoDataValue; + float fDataMin = 0.0, fDataMax = 255.0, fNoDataValue; const char *pszScaleInfo; const char *pszBuckets; - int *cmap, c, j, k, bGotNoData = FALSE, bGotFirstValue; + int *cmap, c, j, k, bGotNoData = FALSE, bGotFirstValue; unsigned char *rb_cmap[4]; CPLErr eErr; rasterBufferObj *mask_rb = NULL; rasterBufferObj s_mask_rb; int lastC; - struct mstimeval starttime={0}, endtime={0}; + struct mstimeval starttime = {0}, endtime = {0}; const char *pszClassifyScaled; int bClassifyScaled = FALSE; - if(layer->mask) { + if (layer->mask) { int ret; - layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map,layer->mask)); + layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map, layer->mask)); mask_rb = &s_mask_rb; memset(mask_rb, 0, sizeof(s_mask_rb)); - ret = MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,mask_rb); - if(ret != MS_SUCCESS) + ret = MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, mask_rb); + if (ret != MS_SUCCESS) return -1; } - assert( rb->type == MS_BUFFER_BYTE_RGBA ); + assert(rb->type == MS_BUFFER_BYTE_RGBA); /* ==================================================================== */ /* Read the requested data in one gulp into a floating point */ /* buffer. */ /* ==================================================================== */ - pafRawData = (float *) malloc(sizeof(float) * dst_xsize * dst_ysize ); - if( pafRawData == NULL ) { - msSetError( MS_MEMERR, "Out of memory allocating working buffer.", - "msDrawRasterLayerGDAL_16BitClassification()" ); + pafRawData = (float *)malloc(sizeof(float) * dst_xsize * dst_ysize); + if (pafRawData == NULL) { + msSetError(MS_MEMERR, "Out of memory allocating working buffer.", + "msDrawRasterLayerGDAL_16BitClassification()"); return -1; } - eErr = GDALRasterIO( hBand, GF_Read, - src_xoff, src_yoff, src_xsize, src_ysize, - pafRawData, dst_xsize, dst_ysize, GDT_Float32, 0, 0 ); + eErr = GDALRasterIO(hBand, GF_Read, src_xoff, src_yoff, src_xsize, src_ysize, + pafRawData, dst_xsize, dst_ysize, GDT_Float32, 0, 0); - if( eErr != CE_None ) { - free( pafRawData ); - msSetError( MS_IOERR, "GDALRasterIO() failed: %s", - "msDrawRasterLayerGDAL_16BitClassification()", - CPLGetLastErrorMsg() ); + if (eErr != CE_None) { + free(pafRawData); + msSetError(MS_IOERR, "GDALRasterIO() failed: %s", + "msDrawRasterLayerGDAL_16BitClassification()", + CPLGetLastErrorMsg()); return -1; } - fNoDataValue = (float) msGetGDALNoDataValue( layer, hBand, &bGotNoData ); + fNoDataValue = (float)msGetGDALNoDataValue(layer, hBand, &bGotNoData); /* ==================================================================== */ /* Determine scaling. */ /* ==================================================================== */ - eDataType = GDALGetRasterDataType( hBand ); + eDataType = GDALGetRasterDataType(hBand); /* -------------------------------------------------------------------- */ /* Scan for absolute min/max of this block. */ /* -------------------------------------------------------------------- */ bGotFirstValue = FALSE; - for( i = 1; i < nPixelCount; i++ ) { - if( bGotNoData && IsNoData(pafRawData[i], fNoDataValue) ) + for (i = 1; i < nPixelCount; i++) { + if (bGotNoData && IsNoData(pafRawData[i], fNoDataValue)) continue; - if( CPLIsNan(pafRawData[i]) ) + if (CPLIsNan(pafRawData[i])) continue; - if( !bGotFirstValue ) { + if (!bGotFirstValue) { fDataMin = fDataMax = pafRawData[i]; bGotFirstValue = TRUE; } else { - fDataMin = MS_MIN(fDataMin,pafRawData[i]); - fDataMax = MS_MAX(fDataMax,pafRawData[i]); + fDataMin = MS_MIN(fDataMin, pafRawData[i]); + fDataMax = MS_MAX(fDataMax, pafRawData[i]); } } /* -------------------------------------------------------------------- */ /* Fetch the scale classification option. */ /* -------------------------------------------------------------------- */ - pszClassifyScaled = CSLFetchNameValue( layer->processing, "CLASSIFY_SCALED" ); - if( pszClassifyScaled != NULL ) + pszClassifyScaled = CSLFetchNameValue(layer->processing, "CLASSIFY_SCALED"); + if (pszClassifyScaled != NULL) bClassifyScaled = CSLTestBoolean(pszClassifyScaled); /* -------------------------------------------------------------------- */ /* Fetch the scale processing option. */ /* -------------------------------------------------------------------- */ - pszBuckets = CSLFetchNameValue( layer->processing, "SCALE_BUCKETS" ); - pszScaleInfo = CSLFetchNameValue( layer->processing, "SCALE" ); + pszBuckets = CSLFetchNameValue(layer->processing, "SCALE_BUCKETS"); + pszScaleInfo = CSLFetchNameValue(layer->processing, "SCALE"); - if( pszScaleInfo != NULL ) { + if (pszScaleInfo != NULL) { char **papszTokens; - papszTokens = CSLTokenizeStringComplex( pszScaleInfo, " ,", - FALSE, FALSE ); - if( CSLCount(papszTokens) == 1 - && EQUAL(papszTokens[0],"AUTO") ) { + papszTokens = CSLTokenizeStringComplex(pszScaleInfo, " ,", FALSE, FALSE); + if (CSLCount(papszTokens) == 1 && EQUAL(papszTokens[0], "AUTO")) { dfScaleMin = dfScaleMax = 0.0; - } else if( CSLCount(papszTokens) != 2 ) { - free( pafRawData ); - CSLDestroy( papszTokens ); - msSetError( MS_MISCERR, - "SCALE PROCESSING option unparsable for layer %s.", - "msDrawGDAL()", - layer->name ); + } else if (CSLCount(papszTokens) != 2) { + free(pafRawData); + CSLDestroy(papszTokens); + msSetError(MS_MISCERR, "SCALE PROCESSING option unparsable for layer %s.", + "msDrawGDAL()", layer->name); return -1; } else { dfScaleMin = atof(papszTokens[0]); dfScaleMax = atof(papszTokens[1]); } - CSLDestroy( papszTokens ); + CSLDestroy(papszTokens); } /* -------------------------------------------------------------------- */ @@ -2096,23 +2005,23 @@ msDrawRasterLayerGDAL_16BitClassification( /* TODO: Treat Int32 and UInt32 case the same way *if* the min */ /* and max are less than 65536 apart. */ /* -------------------------------------------------------------------- */ - if( eDataType == GDT_Byte || eDataType == GDT_Int16 - || eDataType == GDT_UInt16 ) { - if( pszScaleInfo == NULL ) { + if (eDataType == GDT_Byte || eDataType == GDT_Int16 || + eDataType == GDT_UInt16) { + if (pszScaleInfo == NULL) { dfScaleMin = fDataMin - 0.5; dfScaleMax = fDataMax + 0.5; } - if( pszBuckets == NULL ) { - nBucketCount = (int) floor(fDataMax - fDataMin + 1.1); + if (pszBuckets == NULL) { + nBucketCount = (int)floor(fDataMax - fDataMin + 1.1); } } /* -------------------------------------------------------------------- */ /* General case if no scaling values provided in mapfile. */ /* -------------------------------------------------------------------- */ - else if( dfScaleMin == 0.0 && dfScaleMax == 0.0 ) { - double dfEpsilon = (fDataMax - fDataMin) / (65536*2); + else if (dfScaleMin == 0.0 && dfScaleMax == 0.0) { + double dfEpsilon = (fDataMax - fDataMin) / (65536 * 2); dfScaleMin = fDataMin - dfEpsilon; dfScaleMax = fDataMax + dfEpsilon; } @@ -2120,17 +2029,17 @@ msDrawRasterLayerGDAL_16BitClassification( /* -------------------------------------------------------------------- */ /* How many buckets? Only set if we don't already have a value. */ /* -------------------------------------------------------------------- */ - if( pszBuckets == NULL ) { - if( nBucketCount == 0 ) + if (pszBuckets == NULL) { + if (nBucketCount == 0) nBucketCount = 65536; } else { nBucketCount = atoi(pszBuckets); - if( nBucketCount < 2 ) { - free( pafRawData ); - msSetError( MS_MISCERR, - "SCALE_BUCKETS PROCESSING option is not a value of 2 or more: %s.", - "msDrawRasterLayerGDAL_16BitClassification()", - pszBuckets ); + if (nBucketCount < 2) { + free(pafRawData); + msSetError( + MS_MISCERR, + "SCALE_BUCKETS PROCESSING option is not a value of 2 or more: %s.", + "msDrawRasterLayerGDAL_16BitClassification()", pszBuckets); return -1; } } @@ -2138,87 +2047,94 @@ msDrawRasterLayerGDAL_16BitClassification( /* -------------------------------------------------------------------- */ /* Compute scaling ratio. */ /* -------------------------------------------------------------------- */ - if( dfScaleMax == dfScaleMin ) + if (dfScaleMax == dfScaleMin) dfScaleMax = dfScaleMin + 1.0; dfScaleRatio = nBucketCount / (dfScaleMax - dfScaleMin); - if( layer->debug > 0 ) - msDebug( "msDrawRasterGDAL_16BitClassification(%s):\n" - " scaling to %d buckets from range=%g,%g.\n", - layer->name, nBucketCount, dfScaleMin, dfScaleMax ); + if (layer->debug > 0) + msDebug("msDrawRasterGDAL_16BitClassification(%s):\n" + " scaling to %d buckets from range=%g,%g.\n", + layer->name, nBucketCount, dfScaleMin, dfScaleMax); /* ==================================================================== */ /* Compute classification lookup table. */ /* ==================================================================== */ - cmap = (int *) msSmallCalloc(sizeof(int),nBucketCount); - rb_cmap[0] = (unsigned char *) msSmallCalloc(1,nBucketCount); - rb_cmap[1] = (unsigned char *) msSmallCalloc(1,nBucketCount); - rb_cmap[2] = (unsigned char *) msSmallCalloc(1,nBucketCount); - rb_cmap[3] = (unsigned char *) msSmallCalloc(1,nBucketCount); + cmap = (int *)msSmallCalloc(sizeof(int), nBucketCount); + rb_cmap[0] = (unsigned char *)msSmallCalloc(1, nBucketCount); + rb_cmap[1] = (unsigned char *)msSmallCalloc(1, nBucketCount); + rb_cmap[2] = (unsigned char *)msSmallCalloc(1, nBucketCount); + rb_cmap[3] = (unsigned char *)msSmallCalloc(1, nBucketCount); - - if(layer->debug >= MS_DEBUGLEVEL_TUNING) { + if (layer->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&starttime, NULL); } lastC = -1; - for(i=0; i < nBucketCount; i++) { + for (i = 0; i < nBucketCount; i++) { double dfOriginalValue; cmap[i] = -1; // i = (int) ((dfOriginalValue - dfScaleMin) * dfScaleRatio+1)-1; - dfOriginalValue = (i+0.5) / dfScaleRatio + dfScaleMin; - - /* The creation of buckets takes a significant time when they are many, and many classes - as well. When iterating over buckets, a faster strategy is to reuse first the last used - class index. */ - if(bClassifyScaled == TRUE) - c = msGetClass_FloatRGB_WithFirstClassToTry(layer, (float) i, -1, -1, -1, lastC); + dfOriginalValue = (i + 0.5) / dfScaleRatio + dfScaleMin; + + /* The creation of buckets takes a significant time when they are many, and + many classes as well. When iterating over buckets, a faster strategy is + to reuse first the last used class index. */ + if (bClassifyScaled == TRUE) + c = msGetClass_FloatRGB_WithFirstClassToTry(layer, (float)i, -1, -1, -1, + lastC); else - c = msGetClass_FloatRGB_WithFirstClassToTry(layer, (float) dfOriginalValue, -1, -1, -1, lastC); + c = msGetClass_FloatRGB_WithFirstClassToTry(layer, (float)dfOriginalValue, + -1, -1, -1, lastC); lastC = c; - if( c != -1 ) { + if (c != -1) { int s; int styleindex = 0; /* change colour based on colour range? */ - if( MS_VALID_COLOR(layer->class[c]->styles[0]->mincolor) ) - { + if (MS_VALID_COLOR(layer->class[c] -> styles[0] -> mincolor)) { styleindex = -1; - for(s=0; sclass[c]->numstyles; s++) { - if( MS_VALID_COLOR(layer->class[c]->styles[s]->mincolor) - && MS_VALID_COLOR(layer->class[c]->styles[s]->maxcolor) - && dfOriginalValue + 0.5 / dfScaleRatio >= layer->class[c]->styles[s]->minvalue - && dfOriginalValue - 0.5 / dfScaleRatio <= layer->class[c]->styles[s]->maxvalue ) { - msValueToRange(layer->class[c]->styles[s],dfOriginalValue, MS_COLORSPACE_RGB); + for (s = 0; s < layer->class[c] -> numstyles; s++) { + if (MS_VALID_COLOR(layer->class[c] -> styles[s] -> mincolor) && + MS_VALID_COLOR(layer->class[c] -> styles[s] -> maxcolor) && + dfOriginalValue + 0.5 / dfScaleRatio >= + layer->class[c] -> styles[s] + -> minvalue && dfOriginalValue - 0.5 / dfScaleRatio <= + layer -> class[c] -> styles[s] -> maxvalue) { + msValueToRange(layer->class[c] -> styles[s], dfOriginalValue, + MS_COLORSPACE_RGB); styleindex = s; break; } } } - if( styleindex >= 0 ) { - if( MS_TRANSPARENT_COLOR(layer->class[c]->styles[styleindex]->color) ) { + if (styleindex >= 0) { + if (MS_TRANSPARENT_COLOR( + layer->class[c] -> styles[styleindex] -> color)) { /* leave it transparent */ - } else if( MS_VALID_COLOR(layer->class[c]->styles[styleindex]->color)) { + } else if (MS_VALID_COLOR( + layer->class[c] -> styles[styleindex] -> color)) { /* use class color */ rb_cmap[0][i] = layer->class[c]->styles[styleindex]->color.red; rb_cmap[1][i] = layer->class[c]->styles[styleindex]->color.green; rb_cmap[2][i] = layer->class[c]->styles[styleindex]->color.blue; - rb_cmap[3][i] = (255*layer->class[c]->styles[styleindex]->opacity / 100); + rb_cmap[3][i] = + (255 * layer->class[c] -> styles[styleindex] -> opacity / 100); } } } } - if(layer->debug >= MS_DEBUGLEVEL_TUNING) { + if (layer->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&endtime, NULL); - msDebug("msDrawRasterGDAL_16BitClassification() bucket creation time: %.3fs\n", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + msDebug( + "msDrawRasterGDAL_16BitClassification() bucket creation time: %.3fs\n", + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } /* ==================================================================== */ @@ -2226,53 +2142,50 @@ msDrawRasterLayerGDAL_16BitClassification( /* ==================================================================== */ k = 0; - for( i = dst_yoff; i < dst_yoff + dst_ysize; i++ ) { - for( j = dst_xoff; j < dst_xoff + dst_xsize; j++ ) { + for (i = dst_yoff; i < dst_yoff + dst_ysize; i++) { + for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) { float fRawValue = pafRawData[k++]; - int iMapIndex; + int iMapIndex; /* * Skip nodata pixels ... no processing. */ - if( bGotNoData && IsNoData(fRawValue, fNoDataValue) ) + if (bGotNoData && IsNoData(fRawValue, fNoDataValue)) continue; - if( CPLIsNan(fRawValue) ) + if (CPLIsNan(fRawValue)) continue; - if(SKIP_MASK(j,i)) + if (SKIP_MASK(j, i)) continue; /* * The funny +1/-1 is to avoid odd rounding around zero. * We could use floor() but sometimes it is expensive. */ - iMapIndex = (int) ((fRawValue - dfScaleMin) * dfScaleRatio+1)-1; + iMapIndex = (int)((fRawValue - dfScaleMin) * dfScaleRatio + 1) - 1; - if( iMapIndex >= nBucketCount || iMapIndex < 0 ) { + if (iMapIndex >= nBucketCount || iMapIndex < 0) { continue; } /* currently we never have partial alpha so keep simple */ - if( rb_cmap[3][iMapIndex] > 0 ) - RB_SET_PIXEL( rb, j, i, - rb_cmap[0][iMapIndex], - rb_cmap[1][iMapIndex], - rb_cmap[2][iMapIndex], - rb_cmap[3][iMapIndex] ); + if (rb_cmap[3][iMapIndex] > 0) + RB_SET_PIXEL(rb, j, i, rb_cmap[0][iMapIndex], rb_cmap[1][iMapIndex], + rb_cmap[2][iMapIndex], rb_cmap[3][iMapIndex]); } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ - free( pafRawData ); - free( cmap ); - free( rb_cmap[0] ); - free( rb_cmap[1] ); - free( rb_cmap[2] ); - free( rb_cmap[3] ); + free(pafRawData); + free(cmap); + free(rb_cmap[0]); + free(rb_cmap[1]); + free(rb_cmap[2]); + free(rb_cmap[3]); - assert( k == dst_xsize * dst_ysize ); + assert(k == dst_xsize * dst_ysize); return 0; } @@ -2280,17 +2193,14 @@ msDrawRasterLayerGDAL_16BitClassification( /************************************************************************/ /* IsNoData() */ /************************************************************************/ -static bool -IsNoData( double dfValue, double dfNoDataValue ) -{ +static bool IsNoData(double dfValue, double dfNoDataValue) { return isnan(dfValue) || dfValue == dfNoDataValue; } /************************************************************************/ /* msGetGDALNoDataValue() */ /************************************************************************/ -double -msGetGDALNoDataValue( layerObj *layer, void *hBand, int *pbGotNoData ) +double msGetGDALNoDataValue(layerObj *layer, void *hBand, int *pbGotNoData) { const char *pszNODATAOpt; @@ -2300,11 +2210,11 @@ msGetGDALNoDataValue( layerObj *layer, void *hBand, int *pbGotNoData ) /* -------------------------------------------------------------------- */ /* Check for a NODATA setting in the .map file. */ /* -------------------------------------------------------------------- */ - pszNODATAOpt = CSLFetchNameValue(layer->processing,"NODATA"); - if( pszNODATAOpt != NULL ) { - if( EQUAL(pszNODATAOpt,"OFF") || strlen(pszNODATAOpt) == 0 ) + pszNODATAOpt = CSLFetchNameValue(layer->processing, "NODATA"); + if (pszNODATAOpt != NULL) { + if (EQUAL(pszNODATAOpt, "OFF") || strlen(pszNODATAOpt) == 0) return -1234567.0; - if( !EQUAL(pszNODATAOpt,"AUTO") ) { + if (!EQUAL(pszNODATAOpt, "AUTO")) { *pbGotNoData = TRUE; return atof(pszNODATAOpt); } @@ -2313,10 +2223,10 @@ msGetGDALNoDataValue( layerObj *layer, void *hBand, int *pbGotNoData ) /* -------------------------------------------------------------------- */ /* Check for a NODATA setting on the raw file. */ /* -------------------------------------------------------------------- */ - if( hBand == NULL ) + if (hBand == NULL) return -1234567.0; else - return GDALGetRasterNoDataValue( hBand, pbGotNoData ); + return GDALGetRasterNoDataValue(hBand, pbGotNoData); } /************************************************************************/ @@ -2329,19 +2239,18 @@ msGetGDALNoDataValue( layerObj *layer, void *hBand, int *pbGotNoData ) /* returns malloc() list of band numbers (*band_count long). */ /************************************************************************/ -int *msGetGDALBandList( layerObj *layer, void *hDS, - int max_bands, int *band_count ) +int *msGetGDALBandList(layerObj *layer, void *hDS, int max_bands, + int *band_count) { int i, file_bands; int *band_list = NULL; - file_bands = GDALGetRasterCount( hDS ); - if( file_bands == 0 ) { - msSetError( MS_IMGERR, - "Attempt to operate on GDAL file with no bands, layer=%s.", - "msGetGDALBandList()", - layer->name ); + file_bands = GDALGetRasterCount(hDS); + if (file_bands == 0) { + msSetError(MS_IMGERR, + "Attempt to operate on GDAL file with no bands, layer=%s.", + "msGetGDALBandList()", layer->name); return NULL; } @@ -2349,19 +2258,19 @@ int *msGetGDALBandList( layerObj *layer, void *hDS, /* -------------------------------------------------------------------- */ /* Use all (or first) bands. */ /* -------------------------------------------------------------------- */ - if( CSLFetchNameValue( layer->processing, "BANDS" ) == NULL ) { - if( max_bands > 0 ) - *band_count = MS_MIN(file_bands,max_bands); + if (CSLFetchNameValue(layer->processing, "BANDS") == NULL) { + if (max_bands > 0) + *band_count = MS_MIN(file_bands, max_bands); else *band_count = file_bands; - band_list = (int *) malloc(sizeof(int) * *band_count ); + band_list = (int *)malloc(sizeof(int) * *band_count); /* FIXME MS_CHECK_ALLOC leaks papszItems */ MS_CHECK_ALLOC(band_list, sizeof(int) * *band_count, NULL); - for( i = 0; i < *band_count; i++ ) - band_list[i] = i+1; + for (i = 0; i < *band_count; i++) + band_list[i] = i + 1; return band_list; } @@ -2370,38 +2279,40 @@ int *msGetGDALBandList( layerObj *layer, void *hDS, /* -------------------------------------------------------------------- */ else { char **papszItems = CSLTokenizeStringComplex( - CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE ); + CSLFetchNameValue(layer->processing, "BANDS"), " ,", FALSE, FALSE); - if( CSLCount(papszItems) == 0 ) { - CSLDestroy( papszItems ); - msSetError( MS_IMGERR, "BANDS PROCESSING directive has no items.", - "msGetGDALBandList()" ); + if (CSLCount(papszItems) == 0) { + CSLDestroy(papszItems); + msSetError(MS_IMGERR, "BANDS PROCESSING directive has no items.", + "msGetGDALBandList()"); return NULL; - } else if( max_bands != 0 && CSLCount(papszItems) > max_bands ) { - msSetError( MS_IMGERR, "BANDS PROCESSING directive has wrong number of bands, expected at most %d, got %d.", - "msGetGDALBandList()", - max_bands, CSLCount(papszItems) ); - CSLDestroy( papszItems ); + } else if (max_bands != 0 && CSLCount(papszItems) > max_bands) { + msSetError(MS_IMGERR, + "BANDS PROCESSING directive has wrong number of bands, " + "expected at most %d, got %d.", + "msGetGDALBandList()", max_bands, CSLCount(papszItems)); + CSLDestroy(papszItems); return NULL; } *band_count = CSLCount(papszItems); - band_list = (int *) malloc(sizeof(int) * *band_count); + band_list = (int *)malloc(sizeof(int) * *band_count); MS_CHECK_ALLOC(band_list, sizeof(int) * *band_count, NULL); - for( i = 0; i < *band_count; i++ ) { + for (i = 0; i < *band_count; i++) { band_list[i] = atoi(papszItems[i]); - if( band_list[i] < 1 || band_list[i] > GDALGetRasterCount(hDS) ) { - msSetError( MS_IMGERR, - "BANDS PROCESSING directive includes illegal band '%s', should be from 1 to %d.", - "msGetGDALBandList()", - papszItems[i], GDALGetRasterCount(hDS) ); - CSLDestroy( papszItems ); - free( band_list ); + if (band_list[i] < 1 || band_list[i] > GDALGetRasterCount(hDS)) { + msSetError(MS_IMGERR, + "BANDS PROCESSING directive includes illegal band '%s', " + "should be from 1 to %d.", + "msGetGDALBandList()", papszItems[i], + GDALGetRasterCount(hDS)); + CSLDestroy(papszItems); + free(band_list); return NULL; } } - CSLDestroy( papszItems ); + CSLDestroy(papszItems); return band_list; } diff --git a/mapdummyrenderer.c b/mapdummyrenderer.c index 4c2d571af2..e4d967f63d 100644 --- a/mapdummyrenderer.c +++ b/mapdummyrenderer.c @@ -29,202 +29,200 @@ #include "mapserver.h" -int renderLineDummy(imageObj *img, shapeObj *p, strokeStyleObj *style) -{ +int renderLineDummy(imageObj *img, shapeObj *p, strokeStyleObj *style) { (void)img; (void)p; (void)style; - msSetError(MS_RENDERERERR,"renderLine not implemented","renderLine()"); + msSetError(MS_RENDERERERR, "renderLine not implemented", "renderLine()"); return MS_FAILURE; } -int renderPolygonDummy(imageObj *img, shapeObj *p, colorObj *color) -{ +int renderPolygonDummy(imageObj *img, shapeObj *p, colorObj *color) { (void)img; (void)p; (void)color; - msSetError(MS_RENDERERERR,"renderPolygon not implemented","renderPolygon()"); + msSetError(MS_RENDERERERR, "renderPolygon not implemented", + "renderPolygon()"); return MS_FAILURE; } -int renderPolygonTiledDummy(imageObj *img, shapeObj *p, imageObj *tile) -{ +int renderPolygonTiledDummy(imageObj *img, shapeObj *p, imageObj *tile) { (void)img; (void)p; (void)tile; - msSetError(MS_RENDERERERR,"renderPolygonTiled not implemented","renderPolygonTiled()"); + msSetError(MS_RENDERERERR, "renderPolygonTiled not implemented", + "renderPolygonTiled()"); return MS_FAILURE; } -int renderLineTiledDummy(imageObj *img, shapeObj *p, imageObj *tile) -{ +int renderLineTiledDummy(imageObj *img, shapeObj *p, imageObj *tile) { (void)img; (void)p; (void)tile; - msSetError(MS_RENDERERERR,"renderLineTiled not implemented","renderLineTiled()"); + msSetError(MS_RENDERERERR, "renderLineTiled not implemented", + "renderLineTiled()"); return MS_FAILURE; } int renderRasterGlyphsDummy(imageObj *img, double x, double y, int fontIndex, - colorObj *color, char* text) -{ + colorObj *color, char *text) { (void)img; (void)x; (void)y; (void)fontIndex; (void)color; (void)text; - msSetError(MS_RENDERERERR,"renderRasterGlyphs not implemented","renderRasterGlyphs()"); + msSetError(MS_RENDERERERR, "renderRasterGlyphs not implemented", + "renderRasterGlyphs()"); return MS_FAILURE; } -int renderGlyphsLineDummy(imageObj *img,labelPathObj *labelpath, - labelStyleObj *style, char *text) -{ +int renderGlyphsLineDummy(imageObj *img, labelPathObj *labelpath, + labelStyleObj *style, char *text) { (void)img; (void)labelpath; (void)style; (void)text; - msSetError(MS_RENDERERERR,"renderGlyphsLine not implemented","renderGlyphsLine()"); + msSetError(MS_RENDERERERR, "renderGlyphsLine not implemented", + "renderGlyphsLine()"); return MS_FAILURE; } int renderVectorSymbolDummy(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj *style) -{ + symbolObj *symbol, symbolStyleObj *style) { (void)img; (void)x; (void)y; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"renderVectorSymbol not implemented","renderVectorSymbol()"); + msSetError(MS_RENDERERERR, "renderVectorSymbol not implemented", + "renderVectorSymbol()"); return MS_FAILURE; } -void* createVectorSymbolTileDummy(int width, int height, - symbolObj *symbol, symbolStyleObj *style) -{ +void *createVectorSymbolTileDummy(int width, int height, symbolObj *symbol, + symbolStyleObj *style) { (void)width; (void)height; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"createVectorSymbolTile not implemented","createVectorSymbolTile()"); + msSetError(MS_RENDERERERR, "createVectorSymbolTile not implemented", + "createVectorSymbolTile()"); return NULL; } int renderPixmapSymbolDummy(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj *style) -{ + symbolObj *symbol, symbolStyleObj *style) { (void)img; (void)x; (void)y; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"renderPixmapSymbol not implemented","renderPixmapSymbol()"); + msSetError(MS_RENDERERERR, "renderPixmapSymbol not implemented", + "renderPixmapSymbol()"); return MS_FAILURE; } -void* createPixmapSymbolTileDummy(int width, int height, - symbolObj *symbol, symbolStyleObj *style) -{ +void *createPixmapSymbolTileDummy(int width, int height, symbolObj *symbol, + symbolStyleObj *style) { (void)width; (void)height; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"createPixmapSymbolTile not implemented","createPixmapSymbolTile()"); + msSetError(MS_RENDERERERR, "createPixmapSymbolTile not implemented", + "createPixmapSymbolTile()"); return NULL; } int renderEllipseSymbolDummy(imageObj *image, double x, double y, - symbolObj *symbol, symbolStyleObj *style) -{ + symbolObj *symbol, symbolStyleObj *style) { (void)image; (void)x; (void)y; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"renderEllipseSymbol not implemented","renderEllipseSymbol()"); + msSetError(MS_RENDERERERR, "renderEllipseSymbol not implemented", + "renderEllipseSymbol()"); return MS_FAILURE; } -void* createEllipseSymbolTileDummy(int width, int height, - symbolObj *symbol, symbolStyleObj *style) -{ +void *createEllipseSymbolTileDummy(int width, int height, symbolObj *symbol, + symbolStyleObj *style) { (void)width; (void)height; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"createEllipseSymbolTile not implemented","createEllipseSymbolTile()"); + msSetError(MS_RENDERERERR, "createEllipseSymbolTile not implemented", + "createEllipseSymbolTile()"); return NULL; } int renderTruetypeSymbolDummy(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj *style) -{ + symbolObj *symbol, symbolStyleObj *style) { (void)img; (void)x; (void)y; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"renderTruetypeSymbol not implemented","renderTruetypeSymbol()"); + msSetError(MS_RENDERERERR, "renderTruetypeSymbol not implemented", + "renderTruetypeSymbol()"); return MS_FAILURE; } -void* createTruetypeSymbolTileDummy(int width, int height, - symbolObj *symbol, symbolStyleObj *style) -{ +void *createTruetypeSymbolTileDummy(int width, int height, symbolObj *symbol, + symbolStyleObj *style) { (void)width; (void)height; (void)symbol; (void)style; - msSetError(MS_RENDERERERR,"createTruetypeSymbolTile not implemented","createTruetypeSymbolTile()"); + msSetError(MS_RENDERERERR, "createTruetypeSymbolTile not implemented", + "createTruetypeSymbolTile()"); return NULL; } -int renderTileDummy(imageObj *img, imageObj *tile, double x, double y) -{ +int renderTileDummy(imageObj *img, imageObj *tile, double x, double y) { (void)img; (void)tile; (void)x; (void)y; - msSetError(MS_RENDERERERR,"renderTile not implemented","renderTile()"); + msSetError(MS_RENDERERERR, "renderTile not implemented", "renderTile()"); return MS_FAILURE; } -rasterBufferObj* loadImageFromFileDummy(char *path) -{ +rasterBufferObj *loadImageFromFileDummy(char *path) { (void)path; - msSetError(MS_RENDERERERR,"loadImageFromFile not implemented","loadImageFromFile()"); + msSetError(MS_RENDERERERR, "loadImageFromFile not implemented", + "loadImageFromFile()"); return NULL; } - -int getRasterBufferHandleDummy(imageObj *img, rasterBufferObj *rb) -{ +int getRasterBufferHandleDummy(imageObj *img, rasterBufferObj *rb) { (void)img; (void)rb; - msSetError(MS_RENDERERERR,"getRasterBufferHandle not implemented","getRasterBufferHandle()"); + msSetError(MS_RENDERERERR, "getRasterBufferHandle not implemented", + "getRasterBufferHandle()"); return MS_FAILURE; } -int getRasterBufferCopyDummy(imageObj *img, rasterBufferObj *rb) -{ +int getRasterBufferCopyDummy(imageObj *img, rasterBufferObj *rb) { (void)img; (void)rb; - msSetError(MS_RENDERERERR,"getRasterBufferCopy not implemented","getRasterBufferCopy()"); + msSetError(MS_RENDERERERR, "getRasterBufferCopy not implemented", + "getRasterBufferCopy()"); return MS_FAILURE; } -rasterBufferObj* createRasterBufferDummy(int width, int height) -{ +rasterBufferObj *createRasterBufferDummy(int width, int height) { (void)width; (void)height; - msSetError(MS_RENDERERERR,"createRasterBuffer not implemented","createRasterBuffer()"); + msSetError(MS_RENDERERERR, "createRasterBuffer not implemented", + "createRasterBuffer()"); return NULL; } -int mergeRasterBufferDummy(imageObj *dest, rasterBufferObj *overlay, double opacity, int srcX, int srcY, int dstX, int dstY, int width, int height) -{ +int mergeRasterBufferDummy(imageObj *dest, rasterBufferObj *overlay, + double opacity, int srcX, int srcY, int dstX, + int dstY, int width, int height) { (void)dest; (void)overlay; (void)opacity; @@ -234,48 +232,49 @@ int mergeRasterBufferDummy(imageObj *dest, rasterBufferObj *overlay, double opac (void)dstY; (void)width; (void)height; - msSetError(MS_RENDERERERR,"mergeRasterBuffer not implemented","mergeRasterBuffer()"); + msSetError(MS_RENDERERERR, "mergeRasterBuffer not implemented", + "mergeRasterBuffer()"); return MS_FAILURE; } -int initializeRasterBufferDummy(rasterBufferObj *rb, int width, int height, int mode) -{ +int initializeRasterBufferDummy(rasterBufferObj *rb, int width, int height, + int mode) { (void)rb; (void)width; (void)height; (void)mode; - msSetError(MS_RENDERERERR,"initializeRasterBuffer not implemented","initializeRasterBuffer()"); + msSetError(MS_RENDERERERR, "initializeRasterBuffer not implemented", + "initializeRasterBuffer()"); return MS_FAILURE; } - - /* image i/o */ -imageObj* createImageDummy(int width, int height, outputFormatObj *format, colorObj* bg) -{ +imageObj *createImageDummy(int width, int height, outputFormatObj *format, + colorObj *bg) { (void)width; (void)height; (void)format; (void)bg; - msSetError(MS_RENDERERERR,"createImage not implemented","createImage()"); + msSetError(MS_RENDERERERR, "createImage not implemented", "createImage()"); return NULL; } -int saveImageDummy(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *format) -{ +int saveImageDummy(imageObj *img, mapObj *map, FILE *fp, + outputFormatObj *format) { (void)img; (void)map; (void)fp; (void)format; - msSetError(MS_RENDERERERR,"saveImage not implemented","saveImage()"); + msSetError(MS_RENDERERERR, "saveImage not implemented", "saveImage()"); return MS_FAILURE; } /*...*/ /* helper functions */ -int getTruetypeTextBBoxDummy(rendererVTableObj *renderer, char **fonts, int numfonts, double size, - char *string,rectObj *rect, double **advances, int bAdjustBaseline) -{ +int getTruetypeTextBBoxDummy(rendererVTableObj *renderer, char **fonts, + int numfonts, double size, char *string, + rectObj *rect, double **advances, + int bAdjustBaseline) { (void)renderer; (void)fonts; (void)numfonts; @@ -284,87 +283,77 @@ int getTruetypeTextBBoxDummy(rendererVTableObj *renderer, char **fonts, int numf (void)rect; (void)advances; (void)bAdjustBaseline; - msSetError(MS_RENDERERERR,"getTruetypeTextBBox not implemented","getTruetypeTextBBox()"); + msSetError(MS_RENDERERERR, "getTruetypeTextBBox not implemented", + "getTruetypeTextBBox()"); return MS_FAILURE; } -int startLayerDummy(imageObj *img, mapObj *map, layerObj *layer) -{ +int startLayerDummy(imageObj *img, mapObj *map, layerObj *layer) { (void)img; (void)map; (void)layer; - msSetError(MS_RENDERERERR,"startLayer not implemented","startLayer()"); + msSetError(MS_RENDERERERR, "startLayer not implemented", "startLayer()"); return MS_FAILURE; } -int endLayerDummy(imageObj *img, mapObj *map, layerObj *layer) -{ +int endLayerDummy(imageObj *img, mapObj *map, layerObj *layer) { (void)img; (void)map; (void)layer; - msSetError(MS_RENDERERERR,"endLayer not implemented","endLayer()"); + msSetError(MS_RENDERERERR, "endLayer not implemented", "endLayer()"); return MS_FAILURE; } -int startShapeDummy(imageObj *img, shapeObj *shape) -{ +int startShapeDummy(imageObj *img, shapeObj *shape) { (void)img; (void)shape; - msSetError(MS_RENDERERERR,"startShape not implemented","startShape()"); + msSetError(MS_RENDERERERR, "startShape not implemented", "startShape()"); return MS_FAILURE; } -int endShapeDummy(imageObj *img, shapeObj *shape) -{ +int endShapeDummy(imageObj *img, shapeObj *shape) { (void)img; (void)shape; - msSetError(MS_RENDERERERR,"endShape not implemented","endShape()"); + msSetError(MS_RENDERERERR, "endShape not implemented", "endShape()"); return MS_FAILURE; } -int setClipDummy(imageObj *img, rectObj clipRect) -{ +int setClipDummy(imageObj *img, rectObj clipRect) { (void)img; (void)clipRect; - msSetError(MS_RENDERERERR,"setClip not implemented","setClip()"); + msSetError(MS_RENDERERERR, "setClip not implemented", "setClip()"); return MS_FAILURE; } -int resetClipDummy(imageObj *img) -{ +int resetClipDummy(imageObj *img) { (void)img; - msSetError(MS_RENDERERERR,"resetClip not implemented","resetClip()"); + msSetError(MS_RENDERERERR, "resetClip not implemented", "resetClip()"); return MS_FAILURE; } -int freeImageDummy(imageObj *image) -{ +int freeImageDummy(imageObj *image) { (void)image; - msSetError(MS_RENDERERERR,"freeImage not implemented","freeImage()"); + msSetError(MS_RENDERERERR, "freeImage not implemented", "freeImage()"); return MS_FAILURE; } -int freeTileDummy(imageObj *tile) -{ +int freeTileDummy(imageObj *tile) { (void)tile; - msSetError(MS_RENDERERERR,"freeTile not implemented","freeTile()"); + msSetError(MS_RENDERERERR, "freeTile not implemented", "freeTile()"); return MS_FAILURE; } -int freeSymbolDummy(symbolObj *symbol) -{ +int freeSymbolDummy(symbolObj *symbol) { (void)symbol; - msSetError(MS_RENDERERERR,"freeSymbol not implemented","freeSymbol()"); + msSetError(MS_RENDERERERR, "freeSymbol not implemented", "freeSymbol()"); return MS_FAILURE; } -int cleanupDummy(void *renderer_data) -{ +int cleanupDummy(void *renderer_data) { (void)renderer_data; return MS_SUCCESS; } -int msInitializeDummyRenderer(rendererVTableObj *renderer) -{ +int msInitializeDummyRenderer(rendererVTableObj *renderer) { renderer->use_imagecache = 0; renderer->supports_pixel_buffer = 0; @@ -375,15 +364,15 @@ int msInitializeDummyRenderer(rendererVTableObj *renderer) renderer->transform_mode = MS_TRANSFORM_SIMPLIFY; renderer->startLayer = &startLayerDummy; renderer->endLayer = &endLayerDummy; - renderer->renderLine=&renderLineDummy; + renderer->renderLine = &renderLineDummy; renderer->renderLineTiled = NULL; - renderer->createImage=&createImageDummy; - renderer->saveImage=&saveImageDummy; - renderer->getRasterBufferHandle=&getRasterBufferHandleDummy; - renderer->getRasterBufferCopy=getRasterBufferCopyDummy; - renderer->initializeRasterBuffer=initializeRasterBufferDummy; - renderer->renderPolygon=&renderPolygonDummy; - renderer->freeImage=&freeImageDummy; + renderer->createImage = &createImageDummy; + renderer->saveImage = &saveImageDummy; + renderer->getRasterBufferHandle = &getRasterBufferHandleDummy; + renderer->getRasterBufferCopy = getRasterBufferCopyDummy; + renderer->initializeRasterBuffer = initializeRasterBufferDummy; + renderer->renderPolygon = &renderPolygonDummy; + renderer->freeImage = &freeImageDummy; renderer->renderEllipseSymbol = &renderEllipseSymbolDummy; renderer->renderVectorSymbol = &renderVectorSymbolDummy; renderer->renderPixmapSymbol = &renderPixmapSymbolDummy; @@ -397,5 +386,3 @@ int msInitializeDummyRenderer(rendererVTableObj *renderer) renderer->renderGlyphs = NULL; return MS_SUCCESS; } - - diff --git a/mapentities.h b/mapentities.h index aa5a716158..b1283f2b64 100644 --- a/mapentities.h +++ b/mapentities.h @@ -41,263 +41,74 @@ extern "C" { #endif - static const struct mapentities_s { - const char *name; - int value; - } mapentities[] = { - {"AElig", 198}, - {"Aacute", 193}, - {"Acirc", 194}, - {"Agrave", 192}, - {"Alpha", 913}, - {"Aring", 197}, - {"Atilde", 195}, - {"Auml", 196}, - {"Beta", 914}, - {"Ccedil", 199}, - {"Chi", 935}, - {"Dagger", 8225}, - {"Delta", 916}, - {"ETH", 208}, - {"Eacute", 201}, - {"Ecirc", 202}, - {"Egrave", 200}, - {"Epsilon", 917}, - {"Eta", 919}, - {"Euml", 203}, - {"Gamma", 915}, - {"Iacute", 205}, - {"Icirc", 206}, - {"Igrave", 204}, - {"Iota", 921}, - {"Iuml", 207}, - {"Kappa", 922}, - {"Lambda", 923}, - {"Mu", 924}, - {"Ntilde", 209}, - {"Nu", 925}, - {"OElig", 338}, - {"Oacute", 211}, - {"Ocirc", 212}, - {"Ograve", 210}, - {"Omega", 937}, - {"Omicron", 927}, - {"Oslash", 216}, - {"Otilde", 213}, - {"Ouml", 214}, - {"Phi", 934}, - {"Pi", 928}, - {"Prime", 8243}, - {"Psi", 936}, - {"Rho", 929}, - {"Scaron", 352}, - {"Sigma", 931}, - {"THORN", 222}, - {"Tau", 932}, - {"Theta", 920}, - {"Uacute", 218}, - {"Ucirc", 219}, - {"Ugrave", 217}, - {"Upsilon", 933}, - {"Uuml", 220}, - {"Xi", 926}, - {"Yacute", 221}, - {"Yuml", 376}, - {"Zeta", 918}, - {"aacute", 225}, - {"acirc", 226}, - {"acute", 180}, - {"aelig", 230}, - {"agrave", 224}, - {"alefsym", 8501}, - {"alpha", 945}, - {"amp", 38}, - {"and", 8743}, - {"ang", 8736}, - {"aring", 229}, - {"asymp", 8776}, - {"atilde", 227}, - {"auml", 228}, - {"bdquo", 8222}, - {"beta", 946}, - {"brvbar", 166}, - {"bull", 8226}, - {"cap", 8745}, - {"ccedil", 231}, - {"cedil", 184}, - {"cent", 162}, - {"chi", 967}, - {"circ", 710}, - {"clubs", 9827}, - {"cong", 8773}, - {"copy", 169}, - {"crarr", 8629}, - {"cup", 8746}, - {"curren", 164}, - {"dArr", 8659}, - {"dagger", 8224}, - {"darr", 8595}, - {"deg", 176}, - {"delta", 948}, - {"diams", 9830}, - {"divide", 247}, - {"eacute", 233}, - {"ecirc", 234}, - {"egrave", 232}, - {"empty", 8709}, - {"emsp", 8195}, - {"ensp", 8194}, - {"epsilon", 949}, - {"equiv", 8801}, - {"eta", 951}, - {"eth", 240}, - {"euml", 235}, - {"euro", 8364}, - {"exist", 8707}, - {"fnof", 402}, - {"forall", 8704}, - {"frac12", 189}, - {"frac14", 188}, - {"frac34", 190}, - {"frasl", 8260}, - {"gamma", 947}, - {"ge", 8805}, - {"gt", 62}, - {"hArr", 8660}, - {"harr", 8596}, - {"hearts", 9829}, - {"hellip", 8230}, - {"iacute", 237}, - {"icirc", 238}, - {"iexcl", 161}, - {"igrave", 236}, - {"image", 8465}, - {"infin", 8734}, - {"int", 8747}, - {"iota", 953}, - {"iquest", 191}, - {"isin", 8712}, - {"iuml", 239}, - {"kappa", 954}, - {"lArr", 8656}, - {"lambda", 955}, - {"lang", 9001}, - {"laquo", 171}, - {"larr", 8592}, - {"lceil", 8968}, - {"ldquo", 8220}, - {"le", 8804}, - {"lfloor", 8970}, - {"lowast", 8727}, - {"loz", 9674}, - {"lrm", 8206}, - {"lsaquo", 8249}, - {"lsquo", 8216}, - {"lt", 60}, - {"macr", 175}, - {"mdash", 8212}, - {"micro", 181}, - {"middot", 183}, - {"minus", 8722}, - {"mu", 956}, - {"nabla", 8711}, - {"nbsp", 160}, - {"ndash", 8211}, - {"ne", 8800}, - {"ni", 8715}, - {"not", 172}, - {"notin", 8713}, - {"nsub", 8836}, - {"ntilde", 241}, - {"nu", 957}, - {"oacute", 243}, - {"ocirc", 244}, - {"oelig", 339}, - {"ograve", 242}, - {"oline", 8254}, - {"omega", 969}, - {"omicron", 959}, - {"oplus", 8853}, - {"or", 8744}, - {"ordf", 170}, - {"ordm", 186}, - {"oslash", 248}, - {"otilde", 245}, - {"otimes", 8855}, - {"ouml", 246}, - {"para", 182}, - {"part", 8706}, - {"permil", 8240}, - {"perp", 8869}, - {"phi", 966}, - {"pi", 960}, - {"piv", 982}, - {"plusmn", 177}, - {"pound", 163}, - {"prime", 8242}, - {"prod", 8719}, - {"prop", 8733}, - {"psi", 968}, - {"quot", 34}, - {"rArr", 8658}, - {"radic", 8730}, - {"rang", 9002}, - {"raquo", 187}, - {"rarr", 8594}, - {"rceil", 8969}, - {"rdquo", 8221}, - {"real", 8476}, - {"reg", 174}, - {"rfloor", 8971}, - {"rho", 961}, - {"rlm", 8207}, - {"rsaquo", 8250}, - {"rsquo", 8217}, - {"sbquo", 8218}, - {"scaron", 353}, - {"sdot", 8901}, - {"sect", 167}, - {"shy", 173}, - {"sigma", 963}, - {"sigmaf", 962}, - {"sim", 8764}, - {"spades", 9824}, - {"sub", 8834}, - {"sube", 8838}, - {"sum", 8721}, - {"sup", 8835}, - {"sup1", 185}, - {"sup2", 178}, - {"sup3", 179}, - {"supe", 8839}, - {"szlig", 223}, - {"tau", 964}, - {"there4", 8756}, - {"theta", 952}, - {"thetasym", 977}, - {"thinsp", 8201}, - {"thorn", 254}, - {"tilde", 732}, - {"times", 215}, - {"trade", 8482}, - {"uArr", 8657}, - {"uacute", 250}, - {"uarr", 8593}, - {"ucirc", 251}, - {"ugrave", 249}, - {"uml", 168}, - {"upsih", 978}, - {"upsilon", 965}, - {"uuml", 252}, - {"weierp", 8472}, - {"xi", 958}, - {"yacute", 253}, - {"yen", 165}, - {"yuml", 255}, - {"zeta", 950}, - {"zwj", 8205}, - {"zwnj", 8204}, - }; +static const struct mapentities_s { + const char *name; + int value; +} mapentities[] = { + {"AElig", 198}, {"Aacute", 193}, {"Acirc", 194}, {"Agrave", 192}, + {"Alpha", 913}, {"Aring", 197}, {"Atilde", 195}, {"Auml", 196}, + {"Beta", 914}, {"Ccedil", 199}, {"Chi", 935}, {"Dagger", 8225}, + {"Delta", 916}, {"ETH", 208}, {"Eacute", 201}, {"Ecirc", 202}, + {"Egrave", 200}, {"Epsilon", 917}, {"Eta", 919}, {"Euml", 203}, + {"Gamma", 915}, {"Iacute", 205}, {"Icirc", 206}, {"Igrave", 204}, + {"Iota", 921}, {"Iuml", 207}, {"Kappa", 922}, {"Lambda", 923}, + {"Mu", 924}, {"Ntilde", 209}, {"Nu", 925}, {"OElig", 338}, + {"Oacute", 211}, {"Ocirc", 212}, {"Ograve", 210}, {"Omega", 937}, + {"Omicron", 927}, {"Oslash", 216}, {"Otilde", 213}, {"Ouml", 214}, + {"Phi", 934}, {"Pi", 928}, {"Prime", 8243}, {"Psi", 936}, + {"Rho", 929}, {"Scaron", 352}, {"Sigma", 931}, {"THORN", 222}, + {"Tau", 932}, {"Theta", 920}, {"Uacute", 218}, {"Ucirc", 219}, + {"Ugrave", 217}, {"Upsilon", 933}, {"Uuml", 220}, {"Xi", 926}, + {"Yacute", 221}, {"Yuml", 376}, {"Zeta", 918}, {"aacute", 225}, + {"acirc", 226}, {"acute", 180}, {"aelig", 230}, {"agrave", 224}, + {"alefsym", 8501}, {"alpha", 945}, {"amp", 38}, {"and", 8743}, + {"ang", 8736}, {"aring", 229}, {"asymp", 8776}, {"atilde", 227}, + {"auml", 228}, {"bdquo", 8222}, {"beta", 946}, {"brvbar", 166}, + {"bull", 8226}, {"cap", 8745}, {"ccedil", 231}, {"cedil", 184}, + {"cent", 162}, {"chi", 967}, {"circ", 710}, {"clubs", 9827}, + {"cong", 8773}, {"copy", 169}, {"crarr", 8629}, {"cup", 8746}, + {"curren", 164}, {"dArr", 8659}, {"dagger", 8224}, {"darr", 8595}, + {"deg", 176}, {"delta", 948}, {"diams", 9830}, {"divide", 247}, + {"eacute", 233}, {"ecirc", 234}, {"egrave", 232}, {"empty", 8709}, + {"emsp", 8195}, {"ensp", 8194}, {"epsilon", 949}, {"equiv", 8801}, + {"eta", 951}, {"eth", 240}, {"euml", 235}, {"euro", 8364}, + {"exist", 8707}, {"fnof", 402}, {"forall", 8704}, {"frac12", 189}, + {"frac14", 188}, {"frac34", 190}, {"frasl", 8260}, {"gamma", 947}, + {"ge", 8805}, {"gt", 62}, {"hArr", 8660}, {"harr", 8596}, + {"hearts", 9829}, {"hellip", 8230}, {"iacute", 237}, {"icirc", 238}, + {"iexcl", 161}, {"igrave", 236}, {"image", 8465}, {"infin", 8734}, + {"int", 8747}, {"iota", 953}, {"iquest", 191}, {"isin", 8712}, + {"iuml", 239}, {"kappa", 954}, {"lArr", 8656}, {"lambda", 955}, + {"lang", 9001}, {"laquo", 171}, {"larr", 8592}, {"lceil", 8968}, + {"ldquo", 8220}, {"le", 8804}, {"lfloor", 8970}, {"lowast", 8727}, + {"loz", 9674}, {"lrm", 8206}, {"lsaquo", 8249}, {"lsquo", 8216}, + {"lt", 60}, {"macr", 175}, {"mdash", 8212}, {"micro", 181}, + {"middot", 183}, {"minus", 8722}, {"mu", 956}, {"nabla", 8711}, + {"nbsp", 160}, {"ndash", 8211}, {"ne", 8800}, {"ni", 8715}, + {"not", 172}, {"notin", 8713}, {"nsub", 8836}, {"ntilde", 241}, + {"nu", 957}, {"oacute", 243}, {"ocirc", 244}, {"oelig", 339}, + {"ograve", 242}, {"oline", 8254}, {"omega", 969}, {"omicron", 959}, + {"oplus", 8853}, {"or", 8744}, {"ordf", 170}, {"ordm", 186}, + {"oslash", 248}, {"otilde", 245}, {"otimes", 8855}, {"ouml", 246}, + {"para", 182}, {"part", 8706}, {"permil", 8240}, {"perp", 8869}, + {"phi", 966}, {"pi", 960}, {"piv", 982}, {"plusmn", 177}, + {"pound", 163}, {"prime", 8242}, {"prod", 8719}, {"prop", 8733}, + {"psi", 968}, {"quot", 34}, {"rArr", 8658}, {"radic", 8730}, + {"rang", 9002}, {"raquo", 187}, {"rarr", 8594}, {"rceil", 8969}, + {"rdquo", 8221}, {"real", 8476}, {"reg", 174}, {"rfloor", 8971}, + {"rho", 961}, {"rlm", 8207}, {"rsaquo", 8250}, {"rsquo", 8217}, + {"sbquo", 8218}, {"scaron", 353}, {"sdot", 8901}, {"sect", 167}, + {"shy", 173}, {"sigma", 963}, {"sigmaf", 962}, {"sim", 8764}, + {"spades", 9824}, {"sub", 8834}, {"sube", 8838}, {"sum", 8721}, + {"sup", 8835}, {"sup1", 185}, {"sup2", 178}, {"sup3", 179}, + {"supe", 8839}, {"szlig", 223}, {"tau", 964}, {"there4", 8756}, + {"theta", 952}, {"thetasym", 977}, {"thinsp", 8201}, {"thorn", 254}, + {"tilde", 732}, {"times", 215}, {"trade", 8482}, {"uArr", 8657}, + {"uacute", 250}, {"uarr", 8593}, {"ucirc", 251}, {"ugrave", 249}, + {"uml", 168}, {"upsih", 978}, {"upsilon", 965}, {"uuml", 252}, + {"weierp", 8472}, {"xi", 958}, {"yacute", 253}, {"yen", 165}, + {"yuml", 255}, {"zeta", 950}, {"zwj", 8205}, {"zwnj", 8204}, +}; #define MAP_ENTITY_NAME_LENGTH_MAX 8 #define MAP_NR_OF_ENTITIES 252 diff --git a/maperror.c b/maperror.c index 2936f9a3b7..a44332a5ad 100644 --- a/maperror.c +++ b/maperror.c @@ -41,58 +41,57 @@ #include "cpl_conv.h" -static char *const ms_errorCodes[MS_NUMERRORCODES] = { "", - "Unable to access file.", - "Memory allocation error.", - "Incorrect data type.", - "Symbol definition error.", - "Regular expression error.", - "TrueType Font error.", - "DBASE file error.", - "GD library error.", - "Unknown identifier.", - "Premature End-of-File.", - "Projection library error.", - "General error message.", - "CGI error.", - "Web application error.", - "Image handling error.", - "Hash table error.", - "Join error.", - "Search returned no results.", - "Shapefile error.", - "Expression parser error.", - "SDE error.", - "OGR error.", - "Query error.", - "WMS server error.", - "WMS connection error.", - "OracleSpatial error.", - "WFS server error.", - "WFS connection error.", - "WMS Map Context error.", - "HTTP request error.", - "Child array error.", - "WCS server error.", - "GEOS library error.", - "Invalid rectangle.", - "Date/time error.", - "GML encoding error.", - "SOS server error.", - "NULL parent pointer error.", - "AGG library error.", - "OWS error.", - "OpenGL renderer error.", - "Renderer error.", - "V8 engine error.", - "OCG API error." -}; +static char *const ms_errorCodes[MS_NUMERRORCODES] = { + "", + "Unable to access file.", + "Memory allocation error.", + "Incorrect data type.", + "Symbol definition error.", + "Regular expression error.", + "TrueType Font error.", + "DBASE file error.", + "GD library error.", + "Unknown identifier.", + "Premature End-of-File.", + "Projection library error.", + "General error message.", + "CGI error.", + "Web application error.", + "Image handling error.", + "Hash table error.", + "Join error.", + "Search returned no results.", + "Shapefile error.", + "Expression parser error.", + "SDE error.", + "OGR error.", + "Query error.", + "WMS server error.", + "WMS connection error.", + "OracleSpatial error.", + "WFS server error.", + "WFS connection error.", + "WMS Map Context error.", + "HTTP request error.", + "Child array error.", + "WCS server error.", + "GEOS library error.", + "Invalid rectangle.", + "Date/time error.", + "GML encoding error.", + "SOS server error.", + "NULL parent pointer error.", + "AGG library error.", + "OWS error.", + "OpenGL renderer error.", + "Renderer error.", + "V8 engine error.", + "OCG API error."}; #ifndef USE_THREAD // Get the MapServer error object -errorObj *msGetErrorObj() -{ +errorObj *msGetErrorObj() { static errorObj ms_error = {MS_NOERR, "", "", MS_FALSE, 0, NULL}; return &ms_error; } @@ -108,33 +107,33 @@ typedef struct te_info { static te_info_t *error_list = NULL; -errorObj *msGetErrorObj() -{ +errorObj *msGetErrorObj() { te_info_t *link; void *thread_id; errorObj *ret_obj; - msAcquireLock( TLOCK_ERROROBJ ); + msAcquireLock(TLOCK_ERROROBJ); thread_id = msGetThreadId(); /* find link for this thread */ - for( link = error_list; - link != NULL && link->thread_id != thread_id - && link->next != NULL && link->next->thread_id != thread_id; - link = link->next ) {} + for (link = error_list; + link != NULL && link->thread_id != thread_id && link->next != NULL && + link->next->thread_id != thread_id; + link = link->next) { + } /* If the target thread link is already at the head of the list were ok */ - if( error_list != NULL && error_list->thread_id == thread_id ) { + if (error_list != NULL && error_list->thread_id == thread_id) { } /* We don't have one ... initialize one. */ - else if( link == NULL || link->next == NULL ) { + else if (link == NULL || link->next == NULL) { te_info_t *new_link; - errorObj error_obj = { MS_NOERR, "", "", 0, 0, NULL, 0 }; + errorObj error_obj = {MS_NOERR, "", "", 0, 0, NULL, 0}; - new_link = (te_info_t *) malloc(sizeof(te_info_t)); + new_link = (te_info_t *)malloc(sizeof(te_info_t)); new_link->next = error_list; new_link->thread_id = thread_id; new_link->ms_error = error_obj; @@ -153,7 +152,7 @@ errorObj *msGetErrorObj() ret_obj = &(error_list->ms_error); - msReleaseLock( TLOCK_ERROROBJ ); + msReleaseLock(TLOCK_ERROROBJ); return ret_obj; } @@ -175,8 +174,7 @@ errorObj *msGetErrorObj() ** the head is moved to the new errorObj, freeing the head errorObj to receive ** the new error information. */ -static errorObj *msInsertErrorObj(void) -{ +static errorObj *msInsertErrorObj(void) { errorObj *ms_error; ms_error = msGetErrorObj(); @@ -196,8 +194,10 @@ static errorObj *msInsertErrorObj(void) new_error->next = ms_error->next; new_error->code = ms_error->code; new_error->isreported = ms_error->isreported; - strlcpy(new_error->routine, ms_error->routine, sizeof(new_error->routine)); - strlcpy(new_error->message, ms_error->message, sizeof(new_error->message)); + strlcpy(new_error->routine, ms_error->routine, + sizeof(new_error->routine)); + strlcpy(new_error->message, ms_error->message, + sizeof(new_error->message)); new_error->errorcount = ms_error->errorcount; ms_error->next = new_error; @@ -207,7 +207,7 @@ static errorObj *msInsertErrorObj(void) ms_error->message[0] = '\0'; ms_error->errorcount = 0; } - ms_error->totalerrorcount ++; + ms_error->totalerrorcount++; } return ms_error; @@ -217,13 +217,12 @@ static errorObj *msInsertErrorObj(void) ** ** Clear the list of error objects. */ -void msResetErrorList() -{ +void msResetErrorList() { errorObj *ms_error, *this_error; ms_error = msGetErrorObj(); this_error = ms_error->next; - while( this_error != NULL) { + while (this_error != NULL) { errorObj *next_error; next_error = this_error->next; @@ -245,41 +244,41 @@ void msResetErrorList() /* -------------------------------------------------------------------- */ #ifdef USE_THREAD { - void* thread_id = msGetThreadId(); + void *thread_id = msGetThreadId(); te_info_t *link; - msAcquireLock( TLOCK_ERROROBJ ); + msAcquireLock(TLOCK_ERROROBJ); /* find link for this thread */ - for( link = error_list; - link != NULL && link->thread_id != thread_id - && link->next != NULL && link->next->thread_id != thread_id; - link = link->next ) {} + for (link = error_list; + link != NULL && link->thread_id != thread_id && link->next != NULL && + link->next->thread_id != thread_id; + link = link->next) { + } - if( link->thread_id == thread_id ) { + if (link->thread_id == thread_id) { /* presumably link is at head of list. */ - if( error_list == link ) + if (error_list == link) error_list = link->next; - free( link ); - } else if( link->next != NULL && link->next->thread_id == thread_id ) { + free(link); + } else if (link->next != NULL && link->next->thread_id == thread_id) { te_info_t *next_link = link->next; link->next = link->next->next; - free( next_link ); + free(next_link); } - msReleaseLock( TLOCK_ERROROBJ ); + msReleaseLock(TLOCK_ERROROBJ); } #endif } -char *msGetErrorCodeString(int code) -{ +char *msGetErrorCodeString(int code) { - if(code<0 || code>MS_NUMERRORCODES-1) - return("Invalid error code."); + if (code < 0 || code > MS_NUMERRORCODES - 1) + return ("Invalid error code."); - return(ms_errorCodes[code]); + return (ms_errorCodes[code]); } /* -------------------------------------------------------------------- */ @@ -287,63 +286,72 @@ char *msGetErrorCodeString(int code) /* and reallocates the memory enough to hold the characters. */ /* If source is null returns a newly allocated string */ /* -------------------------------------------------------------------- */ -char *msAddErrorDisplayString(char *source, errorObj *error) -{ - if((source = msStringConcatenate(source, error->routine)) == NULL) return(NULL); - if((source = msStringConcatenate(source, ": ")) == NULL) return(NULL); - if((source = msStringConcatenate(source, ms_errorCodes[error->code])) == NULL) return(NULL); - if((source = msStringConcatenate(source, " ")) == NULL) return(NULL); - if((source = msStringConcatenate(source, error->message)) == NULL) return(NULL); +char *msAddErrorDisplayString(char *source, errorObj *error) { + if ((source = msStringConcatenate(source, error->routine)) == NULL) + return (NULL); + if ((source = msStringConcatenate(source, ": ")) == NULL) + return (NULL); + if ((source = msStringConcatenate(source, ms_errorCodes[error->code])) == + NULL) + return (NULL); + if ((source = msStringConcatenate(source, " ")) == NULL) + return (NULL); + if ((source = msStringConcatenate(source, error->message)) == NULL) + return (NULL); if (error->errorcount > 0) { - char* pszTmp; - if((source = msStringConcatenate(source, " (message repeated ")) == NULL) return(NULL); + char *pszTmp; + if ((source = msStringConcatenate(source, " (message repeated ")) == NULL) + return (NULL); pszTmp = msIntToString(error->errorcount); - if((source = msStringConcatenate(source, pszTmp)) == NULL) { + if ((source = msStringConcatenate(source, pszTmp)) == NULL) { msFree(pszTmp); - return(NULL); + return (NULL); } msFree(pszTmp); - if((source = msStringConcatenate(source, " times)")) == NULL) return(NULL); + if ((source = msStringConcatenate(source, " times)")) == NULL) + return (NULL); } return source; } -char *msGetErrorString(const char *delimiter) -{ - char *errstr=NULL; +char *msGetErrorString(const char *delimiter) { + char *errstr = NULL; errorObj *error = msGetErrorObj(); - if(!delimiter || !error) return(NULL); + if (!delimiter || !error) + return (NULL); - while(error && error->code != MS_NOERR) { - if((errstr = msAddErrorDisplayString(errstr, error)) == NULL) return(NULL); + while (error && error->code != MS_NOERR) { + if ((errstr = msAddErrorDisplayString(errstr, error)) == NULL) + return (NULL); - if(error->next && error->next->code != MS_NOERR) { /* (peek ahead) more errors, use delimiter */ - if((errstr = msStringConcatenate(errstr, delimiter)) == NULL) return(NULL); + if (error->next && + error->next->code != + MS_NOERR) { /* (peek ahead) more errors, use delimiter */ + if ((errstr = msStringConcatenate(errstr, delimiter)) == NULL) + return (NULL); } error = error->next; } - return(errstr); + return (errstr); } -void msRedactString(char* str, const char* keyword, const char delimeter) -{ +void msRedactString(char *str, const char *keyword, const char delimeter) { - char* password = strstr(str, keyword); - if (password != NULL) { - char* ptr = password + strlen(keyword); - while (*ptr != '\0' && *ptr != delimeter) { - *ptr = '*'; - ptr++; - } + char *password = strstr(str, keyword); + if (password != NULL) { + char *ptr = password + strlen(keyword); + while (*ptr != '\0' && *ptr != delimeter) { + *ptr = '*'; + ptr++; } + } } -void msRedactCredentials(char* str) -{ +void msRedactCredentials(char *str) { // postgres formats msRedactString(str, "password=", ' '); @@ -353,58 +361,56 @@ void msRedactCredentials(char* str) msRedactString(str, "pwd=", ';'); } -void msSetError(int code, const char *message_fmt, const char *routine, ...) -{ +void msSetError(int code, const char *message_fmt, const char *routine, ...) { errorObj *ms_error; va_list args; char message[MESSAGELENGTH]; - if(!message_fmt) + if (!message_fmt) strcpy(message, ""); else { va_start(args, routine); - vsnprintf( message, MESSAGELENGTH, message_fmt, args ); + vsnprintf(message, MESSAGELENGTH, message_fmt, args); va_end(args); } ms_error = msGetErrorObj(); /* Insert the error to the list if it is not the same as the previous error*/ - if (ms_error->code != code || !EQUAL(message, ms_error->message) || - !EQUAL(routine, ms_error->routine)) { - ms_error = msInsertErrorObj(); - if(!routine) - strcpy(ms_error->routine, ""); - else { - strlcpy(ms_error->routine, routine, sizeof(ms_error->routine)); - } - strlcpy(ms_error->message, message, sizeof(ms_error->message)); - ms_error->code = code; - ms_error->errorcount = 0; - } - else - ++ms_error->errorcount; + if (ms_error->code != code || !EQUAL(message, ms_error->message) || + !EQUAL(routine, ms_error->routine)) { + ms_error = msInsertErrorObj(); + if (!routine) + strcpy(ms_error->routine, ""); + else { + strlcpy(ms_error->routine, routine, sizeof(ms_error->routine)); + } + strlcpy(ms_error->message, message, sizeof(ms_error->message)); + ms_error->code = code; + ms_error->errorcount = 0; + } else + ++ms_error->errorcount; msRedactCredentials(ms_error->message); - /* Log a copy of errors to MS_ERRORFILE if set (handled automatically inside msDebug()) */ - msDebug("%s: %s %s\n", ms_error->routine, ms_errorCodes[ms_error->code], ms_error->message); - + /* Log a copy of errors to MS_ERRORFILE if set (handled automatically inside + * msDebug()) */ + msDebug("%s: %s %s\n", ms_error->routine, ms_errorCodes[ms_error->code], + ms_error->message); } -void msWriteError(FILE *stream) -{ +void msWriteError(FILE *stream) { errorObj *ms_error = msGetErrorObj(); while (ms_error && ms_error->code != MS_NOERR) { - msIO_fprintf(stream, "%s: %s %s
\n", ms_error->routine, ms_errorCodes[ms_error->code], ms_error->message); + msIO_fprintf(stream, "%s: %s %s
\n", ms_error->routine, + ms_errorCodes[ms_error->code], ms_error->message); ms_error->isreported = MS_TRUE; ms_error = ms_error->next; } } -void msWriteErrorXML(FILE *stream) -{ +void msWriteErrorXML(FILE *stream) { char *message; errorObj *ms_error = msGetErrorObj(); @@ -420,28 +426,28 @@ void msWriteErrorXML(FILE *stream) } } -void msWriteErrorImage(mapObj *map, char *filename, int blank) -{ +void msWriteErrorImage(mapObj *map, char *filename, int blank) { imageObj *img; - int width=400, height=300; - const int nMargin =5; + int width = 400, height = 300; + const int nMargin = 5; char **papszLines = NULL; - pointObj pnt = { 0 }; + pointObj pnt = {0}; outputFormatObj *format = NULL; char *errormsg = msGetErrorString("; "); errorObj *error = msGetErrorObj(); char *imagepath = NULL, *imageurl = NULL; - colorObj imagecolor, *imagecolorptr=NULL; + colorObj imagecolor, *imagecolorptr = NULL; textSymbolObj ts; labelObj label; - int charWidth = 5, charHeight = 8; /* hardcoded, should be looked up from ft face */ - if(!errormsg) { + int charWidth = 5, + charHeight = 8; /* hardcoded, should be looked up from ft face */ + if (!errormsg) { errormsg = msStrdup("No error found sorry. This is likely a bug"); } if (map) { - if( map->width > 0 && map->height > 0 ) { + if (map->width > 0 && map->height > 0) { width = map->width; height = map->height; } @@ -452,68 +458,73 @@ void msWriteErrorImage(mapObj *map, char *filename, int blank) /* Default to GIF if no suitable GD output format set */ if (format == NULL || !MS_RENDERER_PLUGIN(format)) - format = msCreateDefaultOutputFormat( NULL, "AGG/PNG8", "png", NULL ); + format = msCreateDefaultOutputFormat(NULL, "AGG/PNG8", "png", NULL); - if(!format->transparent) { - if(map && MS_VALID_COLOR(map->imagecolor)) { + if (!format->transparent) { + if (map && MS_VALID_COLOR(map->imagecolor)) { imagecolorptr = &map->imagecolor; } else { - MS_INIT_COLOR(imagecolor,255,255,255,255); + MS_INIT_COLOR(imagecolor, 255, 255, 255, 255); imagecolorptr = &imagecolor; } } - img = msImageCreate(width,height,format,imagepath,imageurl,MS_DEFAULT_RESOLUTION,MS_DEFAULT_RESOLUTION,imagecolorptr); + img = msImageCreate(width, height, format, imagepath, imageurl, + MS_DEFAULT_RESOLUTION, MS_DEFAULT_RESOLUTION, + imagecolorptr); const int nTextLength = strlen(errormsg); - const int nWidthTxt = nTextLength * charWidth; - const int nUsableWidth = width - (nMargin*2); + const int nWidthTxt = nTextLength * charWidth; + const int nUsableWidth = width - (nMargin * 2); - /* Check to see if it all fits on one line. If not, split the text on several lines. */ - if(!blank) { + /* Check to see if it all fits on one line. If not, split the text on several + * lines. */ + if (!blank) { int nLines; if (nWidthTxt > nUsableWidth) { - const int nMaxCharsPerLine = nUsableWidth/charWidth; - nLines = (int) ceil ((double)nTextLength / (double)nMaxCharsPerLine); + const int nMaxCharsPerLine = nUsableWidth / charWidth; + nLines = (int)ceil((double)nTextLength / (double)nMaxCharsPerLine); if (nLines > 0) { - papszLines = (char **)malloc(nLines*sizeof(char *)); - for (int i=0; i nTextLength) nEnd = nTextLength; - const int nLength = nEnd-nStart; + const int nLength = nEnd - nStart; - strncpy(papszLines[i], errormsg+nStart, nLength); + strncpy(papszLines[i], errormsg + nStart, nLength); papszLines[i][nLength] = '\0'; } } } else { nLines = 1; - papszLines = (char **)malloc(nLines*sizeof(char *)); + papszLines = (char **)malloc(nLines * sizeof(char *)); papszLines[0] = msStrdup(errormsg); } initLabel(&label); - MS_INIT_COLOR(label.color,0,0,0,255); - MS_INIT_COLOR(label.outlinecolor,255,255,255,255); + MS_INIT_COLOR(label.color, 0, 0, 0, 255); + MS_INIT_COLOR(label.outlinecolor, 255, 255, 255, 255); label.outlinewidth = 1; label.size = MS_SMALL; MS_REFCNT_INCR((&label)); - for (int i=0; icode != MS_NOERR) { + while (error && error->code != MS_NOERR) { error->isreported = MS_TRUE; error = error->next; } @@ -542,8 +553,7 @@ void msWriteErrorImage(mapObj *map, char *filename, int blank) msFree(errormsg); } -char *msGetVersion() -{ +char *msGetVersion() { static char version[2048]; sprintf(version, "MapServer version %s", MS_VERSION); @@ -551,12 +561,14 @@ char *msGetVersion() // add versions of required dependencies #if PROJ_VERSION_MAJOR >= 6 static char PROJVersion[20]; - sprintf(PROJVersion, " PROJ version %d.%d", PROJ_VERSION_MAJOR, PROJ_VERSION_MINOR); + sprintf(PROJVersion, " PROJ version %d.%d", PROJ_VERSION_MAJOR, + PROJ_VERSION_MINOR); strcat(version, PROJVersion); #endif static char GDALVersion[20]; - sprintf(GDALVersion, " GDAL version %d.%d", GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR); + sprintf(GDALVersion, " GDAL version %d.%d", GDAL_VERSION_MAJOR, + GDAL_VERSION_MINOR); strcat(version, GDALVersion); #if (defined USE_PNG) @@ -576,11 +588,11 @@ char *msGetVersion() #endif #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) strcat(version, " SUPPORTS=SVG_SYMBOLS"); - #ifdef USE_SVG_CAIRO - strcat(version, " SUPPORTS=SVGCAIRO"); - #else - strcat(version, " SUPPORTS=RSVG"); - #endif +#ifdef USE_SVG_CAIRO + strcat(version, " SUPPORTS=SVGCAIRO"); +#else + strcat(version, " SUPPORTS=RSVG"); +#endif #endif #ifdef USE_OGL strcat(version, " SUPPORTS=OPENGL"); @@ -646,10 +658,7 @@ char *msGetVersion() strcat(version, " INPUT=GDAL"); strcat(version, " INPUT=SHAPEFILE"); strcat(version, " INPUT=FLATGEOBUF"); - return(version); + return (version); } -int msGetVersionInt() -{ - return MS_VERSION_NUM; -} +int msGetVersionInt() { return MS_VERSION_NUM; } diff --git a/maperror.h b/maperror.h index b8196d6325..9da4704a18 100644 --- a/maperror.h +++ b/maperror.h @@ -36,9 +36,9 @@ extern "C" { #endif - /*==================================================================== - * maperror.c - *====================================================================*/ +/*==================================================================== + * maperror.c + *====================================================================*/ #define MS_NOERR 0 /* general error codes */ #define MS_IOERR 1 @@ -63,14 +63,14 @@ extern "C" { #define MS_UNUSEDERR 21 #define MS_OGRERR 22 #define MS_QUERYERR 23 -#define MS_WMSERR 24 /* WMS server error */ -#define MS_WMSCONNERR 25 /* WMS connectiontype error */ +#define MS_WMSERR 24 /* WMS server error */ +#define MS_WMSCONNERR 25 /* WMS connectiontype error */ #define MS_ORACLESPATIALERR 26 -#define MS_WFSERR 27 /* WFS server error */ -#define MS_WFSCONNERR 28 /* WFS connectiontype error */ +#define MS_WFSERR 27 /* WFS server error */ +#define MS_WFSCONNERR 28 /* WFS connectiontype error */ #define MS_MAPCONTEXTERR 29 /* Map Context error */ #define MS_HTTPERR 30 -#define MS_CHILDERR 31 /* Errors involving arrays of child objects */ +#define MS_CHILDERR 31 /* Errors involving arrays of child objects */ #define MS_WCSERR 32 #define MS_GEOSERR 33 #define MS_RECTERR 34 @@ -93,117 +93,129 @@ extern "C" { #define MS_ERROR_LANGUAGE "en-US" #if defined(_WIN32) && !defined(__CYGWIN__) -# define MS_DLL_EXPORT __declspec(dllexport) +#define MS_DLL_EXPORT __declspec(dllexport) #else -#define MS_DLL_EXPORT +#define MS_DLL_EXPORT #endif #ifndef MS_PRINT_FUNC_FORMAT #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP) -#define MS_PRINT_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#define MS_PRINT_FUNC_FORMAT(format_idx, arg_idx) \ + __attribute__((__format__(__printf__, format_idx, arg_idx))) #else -#define MS_PRINT_FUNC_FORMAT( format_idx, arg_idx ) +#define MS_PRINT_FUNC_FORMAT(format_idx, arg_idx) #endif #endif /** -This class allows inspection of the MapServer error stack. -Instances of errorObj are created internally by MapServer as errors happen. -Errors are managed as a chained list with the first item being the most recent error. +This class allows inspection of the MapServer error stack. +Instances of errorObj are created internally by MapServer as errors happen. +Errors are managed as a chained list with the first item being the most recent +error. */ - typedef struct errorObj { - int code; ///< MapServer error code such as :data:`MS_IMGERR` - char routine[ROUTINELENGTH]; ///< MapServer function in which the error was set - char message[MESSAGELENGTH]; ///< Context-dependent error message - int isreported; ///< :data:`MS_TRUE` or :data:`MS_FALSE` flag indicating if the error has been output - int errorcount; ///< Number of subsequent errors +typedef struct errorObj { + int code; ///< MapServer error code such as :data:`MS_IMGERR` + char + routine[ROUTINELENGTH]; ///< MapServer function in which the error was set + char message[MESSAGELENGTH]; ///< Context-dependent error message + int isreported; ///< :data:`MS_TRUE` or :data:`MS_FALSE` flag indicating if + ///< the error has been output + int errorcount; ///< Number of subsequent errors #ifndef SWIG - struct errorObj *next; - int totalerrorcount; + struct errorObj *next; + int totalerrorcount; #endif - } errorObj; - - /* - ** Function prototypes - */ - - /** - Get the MapServer error object - */ - MS_DLL_EXPORT errorObj *msGetErrorObj(void); - /** - Clear the list of error objects - */ - MS_DLL_EXPORT void msResetErrorList(void); - /** - Returns a string containing MapServer version information, and details on what optional components - are built in - the same report as produced by ``mapserv -v`` - */ - MS_DLL_EXPORT char *msGetVersion(void); - /** - Returns the MapServer version number (x.y.z) as an integer (x*10000 + y*100 + z) - e.g. V7.4.2 would return 70402 - */ - MS_DLL_EXPORT int msGetVersionInt(void); - /** - Return a string of all errors - */ - MS_DLL_EXPORT char *msGetErrorString(const char *delimiter); +} errorObj; -#ifndef SWIG - MS_DLL_EXPORT void msRedactCredentials(char* str); - MS_DLL_EXPORT void msSetError(int code, const char *message, const char *routine, ...) MS_PRINT_FUNC_FORMAT(2,4) ; - MS_DLL_EXPORT void msWriteError(FILE *stream); - MS_DLL_EXPORT void msWriteErrorXML(FILE *stream); - MS_DLL_EXPORT char *msGetErrorCodeString(int code); - MS_DLL_EXPORT char *msAddErrorDisplayString(char *source, errorObj *error); +/* +** Function prototypes +*/ - struct mapObj; - MS_DLL_EXPORT void msWriteErrorImage(struct mapObj *map, char *filename, int blank); +/** +Get the MapServer error object +*/ +MS_DLL_EXPORT errorObj *msGetErrorObj(void); +/** +Clear the list of error objects +*/ +MS_DLL_EXPORT void msResetErrorList(void); +/** +Returns a string containing MapServer version information, and details on what +optional components are built in - the same report as produced by ``mapserv -v`` +*/ +MS_DLL_EXPORT char *msGetVersion(void); +/** +Returns the MapServer version number (x.y.z) as an integer (x*10000 + y*100 + z) +e.g. V7.4.2 would return 70402 +*/ +MS_DLL_EXPORT int msGetVersionInt(void); +/** +Return a string of all errors +*/ +MS_DLL_EXPORT char *msGetErrorString(const char *delimiter); -#endif /* SWIG */ +#ifndef SWIG +MS_DLL_EXPORT void msRedactCredentials(char *str); +MS_DLL_EXPORT void msSetError(int code, const char *message, + const char *routine, ...) + MS_PRINT_FUNC_FORMAT(2, 4); +MS_DLL_EXPORT void msWriteError(FILE *stream); +MS_DLL_EXPORT void msWriteErrorXML(FILE *stream); +MS_DLL_EXPORT char *msGetErrorCodeString(int code); +MS_DLL_EXPORT char *msAddErrorDisplayString(char *source, errorObj *error); + +struct mapObj; +MS_DLL_EXPORT void msWriteErrorImage(struct mapObj *map, char *filename, + int blank); - /*==================================================================== - * mapdebug.c (See also MS-RFC-28) - *====================================================================*/ +#endif /* SWIG */ - typedef enum { MS_DEBUGLEVEL_ERRORSONLY = 0, /* DEBUG OFF, log fatal errors */ - MS_DEBUGLEVEL_DEBUG = 1, /* DEBUG ON */ - MS_DEBUGLEVEL_TUNING = 2, /* Reports timing info */ - MS_DEBUGLEVEL_V = 3, /* Verbose */ - MS_DEBUGLEVEL_VV = 4, /* Very verbose */ - MS_DEBUGLEVEL_VVV = 5, /* Very very verbose */ - MS_DEBUGLEVEL_DEVDEBUG = 20, /* Undocumented, will trigger debug messages only useful for developers */ - } debugLevel; +/*==================================================================== + * mapdebug.c (See also MS-RFC-28) + *====================================================================*/ + +typedef enum { + MS_DEBUGLEVEL_ERRORSONLY = 0, /* DEBUG OFF, log fatal errors */ + MS_DEBUGLEVEL_DEBUG = 1, /* DEBUG ON */ + MS_DEBUGLEVEL_TUNING = 2, /* Reports timing info */ + MS_DEBUGLEVEL_V = 3, /* Verbose */ + MS_DEBUGLEVEL_VV = 4, /* Very verbose */ + MS_DEBUGLEVEL_VVV = 5, /* Very very verbose */ + MS_DEBUGLEVEL_DEVDEBUG = 20, /* Undocumented, will trigger debug messages only + useful for developers */ +} debugLevel; #ifndef SWIG - typedef enum { MS_DEBUGMODE_OFF, - MS_DEBUGMODE_FILE, - MS_DEBUGMODE_STDERR, - MS_DEBUGMODE_STDOUT, - MS_DEBUGMODE_WINDOWSDEBUG - } debugMode; - - typedef struct debug_info_obj { - debugLevel global_debug_level; - debugMode debug_mode; - char *errorfile; - FILE *fp; - /* The following 2 members are used only with USE_THREAD (but we won't #ifndef them) */ - void* thread_id; - struct debug_info_obj *next; - } debugInfoObj; - - - MS_DLL_EXPORT void msDebug( const char * pszFormat, ... ) MS_PRINT_FUNC_FORMAT(1,2) ; - MS_DLL_EXPORT int msSetErrorFile(const char *pszErrorFile, const char *pszRelToPath); - MS_DLL_EXPORT void msCloseErrorFile( void ); - MS_DLL_EXPORT const char *msGetErrorFile( void ); - MS_DLL_EXPORT void msSetGlobalDebugLevel(int level); - MS_DLL_EXPORT debugLevel msGetGlobalDebugLevel( void ); - MS_DLL_EXPORT int msDebugInitFromEnv( void ); - MS_DLL_EXPORT void msDebugCleanup( void ); +typedef enum { + MS_DEBUGMODE_OFF, + MS_DEBUGMODE_FILE, + MS_DEBUGMODE_STDERR, + MS_DEBUGMODE_STDOUT, + MS_DEBUGMODE_WINDOWSDEBUG +} debugMode; + +typedef struct debug_info_obj { + debugLevel global_debug_level; + debugMode debug_mode; + char *errorfile; + FILE *fp; + /* The following 2 members are used only with USE_THREAD (but we won't #ifndef + * them) */ + void *thread_id; + struct debug_info_obj *next; +} debugInfoObj; + +MS_DLL_EXPORT void msDebug(const char *pszFormat, ...) + MS_PRINT_FUNC_FORMAT(1, 2); +MS_DLL_EXPORT int msSetErrorFile(const char *pszErrorFile, + const char *pszRelToPath); +MS_DLL_EXPORT void msCloseErrorFile(void); +MS_DLL_EXPORT const char *msGetErrorFile(void); +MS_DLL_EXPORT void msSetGlobalDebugLevel(int level); +MS_DLL_EXPORT debugLevel msGetGlobalDebugLevel(void); +MS_DLL_EXPORT int msDebugInitFromEnv(void); +MS_DLL_EXPORT void msDebugCleanup(void); #endif /* SWIG */ diff --git a/mapfile.c b/mapfile.c old mode 100755 new mode 100644 index 7ebba00b06..6c3bdddc37 --- a/mapfile.c +++ b/mapfile.c @@ -62,24 +62,31 @@ extern char *msyystring_buffer; extern int msyystring_icase; extern int loadSymbol(symbolObj *s, char *symbolpath); /* in mapsymbol.c */ -extern void writeSymbol(symbolObj *s, FILE *stream); /* in mapsymbol.c */ -static int loadGrid( layerObj *pLayer ); +extern void writeSymbol(symbolObj *s, FILE *stream); /* in mapsymbol.c */ +static int loadGrid(layerObj *pLayer); static int loadStyle(styleObj *style); -static void writeStyle(FILE* stream, int indent, styleObj *style); +static void writeStyle(FILE *stream, int indent, styleObj *style); static int resolveSymbolNames(mapObj *map); static int loadExpression(expressionObj *exp); -static void writeExpression(FILE *stream, int indent, const char *name, expressionObj *exp); - +static void writeExpression(FILE *stream, int indent, const char *name, + expressionObj *exp); /* ** Symbol to string static arrays needed for writing map files. ** Must be kept in sync with enumerations and defines found in mapserver.h. */ -/* static char *msUnits[9]={"INCHES", "FEET", "MILES", "METERS", "KILOMETERS", "DD", "PIXELS", "PERCENTAGES", "NAUTICALMILES"}; */ -/* static char *msLayerTypes[10]={"POINT", "LINE", "POLYGON", "RASTER", "ANNOTATION", "QUERY", "CIRCLE", "TILEINDEX","CHART"}; */ -char *msPositionsText[MS_POSITIONS_LENGTH] = {"UL", "LR", "UR", "LL", "CR", "CL", "UC", "LC", "CC", "AUTO", "XY", "FOLLOW"}; /* msLabelPositions[] also used in mapsymbols.c (not static) */ -/* static char *msBitmapFontSizes[5]={"TINY", "SMALL", "MEDIUM", "LARGE", "GIANT"}; */ -/* static char *msQueryMapStyles[4]={"NORMAL", "HILITE", "SELECTED", "INVERTED"}; */ +/* static char *msUnits[9]={"INCHES", "FEET", "MILES", "METERS", "KILOMETERS", + * "DD", "PIXELS", "PERCENTAGES", "NAUTICALMILES"}; */ +/* static char *msLayerTypes[10]={"POINT", "LINE", "POLYGON", "RASTER", + * "ANNOTATION", "QUERY", "CIRCLE", "TILEINDEX","CHART"}; */ +char *msPositionsText[MS_POSITIONS_LENGTH] = { + "UL", "LR", "UR", "LL", "CR", "CL", "UC", + "LC", "CC", "AUTO", "XY", "FOLLOW"}; /* msLabelPositions[] also used in + mapsymbols.c (not static) */ +/* static char *msBitmapFontSizes[5]={"TINY", "SMALL", "MEDIUM", "LARGE", + * "GIANT"}; */ +/* static char *msQueryMapStyles[4]={"NORMAL", "HILITE", "SELECTED", + * "INVERTED"}; */ /* static char *msStatus[4]={"OFF", "ON", "DEFAULT", "EMBED"}; */ /* static char *msOnOff[2]={"OFF", "ON"}; */ /* static char *msTrueFalse[2]={"FALSE", "TRUE"}; */ @@ -88,84 +95,93 @@ char *msPositionsText[MS_POSITIONS_LENGTH] = {"UL", "LR", "UR", "LL", "CR", "CL" /* static char *msAlignValue[3]={"LEFT","CENTER","RIGHT"}; */ /* -** Validates a string (value) against a series of patterns. We support up to four to allow cascading from classObj to +** Validates a string (value) against a series of patterns. We support up to +*four to allow cascading from classObj to ** layerObj to webObj plus a legacy pattern like TEMPLATEPATTERN. */ -int msValidateParameter(const char *value, const char *pattern1, const char *pattern2, const char *pattern3, const char *pattern4) -{ - if(msEvalRegex(pattern1, value) == MS_TRUE) return MS_SUCCESS; - if(msEvalRegex(pattern2, value) == MS_TRUE) return MS_SUCCESS; - if(msEvalRegex(pattern3, value) == MS_TRUE) return MS_SUCCESS; - if(msEvalRegex(pattern4, value) == MS_TRUE) return MS_SUCCESS; +int msValidateParameter(const char *value, const char *pattern1, + const char *pattern2, const char *pattern3, + const char *pattern4) { + if (msEvalRegex(pattern1, value) == MS_TRUE) + return MS_SUCCESS; + if (msEvalRegex(pattern2, value) == MS_TRUE) + return MS_SUCCESS; + if (msEvalRegex(pattern3, value) == MS_TRUE) + return MS_SUCCESS; + if (msEvalRegex(pattern4, value) == MS_TRUE) + return MS_SUCCESS; - return(MS_FAILURE); + return (MS_FAILURE); } -int msIsValidRegex(const char* e) { +int msIsValidRegex(const char *e) { ms_regex_t re; - if(ms_regcomp(&re, e, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { - msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); - return(MS_FALSE); + if (ms_regcomp(&re, e, MS_REG_EXTENDED | MS_REG_NOSUB) != 0) { + msSetError(MS_REGEXERR, "Failed to compile expression (%s).", + "msEvalRegex()", e); + return (MS_FALSE); } ms_regfree(&re); return MS_TRUE; } -int msEvalRegex(const char *e, const char *s) -{ +int msEvalRegex(const char *e, const char *s) { ms_regex_t re; - if(!e || !s) return(MS_FALSE); + if (!e || !s) + return (MS_FALSE); - if(ms_regcomp(&re, e, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { - msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); - return(MS_FALSE); + if (ms_regcomp(&re, e, MS_REG_EXTENDED | MS_REG_NOSUB) != 0) { + msSetError(MS_REGEXERR, "Failed to compile expression (%s).", + "msEvalRegex()", e); + return (MS_FALSE); } - if(ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ + if (ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ ms_regfree(&re); - return(MS_FALSE); + return (MS_FALSE); } ms_regfree(&re); - return(MS_TRUE); + return (MS_TRUE); } -int msCaseEvalRegex(const char *e, const char *s) -{ +int msCaseEvalRegex(const char *e, const char *s) { ms_regex_t re; - if(!e || !s) return(MS_FALSE); + if (!e || !s) + return (MS_FALSE); - if(ms_regcomp(&re, e, MS_REG_EXTENDED|MS_REG_ICASE|MS_REG_NOSUB) != 0) { - msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); - return(MS_FALSE); + if (ms_regcomp(&re, e, MS_REG_EXTENDED | MS_REG_ICASE | MS_REG_NOSUB) != 0) { + msSetError(MS_REGEXERR, "Failed to compile expression (%s).", + "msEvalRegex()", e); + return (MS_FALSE); } - if(ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ + if (ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ ms_regfree(&re); - return(MS_FALSE); + return (MS_FALSE); } ms_regfree(&re); - return(MS_TRUE); + return (MS_TRUE); } #ifdef USE_MSFREE -void msFree(void *p) -{ - if(p) free(p); +void msFree(void *p) { + if (p) + free(p); } #endif /* ** Free memory allocated for a character array */ -void msFreeCharArray(char **array, int num_items) -{ +void msFreeCharArray(char **array, int num_items) { int i; - if(!array) return; - for(i=0; i= value1 && number <= value2) { + } else if (num_check_type == MS_NUM_CHECK_RANGE && number >= value1 && + number <= value2) { return MS_SUCCESS; - } else if(num_check_type == MS_NUM_CHECK_GT && number > value1) { + } else if (num_check_type == MS_NUM_CHECK_GT && number > value1) { return MS_SUCCESS; - } else if(num_check_type == MS_NUM_CHECK_GTE && number >= value1) { + } else if (num_check_type == MS_NUM_CHECK_GTE && number >= value1) { return MS_SUCCESS; } @@ -268,55 +283,56 @@ int msCheckNumber(double number, int num_check_type, double value1, double value /* ** Load a floating point number from the map file. (see lexer.l) */ -int getDouble(double *d, int num_check_type, double value1, double value2) -{ - if(msyylex() == MS_NUMBER) { - if(msCheckNumber(msyynumber, num_check_type, value1, value2) == MS_SUCCESS) { +int getDouble(double *d, int num_check_type, double value1, double value2) { + if (msyylex() == MS_NUMBER) { + if (msCheckNumber(msyynumber, num_check_type, value1, value2) == + MS_SUCCESS) { *d = msyynumber; - return(0); + return (0); } } - msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getDouble()", msyystring_buffer, msyylineno); - return(-1); + msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getDouble()", + msyystring_buffer, msyylineno); + return (-1); } /* ** Load a integer from the map file. (see lexer.l) */ -int getInteger(int *i, int num_check_type, int value1, int value2) -{ - if(msyylex() == MS_NUMBER) { - if(msCheckNumber(msyynumber, num_check_type, value1, value2) == MS_SUCCESS) { +int getInteger(int *i, int num_check_type, int value1, int value2) { + if (msyylex() == MS_NUMBER) { + if (msCheckNumber(msyynumber, num_check_type, value1, value2) == + MS_SUCCESS) { *i = (int)msyynumber; - return(0); + return (0); } } - msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getInteger()", msyystring_buffer, msyylineno); - return(-1); + msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getInteger()", + msyystring_buffer, msyylineno); + return (-1); } -int getCharacter(char *c) -{ - if(msyylex() == MS_STRING) { +int getCharacter(char *c) { + if (msyylex() == MS_STRING) { *c = msyystring_buffer[0]; - return(0); + return (0); } - msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getCharacter()", msyystring_buffer, msyylineno); - return(-1); + msSetError(MS_SYMERR, "Parsing error near (%s):(line %d)", "getCharacter()", + msyystring_buffer, msyylineno); + return (-1); } /* ** Try to load as an integer, then try as a named symbol. ** Part of work on bug 490. */ -int getIntegerOrSymbol(int *i, int n, ...) -{ +int getIntegerOrSymbol(int *i, int n, ...) { int symbol; va_list argp; - int j=0; + int j = 0; symbol = msyylex(); @@ -326,8 +342,8 @@ int getIntegerOrSymbol(int *i, int n, ...) } va_start(argp, n); - while (jconfigoptions), "MS_PLUGIN_DIR"); - /* do nothing on windows, filename without .dll will be loaded by default*/ + /* do nothing on windows, filename without .dll will be loaded by default*/ #if !defined(_WIN32) if (lib_str) { size_t len = strlen(lib_str); - if (3 < len && strcmp(lib_str + len-3, ".so")) { + if (3 < len && strcmp(lib_str + len - 3, ".so")) { strlcpy(szLibPathExt, lib_str, MS_MAXPATHLEN); strlcat(szLibPathExt, ".so", MS_MAXPATHLEN); lib_str = szLibPathExt; @@ -382,70 +396,78 @@ int msBuildPluginLibraryPath(char **dest, const char *lib_str, mapObj *map) ** If try_addimage_if_notfound==MS_TRUE then msAddImageSymbol() will be called ** to try to allocate the symbol as an image symbol. */ -int msGetSymbolIndex(symbolSetObj *symbols, char *name, int try_addimage_if_notfound) -{ +int msGetSymbolIndex(symbolSetObj *symbols, char *name, + int try_addimage_if_notfound) { int i; - if(!symbols || !name) return(-1); + if (!symbols || !name) + return (-1); /* symbol 0 has no name */ - for(i=1; inumsymbols; i++) { - if(symbols->symbol[i]->name) - if(strcasecmp(symbols->symbol[i]->name, name) == 0) return(i); + for (i = 1; i < symbols->numsymbols; i++) { + if (symbols->symbol[i]->name) + if (strcasecmp(symbols->symbol[i]->name, name) == 0) + return (i); } if (try_addimage_if_notfound) - return(msAddImageSymbol(symbols, name)); /* make sure it's not a filename */ + return ( + msAddImageSymbol(symbols, name)); /* make sure it's not a filename */ - return(-1); + return (-1); } /* ** Return the index number for a given layer based on its name. */ -int msGetLayerIndex(mapObj *map, const char *name) -{ +int msGetLayerIndex(mapObj *map, const char *name) { int i; - if(!name) return(-1); + if (!name) + return (-1); - for(i=0; inumlayers; i++) { - if(!GET_LAYER(map, i)->name) /* skip it */ + for (i = 0; i < map->numlayers; i++) { + if (!GET_LAYER(map, i)->name) /* skip it */ continue; - if(strcmp(name, GET_LAYER(map, i)->name) == 0) - return(i); + if (strcmp(name, GET_LAYER(map, i)->name) == 0) + return (i); } - return(-1); + return (-1); } -int loadColor(colorObj *color, attributeBindingObj *binding) -{ +int loadColor(colorObj *color, attributeBindingObj *binding) { int symbol; char hex[2]; /* - ** Note that negative color values can be used to suppress or change behavior. For example, referenceObj uses + ** Note that negative color values can be used to suppress or change behavior. + *For example, referenceObj uses ** a negative color component to suppress rectangle fills. */ - if(binding) { - if((symbol = getSymbol(3, MS_NUMBER, MS_BINDING, MS_STRING)) == -1) return MS_FAILURE; + if (binding) { + if ((symbol = getSymbol(3, MS_NUMBER, MS_BINDING, MS_STRING)) == -1) + return MS_FAILURE; } else { - if((symbol = getSymbol(2, MS_NUMBER, MS_STRING)) == -1) return MS_FAILURE; + if ((symbol = getSymbol(2, MS_NUMBER, MS_STRING)) == -1) + return MS_FAILURE; } - color->alpha=255; - if(symbol == MS_NUMBER) { - if(msyynumber >= -255 && msyynumber <= 255) { - color->red = (int) msyynumber; + color->alpha = 255; + if (symbol == MS_NUMBER) { + if (msyynumber >= -255 && msyynumber <= 255) { + color->red = (int)msyynumber; } else { return MS_FAILURE; } - if(getInteger(&(color->green), MS_NUM_CHECK_RANGE, -255, 255) == -1) return MS_FAILURE; - if(getInteger(&(color->blue), MS_NUM_CHECK_RANGE, -255, 255) == -1) return MS_FAILURE; - } else if(symbol == MS_STRING) { + if (getInteger(&(color->green), MS_NUM_CHECK_RANGE, -255, 255) == -1) + return MS_FAILURE; + if (getInteger(&(color->blue), MS_NUM_CHECK_RANGE, -255, 255) == -1) + return MS_FAILURE; + } else if (symbol == MS_STRING) { int len = strlen(msyystring_buffer); - if(msyystring_buffer[0] == '#' && (len == 7 || len == 9)) { /* got a hex color w/optional alpha */ + if (msyystring_buffer[0] == '#' && + (len == 7 || len == 9)) { /* got a hex color w/optional alpha */ hex[0] = msyystring_buffer[1]; hex[1] = msyystring_buffer[2]; color->red = msHexToInt(hex); @@ -455,14 +477,15 @@ int loadColor(colorObj *color, attributeBindingObj *binding) hex[0] = msyystring_buffer[5]; hex[1] = msyystring_buffer[6]; color->blue = msHexToInt(hex); - if(len == 9) { + if (len == 9) { hex[0] = msyystring_buffer[7]; hex[1] = msyystring_buffer[8]; color->alpha = msHexToInt(hex); } } else { /* TODO: consider named colors here */ - msSetError(MS_SYMERR, "Invalid hex color (%s):(line %d)", "loadColor()", msyystring_buffer, msyylineno); + msSetError(MS_SYMERR, "Invalid hex color (%s):(line %d)", "loadColor()", + msyystring_buffer, msyylineno); return MS_FAILURE; } } else { @@ -476,18 +499,18 @@ int loadColor(colorObj *color, attributeBindingObj *binding) } #if ALPHACOLOR_ENABLED -int loadColorWithAlpha(colorObj *color) -{ +int loadColorWithAlpha(colorObj *color) { char hex[2]; - /* - ** Note that negative color values can be used to suppress or change behavior. For example, referenceObj uses + ** Note that negative color values can be used to suppress or change behavior. + *For example, referenceObj uses ** a negative color component to suppress rectangle fills. */ - if(getInteger(&(color->red), MS_NUM_CHECK_RANGE, -255, 255) == -1) { - if(msyystring_buffer[0] == '#' && strlen(msyystring_buffer) == 7) { /* got a hex color */ + if (getInteger(&(color->red), MS_NUM_CHECK_RANGE, -255, 255) == -1) { + if (msyystring_buffer[0] == '#' && + strlen(msyystring_buffer) == 7) { /* got a hex color */ hex[0] = msyystring_buffer[1]; hex[1] = msyystring_buffer[2]; color->red = msHexToInt(hex); @@ -499,8 +522,10 @@ int loadColorWithAlpha(colorObj *color) color->blue = msHexToInt(hex); color->alpha = 0; - return(MS_SUCCESS); - } else if(msyystring_buffer[0] == '#' && strlen(msyystring_buffer) == 9) { /* got a hex color with alpha */ + return (MS_SUCCESS); + } else if (msyystring_buffer[0] == '#' && + strlen(msyystring_buffer) == + 9) { /* got a hex color with alpha */ hex[0] = msyystring_buffer[1]; hex[1] = msyystring_buffer[2]; color->red = msHexToInt(hex); @@ -513,56 +538,55 @@ int loadColorWithAlpha(colorObj *color) hex[0] = msyystring_buffer[7]; hex[1] = msyystring_buffer[8]; color->alpha = msHexToInt(hex); - return(MS_SUCCESS); + return (MS_SUCCESS); } - return(MS_FAILURE); + return (MS_FAILURE); } - if(getInteger(&(color->green), MS_NUM_CHECK_RANGE, -255, 255) == -1) return(MS_FAILURE); - if(getInteger(&(color->blue), MS_NUM_CHECK_RANGE, -255, 255) == -1) return(MS_FAILURE); - if(getInteger(&(color->alpha), MS_NUM_CHECK_RANGE, 0, 255) == -1) return(MS_FAILURE); + if (getInteger(&(color->green), MS_NUM_CHECK_RANGE, -255, 255) == -1) + return (MS_FAILURE); + if (getInteger(&(color->blue), MS_NUM_CHECK_RANGE, -255, 255) == -1) + return (MS_FAILURE); + if (getInteger(&(color->alpha), MS_NUM_CHECK_RANGE, 0, 255) == -1) + return (MS_FAILURE); - return(MS_SUCCESS); + return (MS_SUCCESS); } #endif /* ** Helper functions for writing mapfiles. */ -static void writeLineFeed(FILE *stream) -{ - msIO_fprintf(stream, "\n"); -} +static void writeLineFeed(FILE *stream) { msIO_fprintf(stream, "\n"); } -static void writeIndent(FILE *stream, int indent) -{ - const char *str=" "; /* change this string to define the indent */ +static void writeIndent(FILE *stream, int indent) { + const char *str = " "; /* change this string to define the indent */ int i; - for(i=0; iitem) return; +static void writeAttributeBinding(FILE *stream, int indent, const char *name, + attributeBindingObj *binding) { + if (!binding || !binding->item) + return; writeIndent(stream, ++indent); msIO_fprintf(stream, "%s [%s]\n", name, binding->item); } -static void writeColor(FILE *stream, int indent, const char *name, colorObj *defaultColor, colorObj *color) -{ - if (!defaultColor && !MS_VALID_COLOR(*color)) return; - else if(defaultColor && MS_COMPARE_COLOR(*defaultColor, *color)) return; /* if defaultColor has the same value than the color, return.*/ +static void writeColor(FILE *stream, int indent, const char *name, + colorObj *defaultColor, colorObj *color) { + if (!defaultColor && !MS_VALID_COLOR(*color)) + return; + else if (defaultColor && MS_COMPARE_COLOR(*defaultColor, *color)) + return; /* if defaultColor has the same value than the color, return.*/ writeIndent(stream, ++indent); #if ALPHACOLOR_ENABLED - msIO_fprintf(stream, "%s %d %d %d\n", name, color->red, color->green, color->blue, color->alpha); + msIO_fprintf(stream, "%s %d %d %d\n", name, color->red, color->green, + color->blue, color->alpha); #else - if(color->alpha != 255) { + if (color->alpha != 255) { char buffer[9]; sprintf(buffer, "%02x", color->red); - sprintf(buffer+2, "%02x", color->green); - sprintf(buffer+4, "%02x", color->blue); - sprintf(buffer+6, "%02x", color->alpha); - *(buffer+8) = 0; + sprintf(buffer + 2, "%02x", color->green); + sprintf(buffer + 4, "%02x", color->blue); + sprintf(buffer + 6, "%02x", color->alpha); + *(buffer + 8) = 0; msIO_fprintf(stream, "%s \"#%s\"\n", name, buffer); } else { - msIO_fprintf(stream, "%s %d %d %d\n", name, color->red, color->green, color->blue); + msIO_fprintf(stream, "%s %d %d %d\n", name, color->red, color->green, + color->blue); } #endif } /* todo: deal with alpha's... */ -static void writeColorRange(FILE *stream, int indent, const char *name, colorObj *mincolor, colorObj *maxcolor) -{ - if(!MS_VALID_COLOR(*mincolor) || !MS_VALID_COLOR(*maxcolor)) return; +static void writeColorRange(FILE *stream, int indent, const char *name, + colorObj *mincolor, colorObj *maxcolor) { + if (!MS_VALID_COLOR(*mincolor) || !MS_VALID_COLOR(*maxcolor)) + return; writeIndent(stream, ++indent); - msIO_fprintf(stream, "%s %d %d %d %d %d %d\n", name, mincolor->red, mincolor->green, mincolor->blue, maxcolor->red, maxcolor->green, maxcolor->blue); + msIO_fprintf(stream, "%s %d %d %d %d %d %d\n", name, mincolor->red, + mincolor->green, mincolor->blue, maxcolor->red, maxcolor->green, + maxcolor->blue); } /* ** Initialize, load and free a single join */ -void initJoin(joinObj *join) -{ +void initJoin(joinObj *join) { join->numitems = 0; join->name = NULL; /* unique join name, used for variable substitution */ - join->items = NULL; /* array to hold item names for the joined table */ + join->items = NULL; /* array to hold item names for the joined table */ join->values = NULL; /* arrays of strings to holds one record worth of data */ join->table = NULL; @@ -752,8 +801,7 @@ void initJoin(joinObj *join) join->connectiontype = MS_DB_XBASE; } -void freeJoin(joinObj *join) -{ +void freeJoin(joinObj *join) { msFree(join->name); msFree(join->table); msFree(join->from); @@ -763,7 +811,8 @@ void freeJoin(joinObj *join) msFree(join->template); msFree(join->footer); - msFreeCharArray(join->items, join->numitems); /* these may have been free'd elsewhere */ + msFreeCharArray(join->items, + join->numitems); /* these may have been free'd elsewhere */ msFreeCharArray(join->values, join->numitems); join->numitems = 0; @@ -771,63 +820,80 @@ void freeJoin(joinObj *join) msFree(join->connection); } -int loadJoin(joinObj *join) -{ +int loadJoin(joinObj *join) { int nTmp; initJoin(join); - for(;;) { - switch(msyylex()) { - case(CONNECTION): - if(getString(&join->connection) == MS_FAILURE) return(-1); - break; - case(CONNECTIONTYPE): - if((nTmp = getSymbol(5, MS_DB_XBASE, MS_DB_MYSQL, MS_DB_ORACLE, MS_DB_POSTGRES, MS_DB_CSV)) == -1) return(-1); - join->connectiontype = nTmp; - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadJoin()"); - return(-1); - case(END): - if((join->from == NULL) || (join->to == NULL) || (join->table == NULL)) { - msSetError(MS_EOFERR, "Join must define table, name, from and to properties.", "loadJoin()"); - return(-1); - } - if((join->type == MS_MULTIPLE) && ((join->template == NULL) || (join->name == NULL))) { - msSetError(MS_EOFERR, "One-to-many joins must define template and name properties.", "loadJoin()"); - return(-1); - } - return(0); - case(FOOTER): - if(getString(&join->footer) == MS_FAILURE) return(-1); - break; - case(FROM): - if(getString(&join->from) == MS_FAILURE) return(-1); - break; - case(HEADER): - if(getString(&join->header) == MS_FAILURE) return(-1); - break; - case(JOIN): - break; /* for string loads */ - case(NAME): - if(getString(&join->name) == MS_FAILURE) return(-1); - break; - case(TABLE): - if(getString(&join->table) == MS_FAILURE) return(-1); - break; - case(TEMPLATE): - if(getString(&join->template) == MS_FAILURE) return(-1); - break; - case(TO): - if(getString(&join->to) == MS_FAILURE) return(-1); - break; - case(TYPE): - if((nTmp = getSymbol(2, MS_JOIN_ONE_TO_ONE, MS_JOIN_ONE_TO_MANY)) == -1) return(-1); - join->type = nTmp; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadJoin()", msyystring_buffer, msyylineno); - return(-1); + for (;;) { + switch (msyylex()) { + case (CONNECTION): + if (getString(&join->connection) == MS_FAILURE) + return (-1); + break; + case (CONNECTIONTYPE): + if ((nTmp = getSymbol(5, MS_DB_XBASE, MS_DB_MYSQL, MS_DB_ORACLE, + MS_DB_POSTGRES, MS_DB_CSV)) == -1) + return (-1); + join->connectiontype = nTmp; + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadJoin()"); + return (-1); + case (END): + if ((join->from == NULL) || (join->to == NULL) || (join->table == NULL)) { + msSetError(MS_EOFERR, + "Join must define table, name, from and to properties.", + "loadJoin()"); + return (-1); + } + if ((join->type == MS_MULTIPLE) && + ((join->template == NULL) || (join->name == NULL))) { + msSetError( + MS_EOFERR, + "One-to-many joins must define template and name properties.", + "loadJoin()"); + return (-1); + } + return (0); + case (FOOTER): + if (getString(&join->footer) == MS_FAILURE) + return (-1); + break; + case (FROM): + if (getString(&join->from) == MS_FAILURE) + return (-1); + break; + case (HEADER): + if (getString(&join->header) == MS_FAILURE) + return (-1); + break; + case (JOIN): + break; /* for string loads */ + case (NAME): + if (getString(&join->name) == MS_FAILURE) + return (-1); + break; + case (TABLE): + if (getString(&join->table) == MS_FAILURE) + return (-1); + break; + case (TEMPLATE): + if (getString(&join->template) == MS_FAILURE) + return (-1); + break; + case (TO): + if (getString(&join->to) == MS_FAILURE) + return (-1); + break; + case (TYPE): + if ((nTmp = getSymbol(2, MS_JOIN_ONE_TO_ONE, MS_JOIN_ONE_TO_MANY)) == -1) + return (-1); + join->type = nTmp; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadJoin()", + msyystring_buffer, msyylineno); + return (-1); } } /* next token */ } @@ -835,22 +901,21 @@ int loadJoin(joinObj *join) static void writeScaleToken(FILE *stream, int indent, scaleTokenObj *token) { int i; indent++; - writeBlockBegin(stream,indent,"SCALETOKEN"); + writeBlockBegin(stream, indent, "SCALETOKEN"); writeString(stream, indent, "NAME", NULL, token->name); indent++; - writeBlockBegin(stream,indent,"VALUES"); - for(i=0;in_entries;i++) { + writeBlockBegin(stream, indent, "VALUES"); + for (i = 0; i < token->n_entries; i++) { char minscale[32]; - sprintf(minscale,"%g",token->tokens[i].minscale); + sprintf(minscale, "%g", token->tokens[i].minscale); writeNameValuePair(stream, indent, minscale, token->tokens[i].value); } - writeBlockEnd(stream,indent,"VALUES"); + writeBlockEnd(stream, indent, "VALUES"); indent--; - writeBlockEnd(stream,indent,"SCALETOKEN"); + writeBlockEnd(stream, indent, "SCALETOKEN"); } -static void writeJoin(FILE *stream, int indent, joinObj *join) -{ +static void writeJoin(FILE *stream, int indent, joinObj *join) { indent++; writeBlockBegin(stream, indent, "JOIN"); writeString(stream, indent, "FOOTER", NULL, join->footer); @@ -860,36 +925,44 @@ static void writeJoin(FILE *stream, int indent, joinObj *join) writeString(stream, indent, "TABLE", NULL, join->table); writeString(stream, indent, "TEMPLATE", NULL, join->template); writeString(stream, indent, "TO", NULL, join->to); - writeKeyword(stream, indent, "CONNECTIONTYPE", join->connectiontype, 3, MS_DB_CSV, "CSV", MS_DB_POSTGRES, "POSTGRESQL", MS_DB_MYSQL, "MYSQL"); - writeKeyword(stream, indent, "TYPE", join->type, 1, MS_JOIN_ONE_TO_MANY, "ONE-TO-MANY"); + writeKeyword(stream, indent, "CONNECTIONTYPE", join->connectiontype, 3, + MS_DB_CSV, "CSV", MS_DB_POSTGRES, "POSTGRESQL", MS_DB_MYSQL, + "MYSQL"); + writeKeyword(stream, indent, "TYPE", join->type, 1, MS_JOIN_ONE_TO_MANY, + "ONE-TO-MANY"); writeBlockEnd(stream, indent, "JOIN"); } /* inserts a feature at the end of the list, can create a new list */ -featureListNodeObjPtr insertFeatureList(featureListNodeObjPtr *list, shapeObj *shape) -{ +featureListNodeObjPtr insertFeatureList(featureListNodeObjPtr *list, + shapeObj *shape) { featureListNodeObjPtr node; - node = (featureListNodeObjPtr) msSmallMalloc(sizeof(featureListNodeObj)); + node = (featureListNodeObjPtr)msSmallMalloc(sizeof(featureListNodeObj)); msInitShape(&(node->shape)); - if(msCopyShape(shape, &(node->shape)) == -1) { + if (msCopyShape(shape, &(node->shape)) == -1) { msFree(node); - return(NULL); + return (NULL); } - /* AJS - alans@wunderground.com O(n^2) -> O(n) conversion, keep a pointer to the end */ + /* AJS - alans@wunderground.com O(n^2) -> O(n) conversion, keep a pointer to + * the end */ - /* set the tailifhead to NULL, since it is only set for the head of the list */ + /* set the tailifhead to NULL, since it is only set for the head of the list + */ node->tailifhead = NULL; node->next = NULL; - /* if we are at the head of the list, we need to set the list to node, before pointing tailifhead somewhere */ - if(*list == NULL) { - *list=node; + /* if we are at the head of the list, we need to set the list to node, before + * pointing tailifhead somewhere */ + if (*list == NULL) { + *list = node; } else { - if((*list)->tailifhead!=NULL) /* this should never be NULL, but just in case */ - (*list)->tailifhead->next=node; /* put the node at the end of the list */ + if ((*list)->tailifhead != + NULL) /* this should never be NULL, but just in case */ + (*list)->tailifhead->next = + node; /* put the node at the end of the list */ } /* repoint the head of the list to the end - our new element @@ -897,13 +970,12 @@ featureListNodeObjPtr insertFeatureList(featureListNodeObjPtr *list, shapeObj *s walk in a loop */ (*list)->tailifhead = node; - return(node); /* a pointer to last object in the list */ + return (node); /* a pointer to last object in the list */ } -void freeFeatureList(featureListNodeObjPtr list) -{ +void freeFeatureList(featureListNodeObjPtr list) { featureListNodeObjPtr listNext = NULL; - while (list!=NULL) { + while (list != NULL) { listNext = list->next; msFreeShape(&(list->shape)); msFree(list); @@ -912,53 +984,59 @@ void freeFeatureList(featureListNodeObjPtr list) } /* lineObj = multipointObj */ -static int loadFeaturePoints(lineObj *points) -{ +static int loadFeaturePoints(lineObj *points) { int ret = -1; - int buffer_size=0; + int buffer_size = 0; - points->point = (pointObj *)malloc(sizeof(pointObj)*MS_FEATUREINITSIZE); - MS_CHECK_ALLOC(points->point, sizeof(pointObj)*MS_FEATUREINITSIZE, MS_FAILURE); + points->point = (pointObj *)malloc(sizeof(pointObj) * MS_FEATUREINITSIZE); + MS_CHECK_ALLOC(points->point, sizeof(pointObj) * MS_FEATUREINITSIZE, + MS_FAILURE); points->numpoints = 0; buffer_size = MS_FEATUREINITSIZE; - while( ret < 0 ) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadFeaturePoints()"); - ret = MS_FAILURE; - break; - case(END): - ret = MS_SUCCESS; - break; - case(MS_NUMBER): - if(points->numpoints == buffer_size) { /* just add it to the end */ - pointObj* newPoints = (pointObj *) realloc(points->point, sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT)); - if( newPoints == NULL ) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", __FUNCTION__, - __FILE__, __LINE__, (unsigned int)(sizeof(pointObj)*(buffer_size+MS_FEATUREINCREMENT))); - ret = MS_FAILURE; - break; - } - points->point = newPoints; - buffer_size+=MS_FEATUREINCREMENT; - } - - points->point[points->numpoints].x = atof(msyystring_buffer); - if(getDouble(&(points->point[points->numpoints].y), MS_NUM_CHECK_NONE, -1, -1) == -1) { + while (ret < 0) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadFeaturePoints()"); + ret = MS_FAILURE; + break; + case (END): + ret = MS_SUCCESS; + break; + case (MS_NUMBER): + if (points->numpoints == buffer_size) { /* just add it to the end */ + pointObj *newPoints = (pointObj *)realloc( + points->point, + sizeof(pointObj) * (buffer_size + MS_FEATUREINCREMENT)); + if (newPoints == NULL) { + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + __FUNCTION__, __FILE__, __LINE__, + (unsigned int)(sizeof(pointObj) * + (buffer_size + MS_FEATUREINCREMENT))); ret = MS_FAILURE; break; } - points->numpoints++; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadFeaturePoints()", msyystring_buffer, msyylineno ); + points->point = newPoints; + buffer_size += MS_FEATUREINCREMENT; + } + + points->point[points->numpoints].x = atof(msyystring_buffer); + if (getDouble(&(points->point[points->numpoints].y), MS_NUM_CHECK_NONE, + -1, -1) == -1) { ret = MS_FAILURE; break; + } + points->numpoints++; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadFeaturePoints()", msyystring_buffer, msyylineno); + ret = MS_FAILURE; + break; } } - if( ret == MS_FAILURE ) { + if (ret == MS_FAILURE) { msFree(points->point); /* clean up */ points->point = NULL; points->numpoints = 0; @@ -966,121 +1044,124 @@ static int loadFeaturePoints(lineObj *points) return ret; } -static int loadFeature(layerObj *player, int type) -{ - int status=MS_SUCCESS; +static int loadFeature(layerObj *player, int type) { + int status = MS_SUCCESS; featureListNodeObjPtr *list = &(player->features); - multipointObj points= {0,NULL}; - shapeObj *shape=NULL; + multipointObj points = {0, NULL}; + shapeObj *shape = NULL; - shape = (shapeObj *) malloc(sizeof(shapeObj)); + shape = (shapeObj *)malloc(sizeof(shapeObj)); MS_CHECK_ALLOC(shape, sizeof(shapeObj), MS_FAILURE); msInitShape(shape); shape->type = type; - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadFeature()"); + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadFeature()"); + msFreeShape(shape); /* clean up */ + msFree(shape); + return (MS_FAILURE); + case (END): + if (player->features != NULL && player->features->tailifhead != NULL) + shape->index = player->features->tailifhead->shape.index + 1; + else + shape->index = 0; + if (insertFeatureList(list, shape) == NULL) + status = MS_FAILURE; + + msFreeShape(shape); /* clean up */ + msFree(shape); + + return (status); + case (FEATURE): + break; /* for string loads */ + case (POINTS): + if (loadFeaturePoints(&points) == MS_FAILURE) { msFreeShape(shape); /* clean up */ msFree(shape); - return(MS_FAILURE); - case(END): - if(player->features != NULL && player->features->tailifhead != NULL) - shape->index = player->features->tailifhead->shape.index + 1; - else - shape->index = 0; - if(insertFeatureList(list, shape) == NULL) - status = MS_FAILURE; + return (MS_FAILURE); + } + status = msAddLine(shape, &points); + msFree(points.point); /* clean up */ + points.numpoints = 0; + + if (status == MS_FAILURE) { msFreeShape(shape); /* clean up */ msFree(shape); - - return(status); - case(FEATURE): - break; /* for string loads */ - case(POINTS): - if(loadFeaturePoints(&points) == MS_FAILURE) { - msFreeShape(shape); /* clean up */ - msFree(shape); - return(MS_FAILURE); - } - status = msAddLine(shape, &points); - - msFree(points.point); /* clean up */ - points.numpoints = 0; - - if(status == MS_FAILURE) { - msFreeShape(shape); /* clean up */ - msFree(shape); - return(MS_FAILURE); - } - break; - case(ITEMS): { - char *string=NULL; - if(getString(&string) == MS_FAILURE) { - msFreeShape(shape); /* clean up */ - msFree(shape); - return(MS_FAILURE); - } - if (string) { - if(shape->values) msFreeCharArray(shape->values, shape->numvalues); - shape->values = msStringSplitComplex(string, ";", &shape->numvalues,MS_ALLOWEMPTYTOKENS); - msFree(string); /* clean up */ - } - break; + return (MS_FAILURE); } - case(TEXT): - if(getString(&shape->text) == MS_FAILURE) { - msFreeShape(shape); /* clean up */ - msFree(shape); - return(MS_FAILURE); - } - break; - case(WKT): { - char *string=NULL; + break; + case (ITEMS): { + char *string = NULL; + if (getString(&string) == MS_FAILURE) { + msFreeShape(shape); /* clean up */ + msFree(shape); + return (MS_FAILURE); + } + if (string) { + if (shape->values) + msFreeCharArray(shape->values, shape->numvalues); + shape->values = msStringSplitComplex(string, ";", &shape->numvalues, + MS_ALLOWEMPTYTOKENS); + msFree(string); /* clean up */ + } + break; + } + case (TEXT): + if (getString(&shape->text) == MS_FAILURE) { + msFreeShape(shape); /* clean up */ + msFree(shape); + return (MS_FAILURE); + } + break; + case (WKT): { + char *string = NULL; - /* todo, what do we do with multiple WKT property occurances? */ + /* todo, what do we do with multiple WKT property occurances? */ - msFreeShape(shape); - msFree(shape); - if(getString(&string) == MS_FAILURE) return(MS_FAILURE); + msFreeShape(shape); + msFree(shape); + if (getString(&string) == MS_FAILURE) + return (MS_FAILURE); - if((shape = msShapeFromWKT(string)) == NULL) - status = MS_FAILURE; + if ((shape = msShapeFromWKT(string)) == NULL) + status = MS_FAILURE; - msFree(string); /* clean up */ + msFree(string); /* clean up */ - if(status == MS_FAILURE) { - msFreeShape(shape); /* clean up */ - msFree(shape); - return(MS_FAILURE); - } - break; - } - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadfeature()", msyystring_buffer, msyylineno); + if (status == MS_FAILURE) { msFreeShape(shape); /* clean up */ msFree(shape); - return(MS_FAILURE); + return (MS_FAILURE); + } + break; + } + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadfeature()", msyystring_buffer, msyylineno); + msFreeShape(shape); /* clean up */ + msFree(shape); + return (MS_FAILURE); } } /* next token */ } -static void writeFeature(FILE *stream, int indent, shapeObj *feature) -{ - int i,j; +static void writeFeature(FILE *stream, int indent, shapeObj *feature) { + int i, j; indent++; writeBlockBegin(stream, indent, "FEATURE"); indent++; - for(i=0; inumlines; i++) { + for (i = 0; i < feature->numlines; i++) { writeBlockBegin(stream, indent, "POINTS"); - for(j=0; jline[i].numpoints; j++) { + for (j = 0; j < feature->line[i].numpoints; j++) { writeIndent(stream, indent); - msIO_fprintf(stream, "%.15g %.15g\n", feature->line[i].point[j].x, feature->line[i].point[j].y); + msIO_fprintf(stream, "%.15g %.15g\n", feature->line[i].point[j].x, + feature->line[i].point[j].y); } writeBlockEnd(stream, indent, "POINTS"); } @@ -1089,7 +1170,7 @@ static void writeFeature(FILE *stream, int indent, shapeObj *feature) if (feature->numvalues) { writeIndent(stream, indent); msIO_fprintf(stream, "ITEMS \""); - for (i=0; inumvalues; i++) { + for (i = 0; i < feature->numvalues; i++) { if (i == 0) msIO_fprintf(stream, "%s", feature->values[i]); else @@ -1102,73 +1183,77 @@ static void writeFeature(FILE *stream, int indent, shapeObj *feature) writeBlockEnd(stream, indent, "FEATURE"); } -void initGrid( graticuleObj *pGraticule ) -{ - memset( pGraticule, 0, sizeof( graticuleObj ) ); +void initGrid(graticuleObj *pGraticule) { + memset(pGraticule, 0, sizeof(graticuleObj)); } -void freeGrid( graticuleObj *pGraticule ) -{ +void freeGrid(graticuleObj *pGraticule) { msFree(pGraticule->labelformat); msFree(pGraticule->pboundingpoints); msFree(pGraticule->pboundinglines); } -static int loadGrid( layerObj *pLayer ) -{ - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadGrid()"); - return(-1); - case(END): - return(0); - case(GRID): - break; /* for string loads */ - case( LABELFORMAT ): - if(getString(&(pLayer->grid->labelformat)) == MS_FAILURE) { - if(strcasecmp(msyystring_buffer, "DD") == 0) /* DD triggers a symbol to be returned instead of a string so check for this special case */ { - msFree(pLayer->grid->labelformat); - pLayer->grid->labelformat = msStrdup("DD"); - } - else - return(-1); - } - break; - case( MINARCS ): - if(getDouble(&(pLayer->grid->minarcs), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - case( MAXARCS ): - if(getDouble(&(pLayer->grid->maxarcs), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - case( MININTERVAL ): - if(getDouble(&(pLayer->grid->minincrement), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - case( MAXINTERVAL ): - if(getDouble(&(pLayer->grid->maxincrement), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - case( MINSUBDIVIDE ): - if(getDouble(&(pLayer->grid->minsubdivides), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - case( MAXSUBDIVIDE ): - if(getDouble(&(pLayer->grid->maxsubdivides), MS_NUM_CHECK_GT, 0, -1) == -1) - return(-1); - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadGrid()", msyystring_buffer, msyylineno); - return(-1); +static int loadGrid(layerObj *pLayer) { + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadGrid()"); + return (-1); + case (END): + return (0); + case (GRID): + break; /* for string loads */ + case (LABELFORMAT): + if (getString(&(pLayer->grid->labelformat)) == MS_FAILURE) { + if (strcasecmp(msyystring_buffer, "DD") == + 0) /* DD triggers a symbol to be returned instead of a string so + check for this special case */ + { + msFree(pLayer->grid->labelformat); + pLayer->grid->labelformat = msStrdup("DD"); + } else + return (-1); + } + break; + case (MINARCS): + if (getDouble(&(pLayer->grid->minarcs), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MAXARCS): + if (getDouble(&(pLayer->grid->maxarcs), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MININTERVAL): + if (getDouble(&(pLayer->grid->minincrement), MS_NUM_CHECK_GT, 0, -1) == + -1) + return (-1); + break; + case (MAXINTERVAL): + if (getDouble(&(pLayer->grid->maxincrement), MS_NUM_CHECK_GT, 0, -1) == + -1) + return (-1); + break; + case (MINSUBDIVIDE): + if (getDouble(&(pLayer->grid->minsubdivides), MS_NUM_CHECK_GT, 0, -1) == + -1) + return (-1); + break; + case (MAXSUBDIVIDE): + if (getDouble(&(pLayer->grid->maxsubdivides), MS_NUM_CHECK_GT, 0, -1) == + -1) + return (-1); + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadGrid()", + msyystring_buffer, msyylineno); + return (-1); } } } -static void writeGrid(FILE *stream, int indent, graticuleObj *pGraticule) -{ - if(!pGraticule) return; +static void writeGrid(FILE *stream, int indent, graticuleObj *pGraticule) { + if (!pGraticule) + return; indent++; writeBlockBegin(stream, indent, "GRID"); @@ -1182,97 +1267,98 @@ static void writeGrid(FILE *stream, int indent, graticuleObj *pGraticule) writeBlockEnd(stream, indent, "GRID"); } -static int loadProjection(projectionObj *p) -{ +static int loadProjection(projectionObj *p) { p->gt.need_geotransform = MS_FALSE; - if ( p->proj != NULL || p->numargs != 0 ) { - msSetError(MS_MISCERR, "Projection is already initialized. Multiple projection definitions are not allowed in this object. (line %d)", + if (p->proj != NULL || p->numargs != 0) { + msSetError(MS_MISCERR, + "Projection is already initialized. Multiple projection " + "definitions are not allowed in this object. (line %d)", "loadProjection()", msyylineno); - return(-1); - } - - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadProjection()"); - return(-1); - case(END): - if( p->numargs == 1 && strstr(p->args[0],"+") != NULL ) { - char *one_line_def = p->args[0]; - int result; - - p->args[0] = NULL; - p->numargs = 0; - result = msLoadProjectionString( p, one_line_def ); - free( one_line_def ); - return result; - } else { - if(p->numargs != 0) - return msProcessProjection(p); - else - return 0; - } - break; - case(MS_STRING): - case(MS_AUTO): - if( p->numargs == MS_MAXPROJARGS ) { - msSetError(MS_MISCERR, "Parsing error near (%s):(line %d): Too many arguments in projection string", "loadProjection()", - msyystring_buffer, msyylineno); - return -1; - } - p->args[p->numargs] = msStrdup(msyystring_buffer); - p->automatic = MS_TRUE; - p->numargs++; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadProjection()", - msyystring_buffer, msyylineno); - return(-1); + return (-1); + } + + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadProjection()"); + return (-1); + case (END): + if (p->numargs == 1 && strstr(p->args[0], "+") != NULL) { + char *one_line_def = p->args[0]; + int result; + + p->args[0] = NULL; + p->numargs = 0; + result = msLoadProjectionString(p, one_line_def); + free(one_line_def); + return result; + } else { + if (p->numargs != 0) + return msProcessProjection(p); + else + return 0; + } + break; + case (MS_STRING): + case (MS_AUTO): + if (p->numargs == MS_MAXPROJARGS) { + msSetError(MS_MISCERR, + "Parsing error near (%s):(line %d): Too many arguments in " + "projection string", + "loadProjection()", msyystring_buffer, msyylineno); + return -1; + } + p->args[p->numargs] = msStrdup(msyystring_buffer); + p->automatic = MS_TRUE; + p->numargs++; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadProjection()", msyystring_buffer, msyylineno); + return (-1); } } /* next token */ } - /************************************************************************/ /* msLoadProjectionStringEPSGLike */ /************************************************************************/ static int msLoadProjectionStringEPSGLike(projectionObj *p, const char *value, - const char* pszPrefix, - int bFollowEPSGAxisOrder) -{ - size_t buffer_size = 0; - char *init_string = NULL; - const char *code; - const char *next_sep; - size_t prefix_len; - - prefix_len = strlen(pszPrefix); - if( strncasecmp(value, pszPrefix, prefix_len) != 0 ) - return -1; + const char *pszPrefix, + int bFollowEPSGAxisOrder) { + size_t buffer_size = 0; + char *init_string = NULL; + const char *code; + const char *next_sep; + size_t prefix_len; - code = value + prefix_len; - next_sep = strchr(code, pszPrefix[prefix_len-1]); - if( next_sep != NULL ) - code = next_sep + 1; + prefix_len = strlen(pszPrefix); + if (strncasecmp(value, pszPrefix, prefix_len) != 0) + return -1; - buffer_size = 10 + strlen(code) + 1; - init_string = (char*)msSmallMalloc(buffer_size); + code = value + prefix_len; + next_sep = strchr(code, pszPrefix[prefix_len - 1]); + if (next_sep != NULL) + code = next_sep + 1; - /* translate into PROJ.4 format. */ - snprintf( init_string, buffer_size, "init=epsg:%s", code ); + buffer_size = 10 + strlen(code) + 1; + init_string = (char *)msSmallMalloc(buffer_size); - p->args = (char**)msSmallMalloc(sizeof(char*) * 2); - p->args[0] = init_string; - p->numargs = 1; + /* translate into PROJ.4 format. */ + snprintf(init_string, buffer_size, "init=epsg:%s", code); - if( bFollowEPSGAxisOrder && msIsAxisInverted(atoi(code))) { - p->args[1] = msStrdup("+epsgaxis=ne"); - p->numargs = 2; - } + p->args = (char **)msSmallMalloc(sizeof(char *) * 2); + p->args[0] = init_string; + p->numargs = 1; + + if (bFollowEPSGAxisOrder && msIsAxisInverted(atoi(code))) { + p->args[1] = msStrdup("+epsgaxis=ne"); + p->numargs = 2; + } - return 0; + return 0; } /************************************************************************/ @@ -1280,43 +1366,40 @@ static int msLoadProjectionStringEPSGLike(projectionObj *p, const char *value, /************************************************************************/ static int msLoadProjectionStringCRSLike(projectionObj *p, const char *value, - const char* pszPrefix) -{ - char init_string[100]; - const char *id; - const char *next_sep; - size_t prefix_len; - - prefix_len = strlen(pszPrefix); - if( strncasecmp(value, pszPrefix, prefix_len) != 0 ) - return -1; - - id = value + prefix_len; - next_sep = strchr(id, pszPrefix[prefix_len-1]); - if( next_sep != NULL ) - id = next_sep + 1; - - init_string[0] = '\0'; - - if( strcasecmp(id,"84") == 0 || strcasecmp(id,"CRS84") == 0 ) - strncpy( init_string, "init=epsg:4326", sizeof(init_string) ); - else if( strcasecmp(id,"83") == 0 || strcasecmp(id,"CRS83") == 0 ) - strncpy( init_string, "init=epsg:4269", sizeof(init_string) ); - else if( strcasecmp(id,"27") == 0 || strcasecmp(id,"CRS27") == 0 ) - strncpy( init_string, "init=epsg:4267", sizeof(init_string) ); - else { - msSetError( MS_PROJERR, - "Unrecognised OGC CRS def '%s'.", - "msLoadProjectionString()", - value ); - return -1; - } + const char *pszPrefix) { + char init_string[100]; + const char *id; + const char *next_sep; + size_t prefix_len; + + prefix_len = strlen(pszPrefix); + if (strncasecmp(value, pszPrefix, prefix_len) != 0) + return -1; + + id = value + prefix_len; + next_sep = strchr(id, pszPrefix[prefix_len - 1]); + if (next_sep != NULL) + id = next_sep + 1; + + init_string[0] = '\0'; + + if (strcasecmp(id, "84") == 0 || strcasecmp(id, "CRS84") == 0) + strncpy(init_string, "init=epsg:4326", sizeof(init_string)); + else if (strcasecmp(id, "83") == 0 || strcasecmp(id, "CRS83") == 0) + strncpy(init_string, "init=epsg:4269", sizeof(init_string)); + else if (strcasecmp(id, "27") == 0 || strcasecmp(id, "CRS27") == 0) + strncpy(init_string, "init=epsg:4267", sizeof(init_string)); + else { + msSetError(MS_PROJERR, "Unrecognised OGC CRS def '%s'.", + "msLoadProjectionString()", value); + return -1; + } - p->args = (char**)msSmallMalloc(sizeof(char*) * 2); - p->args[0] = msStrdup(init_string); - p->numargs = 1; + p->args = (char **)msSmallMalloc(sizeof(char *) * 2); + p->args[0] = msStrdup(init_string); + p->numargs = 1; - return 0; + return 0; } /************************************************************************/ @@ -1326,33 +1409,30 @@ static int msLoadProjectionStringCRSLike(projectionObj *p, const char *value, /* certain code ranges. */ /* Use for now in WMS 1.3.0 and WFS >= 1.1.0 */ /************************************************************************/ -int msLoadProjectionStringEPSG(projectionObj *p, const char *value) -{ +int msLoadProjectionStringEPSG(projectionObj *p, const char *value) { assert(p); msFreeProjectionExceptContext(p); p->gt.need_geotransform = MS_FALSE; #ifdef USE_PROJ_FASTPATHS - if(strcasestr(value,"epsg:4326")) { + if (strcasestr(value, "epsg:4326")) { p->wellknownprojection = wkp_lonlat; - } else if(strcasestr(value,"epsg:3857")) { + } else if (strcasestr(value, "epsg:3857")) { p->wellknownprojection = wkp_gmerc; } else { p->wellknownprojection = wkp_none; } #endif - if( msLoadProjectionStringEPSGLike(p, value, "EPSG:", MS_TRUE) == 0 ) - { - return msProcessProjection( p ); + if (msLoadProjectionStringEPSGLike(p, value, "EPSG:", MS_TRUE) == 0) { + return msProcessProjection(p); } return msLoadProjectionString(p, value); } -int msLoadProjectionString(projectionObj *p, const char *value) -{ +int msLoadProjectionString(projectionObj *p, const char *value) { assert(p); p->gt.need_geotransform = MS_FALSE; @@ -1364,70 +1444,80 @@ int msLoadProjectionString(projectionObj *p, const char *value) * eg. * "+proj=utm +zone=11 +ellps=WGS84" */ - if( value[0] == '+' ) { - char *trimmed; - int i, i_out=0; + if (value[0] == '+') { + char *trimmed; + int i, i_out = 0; - trimmed = msStrdup(value+1); - for( i = 1; value[i] != '\0'; i++ ) { - if( !isspace( value[i] ) ) + trimmed = msStrdup(value + 1); + for (i = 1; value[i] != '\0'; i++) { + if (!isspace(value[i])) trimmed[i_out++] = value[i]; } trimmed[i_out] = '\0'; - p->args = msStringSplit(trimmed,'+', &p->numargs); - free( trimmed ); + p->args = msStringSplit(trimmed, '+', &p->numargs); + free(trimmed); } else if (strncasecmp(value, "AUTO:", 5) == 0 || strncasecmp(value, "AUTO2:", 6) == 0) { /* WMS/WFS AUTO projection: "AUTO:proj_id,units_id,lon0,lat0" */ /* WMS 1.3.0 projection: "AUTO2:auto_crs_id,factor,lon0,lat0"*/ /* Keep the projection defn into a single token for writeProjection() */ /* to work fine. */ - p->args = (char**)msSmallMalloc(sizeof(char*)); + p->args = (char **)msSmallMalloc(sizeof(char *)); p->args[0] = msStrdup(value); p->numargs = 1; - } else if (msLoadProjectionStringEPSGLike(p, value, "EPSG:", MS_FALSE) == 0 ) { - /* Assume lon/lat ordering. Use msLoadProjectionStringEPSG() if wanting to follow EPSG axis */ - } else if (msLoadProjectionStringEPSGLike(p, value, "urn:ogc:def:crs:EPSG:", MS_TRUE) == 0 ) { - } else if (msLoadProjectionStringEPSGLike(p, value, "urn:EPSG:geographicCRS:", MS_TRUE) == 0 ) { - } else if (msLoadProjectionStringEPSGLike(p, value, "urn:x-ogc:def:crs:EPSG:", MS_TRUE) == 0 ) { + } else if (msLoadProjectionStringEPSGLike(p, value, "EPSG:", MS_FALSE) == 0) { + /* Assume lon/lat ordering. Use msLoadProjectionStringEPSG() if wanting to + * follow EPSG axis */ + } else if (msLoadProjectionStringEPSGLike( + p, value, "urn:ogc:def:crs:EPSG:", MS_TRUE) == 0) { + } else if (msLoadProjectionStringEPSGLike( + p, value, "urn:EPSG:geographicCRS:", MS_TRUE) == 0) { + } else if (msLoadProjectionStringEPSGLike( + p, value, "urn:x-ogc:def:crs:EPSG:", MS_TRUE) == 0) { /*this case is to account for OGC CITE tests where x-ogc was used before the ogc name became an official NID. Note also we also account - for the fact that a space for the version of the espg is not used with CITE tests. - (Syntax used could be urn:ogc:def:objectType:authority:code)*/ - } else if (msLoadProjectionStringCRSLike(p, value, "urn:ogc:def:crs:OGC:") == 0 ) { - } else if (msLoadProjectionStringEPSGLike(p, value, "http://www.opengis.net/def/crs/EPSG/", MS_TRUE) == 0 ) { + for the fact that a space for the version of the espg is not used with + CITE tests. (Syntax used could be urn:ogc:def:objectType:authority:code)*/ + } else if (msLoadProjectionStringCRSLike(p, value, "urn:ogc:def:crs:OGC:") == + 0) { + } else if (msLoadProjectionStringEPSGLike( + p, value, "http://www.opengis.net/def/crs/EPSG/", MS_TRUE) == + 0) { /* URI projection support */ - } else if (msLoadProjectionStringCRSLike(p, value, "http://www.opengis.net/def/crs/OGC/") == 0 ) { - /* Mandatory support for this URI format specified in WFS1.1 (also in 1.0?) */ - } else if (msLoadProjectionStringEPSGLike(p, value, "http://www.opengis.net/gml/srs/epsg.xml#", MS_FALSE) == 0 ) { + } else if (msLoadProjectionStringCRSLike( + p, value, "http://www.opengis.net/def/crs/OGC/") == 0) { + /* Mandatory support for this URI format specified in WFS1.1 (also in 1.0?) + */ + } else if (msLoadProjectionStringEPSGLike( + p, value, "http://www.opengis.net/gml/srs/epsg.xml#", + MS_FALSE) == 0) { /* We assume always lon/lat ordering, as that is what GeoServer does... */ - } else if (msLoadProjectionStringCRSLike(p, value, "CRS:") == 0 ) { + } else if (msLoadProjectionStringCRSLike(p, value, "CRS:") == 0) { } /* * Handle old style comma delimited. eg. "proj=utm,zone=11,ellps=WGS84". */ else { - p->args = msStringSplit(value,',', &p->numargs); + p->args = msStringSplit(value, ',', &p->numargs); } - return msProcessProjection( p ); + return msProcessProjection(p); } -static void writeProjection(FILE *stream, int indent, projectionObj *p) -{ +static void writeProjection(FILE *stream, int indent, projectionObj *p) { int i; - if(!p || p->numargs <= 0) return; + if (!p || p->numargs <= 0) + return; indent++; writeBlockBegin(stream, indent, "PROJECTION"); - for(i=0; inumargs; i++) + for (i = 0; i < p->numargs; i++) writeString(stream, indent, NULL, NULL, p->args[i]); writeBlockEnd(stream, indent, "PROJECTION"); } -void initLeader(labelLeaderObj *leader) -{ +void initLeader(labelLeaderObj *leader) { leader->gridstep = 5; leader->maxdistance = 0; @@ -1441,18 +1531,17 @@ void initLeader(labelLeaderObj *leader) /* ** Initialize, load and free a labelObj structure */ -void initLabel(labelObj *label) -{ +void initLabel(labelObj *label) { int i; MS_REFCNT_INIT(label); label->align = MS_ALIGN_DEFAULT; - MS_INIT_COLOR(label->color, 0,0,0,255); - MS_INIT_COLOR(label->outlinecolor, -1,-1,-1,255); /* don't use it */ - label->outlinewidth=1; + MS_INIT_COLOR(label->color, 0, 0, 0, 255); + MS_INIT_COLOR(label->outlinecolor, -1, -1, -1, 255); /* don't use it */ + label->outlinewidth = 1; - MS_INIT_COLOR(label->shadowcolor, -1,-1,-1,255); /* don't use it */ + MS_INIT_COLOR(label->shadowcolor, -1, -1, -1, 255); /* don't use it */ label->shadowsizex = label->shadowsizey = 1; label->font = NULL; @@ -1465,17 +1554,17 @@ void initLabel(labelObj *label) label->maxsize = MS_MAXFONTSIZE; label->buffer = 0; label->offsetx = label->offsety = 0; - label->minscaledenom=-1; - label->maxscaledenom=-1; + label->minscaledenom = -1; + label->maxscaledenom = -1; label->minfeaturesize = -1; /* no limit */ label->autominfeaturesize = MS_FALSE; - label->mindistance = -1; /* no limit */ - label->repeatdistance = 0; /* no repeat */ + label->mindistance = -1; /* no limit */ + label->repeatdistance = 0; /* no repeat */ label->maxoverlapangle = 22.5; /* default max overlap angle */ label->partials = MS_FALSE; label->wrap = '\0'; label->maxlength = 0; - label->space_size_10=0.0; + label->space_size_10 = 0.0; label->encoding = NULL; @@ -1490,7 +1579,7 @@ void initLabel(labelObj *label) label->numbindings = 0; label->nexprbindings = 0; - for(i=0; ibindings[i].item = NULL; label->bindings[i].index = -1; msInitExpression(&(label->exprBindings[i])); @@ -1507,11 +1596,10 @@ void initLabel(labelObj *label) return; } -int freeLabelLeader(labelLeaderObj *leader) -{ +int freeLabelLeader(labelLeaderObj *leader) { int i; - for(i=0; inumstyles; i++) { - if(freeStyle(leader->styles[i]) == MS_SUCCESS) { + for (i = 0; i < leader->numstyles; i++) { + if (freeStyle(leader->styles[i]) == MS_SUCCESS) { msFree(leader->styles[i]); } } @@ -1519,27 +1607,26 @@ int freeLabelLeader(labelLeaderObj *leader) return MS_SUCCESS; } -int freeLabel(labelObj *label) -{ +int freeLabel(labelObj *label) { int i; - if( MS_REFCNT_DECR_IS_NOT_ZERO(label) ) { + if (MS_REFCNT_DECR_IS_NOT_ZERO(label)) { return MS_FAILURE; } msFree(label->font); msFree(label->encoding); - for(i=0; inumstyles; i++) { /* each style */ - if(label->styles[i]!=NULL) { - if(freeStyle(label->styles[i]) == MS_SUCCESS) { + for (i = 0; i < label->numstyles; i++) { /* each style */ + if (label->styles[i] != NULL) { + if (freeStyle(label->styles[i]) == MS_SUCCESS) { msFree(label->styles[i]); } } } msFree(label->styles); - for(i=0; ibindings[i].item); msFreeExpression(&(label->exprBindings[i])); } @@ -1547,7 +1634,7 @@ int freeLabel(labelObj *label) msFreeExpression(&(label->expression)); msFreeExpression(&(label->text)); - if(label->leader) { + if (label->leader) { freeLabelLeader(label->leader); msFree(label->leader); label->leader = NULL; @@ -1556,330 +1643,403 @@ int freeLabel(labelObj *label) return MS_SUCCESS; } -static int loadLeader(labelLeaderObj *leader) -{ - for(;;) { - switch(msyylex()) { - case(END): - return(0); - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadLeader()"); - return(-1); - case GRIDSTEP: - if(getInteger(&(leader->gridstep), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case MAXDISTANCE: - if(getInteger(&(leader->maxdistance), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case STYLE: - if(msGrowLeaderStyles(leader) == NULL) - return(-1); - initStyle(leader->styles[leader->numstyles]); - if(loadStyle(leader->styles[leader->numstyles]) != MS_SUCCESS) - { - freeStyle(leader->styles[leader->numstyles]); - free(leader->styles[leader->numstyles]); - leader->styles[leader->numstyles] = NULL; - return -1; - } - leader->numstyles++; - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadLeader()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } +static int loadLeader(labelLeaderObj *leader) { + for (;;) { + switch (msyylex()) { + case (END): + return (0); + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadLeader()"); + return (-1); + case GRIDSTEP: + if (getInteger(&(leader->gridstep), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case MAXDISTANCE: + if (getInteger(&(leader->maxdistance), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case STYLE: + if (msGrowLeaderStyles(leader) == NULL) + return (-1); + initStyle(leader->styles[leader->numstyles]); + if (loadStyle(leader->styles[leader->numstyles]) != MS_SUCCESS) { + freeStyle(leader->styles[leader->numstyles]); + free(leader->styles[leader->numstyles]); + leader->styles[leader->numstyles] = NULL; + return -1; + } + leader->numstyles++; + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadLeader()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } } -static int loadLabel(labelObj *label) -{ +static int loadLabel(labelObj *label) { int symbol; - for(;;) { - switch(msyylex()) { - case(ANGLE): - if((symbol = getSymbol(5, MS_NUMBER,MS_AUTO,MS_AUTO2,MS_FOLLOW,MS_BINDING)) == -1) - return(-1); + for (;;) { + switch (msyylex()) { + case (ANGLE): + if ((symbol = getSymbol(5, MS_NUMBER, MS_AUTO, MS_AUTO2, MS_FOLLOW, + MS_BINDING)) == -1) + return (-1); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, -360.0, 360.0) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid ANGLE, must be between -360 and 360 (line %d)", "loadLabel()", msyylineno); - return(MS_FAILURE); - } - label->angle = (double) msyynumber; - } else if(symbol == MS_BINDING) { - if (label->bindings[MS_LABEL_BINDING_ANGLE].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_ANGLE].item); - label->bindings[MS_LABEL_BINDING_ANGLE].item = msStrdup(msyystring_buffer); - label->numbindings++; - } else { - label->anglemode = symbol; - } - break; - case(ALIGN): - if((symbol = getSymbol(4, MS_ALIGN_LEFT,MS_ALIGN_CENTER,MS_ALIGN_RIGHT,MS_BINDING)) == -1) - return(-1); - if((symbol == MS_ALIGN_LEFT)||(symbol == MS_ALIGN_CENTER)||(symbol == MS_ALIGN_RIGHT)) { - label->align = symbol; - } else { - if (label->bindings[MS_LABEL_BINDING_ALIGN].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_ALIGN].item); - label->bindings[MS_LABEL_BINDING_ALIGN].item = msStrdup(msyystring_buffer); - label->numbindings++; + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, -360.0, 360.0) == + MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid ANGLE, must be between -360 and 360 (line %d)", + "loadLabel()", msyylineno); + return (MS_FAILURE); } + label->angle = (double)msyynumber; + } else if (symbol == MS_BINDING) { + if (label->bindings[MS_LABEL_BINDING_ANGLE].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_ANGLE].item); + label->bindings[MS_LABEL_BINDING_ANGLE].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } else { + label->anglemode = symbol; + } + break; + case (ALIGN): + if ((symbol = getSymbol(4, MS_ALIGN_LEFT, MS_ALIGN_CENTER, MS_ALIGN_RIGHT, + MS_BINDING)) == -1) + return (-1); + if ((symbol == MS_ALIGN_LEFT) || (symbol == MS_ALIGN_CENTER) || + (symbol == MS_ALIGN_RIGHT)) { + label->align = symbol; + } else { + if (label->bindings[MS_LABEL_BINDING_ALIGN].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_ALIGN].item); + label->bindings[MS_LABEL_BINDING_ALIGN].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (ANTIALIAS): /*ignore*/ + msyylex(); + break; + case (BUFFER): + if (getInteger(&(label->buffer), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + break; + case (COLOR): + if (loadColor(&(label->color), + &(label->bindings[MS_LABEL_BINDING_COLOR])) != MS_SUCCESS) + return (-1); + if (label->bindings[MS_LABEL_BINDING_COLOR].item) + label->numbindings++; + break; + case (ENCODING): + if ((getString(&label->encoding)) == MS_FAILURE) + return (-1); + break; + case (END): + return (0); + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadLabel()"); + return (-1); + case (EXPRESSION): + if (loadExpression(&(label->expression)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + break; + case (FONT): + if ((symbol = getSymbol(2, MS_STRING, MS_BINDING)) == -1) + return (-1); + + if (symbol == MS_STRING) { + if (label->font != NULL) + msFree(label->font); + label->font = msStrdup(msyystring_buffer); + } else { + if (label->bindings[MS_LABEL_BINDING_FONT].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_FONT].item); + label->bindings[MS_LABEL_BINDING_FONT].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (FORCE): + switch (msyylex()) { + case MS_ON: + label->force = MS_ON; break; - case(ANTIALIAS): /*ignore*/ - msyylex(); - break; - case(BUFFER): - if(getInteger(&(label->buffer), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - break; - case(COLOR): - if(loadColor(&(label->color), &(label->bindings[MS_LABEL_BINDING_COLOR])) != MS_SUCCESS) return(-1); - if(label->bindings[MS_LABEL_BINDING_COLOR].item) label->numbindings++; - break; - case(ENCODING): - if((getString(&label->encoding)) == MS_FAILURE) return(-1); - break; - case(END): - return(0); - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadLabel()"); - return(-1); - case(EXPRESSION): - if(loadExpression(&(label->expression)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ + case MS_OFF: + label->force = MS_OFF; break; - case(FONT): - if((symbol = getSymbol(2, MS_STRING, MS_BINDING)) == -1) - return(-1); - - if(symbol == MS_STRING) { - if (label->font != NULL) - msFree(label->font); - label->font = msStrdup(msyystring_buffer); - } else { - if (label->bindings[MS_LABEL_BINDING_FONT].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_FONT].item); - label->bindings[MS_LABEL_BINDING_FONT].item = msStrdup(msyystring_buffer); - label->numbindings++; - } + case GROUP: + label->force = MS_LABEL_FORCE_GROUP; break; - case(FORCE): - switch(msyylex()) { - case MS_ON: - label->force = MS_ON; - break; - case MS_OFF: - label->force = MS_OFF; - break; - case GROUP: - label->force = MS_LABEL_FORCE_GROUP; - break; - default: - msSetError(MS_MISCERR, "Invalid FORCE, must be ON,OFF,or GROUP (line %d)" , "loadLabel()", msyylineno); - return(-1); + default: + msSetError(MS_MISCERR, + "Invalid FORCE, must be ON,OFF,or GROUP (line %d)", + "loadLabel()", msyylineno); + return (-1); + } + break; + case (LABEL): + break; /* for string loads */ + case (LEADER): + msSetError(MS_MISCERR, + "LABEL LEADER not implemented. LEADER goes at the CLASS level " + "(line %d)", + "loadLabel()", msyylineno); + return (-1); + case (MAXSIZE): + if (getInteger(&(label->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MAXSCALEDENOM): + if (getDouble(&(label->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MAXLENGTH): + if (getInteger(&(label->maxlength), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MINDISTANCE): + if (getInteger(&(label->mindistance), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (REPEATDISTANCE): + if (getInteger(&(label->repeatdistance), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MAXOVERLAPANGLE): + if (getDouble(&(label->maxoverlapangle), MS_NUM_CHECK_RANGE, 0, 360) == + -1) + return (-1); + break; + case (MINFEATURESIZE): + if ((symbol = getSymbol(2, MS_NUMBER, MS_AUTO)) == -1) + return (-1); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid MINFEATURESIZE, must be greater than 0 (line %d)", + "loadLabel()", msyylineno); + return (MS_FAILURE); } - break; - case(LABEL): - break; /* for string loads */ - case(LEADER): - msSetError(MS_MISCERR, "LABEL LEADER not implemented. LEADER goes at the CLASS level (line %d)" , "loadLabel()", msyylineno); - return(-1); - case(MAXSIZE): - if(getInteger(&(label->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MAXSCALEDENOM): - if(getDouble(&(label->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MAXLENGTH): - if(getInteger(&(label->maxlength), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MINDISTANCE): - if(getInteger(&(label->mindistance), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(REPEATDISTANCE): - if(getInteger(&(label->repeatdistance), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MAXOVERLAPANGLE): - if(getDouble(&(label->maxoverlapangle), MS_NUM_CHECK_RANGE, 0, 360) == -1) return(-1); - break; - case(MINFEATURESIZE): - if((symbol = getSymbol(2, MS_NUMBER,MS_AUTO)) == -1) return(-1); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid MINFEATURESIZE, must be greater than 0 (line %d)", "loadLabel()", msyylineno); - return(MS_FAILURE); - } - label->minfeaturesize = (int)msyynumber; - } else - label->autominfeaturesize = MS_TRUE; - break; - case(MINSCALEDENOM): - if(getDouble(&(label->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MINSIZE): - if(getInteger(&(label->minsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(OFFSET): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) - label->offsetx = (int) msyynumber; // any integer ok - else { - if (label->bindings[MS_LABEL_BINDING_OFFSET_X].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_OFFSET_X].item); - label->bindings[MS_LABEL_BINDING_OFFSET_X].item = msStrdup(msyystring_buffer); - label->numbindings++; + label->minfeaturesize = (int)msyynumber; + } else + label->autominfeaturesize = MS_TRUE; + break; + case (MINSCALEDENOM): + if (getDouble(&(label->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MINSIZE): + if (getInteger(&(label->minsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (OFFSET): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) + label->offsetx = (int)msyynumber; // any integer ok + else { + if (label->bindings[MS_LABEL_BINDING_OFFSET_X].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_OFFSET_X].item); + label->bindings[MS_LABEL_BINDING_OFFSET_X].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) + label->offsety = (int)msyynumber; // any integer ok + else { + if (label->bindings[MS_LABEL_BINDING_OFFSET_Y].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_OFFSET_Y].item); + label->bindings[MS_LABEL_BINDING_OFFSET_Y].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (OUTLINECOLOR): + if (loadColor(&(label->outlinecolor), + &(label->bindings[MS_LABEL_BINDING_OUTLINECOLOR])) != + MS_SUCCESS) + return (-1); + if (label->bindings[MS_LABEL_BINDING_OUTLINECOLOR].item) + label->numbindings++; + break; + case (OUTLINEWIDTH): + if (getInteger(&(label->outlinewidth), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (PARTIALS): + if ((label->partials = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) + return (-1); + break; + case (POSITION): + if ((label->position = + getSymbol(11, MS_UL, MS_UC, MS_UR, MS_CL, MS_CC, MS_CR, MS_LL, + MS_LC, MS_LR, MS_AUTO, MS_BINDING)) == -1) + return (-1); + if (label->position == MS_BINDING) { + if (label->bindings[MS_LABEL_BINDING_POSITION].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_POSITION].item); + label->bindings[MS_LABEL_BINDING_POSITION].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (PRIORITY): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (-1); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 1, + MS_MAX_LABEL_PRIORITY) == MS_FAILURE) { + msSetError( + MS_MISCERR, + "Invalid PRIORITY, must be an integer between 1 and %d (line %d)", + "loadLabel()", MS_MAX_LABEL_PRIORITY, msyylineno); + return (-1); } + label->priority = (int)msyynumber; + } else { + if (label->bindings[MS_LABEL_BINDING_PRIORITY].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_PRIORITY].item); + label->bindings[MS_LABEL_BINDING_PRIORITY].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (SHADOWCOLOR): + if (loadColor(&(label->shadowcolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (SHADOWSIZE): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (-1); + if (symbol == MS_NUMBER) { + label->shadowsizex = (int)msyynumber; // x offset, any int ok + } else { + if (label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item); + label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (-1); + if (symbol == MS_NUMBER) { + label->shadowsizey = (int)msyynumber; // y offset, any int ok + } else { + if (label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item != NULL) + msFree(label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item); + label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } + break; + case (SIZE): + if (label->bindings[MS_LABEL_BINDING_SIZE].item) { + msFree(label->bindings[MS_LABEL_BINDING_SIZE].item); + label->bindings[MS_LABEL_BINDING_SIZE].item = NULL; + label->numbindings--; + } + if (label->exprBindings[MS_LABEL_BINDING_SIZE].string) { + msFreeExpression(&label->exprBindings[MS_LABEL_BINDING_SIZE]); + label->nexprbindings--; + } - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) - label->offsety = (int) msyynumber; // any integer ok - else { - if (label->bindings[MS_LABEL_BINDING_OFFSET_Y].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_OFFSET_Y].item); - label->bindings[MS_LABEL_BINDING_OFFSET_Y].item = msStrdup(msyystring_buffer); - label->numbindings++; - } - break; - case(OUTLINECOLOR): - if(loadColor(&(label->outlinecolor), &(label->bindings[MS_LABEL_BINDING_OUTLINECOLOR])) != MS_SUCCESS) return(-1); - if(label->bindings[MS_LABEL_BINDING_OUTLINECOLOR].item) label->numbindings++; - break; - case(OUTLINEWIDTH): - if(getInteger(&(label->outlinewidth), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(PARTIALS): - if((label->partials = getSymbol(2, MS_TRUE,MS_FALSE)) == -1) return(-1); - break; - case(POSITION): - if((label->position = getSymbol(11, MS_UL,MS_UC,MS_UR,MS_CL,MS_CC,MS_CR,MS_LL,MS_LC,MS_LR,MS_AUTO,MS_BINDING)) == -1) - return(-1); - if(label->position == MS_BINDING) { - if(label->bindings[MS_LABEL_BINDING_POSITION].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_POSITION].item); - label->bindings[MS_LABEL_BINDING_POSITION].item = msStrdup(msyystring_buffer); - label->numbindings++; - } - break; - case(PRIORITY): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(-1); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 1, MS_MAX_LABEL_PRIORITY) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid PRIORITY, must be an integer between 1 and %d (line %d)" , "loadLabel()", MS_MAX_LABEL_PRIORITY, msyylineno); - return(-1); - } - label->priority = (int) msyynumber; - } else { - if (label->bindings[MS_LABEL_BINDING_PRIORITY].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_PRIORITY].item); - label->bindings[MS_LABEL_BINDING_PRIORITY].item = msStrdup(msyystring_buffer); - label->numbindings++; - } - break; - case(SHADOWCOLOR): - if(loadColor(&(label->shadowcolor), NULL) != MS_SUCCESS) return(-1); - break; - case(SHADOWSIZE): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(-1); - if(symbol == MS_NUMBER) { - label->shadowsizex = (int) msyynumber; // x offset, any int ok - } else { - if (label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item); - label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item = msStrdup(msyystring_buffer); - label->numbindings++; - } - - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(-1); - if(symbol == MS_NUMBER) { - label->shadowsizey = (int) msyynumber; // y offset, any int ok - } else { - if (label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item != NULL) - msFree(label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item); - label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item = msStrdup(msyystring_buffer); - label->numbindings++; - } - break; - case(SIZE): - if(label->bindings[MS_LABEL_BINDING_SIZE].item) { - msFree(label->bindings[MS_LABEL_BINDING_SIZE].item); - label->bindings[MS_LABEL_BINDING_SIZE].item = NULL; - label->numbindings--; - } - if (label->exprBindings[MS_LABEL_BINDING_SIZE].string) { - msFreeExpression(&label->exprBindings[MS_LABEL_BINDING_SIZE]); - label->nexprbindings--; - } - - if((symbol = getSymbol(8, MS_EXPRESSION,MS_NUMBER,MS_BINDING,MS_TINY,MS_SMALL,MS_MEDIUM,MS_LARGE,MS_GIANT)) == -1) - return(-1); - - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid SIZE, must be greater than 0 (line %d)" , "loadLabel()", msyylineno); - return(-1); - } - label->size = (double) msyynumber; - } else if(symbol == MS_BINDING) { - label->bindings[MS_LABEL_BINDING_SIZE].item = msStrdup(msyystring_buffer); - label->numbindings++; - } else if (symbol == MS_EXPRESSION) { - msFree(label->exprBindings[MS_LABEL_BINDING_SIZE].string); - label->exprBindings[MS_LABEL_BINDING_SIZE].string = msStrdup(msyystring_buffer); - label->exprBindings[MS_LABEL_BINDING_SIZE].type = MS_EXPRESSION; - label->nexprbindings++; - } else - label->size = symbol; - break; - case(STYLE): - if(msGrowLabelStyles(label) == NULL) - return(-1); - initStyle(label->styles[label->numstyles]); - if(loadStyle(label->styles[label->numstyles]) != MS_SUCCESS) { - freeStyle(label->styles[label->numstyles]); - free(label->styles[label->numstyles]); - label->styles[label->numstyles] = NULL; - return(-1); - } - if(label->styles[label->numstyles]->_geomtransform.type == MS_GEOMTRANSFORM_NONE) - label->styles[label->numstyles]->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOINT; /* set a default, a marker? */ - label->numstyles++; - break; - case(TEXT): - if(loadExpression(&(label->text)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ - if((label->text.type != MS_STRING) && (label->text.type != MS_EXPRESSION)) { - msSetError(MS_MISCERR, "Text expressions support constant or tagged replacement strings." , "loadLabel()"); - return(-1); - } - break; - case(TYPE): - if(getSymbol(2, MS_TRUETYPE,MS_BITMAP) == -1) return(-1); /* ignore TYPE */ - break; - case(WRAP): - if(getCharacter(&(label->wrap)) == -1) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadLabel()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ + if ((symbol = getSymbol(8, MS_EXPRESSION, MS_NUMBER, MS_BINDING, MS_TINY, + MS_SMALL, MS_MEDIUM, MS_LARGE, MS_GIANT)) == -1) + return (-1); + + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid SIZE, must be greater than 0 (line %d)", + "loadLabel()", msyylineno); + return (-1); } + label->size = (double)msyynumber; + } else if (symbol == MS_BINDING) { + label->bindings[MS_LABEL_BINDING_SIZE].item = + msStrdup(msyystring_buffer); + label->numbindings++; + } else if (symbol == MS_EXPRESSION) { + msFree(label->exprBindings[MS_LABEL_BINDING_SIZE].string); + label->exprBindings[MS_LABEL_BINDING_SIZE].string = + msStrdup(msyystring_buffer); + label->exprBindings[MS_LABEL_BINDING_SIZE].type = MS_EXPRESSION; + label->nexprbindings++; + } else + label->size = symbol; + break; + case (STYLE): + if (msGrowLabelStyles(label) == NULL) + return (-1); + initStyle(label->styles[label->numstyles]); + if (loadStyle(label->styles[label->numstyles]) != MS_SUCCESS) { + freeStyle(label->styles[label->numstyles]); + free(label->styles[label->numstyles]); + label->styles[label->numstyles] = NULL; + return (-1); + } + if (label->styles[label->numstyles]->_geomtransform.type == + MS_GEOMTRANSFORM_NONE) + label->styles[label->numstyles]->_geomtransform.type = + MS_GEOMTRANSFORM_LABELPOINT; /* set a default, a marker? */ + label->numstyles++; + break; + case (TEXT): + if (loadExpression(&(label->text)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + if ((label->text.type != MS_STRING) && + (label->text.type != MS_EXPRESSION)) { + msSetError( + MS_MISCERR, + "Text expressions support constant or tagged replacement strings.", + "loadLabel()"); + return (-1); + } + break; + case (TYPE): + if (getSymbol(2, MS_TRUETYPE, MS_BITMAP) == -1) + return (-1); /* ignore TYPE */ + break; + case (WRAP): + if (getCharacter(&(label->wrap)) == -1) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadLabel()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } /* next token */ } -int msUpdateLabelFromString(labelObj *label, char *string) -{ - if(!label || !string) return MS_FAILURE; +int msUpdateLabelFromString(labelObj *label, char *string) { + if (!label || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -1887,101 +2047,128 @@ int msUpdateLabelFromString(labelObj *label, char *string) msyylineno = 1; /* start at line 1 */ - if(loadLabel(label) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadLabel(label) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeLeader(FILE *stream, int indent, labelLeaderObj *leader) -{ +static void writeLeader(FILE *stream, int indent, labelLeaderObj *leader) { int i; - if(leader->maxdistance == 0 && leader->numstyles == 0) { + if (leader->maxdistance == 0 && leader->numstyles == 0) { return; } indent++; writeBlockBegin(stream, indent, "LEADER"); writeNumber(stream, indent, "MAXDISTANCE", 0, leader->maxdistance); writeNumber(stream, indent, "GRIDSTEP", 5, leader->gridstep); - for(i=0; inumstyles; i++) + for (i = 0; i < leader->numstyles; i++) writeStyle(stream, indent, leader->styles[i]); writeBlockEnd(stream, indent, "LEADER"); } -static void writeLabel(FILE *stream, int indent, labelObj *label) -{ +static void writeLabel(FILE *stream, int indent, labelObj *label) { int i; colorObj c; - if(label->size == -1) return; /* there is no default label anymore */ + if (label->size == -1) + return; /* there is no default label anymore */ indent++; writeBlockBegin(stream, indent, "LABEL"); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_ANGLE].item) - writeAttributeBinding(stream, indent, "ANGLE", &(label->bindings[MS_LABEL_BINDING_ANGLE])); - else writeNumberOrKeyword(stream, indent, "ANGLE", 0, label->angle, label->anglemode, 3, MS_FOLLOW, "FOLLOW", MS_AUTO, "AUTO", MS_AUTO2, "AUTO2"); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_ANGLE].item) + writeAttributeBinding(stream, indent, "ANGLE", + &(label->bindings[MS_LABEL_BINDING_ANGLE])); + else + writeNumberOrKeyword(stream, indent, "ANGLE", 0, label->angle, + label->anglemode, 3, MS_FOLLOW, "FOLLOW", MS_AUTO, + "AUTO", MS_AUTO2, "AUTO2"); writeExpression(stream, indent, "EXPRESSION", &(label->expression)); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_FONT].item) - writeAttributeBinding(stream, indent, "FONT", &(label->bindings[MS_LABEL_BINDING_FONT])); - else writeString(stream, indent, "FONT", NULL, label->font); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_FONT].item) + writeAttributeBinding(stream, indent, "FONT", + &(label->bindings[MS_LABEL_BINDING_FONT])); + else + writeString(stream, indent, "FONT", NULL, label->font); - writeNumber(stream, indent, "MAXSIZE", MS_MAXFONTSIZE, label->maxsize); - writeNumber(stream, indent, "MINSIZE", MS_MINFONTSIZE, label->minsize); + writeNumber(stream, indent, "MAXSIZE", MS_MAXFONTSIZE, label->maxsize); + writeNumber(stream, indent, "MINSIZE", MS_MINFONTSIZE, label->minsize); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_SIZE].item) - writeAttributeBinding(stream, indent, "SIZE", &(label->bindings[MS_LABEL_BINDING_SIZE])); - else writeNumber(stream, indent, "SIZE", -1, label->size); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_SIZE].item) + writeAttributeBinding(stream, indent, "SIZE", + &(label->bindings[MS_LABEL_BINDING_SIZE])); + else + writeNumber(stream, indent, "SIZE", -1, label->size); - writeKeyword(stream, indent, "ALIGN", label->align, 3, MS_ALIGN_LEFT, "LEFT", MS_ALIGN_CENTER, "CENTER", MS_ALIGN_RIGHT, "RIGHT"); + writeKeyword(stream, indent, "ALIGN", label->align, 3, MS_ALIGN_LEFT, "LEFT", + MS_ALIGN_CENTER, "CENTER", MS_ALIGN_RIGHT, "RIGHT"); writeNumber(stream, indent, "BUFFER", 0, label->buffer); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_COLOR].item) - writeAttributeBinding(stream, indent, "COLOR", &(label->bindings[MS_LABEL_BINDING_COLOR])); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_COLOR].item) + writeAttributeBinding(stream, indent, "COLOR", + &(label->bindings[MS_LABEL_BINDING_COLOR])); else { - MS_INIT_COLOR(c,0,0,0,255); + MS_INIT_COLOR(c, 0, 0, 0, 255); writeColor(stream, indent, "COLOR", &c, &(label->color)); } writeString(stream, indent, "ENCODING", NULL, label->encoding); - if(label->leader) - writeLeader(stream,indent,label->leader); - writeKeyword(stream, indent, "FORCE", label->force, 2, MS_TRUE, "TRUE", MS_LABEL_FORCE_GROUP, "GROUP"); + if (label->leader) + writeLeader(stream, indent, label->leader); + writeKeyword(stream, indent, "FORCE", label->force, 2, MS_TRUE, "TRUE", + MS_LABEL_FORCE_GROUP, "GROUP"); writeNumber(stream, indent, "MAXLENGTH", 0, label->maxlength); writeNumber(stream, indent, "MAXSCALEDENOM", -1, label->maxscaledenom); writeNumber(stream, indent, "MINDISTANCE", -1, label->mindistance); - writeNumberOrKeyword(stream, indent, "MINFEATURESIZE", -1, label->minfeaturesize, 1, label->autominfeaturesize, MS_TRUE, "AUTO"); + writeNumberOrKeyword(stream, indent, "MINFEATURESIZE", -1, + label->minfeaturesize, 1, label->autominfeaturesize, + MS_TRUE, "AUTO"); writeNumber(stream, indent, "MINSCALEDENOM", -1, label->minscaledenom); - writeDimension(stream, indent, "OFFSET", label->offsetx, label->offsety, NULL, NULL); + writeDimension(stream, indent, "OFFSET", label->offsetx, label->offsety, NULL, + NULL); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_OUTLINECOLOR].item) - writeAttributeBinding(stream, indent, "OUTLINECOLOR", &(label->bindings[MS_LABEL_BINDING_OUTLINECOLOR])); - else writeColor(stream, indent, "OUTLINECOLOR", NULL, &(label->outlinecolor)); + if (label->numbindings > 0 && + label->bindings[MS_LABEL_BINDING_OUTLINECOLOR].item) + writeAttributeBinding(stream, indent, "OUTLINECOLOR", + &(label->bindings[MS_LABEL_BINDING_OUTLINECOLOR])); + else + writeColor(stream, indent, "OUTLINECOLOR", NULL, &(label->outlinecolor)); writeNumber(stream, indent, "OUTLINEWIDTH", 1, label->outlinewidth); writeKeyword(stream, indent, "PARTIALS", label->partials, 1, MS_TRUE, "TRUE"); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_POSITION].item) - writeAttributeBinding(stream, indent, "POSITION", &(label->bindings[MS_LABEL_BINDING_POSITION])); - else writeKeyword(stream, indent, "POSITION", label->position, 10, MS_UL, "UL", MS_UC, "UC", MS_UR, "UR", MS_CL, "CL", MS_CC, "CC", MS_CR, "CR", MS_LL, "LL", MS_LC, "LC", MS_LR, "LR", MS_AUTO, "AUTO"); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_POSITION].item) + writeAttributeBinding(stream, indent, "POSITION", + &(label->bindings[MS_LABEL_BINDING_POSITION])); + else + writeKeyword(stream, indent, "POSITION", label->position, 10, MS_UL, "UL", + MS_UC, "UC", MS_UR, "UR", MS_CL, "CL", MS_CC, "CC", MS_CR, + "CR", MS_LL, "LL", MS_LC, "LC", MS_LR, "LR", MS_AUTO, "AUTO"); - if(label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_PRIORITY].item) - writeAttributeBinding(stream, indent, "PRIORITY", &(label->bindings[MS_LABEL_BINDING_PRIORITY])); - else writeNumber(stream, indent, "PRIORITY", MS_DEFAULT_LABEL_PRIORITY, label->priority); + if (label->numbindings > 0 && label->bindings[MS_LABEL_BINDING_PRIORITY].item) + writeAttributeBinding(stream, indent, "PRIORITY", + &(label->bindings[MS_LABEL_BINDING_PRIORITY])); + else + writeNumber(stream, indent, "PRIORITY", MS_DEFAULT_LABEL_PRIORITY, + label->priority); writeNumber(stream, indent, "REPEATDISTANCE", 0, label->repeatdistance); writeColor(stream, indent, "SHADOWCOLOR", NULL, &(label->shadowcolor)); - writeDimension(stream, indent, "SHADOWSIZE", label->shadowsizex, label->shadowsizey, label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item, label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item); + writeDimension(stream, indent, "SHADOWSIZE", label->shadowsizex, + label->shadowsizey, + label->bindings[MS_LABEL_BINDING_SHADOWSIZEX].item, + label->bindings[MS_LABEL_BINDING_SHADOWSIZEY].item); writeNumber(stream, indent, "MAXOVERLAPANGLE", 22.5, label->maxoverlapangle); - for(i=0; inumstyles; i++) + for (i = 0; i < label->numstyles; i++) writeStyle(stream, indent, label->styles[i]); writeExpression(stream, indent, "TEXT", &(label->text)); @@ -1990,9 +2177,8 @@ static void writeLabel(FILE *stream, int indent, labelObj *label) writeBlockEnd(stream, indent, "LABEL"); } -char* msWriteLabelToString(labelObj *label) -{ - msIOContext context; +char *msWriteLabelToString(labelObj *label) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -2003,53 +2189,52 @@ char* msWriteLabelToString(labelObj *label) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeLabel(stdout, -1, label); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } -void msInitExpression(expressionObj *exp) -{ +void msInitExpression(expressionObj *exp) { memset(exp, 0, sizeof(*exp)); exp->type = MS_STRING; } -void msFreeExpressionTokens(expressionObj *exp) -{ +void msFreeExpressionTokens(expressionObj *exp) { tokenListNodeObjPtr node = NULL; tokenListNodeObjPtr nextNode = NULL; - if(!exp) return; + if (!exp) + return; - if(exp->tokens) { + if (exp->tokens) { node = exp->tokens; while (node != NULL) { nextNode = node->next; msFree(node->tokensrc); /* not set very often */ - switch(node->token) { - case MS_TOKEN_BINDING_DOUBLE: - case MS_TOKEN_BINDING_INTEGER: - case MS_TOKEN_BINDING_STRING: - case MS_TOKEN_BINDING_TIME: - msFree(node->tokenval.bindval.item); - break; - case MS_TOKEN_LITERAL_TIME: - /* anything to do? */ - break; - case MS_TOKEN_LITERAL_STRING: - msFree(node->tokenval.strval); - break; - case MS_TOKEN_LITERAL_SHAPE: - msFreeShape(node->tokenval.shpval); - free(node->tokenval.shpval); - break; + switch (node->token) { + case MS_TOKEN_BINDING_DOUBLE: + case MS_TOKEN_BINDING_INTEGER: + case MS_TOKEN_BINDING_STRING: + case MS_TOKEN_BINDING_TIME: + msFree(node->tokenval.bindval.item); + break; + case MS_TOKEN_LITERAL_TIME: + /* anything to do? */ + break; + case MS_TOKEN_LITERAL_STRING: + msFree(node->tokenval.strval); + break; + case MS_TOKEN_LITERAL_SHAPE: + msFreeShape(node->tokenval.shpval); + free(node->tokenval.shpval); + break; } msFree(node); @@ -2059,22 +2244,25 @@ void msFreeExpressionTokens(expressionObj *exp) } } -void msFreeExpression(expressionObj *exp) -{ - if(!exp) return; +void msFreeExpression(expressionObj *exp) { + if (!exp) + return; msFree(exp->string); msFree(exp->native_string); - if((exp->type == MS_REGEX) && exp->compiled) ms_regfree(&(exp->regex)); + if ((exp->type == MS_REGEX) && exp->compiled) + ms_regfree(&(exp->regex)); msFreeExpressionTokens(exp); msInitExpression(exp); /* re-initialize */ } -int loadExpression(expressionObj *exp) -{ - /* TODO: should we call msFreeExpression if exp->string != NULL? We do some checking to avoid a leak but is it enough... */ +int loadExpression(expressionObj *exp) { + /* TODO: should we call msFreeExpression if exp->string != NULL? We do some + * checking to avoid a leak but is it enough... */ msyystring_icase = MS_TRUE; - if((exp->type = getSymbol(6, MS_STRING,MS_EXPRESSION,MS_REGEX,MS_ISTRING,MS_IREGEX,MS_LIST)) == -1) return(-1); + if ((exp->type = getSymbol(6, MS_STRING, MS_EXPRESSION, MS_REGEX, MS_ISTRING, + MS_IREGEX, MS_LIST)) == -1) + return (-1); if (exp->string != NULL) { msFree(exp->string); msFree(exp->native_string); @@ -2082,15 +2270,15 @@ int loadExpression(expressionObj *exp) exp->string = msStrdup(msyystring_buffer); exp->native_string = NULL; - if(exp->type == MS_ISTRING) { + if (exp->type == MS_ISTRING) { exp->flags = exp->flags | MS_EXP_INSENSITIVE; exp->type = MS_STRING; - } else if(exp->type == MS_IREGEX) { + } else if (exp->type == MS_IREGEX) { exp->flags = exp->flags | MS_EXP_INSENSITIVE; exp->type = MS_REGEX; } - return(0); + return (0); } /* --------------------------------------------------------------------------- @@ -2105,46 +2293,47 @@ int loadExpression(expressionObj *exp) See bug 339 for more details -- SG. ------------------------------------------------------------------------ */ -int msLoadExpressionString(expressionObj *exp, char *value) -{ +int msLoadExpressionString(expressionObj *exp, char *value) { int retval = MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); - retval = loadExpressionString( exp, value ); - msReleaseLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); + retval = loadExpressionString(exp, value); + msReleaseLock(TLOCK_PARSER); return retval; } -int loadExpressionString(expressionObj *exp, char *value) -{ +int loadExpressionString(expressionObj *exp, char *value) { msyystate = MS_TOKENIZE_STRING; msyystring = value; msyylex(); /* sets things up but processes no tokens */ - msFreeExpression(exp); /* we're totally replacing the old expression so free (which re-inits) to start over */ + msFreeExpression(exp); /* we're totally replacing the old expression so free + (which re-inits) to start over */ msyystring_icase = MS_TRUE; - if((exp->type = getSymbol2(5, MS_EXPRESSION,MS_REGEX,MS_IREGEX,MS_ISTRING,MS_LIST)) != -1) { + if ((exp->type = getSymbol2(5, MS_EXPRESSION, MS_REGEX, MS_IREGEX, MS_ISTRING, + MS_LIST)) != -1) { exp->string = msStrdup(msyystring_buffer); - if(exp->type == MS_ISTRING) { + if (exp->type == MS_ISTRING) { exp->type = MS_STRING; exp->flags = exp->flags | MS_EXP_INSENSITIVE; - } else if(exp->type == MS_IREGEX) { + } else if (exp->type == MS_IREGEX) { exp->type = MS_REGEX; exp->flags = exp->flags | MS_EXP_INSENSITIVE; } } else { - /* failure above is not an error since we'll consider anything not matching (like an unquoted number) as a STRING) */ + /* failure above is not an error since we'll consider anything not matching + * (like an unquoted number) as a STRING) */ exp->type = MS_STRING; - if((strlen(value) - strlen(msyystring_buffer)) == 2) + if ((strlen(value) - strlen(msyystring_buffer)) == 2) exp->string = msStrdup(msyystring_buffer); /* value was quoted */ else exp->string = msStrdup(value); /* use the whole value */ } - return(0); + return (0); } /* msGetExpressionString() @@ -2154,136 +2343,143 @@ int loadExpressionString(expressionObj *exp, char *value) * * Returns a newly allocated buffer that should be freed by the caller or NULL. */ -char *msGetExpressionString(expressionObj *exp) -{ - if(exp->string) { +char *msGetExpressionString(expressionObj *exp) { + if (exp->string) { char *exprstring; size_t buffer_size; const char *case_insensitive = ""; - if(exp->flags & MS_EXP_INSENSITIVE) + if (exp->flags & MS_EXP_INSENSITIVE) case_insensitive = "i"; /* Alloc buffer big enough for string + 2 delimiters + 'i' + \0 */ - buffer_size = strlen(exp->string)+4; - exprstring = (char*)msSmallMalloc(buffer_size); - - switch(exp->type) { - case(MS_REGEX): - snprintf(exprstring, buffer_size, "/%s/%s", exp->string, case_insensitive); - return exprstring; - case(MS_STRING): - snprintf(exprstring, buffer_size, "\"%s\"%s", exp->string, case_insensitive); - return exprstring; - case(MS_EXPRESSION): - snprintf(exprstring, buffer_size, "(%s)", exp->string); - return exprstring; - case(MS_LIST): - snprintf(exprstring, buffer_size, "{%s}", exp->string); - return exprstring; - default: - /* We should never get to here really! */ - free(exprstring); - return NULL; + buffer_size = strlen(exp->string) + 4; + exprstring = (char *)msSmallMalloc(buffer_size); + + switch (exp->type) { + case (MS_REGEX): + snprintf(exprstring, buffer_size, "/%s/%s", exp->string, + case_insensitive); + return exprstring; + case (MS_STRING): + snprintf(exprstring, buffer_size, "\"%s\"%s", exp->string, + case_insensitive); + return exprstring; + case (MS_EXPRESSION): + snprintf(exprstring, buffer_size, "(%s)", exp->string); + return exprstring; + case (MS_LIST): + snprintf(exprstring, buffer_size, "{%s}", exp->string); + return exprstring; + default: + /* We should never get to here really! */ + free(exprstring); + return NULL; } } return NULL; } -static void writeExpression(FILE *stream, int indent, const char *name, expressionObj *exp) -{ - if(!exp || !exp->string) return; +static void writeExpression(FILE *stream, int indent, const char *name, + expressionObj *exp) { + if (!exp || !exp->string) + return; writeIndent(stream, ++indent); - switch(exp->type) { - case(MS_LIST): - fprintf(stream, "%s {%s}", name, exp->string); - break; - case(MS_REGEX): - msIO_fprintf(stream, "%s /%s/", name, exp->string); - break; - case(MS_STRING): - msIO_fprintf(stream, "%s ", name); - writeStringElement(stream, exp->string); - break; - case(MS_EXPRESSION): - msIO_fprintf(stream, "%s (%s)", name, exp->string); - break; - } - if((exp->type == MS_STRING || exp->type == MS_REGEX) && (exp->flags & MS_EXP_INSENSITIVE)) + switch (exp->type) { + case (MS_LIST): + fprintf(stream, "%s {%s}", name, exp->string); + break; + case (MS_REGEX): + msIO_fprintf(stream, "%s /%s/", name, exp->string); + break; + case (MS_STRING): + msIO_fprintf(stream, "%s ", name); + writeStringElement(stream, exp->string); + break; + case (MS_EXPRESSION): + msIO_fprintf(stream, "%s (%s)", name, exp->string); + break; + } + if ((exp->type == MS_STRING || exp->type == MS_REGEX) && + (exp->flags & MS_EXP_INSENSITIVE)) msIO_fprintf(stream, "i"); writeLineFeed(stream); } -int loadHashTable(hashTableObj *ptable) -{ +int loadHashTable(hashTableObj *ptable) { assert(ptable); - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadHashTable()"); - return(MS_FAILURE); - case(END): - return(MS_SUCCESS); - case(MS_STRING): - { - char* data = NULL; - char* key = msStrdup(msyystring_buffer); /* the key is *always* a string */ - if(getString(&data) == MS_FAILURE) { - free(key); - return(MS_FAILURE); - } - msInsertHashTable(ptable, key, data); - + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadHashTable()"); + return (MS_FAILURE); + case (END): + return (MS_SUCCESS); + case (MS_STRING): { + char *data = NULL; + char *key = + msStrdup(msyystring_buffer); /* the key is *always* a string */ + if (getString(&data) == MS_FAILURE) { free(key); - free(data); - break; + return (MS_FAILURE); } - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadHashTable()", msyystring_buffer, msyylineno ); - return(MS_FAILURE); + msInsertHashTable(ptable, key, data); + + free(key); + free(data); + break; + } + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadHashTable()", msyystring_buffer, msyylineno); + return (MS_FAILURE); } } - return(MS_SUCCESS); + return (MS_SUCCESS); } -static void writeHashTable(FILE *stream, int indent, const char *title, hashTableObj *table) -{ +static void writeHashTable(FILE *stream, int indent, const char *title, + hashTableObj *table) { struct hashObj *tp; int i; - if(!table) return; - if(msHashIsEmpty(table)) return; + if (!table) + return; + if (msHashIsEmpty(table)) + return; indent++; writeBlockBegin(stream, indent, title); - for (i=0; iitems[i] != NULL) { - for (tp=table->items[i]; tp!=NULL; tp=tp->next) + for (tp = table->items[i]; tp != NULL; tp = tp->next) writeNameValuePair(stream, indent, tp->key, tp->data); } } writeBlockEnd(stream, indent, title); } -static void writeHashTableInline(FILE *stream, int indent, char *name, hashTableObj* table) -{ +static void writeHashTableInline(FILE *stream, int indent, char *name, + hashTableObj *table) { struct hashObj *tp = NULL; int i; - if(!table) return; - if(msHashIsEmpty(table)) return; + if (!table) + return; + if (msHashIsEmpty(table)) + return; ++indent; - for (i=0; iitems[i] != NULL) { - for (tp=table->items[i]; tp!=NULL; tp=tp->next) { + for (tp = table->items[i]; tp != NULL; tp = tp->next) { writeIndent(stream, indent); msIO_fprintf(stream, "%s ", name); writeStringElement(stream, tp->key); - msIO_fprintf(stream," "); + msIO_fprintf(stream, " "); writeStringElement(stream, tp->data); writeLineFeed(stream); } @@ -2294,8 +2490,7 @@ static void writeHashTableInline(FILE *stream, int indent, char *name, hashTable /* ** Initialize, load and free a cluster object */ -void initCluster(clusterObj *cluster) -{ +void initCluster(clusterObj *cluster) { cluster->maxdistance = 10; cluster->buffer = 0; cluster->region = NULL; @@ -2303,55 +2498,58 @@ void initCluster(clusterObj *cluster) msInitExpression(&(cluster->filter)); } -void freeCluster(clusterObj *cluster) -{ +void freeCluster(clusterObj *cluster) { msFree(cluster->region); msFreeExpression(&(cluster->group)); msFreeExpression(&(cluster->filter)); } -int loadCluster(clusterObj *cluster) -{ - for(;;) { - switch(msyylex()) { - case(CLUSTER): - break; /* for string loads */ - case(MAXDISTANCE): - if(getDouble(&(cluster->maxdistance), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(BUFFER): - if(getDouble(&(cluster->buffer), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(REGION): - if(getString(&cluster->region) == MS_FAILURE) return(-1); - break; - case(END): - return(0); - break; - case(GROUP): - if(loadExpression(&(cluster->group)) == -1) return(-1); - break; - case(FILTER): - if(loadExpression(&(cluster->filter)) == -1) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadCluster()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } - +int loadCluster(clusterObj *cluster) { + for (;;) { + switch (msyylex()) { + case (CLUSTER): + break; /* for string loads */ + case (MAXDISTANCE): + if (getDouble(&(cluster->maxdistance), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (BUFFER): + if (getDouble(&(cluster->buffer), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (REGION): + if (getString(&cluster->region) == MS_FAILURE) + return (-1); + break; + case (END): + return (0); + break; + case (GROUP): + if (loadExpression(&(cluster->group)) == -1) + return (-1); + break; + case (FILTER): + if (loadExpression(&(cluster->filter)) == -1) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadCluster()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msUpdateClusterFromString(clusterObj *cluster, char *string) -{ - if(!cluster || !string) return MS_FAILURE; +int msUpdateClusterFromString(clusterObj *cluster, char *string) { + if (!cluster || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -2359,25 +2557,23 @@ int msUpdateClusterFromString(clusterObj *cluster, char *string) msyylineno = 1; /* start at line 1 */ - if(loadCluster(cluster) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadCluster(cluster) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeCluster(FILE *stream, int indent, clusterObj *cluster) -{ +static void writeCluster(FILE *stream, int indent, clusterObj *cluster) { - if (cluster->maxdistance == 10 && - cluster->buffer == 0.0 && - cluster->region == NULL && - cluster->group.string == NULL && + if (cluster->maxdistance == 10 && cluster->buffer == 0.0 && + cluster->region == NULL && cluster->group.string == NULL && cluster->filter.string == NULL) - return; /* Nothing to write */ + return; /* Nothing to write */ indent++; writeBlockBegin(stream, indent, "CLUSTER"); @@ -2389,9 +2585,8 @@ static void writeCluster(FILE *stream, int indent, clusterObj *cluster) writeBlockEnd(stream, indent, "CLUSTER"); } -char* msWriteClusterToString(clusterObj *cluster) -{ - msIOContext context; +char *msWriteClusterToString(clusterObj *cluster) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -2402,28 +2597,27 @@ char* msWriteClusterToString(clusterObj *cluster) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeCluster(stdout, -1, cluster); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize, load and free a single style */ -int initStyle(styleObj *style) -{ +int initStyle(styleObj *style) { int i; MS_REFCNT_INIT(style); - MS_INIT_COLOR(style->color, -1,-1,-1,255); /* must explictly set colors */ - MS_INIT_COLOR(style->outlinecolor, -1,-1,-1,255); + MS_INIT_COLOR(style->color, -1, -1, -1, 255); /* must explictly set colors */ + MS_INIT_COLOR(style->outlinecolor, -1, -1, -1, 255); /* New Color Range fields*/ - MS_INIT_COLOR(style->mincolor, -1,-1,-1,255); - MS_INIT_COLOR(style->maxcolor, -1,-1,-1,255); + MS_INIT_COLOR(style->mincolor, -1, -1, -1, 255); + MS_INIT_COLOR(style->maxcolor, -1, -1, -1, 255); style->minvalue = 0.0; style->maxvalue = 1.0; style->rangeitem = NULL; @@ -2433,15 +2627,15 @@ int initStyle(styleObj *style) style->size = -1; /* in SIZEUNITS (layerObj) */ style->minsize = MS_MINSYMBOLSIZE; style->maxsize = MS_MAXSYMBOLSIZE; - style->width = 1; /* in pixels */ + style->width = 1; /* in pixels */ style->outlinewidth = 0; /* in pixels */ style->minwidth = MS_MINSYMBOLWIDTH; style->maxwidth = MS_MAXSYMBOLWIDTH; - style->minscaledenom=style->maxscaledenom = -1.0; - style->offsetx = style->offsety = 0; /* no offset */ + style->minscaledenom = style->maxscaledenom = -1.0; + style->offsetx = style->offsety = 0; /* no offset */ style->polaroffsetpixel = style->polaroffsetangle = 0; /* no polar offset */ style->angle = 0; - style->autoangle= MS_FALSE; + style->autoangle = MS_FALSE; style->antialiased = MS_TRUE; style->opacity = 100; /* fully opaque */ @@ -2457,7 +2651,7 @@ int initStyle(styleObj *style) style->numbindings = 0; style->nexprbindings = 0; - for(i=0; ibindings[i].item = NULL; style->bindings[i].index = -1; msInitExpression(&(style->exprBindings[i])); @@ -2469,295 +2663,362 @@ int initStyle(styleObj *style) return MS_SUCCESS; } -int loadStyle(styleObj *style) -{ +int loadStyle(styleObj *style) { int symbol; - for(;;) { - switch(msyylex()) { - /* New Color Range fields*/ - case (COLORRANGE): - /*These are both in one line now*/ - if(loadColor(&(style->mincolor), NULL) != MS_SUCCESS) return(MS_FAILURE); - if(loadColor(&(style->maxcolor), NULL) != MS_SUCCESS) return(MS_FAILURE); - break; - case(DATARANGE): - /*These are both in one line now*/ - if(getDouble(&(style->minvalue), MS_NUM_CHECK_NONE, -1, -1) == -1) return(MS_FAILURE); - if(getDouble(&(style->maxvalue), MS_NUM_CHECK_NONE, -1, -1) == -1) return(MS_FAILURE); - break; - case(RANGEITEM): - if(getString(&style->rangeitem) == MS_FAILURE) return(MS_FAILURE); - break; - /* End Range fields*/ - case(ANGLE): - if((symbol = getSymbol(3, MS_NUMBER,MS_BINDING,MS_AUTO)) == -1) return(MS_FAILURE); - - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, -360.0, 360.0) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid ANGLE, must be between -360 and 360 (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); - } - style->angle = (double) msyynumber; - } else if(symbol==MS_BINDING) { - if (style->bindings[MS_STYLE_BINDING_ANGLE].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_ANGLE].item); - style->bindings[MS_STYLE_BINDING_ANGLE].item = msStrdup(msyystring_buffer); - style->numbindings++; - } else { - style->autoangle=MS_TRUE; - } - break; - case(ANTIALIAS): - if ((symbol = getSymbol(2, MS_TRUE,MS_FALSE)) == -1) return(MS_FAILURE); - if (symbol == MS_FALSE) { - style->antialiased = MS_FALSE; + for (;;) { + switch (msyylex()) { + /* New Color Range fields*/ + case (COLORRANGE): + /*These are both in one line now*/ + if (loadColor(&(style->mincolor), NULL) != MS_SUCCESS) + return (MS_FAILURE); + if (loadColor(&(style->maxcolor), NULL) != MS_SUCCESS) + return (MS_FAILURE); + break; + case (DATARANGE): + /*These are both in one line now*/ + if (getDouble(&(style->minvalue), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (MS_FAILURE); + if (getDouble(&(style->maxvalue), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (MS_FAILURE); + break; + case (RANGEITEM): + if (getString(&style->rangeitem) == MS_FAILURE) + return (MS_FAILURE); + break; + /* End Range fields*/ + case (ANGLE): + if ((symbol = getSymbol(3, MS_NUMBER, MS_BINDING, MS_AUTO)) == -1) + return (MS_FAILURE); + + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, -360.0, 360.0) == + MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid ANGLE, must be between -360 and 360 (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } - break; - case(COLOR): - if(loadColor(&(style->color), &(style->bindings[MS_STYLE_BINDING_COLOR])) != MS_SUCCESS) return(MS_FAILURE); - if(style->bindings[MS_STYLE_BINDING_COLOR].item) style->numbindings++; - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadStyle()"); - return(MS_FAILURE); /* missing END (probably) */ - case(END): { - int alpha; + style->angle = (double)msyynumber; + } else if (symbol == MS_BINDING) { + if (style->bindings[MS_STYLE_BINDING_ANGLE].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_ANGLE].item); + style->bindings[MS_STYLE_BINDING_ANGLE].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } else { + style->autoangle = MS_TRUE; + } + break; + case (ANTIALIAS): + if ((symbol = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) + return (MS_FAILURE); + if (symbol == MS_FALSE) { + style->antialiased = MS_FALSE; + } + break; + case (COLOR): + if (loadColor(&(style->color), + &(style->bindings[MS_STYLE_BINDING_COLOR])) != MS_SUCCESS) + return (MS_FAILURE); + if (style->bindings[MS_STYLE_BINDING_COLOR].item) + style->numbindings++; + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadStyle()"); + return (MS_FAILURE); /* missing END (probably) */ + case (END): { + int alpha; - /* apply opacity as the alpha channel color(s) */ - if(style->opacity < 100) { - alpha = MS_NINT(style->opacity*2.55); + /* apply opacity as the alpha channel color(s) */ + if (style->opacity < 100) { + alpha = MS_NINT(style->opacity * 2.55); - style->color.alpha = alpha; - style->outlinecolor.alpha = alpha; + style->color.alpha = alpha; + style->outlinecolor.alpha = alpha; - style->mincolor.alpha = alpha; - style->maxcolor.alpha = alpha; - } + style->mincolor.alpha = alpha; + style->maxcolor.alpha = alpha; + } - return(MS_SUCCESS); + return (MS_SUCCESS); + } break; + case (GAP): + if (getDouble(&(style->gap), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (MS_FAILURE); + break; + case (INITIALGAP): + if (getDouble(&(style->initialgap), MS_NUM_CHECK_GTE, 0, -1) == + -1) { // zero is ok + msSetError(MS_MISCERR, + "INITIALGAP requires a positive values (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } break; - case(GAP): - if(getDouble(&(style->gap), MS_NUM_CHECK_NONE, -1, -1) == -1) return(MS_FAILURE); - break; - case(INITIALGAP): - if(getDouble(&(style->initialgap), MS_NUM_CHECK_GTE, 0, -1) == -1) { // zero is ok - msSetError(MS_MISCERR, "INITIALGAP requires a positive values (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); - } - break; - case(MAXSCALEDENOM): - if(getDouble(&(style->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(MS_FAILURE); - break; - case(MINSCALEDENOM): - if(getDouble(&(style->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(MS_FAILURE); - break; - case(GEOMTRANSFORM): { - int s; - if((s = getSymbol(2, MS_STRING, MS_EXPRESSION)) == -1) return(MS_FAILURE); - if(s == MS_STRING) - msStyleSetGeomTransform(style, msyystring_buffer); - else { - /* handle expression case here for the moment */ - msFree(style->_geomtransform.string); - style->_geomtransform.string = msStrdup(msyystring_buffer); - style->_geomtransform.type = MS_GEOMTRANSFORM_EXPRESSION; - } + case (MAXSCALEDENOM): + if (getDouble(&(style->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (MS_FAILURE); + break; + case (MINSCALEDENOM): + if (getDouble(&(style->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (MS_FAILURE); + break; + case (GEOMTRANSFORM): { + int s; + if ((s = getSymbol(2, MS_STRING, MS_EXPRESSION)) == -1) + return (MS_FAILURE); + if (s == MS_STRING) + msStyleSetGeomTransform(style, msyystring_buffer); + else { + /* handle expression case here for the moment */ + msFree(style->_geomtransform.string); + style->_geomtransform.string = msStrdup(msyystring_buffer); + style->_geomtransform.type = MS_GEOMTRANSFORM_EXPRESSION; } + } break; + case (LINECAP): + if ((style->linecap = getSymbol(4, MS_CJC_BUTT, MS_CJC_ROUND, + MS_CJC_SQUARE, MS_CJC_TRIANGLE)) == -1) + return (MS_FAILURE); break; - case(LINECAP): - if((style->linecap = getSymbol(4,MS_CJC_BUTT, MS_CJC_ROUND, MS_CJC_SQUARE, MS_CJC_TRIANGLE)) == -1) return(MS_FAILURE); - break; - case(LINEJOIN): - if((style->linejoin = getSymbol(4,MS_CJC_NONE, MS_CJC_ROUND, MS_CJC_MITER, MS_CJC_BEVEL)) == -1) return(MS_FAILURE); - break; - case(LINEJOINMAXSIZE): - if(getDouble(&(style->linejoinmaxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(MS_FAILURE); - break; - case(MAXSIZE): - if(getDouble(&(style->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(MS_FAILURE); - break; - case(MINSIZE): - if(getDouble(&(style->minsize), MS_NUM_CHECK_GTE, 0, -1) == -1) return(MS_FAILURE); - break; - case(MAXWIDTH): - if(getDouble(&(style->maxwidth), MS_NUM_CHECK_GT, 0, -1) == -1) return(MS_FAILURE); - break; - case(MINWIDTH): - if(getDouble(&(style->minwidth), MS_NUM_CHECK_GTE, 0, -1) == -1) return(MS_FAILURE); - break; - case(OFFSET): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) - style->offsetx = (double) msyynumber; // any double ok - else { - if (style->bindings[MS_STYLE_BINDING_OFFSET_X].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_OFFSET_X].item); - style->bindings[MS_STYLE_BINDING_OFFSET_X].item = msStrdup(msyystring_buffer); - style->numbindings++; - } + case (LINEJOIN): + if ((style->linejoin = getSymbol(4, MS_CJC_NONE, MS_CJC_ROUND, + MS_CJC_MITER, MS_CJC_BEVEL)) == -1) + return (MS_FAILURE); + break; + case (LINEJOINMAXSIZE): + if (getDouble(&(style->linejoinmaxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (MS_FAILURE); + break; + case (MAXSIZE): + if (getDouble(&(style->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (MS_FAILURE); + break; + case (MINSIZE): + if (getDouble(&(style->minsize), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (MS_FAILURE); + break; + case (MAXWIDTH): + if (getDouble(&(style->maxwidth), MS_NUM_CHECK_GT, 0, -1) == -1) + return (MS_FAILURE); + break; + case (MINWIDTH): + if (getDouble(&(style->minwidth), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (MS_FAILURE); + break; + case (OFFSET): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) + style->offsetx = (double)msyynumber; // any double ok + else { + if (style->bindings[MS_STYLE_BINDING_OFFSET_X].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_OFFSET_X].item); + style->bindings[MS_STYLE_BINDING_OFFSET_X].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) - style->offsety = (double) msyynumber; // any double ok - else { - if (style->bindings[MS_STYLE_BINDING_OFFSET_Y].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_OFFSET_Y].item); - style->bindings[MS_STYLE_BINDING_OFFSET_Y].item = msStrdup(msyystring_buffer); - style->numbindings++; - } - break; - case(OPACITY): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) - style->opacity = MS_MAX(MS_MIN((int) msyynumber, 100), 0); /* force opacity to between 0 and 100 */ - else { - if (style->bindings[MS_STYLE_BINDING_OPACITY].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_OPACITY].item); - style->bindings[MS_STYLE_BINDING_OPACITY].item = msStrdup(msyystring_buffer); - style->numbindings++; - } - break; - case(OUTLINECOLOR): - if(loadColor(&(style->outlinecolor), &(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR])) != MS_SUCCESS) return(MS_FAILURE); - if(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR].item) style->numbindings++; - break; - case(PATTERN): { - int done = MS_FALSE; - for(;;) { /* read till the next END */ - switch(msyylex()) { - case(END): - if(style->patternlength < 2) { - msSetError(MS_SYMERR, "Not enough pattern elements. A minimum of 2 are required (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); - } - done = MS_TRUE; - break; - case(MS_NUMBER): /* read the pattern values */ - if(style->patternlength == MS_MAXPATTERNLENGTH) { - msSetError(MS_SYMERR, "Pattern too long.", "loadStyle()"); - return(MS_FAILURE); - } - style->pattern[style->patternlength] = atof(msyystring_buffer); // good enough? - style->patternlength++; - break; - default: - msSetError(MS_TYPEERR, "Parsing error near (%s):(line %d)", "loadStyle()", msyystring_buffer, msyylineno); - return(MS_FAILURE); - } - if(done == MS_TRUE) - break; - } - break; + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) + style->offsety = (double)msyynumber; // any double ok + else { + if (style->bindings[MS_STYLE_BINDING_OFFSET_Y].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_OFFSET_Y].item); + style->bindings[MS_STYLE_BINDING_OFFSET_Y].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + case (OPACITY): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) + style->opacity = MS_MAX(MS_MIN((int)msyynumber, 100), + 0); /* force opacity to between 0 and 100 */ + else { + if (style->bindings[MS_STYLE_BINDING_OPACITY].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_OPACITY].item); + style->bindings[MS_STYLE_BINDING_OPACITY].item = + msStrdup(msyystring_buffer); + style->numbindings++; } - case(OUTLINEWIDTH): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid OUTLINEWIDTH, must be greater then or equal to 0 (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); + break; + case (OUTLINECOLOR): + if (loadColor(&(style->outlinecolor), + &(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR])) != + MS_SUCCESS) + return (MS_FAILURE); + if (style->bindings[MS_STYLE_BINDING_OUTLINECOLOR].item) + style->numbindings++; + break; + case (PATTERN): { + int done = MS_FALSE; + for (;;) { /* read till the next END */ + switch (msyylex()) { + case (END): + if (style->patternlength < 2) { + msSetError(MS_SYMERR, + "Not enough pattern elements. A minimum of 2 are " + "required (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } - style->outlinewidth = (double) msyynumber; - } else { - if (style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item); - style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item = msStrdup(msyystring_buffer); - style->numbindings++; - } - break; - case(SIZE): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid SIZE, must be greater than 0 (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); + done = MS_TRUE; + break; + case (MS_NUMBER): /* read the pattern values */ + if (style->patternlength == MS_MAXPATTERNLENGTH) { + msSetError(MS_SYMERR, "Pattern too long.", "loadStyle()"); + return (MS_FAILURE); } - style->size = (double) msyynumber; - } else { - if (style->bindings[MS_STYLE_BINDING_SIZE].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_SIZE].item); - style->bindings[MS_STYLE_BINDING_SIZE].item = msStrdup(msyystring_buffer); - style->numbindings++; + style->pattern[style->patternlength] = + atof(msyystring_buffer); // good enough? + style->patternlength++; + break; + default: + msSetError(MS_TYPEERR, "Parsing error near (%s):(line %d)", + "loadStyle()", msyystring_buffer, msyylineno); + return (MS_FAILURE); } - break; - case(STYLE): - break; /* for string loads */ - case(SYMBOL): - if((symbol = getSymbol(3, MS_NUMBER,MS_STRING,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid SYMBOL id, must be greater than or equal to 0 (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); - } - if(style->symbolname != NULL) { - msFree(style->symbolname); - style->symbolname = NULL; - } - style->symbol = (int) msyynumber; - } else if(symbol == MS_STRING) { - if (style->symbolname != NULL) - msFree(style->symbolname); - style->symbolname = msStrdup(msyystring_buffer); - } else { - if (style->bindings[MS_STYLE_BINDING_SYMBOL].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_SYMBOL].item); - style->bindings[MS_STYLE_BINDING_SYMBOL].item = msStrdup(msyystring_buffer); - style->numbindings++; + if (done == MS_TRUE) + break; + } + break; + } + case (OUTLINEWIDTH): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid OUTLINEWIDTH, must be greater then or equal to 0 " + "(line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } - break; - case(WIDTH): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid WIDTH, must be greater than or equal to 0 (line %d)", "loadStyle()", msyylineno); - return(MS_FAILURE); - } - style->width = (double) msyynumber; - } else { - if (style->bindings[MS_STYLE_BINDING_WIDTH].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_WIDTH].item); - style->bindings[MS_STYLE_BINDING_WIDTH].item = msStrdup(msyystring_buffer); - style->numbindings++; + style->outlinewidth = (double)msyynumber; + } else { + if (style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item); + style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + case (SIZE): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GT, 0, -1) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid SIZE, must be greater than 0 (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } - break; - case(POLAROFFSET): - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - style->polaroffsetpixel = (double) msyynumber; // ok? - } else { - if (style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item); - style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item = msStrdup(msyystring_buffer); - style->numbindings++; + style->size = (double)msyynumber; + } else { + if (style->bindings[MS_STYLE_BINDING_SIZE].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_SIZE].item); + style->bindings[MS_STYLE_BINDING_SIZE].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + case (STYLE): + break; /* for string loads */ + case (SYMBOL): + if ((symbol = getSymbol(3, MS_NUMBER, MS_STRING, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { + msSetError( + MS_MISCERR, + "Invalid SYMBOL id, must be greater than or equal to 0 (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } - - if((symbol = getSymbol(2, MS_NUMBER,MS_BINDING)) == -1) return(MS_FAILURE); - if(symbol == MS_NUMBER) { - style->polaroffsetangle = (double) msyynumber; // ok? - } else { - if (style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item != NULL) - msFree(style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item); - style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item = msStrdup(msyystring_buffer); - style->numbindings++; + if (style->symbolname != NULL) { + msFree(style->symbolname); + style->symbolname = NULL; } - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadStyle()", msyystring_buffer, msyylineno); - return(MS_FAILURE); - } else { - return(MS_SUCCESS); /* end of a string, not an error */ + style->symbol = (int)msyynumber; + } else if (symbol == MS_STRING) { + if (style->symbolname != NULL) + msFree(style->symbolname); + style->symbolname = msStrdup(msyystring_buffer); + } else { + if (style->bindings[MS_STYLE_BINDING_SYMBOL].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_SYMBOL].item); + style->bindings[MS_STYLE_BINDING_SYMBOL].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + case (WIDTH): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { + msSetError( + MS_MISCERR, + "Invalid WIDTH, must be greater than or equal to 0 (line %d)", + "loadStyle()", msyylineno); + return (MS_FAILURE); } + style->width = (double)msyynumber; + } else { + if (style->bindings[MS_STYLE_BINDING_WIDTH].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_WIDTH].item); + style->bindings[MS_STYLE_BINDING_WIDTH].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + case (POLAROFFSET): + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + style->polaroffsetpixel = (double)msyynumber; // ok? + } else { + if (style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item); + style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + + if ((symbol = getSymbol(2, MS_NUMBER, MS_BINDING)) == -1) + return (MS_FAILURE); + if (symbol == MS_NUMBER) { + style->polaroffsetangle = (double)msyynumber; // ok? + } else { + if (style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item != NULL) + msFree(style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item); + style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item = + msStrdup(msyystring_buffer); + style->numbindings++; + } + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadStyle()", msyystring_buffer, msyylineno); + return (MS_FAILURE); + } else { + return (MS_SUCCESS); /* end of a string, not an error */ + } } } } -int msUpdateStyleFromString(styleObj *style, char *string) -{ - if(!style || !string) return MS_FAILURE; +int msUpdateStyleFromString(styleObj *style, char *string) { + if (!style || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -2765,21 +3026,21 @@ int msUpdateStyleFromString(styleObj *style, char *string) msyylineno = 1; /* start at line 1 */ - if(loadStyle(style) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadStyle(style) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -int freeStyle(styleObj *style) -{ +int freeStyle(styleObj *style) { int i; - if( MS_REFCNT_DECR_IS_NOT_ZERO(style) ) { + if (MS_REFCNT_DECR_IS_NOT_ZERO(style)) { return MS_FAILURE; } @@ -2787,7 +3048,7 @@ int freeStyle(styleObj *style) msFreeExpression(&style->_geomtransform); msFree(style->rangeitem); - for(i=0; ibindings[i].item); msFreeExpression(&(style->exprBindings[i])); } @@ -2795,57 +3056,52 @@ int freeStyle(styleObj *style) return MS_SUCCESS; } -void writeStyle(FILE *stream, int indent, styleObj *style) -{ +void writeStyle(FILE *stream, int indent, styleObj *style) { indent++; writeBlockBegin(stream, indent, "STYLE"); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_ANGLE].item) - writeAttributeBinding(stream, indent, "ANGLE", &(style->bindings[MS_STYLE_BINDING_ANGLE])); - else writeNumberOrKeyword(stream, indent, "ANGLE", 0, style->angle, style->autoangle, 1, MS_TRUE, "AUTO"); + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_ANGLE].item) + writeAttributeBinding(stream, indent, "ANGLE", + &(style->bindings[MS_STYLE_BINDING_ANGLE])); + else + writeNumberOrKeyword(stream, indent, "ANGLE", 0, style->angle, + style->autoangle, 1, MS_TRUE, "AUTO"); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_COLOR].item) - writeAttributeBinding(stream, indent, "COLOR", &(style->bindings[MS_STYLE_BINDING_COLOR])); - else writeColor(stream, indent, "COLOR", NULL, &(style->color)); + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_COLOR].item) + writeAttributeBinding(stream, indent, "COLOR", + &(style->bindings[MS_STYLE_BINDING_COLOR])); + else + writeColor(stream, indent, "COLOR", NULL, &(style->color)); writeNumber(stream, indent, "GAP", 0, style->gap); writeNumber(stream, indent, "INITIALGAP", -1, style->initialgap); - if(style->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) { + if (style->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) { writeIndent(stream, indent + 1); msIO_fprintf(stream, "GEOMTRANSFORM (%s)\n", style->_geomtransform.string); - } - else if(style->_geomtransform.type != MS_GEOMTRANSFORM_NONE) { + } else if (style->_geomtransform.type != MS_GEOMTRANSFORM_NONE) { writeKeyword(stream, indent, "GEOMTRANSFORM", style->_geomtransform.type, 8, - MS_GEOMTRANSFORM_BBOX, "\"bbox\"", - MS_GEOMTRANSFORM_END, "\"end\"", - MS_GEOMTRANSFORM_LABELPOINT, "\"labelpnt\"", + MS_GEOMTRANSFORM_BBOX, "\"bbox\"", MS_GEOMTRANSFORM_END, + "\"end\"", MS_GEOMTRANSFORM_LABELPOINT, "\"labelpnt\"", MS_GEOMTRANSFORM_LABELPOLY, "\"labelpoly\"", MS_GEOMTRANSFORM_LABELCENTER, "\"labelcenter\"", - MS_GEOMTRANSFORM_START, "\"start\"", - MS_GEOMTRANSFORM_VERTICES, "\"vertices\"", - MS_GEOMTRANSFORM_CENTROID, "\"centroid\"" - ); + MS_GEOMTRANSFORM_START, "\"start\"", MS_GEOMTRANSFORM_VERTICES, + "\"vertices\"", MS_GEOMTRANSFORM_CENTROID, "\"centroid\""); } - if(style->linecap != MS_CJC_DEFAULT_CAPS) { - writeKeyword(stream,indent,"LINECAP",(int)style->linecap,5, - MS_CJC_NONE,"NONE", - MS_CJC_ROUND, "ROUND", - MS_CJC_SQUARE, "SQUARE", - MS_CJC_BUTT, "BUTT", - MS_CJC_TRIANGLE, "TRIANGLE"); + if (style->linecap != MS_CJC_DEFAULT_CAPS) { + writeKeyword(stream, indent, "LINECAP", (int)style->linecap, 5, MS_CJC_NONE, + "NONE", MS_CJC_ROUND, "ROUND", MS_CJC_SQUARE, "SQUARE", + MS_CJC_BUTT, "BUTT", MS_CJC_TRIANGLE, "TRIANGLE"); } - if(style->linejoin != MS_CJC_DEFAULT_JOINS) { - writeKeyword(stream,indent,"LINEJOIN",(int)style->linejoin,5, - MS_CJC_NONE,"NONE", - MS_CJC_ROUND, "ROUND", - MS_CJC_BEVEL, "BEVEL", - MS_CJC_MITER, "MITER"); + if (style->linejoin != MS_CJC_DEFAULT_JOINS) { + writeKeyword(stream, indent, "LINEJOIN", (int)style->linejoin, 5, + MS_CJC_NONE, "NONE", MS_CJC_ROUND, "ROUND", MS_CJC_BEVEL, + "BEVEL", MS_CJC_MITER, "MITER"); } - writeNumber(stream, indent, "LINEJOINMAXSIZE", MS_CJC_DEFAULT_JOIN_MAXSIZE , style->linejoinmaxsize); - + writeNumber(stream, indent, "LINEJOINMAXSIZE", MS_CJC_DEFAULT_JOIN_MAXSIZE, + style->linejoinmaxsize); writeNumber(stream, indent, "MAXSCALEDENOM", -1, style->maxscaledenom); writeNumber(stream, indent, "MAXSIZE", MS_MAXSYMBOLSIZE, style->maxsize); @@ -2853,62 +3109,88 @@ void writeStyle(FILE *stream, int indent, styleObj *style) writeNumber(stream, indent, "MINSCALEDENOM", -1, style->minscaledenom); writeNumber(stream, indent, "MINSIZE", MS_MINSYMBOLSIZE, style->minsize); writeNumber(stream, indent, "MINWIDTH", MS_MINSYMBOLWIDTH, style->minwidth); - if((style->numbindings > 0 && (style->bindings[MS_STYLE_BINDING_OFFSET_X].item||style->bindings[MS_STYLE_BINDING_OFFSET_Y].item))||style->offsetx!=0||style->offsety!=0) - writeDimension(stream, indent, "OFFSET", style->offsetx, style->offsety, style->bindings[MS_STYLE_BINDING_OFFSET_X].item, style->bindings[MS_STYLE_BINDING_OFFSET_Y].item); - if((style->numbindings > 0 && (style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item||style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item))||style->polaroffsetangle!=0||style->polaroffsetpixel!=0) - writeDimension(stream, indent, "POLAROFFSET", style->polaroffsetpixel, style->polaroffsetangle, - style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item, style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item); - - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_OPACITY].item) - writeAttributeBinding(stream, indent, "OPACITY", &(style->bindings[MS_STYLE_BINDING_OPACITY])); - else writeNumber(stream, indent, "OPACITY", 100, style->opacity); + if ((style->numbindings > 0 && + (style->bindings[MS_STYLE_BINDING_OFFSET_X].item || + style->bindings[MS_STYLE_BINDING_OFFSET_Y].item)) || + style->offsetx != 0 || style->offsety != 0) + writeDimension(stream, indent, "OFFSET", style->offsetx, style->offsety, + style->bindings[MS_STYLE_BINDING_OFFSET_X].item, + style->bindings[MS_STYLE_BINDING_OFFSET_Y].item); + if ((style->numbindings > 0 && + (style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item || + style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item)) || + style->polaroffsetangle != 0 || style->polaroffsetpixel != 0) + writeDimension(stream, indent, "POLAROFFSET", style->polaroffsetpixel, + style->polaroffsetangle, + style->bindings[MS_STYLE_BINDING_POLAROFFSET_PIXEL].item, + style->bindings[MS_STYLE_BINDING_POLAROFFSET_ANGLE].item); + + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_OPACITY].item) + writeAttributeBinding(stream, indent, "OPACITY", + &(style->bindings[MS_STYLE_BINDING_OPACITY])); + else + writeNumber(stream, indent, "OPACITY", 100, style->opacity); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_OUTLINECOLOR].item) - writeAttributeBinding(stream, indent, "OUTLINECOLOR", &(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR])); - else writeColor(stream, indent, "OUTLINECOLOR", NULL, &(style->outlinecolor)); + if (style->numbindings > 0 && + style->bindings[MS_STYLE_BINDING_OUTLINECOLOR].item) + writeAttributeBinding(stream, indent, "OUTLINECOLOR", + &(style->bindings[MS_STYLE_BINDING_OUTLINECOLOR])); + else + writeColor(stream, indent, "OUTLINECOLOR", NULL, &(style->outlinecolor)); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item) - writeAttributeBinding(stream, indent, "OUTLINEWIDTH", &(style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH])); - else writeNumber(stream, indent, "OUTLINEWIDTH", 0, style->outlinewidth); + if (style->numbindings > 0 && + style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH].item) + writeAttributeBinding(stream, indent, "OUTLINEWIDTH", + &(style->bindings[MS_STYLE_BINDING_OUTLINEWIDTH])); + else + writeNumber(stream, indent, "OUTLINEWIDTH", 0, style->outlinewidth); /* PATTERN */ - if(style->patternlength != 0) { + if (style->patternlength != 0) { int i; indent++; - writeBlockBegin(stream,indent,"PATTERN"); + writeBlockBegin(stream, indent, "PATTERN"); writeIndent(stream, indent); - for(i=0; ipatternlength; i++) + for (i = 0; i < style->patternlength; i++) msIO_fprintf(stream, " %.2f", style->pattern[i]); - msIO_fprintf(stream,"\n"); - writeBlockEnd(stream,indent,"PATTERN"); + msIO_fprintf(stream, "\n"); + writeBlockEnd(stream, indent, "PATTERN"); indent--; } - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_SIZE].item) - writeAttributeBinding(stream, indent, "SIZE", &(style->bindings[MS_STYLE_BINDING_SIZE])); - else writeNumber(stream, indent, "SIZE", -1, style->size); + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_SIZE].item) + writeAttributeBinding(stream, indent, "SIZE", + &(style->bindings[MS_STYLE_BINDING_SIZE])); + else + writeNumber(stream, indent, "SIZE", -1, style->size); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_SYMBOL].item) - writeAttributeBinding(stream, indent, "SYMBOL", &(style->bindings[MS_STYLE_BINDING_SYMBOL])); - else writeNumberOrString(stream, indent, "SYMBOL", 0, style->symbol, style->symbolname); + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_SYMBOL].item) + writeAttributeBinding(stream, indent, "SYMBOL", + &(style->bindings[MS_STYLE_BINDING_SYMBOL])); + else + writeNumberOrString(stream, indent, "SYMBOL", 0, style->symbol, + style->symbolname); - if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_WIDTH].item) - writeAttributeBinding(stream, indent, "WIDTH", &(style->bindings[MS_STYLE_BINDING_WIDTH])); - else writeNumber(stream, indent, "WIDTH", 1, style->width); + if (style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_WIDTH].item) + writeAttributeBinding(stream, indent, "WIDTH", + &(style->bindings[MS_STYLE_BINDING_WIDTH])); + else + writeNumber(stream, indent, "WIDTH", 1, style->width); writeString(stream, indent, "RANGEITEM", NULL, style->rangeitem); /* If COLORRANGE is valid, assume DATARANGE also needs to be written */ - if(MS_VALID_COLOR(style->mincolor) && MS_VALID_COLOR(style->maxcolor)) { - writeColorRange(stream, indent, "COLORRANGE", &(style->mincolor), &(style->maxcolor)); - writeDoubleRange(stream, indent, "DATARANGE", style->minvalue, style->maxvalue); + if (MS_VALID_COLOR(style->mincolor) && MS_VALID_COLOR(style->maxcolor)) { + writeColorRange(stream, indent, "COLORRANGE", &(style->mincolor), + &(style->maxcolor)); + writeDoubleRange(stream, indent, "DATARANGE", style->minvalue, + style->maxvalue); } writeBlockEnd(stream, indent, "STYLE"); } -char* msWriteStyleToString(styleObj *style) -{ - msIOContext context; +char *msWriteStyleToString(styleObj *style) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -2919,21 +3201,20 @@ char* msWriteStyleToString(styleObj *style) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeStyle(stdout, -1, style); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize, load and free a single class */ -int initClass(classObj *class) -{ +int initClass(classObj *class) { class->status = MS_ON; class->debug = MS_OFF; MS_REFCNT_INIT(class); @@ -2970,14 +3251,13 @@ int initClass(classObj *class) class->sizeunits = MS_INHERIT; class->scalefactor = 1.0; - return(0); + return (0); } -int freeClass(classObj *class) -{ +int freeClass(classObj *class) { int i; - if( MS_REFCNT_DECR_IS_NOT_ZERO(class) ) { + if (MS_REFCNT_DECR_IS_NOT_ZERO(class)) { return MS_FAILURE; } @@ -2988,21 +3268,23 @@ int freeClass(classObj *class) msFree(class->template); msFree(class->group); - if (&(class->metadata)) msFreeHashItems(&(class->metadata)); - if (&(class->validation)) msFreeHashItems(&(class->validation)); + if (&(class->metadata)) + msFreeHashItems(&(class->metadata)); + if (&(class->validation)) + msFreeHashItems(&(class->validation)); - for(i=0; inumstyles; i++) { /* each style */ - if(class->styles[i]!=NULL) { - if(freeStyle(class->styles[i]) == MS_SUCCESS) { + for (i = 0; i < class->numstyles; i++) { /* each style */ + if (class->styles[i] != NULL) { + if (freeStyle(class->styles[i]) == MS_SUCCESS) { msFree(class->styles[i]); } } } msFree(class->styles); - for(i=0; inumlabels; i++) { /* each label */ - if(class->labels[i]!=NULL) { - if(freeLabel(class->labels[i]) == MS_SUCCESS) { + for (i = 0; i < class->numlabels; i++) { /* each label */ + if (class->labels[i] != NULL) { + if (freeLabel(class->labels[i]) == MS_SUCCESS) { msFree(class->labels[i]); } } @@ -3011,7 +3293,7 @@ int freeClass(classObj *class) msFree(class->keyimage); - if(class->leader) { + if (class->leader) { freeLabelLeader(class->leader); msFree(class->leader); class->leader = NULL; @@ -3032,8 +3314,7 @@ int freeClass(classObj *class) ** ** Returns a reference to the new styleObj on success, NULL on error. */ -styleObj *msGrowClassStyles( classObj *class ) -{ +styleObj *msGrowClassStyles(classObj *class) { /* Do we need to increase the size of styles[] by MS_STYLE_ALLOCSIZE? */ if (class->numstyles == class->maxstyles) { @@ -3043,18 +3324,19 @@ styleObj *msGrowClassStyles( classObj *class ) newsize = class->maxstyles + MS_STYLE_ALLOCSIZE; /* Alloc/realloc styles */ - newStylePtr = (styleObj**)realloc(class->styles, newsize*sizeof(styleObj*)); - MS_CHECK_ALLOC(newStylePtr, newsize*sizeof(styleObj*), NULL); + newStylePtr = + (styleObj **)realloc(class->styles, newsize * sizeof(styleObj *)); + MS_CHECK_ALLOC(newStylePtr, newsize * sizeof(styleObj *), NULL); class->styles = newStylePtr; class->maxstyles = newsize; - for(i=class->numstyles; imaxstyles; i++) { + for (i = class->numstyles; i < class->maxstyles; i++) { class->styles[i] = NULL; } } - if (class->styles[class->numstyles]==NULL) { - class->styles[class->numstyles]=(styleObj*)calloc(1,sizeof(styleObj)); + if (class->styles[class->numstyles] == NULL) { + class->styles[class->numstyles] = (styleObj *)calloc(1, sizeof(styleObj)); MS_CHECK_ALLOC(class->styles[class->numstyles], sizeof(styleObj), NULL); } @@ -3062,8 +3344,7 @@ styleObj *msGrowClassStyles( classObj *class ) } /* exactly the same as for a classObj */ -styleObj *msGrowLabelStyles( labelObj *label ) -{ +styleObj *msGrowLabelStyles(labelObj *label) { /* Do we need to increase the size of styles[] by MS_STYLE_ALLOCSIZE? */ if (label->numstyles == label->maxstyles) { @@ -3073,18 +3354,19 @@ styleObj *msGrowLabelStyles( labelObj *label ) newsize = label->maxstyles + MS_STYLE_ALLOCSIZE; /* Alloc/realloc styles */ - newStylePtr = (styleObj**)realloc(label->styles, newsize*sizeof(styleObj*)); - MS_CHECK_ALLOC(newStylePtr, newsize*sizeof(styleObj*), NULL); + newStylePtr = + (styleObj **)realloc(label->styles, newsize * sizeof(styleObj *)); + MS_CHECK_ALLOC(newStylePtr, newsize * sizeof(styleObj *), NULL); label->styles = newStylePtr; label->maxstyles = newsize; - for(i=label->numstyles; imaxstyles; i++) { + for (i = label->numstyles; i < label->maxstyles; i++) { label->styles[i] = NULL; } } - if (label->styles[label->numstyles]==NULL) { - label->styles[label->numstyles]=(styleObj*)calloc(1,sizeof(styleObj)); + if (label->styles[label->numstyles] == NULL) { + label->styles[label->numstyles] = (styleObj *)calloc(1, sizeof(styleObj)); MS_CHECK_ALLOC(label->styles[label->numstyles], sizeof(styleObj), NULL); } @@ -3092,8 +3374,7 @@ styleObj *msGrowLabelStyles( labelObj *label ) } /* exactly the same as for a labelLeaderObj, needs refactoring */ -styleObj *msGrowLeaderStyles( labelLeaderObj *leader ) -{ +styleObj *msGrowLeaderStyles(labelLeaderObj *leader) { /* Do we need to increase the size of styles[] by MS_STYLE_ALLOCSIZE? */ if (leader->numstyles == leader->maxstyles) { @@ -3103,19 +3384,19 @@ styleObj *msGrowLeaderStyles( labelLeaderObj *leader ) newsize = leader->maxstyles + MS_STYLE_ALLOCSIZE; /* Alloc/realloc styles */ - newStylePtr = (styleObj**)realloc(leader->styles, - newsize*sizeof(styleObj*)); - MS_CHECK_ALLOC(newStylePtr, newsize*sizeof(styleObj*), NULL); + newStylePtr = + (styleObj **)realloc(leader->styles, newsize * sizeof(styleObj *)); + MS_CHECK_ALLOC(newStylePtr, newsize * sizeof(styleObj *), NULL); leader->styles = newStylePtr; leader->maxstyles = newsize; - for(i=leader->numstyles; imaxstyles; i++) { + for (i = leader->numstyles; i < leader->maxstyles; i++) { leader->styles[i] = NULL; } } - if (leader->styles[leader->numstyles]==NULL) { - leader->styles[leader->numstyles]=(styleObj*)calloc(1,sizeof(styleObj)); + if (leader->styles[leader->numstyles] == NULL) { + leader->styles[leader->numstyles] = (styleObj *)calloc(1, sizeof(styleObj)); MS_CHECK_ALLOC(leader->styles[leader->numstyles], sizeof(styleObj), NULL); } @@ -3128,50 +3409,48 @@ styleObj *msGrowLeaderStyles( labelLeaderObj *leader ) ** ** Returns MS_SUCCESS/MS_FAILURE. */ -int msMaybeAllocateClassStyle(classObj* c, int idx) -{ - if (c==NULL) return MS_FAILURE; +int msMaybeAllocateClassStyle(classObj *c, int idx) { + if (c == NULL) + return MS_FAILURE; - if ( idx < 0 ) { - msSetError(MS_MISCERR, "Invalid style index: %d", "msMaybeAllocateClassStyle()", idx); + if (idx < 0) { + msSetError(MS_MISCERR, "Invalid style index: %d", + "msMaybeAllocateClassStyle()", idx); return MS_FAILURE; } /* Alloc empty styles as needed up to idx. * Nothing to do if requested style already exists */ - while(c->numstyles <= idx) { + while (c->numstyles <= idx) { if (msGrowClassStyles(c) == NULL) return MS_FAILURE; - if ( initStyle(c->styles[c->numstyles]) == MS_FAILURE ) { + if (initStyle(c->styles[c->numstyles]) == MS_FAILURE) { msSetError(MS_MISCERR, "Failed to init new styleObj", "msMaybeAllocateClassStyle()"); freeStyle(c->styles[c->numstyles]); free(c->styles[c->numstyles]); c->styles[c->numstyles] = NULL; - return(MS_FAILURE); + return (MS_FAILURE); } c->numstyles++; } return MS_SUCCESS; } - - /* * Reset style info in the class to defaults * the only members we don't touch are name, expression, and join/query stuff * This is used with STYLEITEM before overwriting the contents of a class. */ -void resetClassStyle(classObj *class) -{ +void resetClassStyle(classObj *class) { int i; /* reset labels */ - for(i=0; inumlabels; i++) { - if(class->labels[i] != NULL) { - if(freeLabel(class->labels[i]) == MS_SUCCESS ) { + for (i = 0; i < class->numlabels; i++) { + if (class->labels[i] != NULL) { + if (freeLabel(class->labels[i]) == MS_SUCCESS) { msFree(class->labels[i]); } class->labels[i] = NULL; @@ -3183,9 +3462,9 @@ void resetClassStyle(classObj *class) msInitExpression(&(class->text)); /* reset styles */ - for(i=0; inumstyles; i++) { - if(class->styles[i] != NULL) { - if( freeStyle(class->styles[i]) == MS_SUCCESS ) { + for (i = 0; i < class->numstyles; i++) { + if (class->styles[i] != NULL) { + if (freeStyle(class->styles[i]) == MS_SUCCESS) { msFree(class->styles[i]); } class->styles[i] = NULL; @@ -3196,8 +3475,7 @@ void resetClassStyle(classObj *class) class->layer = NULL; } -labelObj *msGrowClassLabels( classObj *class ) -{ +labelObj *msGrowClassLabels(classObj *class) { /* Do we need to increase the size of labels[] by MS_LABEL_ALLOCSIZE? */ @@ -3208,159 +3486,197 @@ labelObj *msGrowClassLabels( classObj *class ) newsize = class->maxlabels + MS_LABEL_ALLOCSIZE; /* Alloc/realloc labels */ - newLabelPtr = (labelObj**)realloc(class->labels, newsize*sizeof(labelObj*)); - MS_CHECK_ALLOC(newLabelPtr, newsize*sizeof(labelObj*), NULL); + newLabelPtr = + (labelObj **)realloc(class->labels, newsize * sizeof(labelObj *)); + MS_CHECK_ALLOC(newLabelPtr, newsize * sizeof(labelObj *), NULL); class->labels = newLabelPtr; class->maxlabels = newsize; - for(i=class->numlabels; imaxlabels; i++) { + for (i = class->numlabels; i < class->maxlabels; i++) { class->labels[i] = NULL; } } - if (class->labels[class->numlabels]==NULL) { - class->labels[class->numlabels]=(labelObj*)calloc(1,sizeof(labelObj)); + if (class->labels[class->numlabels] == NULL) { + class->labels[class->numlabels] = (labelObj *)calloc(1, sizeof(labelObj)); MS_CHECK_ALLOC(class->labels[class->numlabels], sizeof(labelObj), NULL); } return class->labels[class->numlabels]; } -int loadClass(classObj *class, layerObj *layer) -{ - if(!class || !layer) return(-1); +int loadClass(classObj *class, layerObj *layer) { + if (!class || !layer) + return (-1); - class->layer = (layerObj *) layer; + class->layer = (layerObj *)layer; - for(;;) { - switch(msyylex()) { - case(CLASS): - break; /* for string loads */ - case(DEBUG): - if((class->debug = getSymbol(3, MS_ON,MS_OFF, MS_NUMBER)) == -1) return(-1); - if(class->debug == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid DEBUG level, must be between 0 and 5 (line %d)", "loadClass()", msyylineno); - return(-1); - } - class->debug = (int) msyynumber; - } - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadClass()"); - return(-1); - case(END): - return(0); - break; - case(EXPRESSION): - if(loadExpression(&(class->expression)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ - break; - case(GROUP): - if(getString(&class->group) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(KEYIMAGE): - if(getString(&class->keyimage) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(LABEL): - if(msGrowClassLabels(class) == NULL) return(-1); - initLabel(class->labels[class->numlabels]); - class->labels[class->numlabels]->size = MS_MEDIUM; /* only set a default if the LABEL section is present */ - if(loadLabel(class->labels[class->numlabels]) == -1) { - freeLabel(class->labels[class->numlabels]); - free(class->labels[class->numlabels]); - class->labels[class->numlabels] = NULL; - return(-1); - } - class->numlabels++; - break; - case(LEADER): - if(!class->leader) { - class->leader = msSmallMalloc(sizeof(labelLeaderObj)); - initLeader(class->leader); - } - if(loadLeader(class->leader) == -1) return(-1); - break; - case(MAXSCALE): - case(MAXSCALEDENOM): - if(getDouble(&(class->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(METADATA): - if(loadHashTable(&(class->metadata)) != MS_SUCCESS) return(-1); - break; - case(MINSCALE): - case(MINSCALEDENOM): - if(getDouble(&(class->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MINFEATURESIZE): - if(getInteger(&(class->minfeaturesize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(NAME): - if(getString(&class->name) == MS_FAILURE) return(-1); - break; - case(STATUS): - if((class->status = getSymbol(2, MS_ON,MS_OFF)) == -1) return(-1); - break; - case(STYLE): - if(msGrowClassStyles(class) == NULL) - return(-1); - initStyle(class->styles[class->numstyles]); - if(loadStyle(class->styles[class->numstyles]) != MS_SUCCESS) { - freeStyle(class->styles[class->numstyles]); - free(class->styles[class->numstyles]); - class->styles[class->numstyles] = NULL; - return(-1); - } - class->numstyles++; - break; - case(TEMPLATE): - if(getString(&class->template) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(TEXT): - if(loadExpression(&(class->text)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ - if((class->text.type != MS_STRING) && (class->text.type != MS_EXPRESSION)) { - msSetError(MS_MISCERR, "Text expressions support constant or tagged replacement strings." , "loadClass()"); - return(-1); - } - break; - case(TITLE): - if(getString(&class->title) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(VALIDATION): - if(loadHashTable(&(class->validation)) != MS_SUCCESS) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadClass()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ + for (;;) { + switch (msyylex()) { + case (CLASS): + break; /* for string loads */ + case (DEBUG): + if ((class->debug = getSymbol(3, MS_ON, MS_OFF, MS_NUMBER)) == -1) + return (-1); + if (class->debug == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid DEBUG level, must be between 0 and 5 (line %d)", + "loadClass()", msyylineno); + return (-1); } - } - } -} - -static int classResolveSymbolNames(classObj *class) -{ - int i,j; - int try_addimage_if_notfound = MS_TRUE; - - /* step through styles and labels to resolve symbol names */ - /* class styles */ - for(i=0; inumstyles; i++) { - if(class->styles[i]->symbolname) { - if((class->styles[i]->symbol = msGetSymbolIndex(&(class->layer->map->symbolset), class->styles[i]->symbolname, try_addimage_if_notfound)) == -1) { - msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class, style %d of layer %s.", "classResolveSymbolNames()", class->styles[i]->symbolname, i, class->layer->name); - return MS_FAILURE; + class->debug = (int)msyynumber; } - } - } - - /* label styles */ - for(i=0; inumlabels; i++) { - for(j=0; jlabels[i]->numstyles; j++) { - if(class->labels[i]->styles[j]->symbolname) { - if((class->labels[i]->styles[j]->symbol = msGetSymbolIndex(&(class->layer->map->symbolset), class->labels[i]->styles[j]->symbolname, try_addimage_if_notfound)) == -1) { - msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class, label style %d of layer %s.", "classResolveSymbolNames()", class->labels[i]->styles[j]->symbolname, j, class->layer->name); + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadClass()"); + return (-1); + case (END): + return (0); + break; + case (EXPRESSION): + if (loadExpression(&(class->expression)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + break; + case (GROUP): + if (getString(&class->group) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (KEYIMAGE): + if (getString(&class->keyimage) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (LABEL): + if (msGrowClassLabels(class) == NULL) + return (-1); + initLabel(class->labels[class->numlabels]); + class->labels[class->numlabels]->size = + MS_MEDIUM; /* only set a default if the LABEL section is present */ + if (loadLabel(class->labels[class->numlabels]) == -1) { + freeLabel(class->labels[class->numlabels]); + free(class->labels[class->numlabels]); + class->labels[class->numlabels] = NULL; + return (-1); + } + class->numlabels++; + break; + case (LEADER): + if (!class->leader) { + class->leader = msSmallMalloc(sizeof(labelLeaderObj)); + initLeader(class->leader); + } + if (loadLeader(class->leader) == -1) + return (-1); + break; + case (MAXSCALE): + case (MAXSCALEDENOM): + if (getDouble(&(class->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (METADATA): + if (loadHashTable(&(class->metadata)) != MS_SUCCESS) + return (-1); + break; + case (MINSCALE): + case (MINSCALEDENOM): + if (getDouble(&(class->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MINFEATURESIZE): + if (getInteger(&(class->minfeaturesize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (NAME): + if (getString(&class->name) == MS_FAILURE) + return (-1); + break; + case (STATUS): + if ((class->status = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (STYLE): + if (msGrowClassStyles(class) == NULL) + return (-1); + initStyle(class->styles[class->numstyles]); + if (loadStyle(class->styles[class->numstyles]) != MS_SUCCESS) { + freeStyle(class->styles[class->numstyles]); + free(class->styles[class->numstyles]); + class->styles[class->numstyles] = NULL; + return (-1); + } + class->numstyles++; + break; + case (TEMPLATE): + if (getString(&class->template) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (TEXT): + if (loadExpression(&(class->text)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + if ((class->text.type != MS_STRING) && + (class->text.type != MS_EXPRESSION)) { + msSetError( + MS_MISCERR, + "Text expressions support constant or tagged replacement strings.", + "loadClass()"); + return (-1); + } + break; + case (TITLE): + if (getString(&class->title) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (VALIDATION): + if (loadHashTable(&(class->validation)) != MS_SUCCESS) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadClass()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } + } + } +} + +static int classResolveSymbolNames(classObj *class) { + int i, j; + int try_addimage_if_notfound = MS_TRUE; + + /* step through styles and labels to resolve symbol names */ + /* class styles */ + for (i = 0; i < class->numstyles; i++) { + if (class->styles[i]->symbolname) { + if ((class->styles[i]->symbol = msGetSymbolIndex( + &(class->layer->map->symbolset), class->styles[i]->symbolname, + try_addimage_if_notfound)) == -1) { + msSetError(MS_MISCERR, + "Undefined symbol \"%s\" in class, style %d of layer %s.", + "classResolveSymbolNames()", class->styles[i]->symbolname, i, + class->layer->name); + return MS_FAILURE; + } + } + } + + /* label styles */ + for (i = 0; i < class->numlabels; i++) { + for (j = 0; j < class->labels[i]->numstyles; j++) { + if (class->labels[i]->styles[j]->symbolname) { + if ((class->labels[i]->styles[j]->symbol = + msGetSymbolIndex(&(class->layer->map->symbolset), + class->labels[i]->styles[j]->symbolname, + try_addimage_if_notfound)) == -1) { + msSetError( + MS_MISCERR, + "Undefined symbol \"%s\" in class, label style %d of layer %s.", + "classResolveSymbolNames()", + class->labels[i]->styles[j]->symbolname, j, class->layer->name); return MS_FAILURE; } } @@ -3370,11 +3686,11 @@ static int classResolveSymbolNames(classObj *class) return MS_SUCCESS; } -int msUpdateClassFromString(classObj *class, char *string) -{ - if(!class || !string) return MS_FAILURE; +int msUpdateClassFromString(classObj *class, char *string) { + if (!class || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -3382,24 +3698,26 @@ int msUpdateClassFromString(classObj *class, char *string) msyylineno = 1; /* start at line 1 */ - if(loadClass(class, class->layer) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadClass(class, class->layer) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); - if(classResolveSymbolNames(class) != MS_SUCCESS) return MS_FAILURE; + if (classResolveSymbolNames(class) != MS_SUCCESS) + return MS_FAILURE; return MS_SUCCESS; } -static void writeClass(FILE *stream, int indent, classObj *class) -{ +static void writeClass(FILE *stream, int indent, classObj *class) { int i; - if(class->status == MS_DELETE) return; + if (class->status == MS_DELETE) + return; indent++; writeBlockBegin(stream, indent, "CLASS"); @@ -3408,15 +3726,17 @@ static void writeClass(FILE *stream, int indent, classObj *class) writeNumber(stream, indent, "DEBUG", 0, class->debug); writeExpression(stream, indent, "EXPRESSION", &(class->expression)); writeString(stream, indent, "KEYIMAGE", NULL, class->keyimage); - for(i=0; inumlabels; i++) writeLabel(stream, indent, class->labels[i]); - if(class->leader) - writeLeader(stream,indent,class->leader); + for (i = 0; i < class->numlabels; i++) + writeLabel(stream, indent, class->labels[i]); + if (class->leader) + writeLeader(stream, indent, class->leader); writeNumber(stream, indent, "MAXSCALEDENOM", -1, class->maxscaledenom); writeHashTable(stream, indent, "METADATA", &(class->metadata)); writeNumber(stream, indent, "MINSCALEDENOM", -1, class->minscaledenom); writeNumber(stream, indent, "MINFEATURESIZE", -1, class->minfeaturesize); writeKeyword(stream, indent, "STATUS", class->status, 1, MS_OFF, "OFF"); - for(i=0; inumstyles; i++) writeStyle(stream, indent, class->styles[i]); + for (i = 0; i < class->numstyles; i++) + writeStyle(stream, indent, class->styles[i]); writeString(stream, indent, "TEMPLATE", NULL, class->template); writeExpression(stream, indent, "TEXT", &(class->text)); writeString(stream, indent, "TITLE", NULL, class->title); @@ -3424,9 +3744,8 @@ static void writeClass(FILE *stream, int indent, classObj *class) writeBlockEnd(stream, indent, "CLASS"); } -char* msWriteClassToString(classObj *class) -{ - msIOContext context; +char *msWriteClassToString(classObj *class) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -3437,14 +3756,14 @@ char* msWriteClassToString(classObj *class) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeClass(stdout, -1, class); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } int initCompositingFilter(CompositingFilter *filter) { @@ -3454,8 +3773,9 @@ int initCompositingFilter(CompositingFilter *filter) { } void freeCompositingFilter(CompositingFilter *filter) { - if(!filter) return; - if(filter->next) + if (!filter) + return; + if (filter->next) freeCompositingFilter(filter->next); free(filter->filter); free(filter); @@ -3470,8 +3790,9 @@ int initLayerCompositer(LayerCompositer *compositer) { } void freeLayerCompositer(LayerCompositer *compositer) { - if(!compositer) return; - if(compositer->next) + if (!compositer) + return; + if (compositer->next) freeLayerCompositer(compositer->next); freeCompositingFilter(compositer->filter); free(compositer); @@ -3480,11 +3801,10 @@ void freeLayerCompositer(LayerCompositer *compositer) { /* ** Initialize, load and free a single layer structure */ -int initLayer(layerObj *layer, mapObj *map) -{ - if (layer==NULL) { +int initLayer(layerObj *layer, mapObj *map) { + if (layer == NULL) { msSetError(MS_MEMERR, "Layer is null", "initLayer()"); - return(-1); + return (-1); } layer->debug = (int)msGetGlobalDebugLevel(); MS_REFCNT_INIT(layer); @@ -3507,7 +3827,8 @@ int initLayer(layerObj *layer, mapObj *map) layer->type = -1; layer->toleranceunits = MS_PIXELS; - layer->tolerance = -1; /* perhaps this should have a different value based on type */ + layer->tolerance = + -1; /* perhaps this should have a different value based on type */ layer->symbolscaledenom = -1.0; /* -1 means nothing is set */ layer->scalefactor = 1.0; @@ -3520,7 +3841,7 @@ int initLayer(layerObj *layer, mapObj *map) layer->sizeunits = MS_PIXELS; layer->maxfeatures = -1; /* no quota */ - layer->startindex = -1; /*used for pagination*/ + layer->startindex = -1; /*used for pagination*/ layer->scaletokens = NULL; layer->numscaletokens = 0; @@ -3533,10 +3854,10 @@ int initLayer(layerObj *layer, mapObj *map) layer->classitemindex = -1; layer->units = MS_METERS; - if(msInitProjection(&(layer->projection)) == -1) return(-1); + if (msInitProjection(&(layer->projection)) == -1) + return (-1); - if( map ) - { + if (map) { msProjectionInheritContextFrom(&(layer->projection), &(map->projection)); } @@ -3546,7 +3867,7 @@ int initLayer(layerObj *layer, mapObj *map) initCluster(&layer->cluster); - MS_INIT_COLOR(layer->offsite, -1,-1,-1, 255); + MS_INIT_COLOR(layer->offsite, -1, -1, -1, 255); layer->labelcache = MS_ON; layer->postlabelcache = MS_FALSE; @@ -3581,13 +3902,15 @@ int initLayer(layerObj *layer, mapObj *map) layer->iteminfo = NULL; layer->numitems = 0; - layer->resultcache= NULL; + layer->resultcache = NULL; msInitExpression(&(layer->filter)); layer->filteritem = NULL; layer->filteritemindex = -1; - layer->requires = layer->labelrequires = NULL; + layer-> + requires + = layer->labelrequires = NULL; initHashTable(&(layer->metadata)); initHashTable(&(layer->bindvals)); @@ -3599,8 +3922,8 @@ int initLayer(layerObj *layer, mapObj *map) layer->numprocessing = 0; layer->processing = NULL; layer->numjoins = 0; - layer->joins = (joinObj *) malloc(MS_MAXJOINS*sizeof(joinObj)); - MS_CHECK_ALLOC(layer->joins, MS_MAXJOINS*sizeof(joinObj), -1); + layer->joins = (joinObj *)malloc(MS_MAXJOINS * sizeof(joinObj)); + MS_CHECK_ALLOC(layer->joins, MS_MAXJOINS * sizeof(joinObj), -1); layer->extent.minx = -1.0; layer->extent.miny = -1.0; @@ -3628,17 +3951,17 @@ int initLayer(layerObj *layer, mapObj *map) initHashTable(&(layer->connectionoptions)); - return(0); + return (0); } -int initScaleToken(scaleTokenObj* token) { +int initScaleToken(scaleTokenObj *token) { token->n_entries = 0; token->name = NULL; token->tokens = NULL; return MS_SUCCESS; } -int freeScaleTokenEntry( scaleTokenEntryObj *token) { +int freeScaleTokenEntry(scaleTokenEntryObj *token) { msFree(token->value); return MS_SUCCESS; } @@ -3646,25 +3969,25 @@ int freeScaleTokenEntry( scaleTokenEntryObj *token) { int freeScaleToken(scaleTokenObj *scaletoken) { int i; msFree(scaletoken->name); - for(i=0;in_entries;i++) { + for (i = 0; i < scaletoken->n_entries; i++) { freeScaleTokenEntry(&scaletoken->tokens[i]); } msFree(scaletoken->tokens); return MS_SUCCESS; } -int freeLayer(layerObj *layer) -{ +int freeLayer(layerObj *layer) { int i; - if (!layer) return MS_FAILURE; - if( MS_REFCNT_DECR_IS_NOT_ZERO(layer) ) { + if (!layer) + return MS_FAILURE; + if (MS_REFCNT_DECR_IS_NOT_ZERO(layer)) { return MS_FAILURE; } if (layer->debug >= MS_DEBUGLEVEL_VVV) - msDebug("freeLayer(): freeing layer at %p.\n",layer); + msDebug("freeLayer(): freeing layer at %p.\n", layer); - if(msLayerIsOpen(layer)) + if (msLayerIsOpen(layer)) msLayerClose(layer); msFree(layer->name); @@ -3693,27 +4016,27 @@ int freeLayer(layerObj *layer) freeCluster(&layer->cluster); - for(i=0; imaxclasses; i++) { + for (i = 0; i < layer->maxclasses; i++) { if (layer->class[i] != NULL) { - layer->class[i]->layer=NULL; - if ( freeClass(layer->class[i]) == MS_SUCCESS ) { + layer->class[i]->layer = NULL; + if (freeClass(layer->class[i]) == MS_SUCCESS) { msFree(layer->class[i]); } } } msFree(layer->class); - if(layer->numscaletokens>0) { - for(i=0;inumscaletokens;i++) { + if (layer->numscaletokens > 0) { + for (i = 0; i < layer->numscaletokens; i++) { freeScaleToken(&layer->scaletokens[i]); } msFree(layer->scaletokens); } - if(layer->features) + if (layer->features) freeFeatureList(layer->features); - if(layer->resultcache) { + if (layer->resultcache) { cleanupResultCache(layer->resultcache); msFree(layer->resultcache); } @@ -3726,14 +4049,17 @@ int freeLayer(layerObj *layer) msFree(layer->requires); msFree(layer->labelrequires); - if(&(layer->metadata)) msFreeHashItems(&(layer->metadata)); - if(&(layer->validation)) msFreeHashItems(&(layer->validation)); - if(&(layer->bindvals)) msFreeHashItems(&layer->bindvals); + if (&(layer->metadata)) + msFreeHashItems(&(layer->metadata)); + if (&(layer->validation)) + msFreeHashItems(&(layer->validation)); + if (&(layer->bindvals)) + msFreeHashItems(&layer->bindvals); - if(layer->numprocessing > 0) + if (layer->numprocessing > 0) msFreeCharArray(layer->processing, layer->numprocessing); - for(i=0; inumjoins; i++) /* each join */ + for (i = 0; i < layer->numjoins; i++) /* each join */ freeJoin(&(layer->joins[i])); msFree(layer->joins); layer->numjoins = 0; @@ -3741,11 +4067,11 @@ int freeLayer(layerObj *layer) layer->classgroup = NULL; msFree(layer->mask); - if(layer->maskimage) { + if (layer->maskimage) { msFreeImage(layer->maskimage); } - if(layer->compositer) { + if (layer->compositer) { freeLayerCompositer(layer->compositer); } @@ -3757,11 +4083,12 @@ int freeLayer(layerObj *layer) msFreeExpression(&(layer->utfdata)); msFree(layer->utfitem); - for(i=0;isortBy.nProperties;i++) - msFree(layer->sortBy.properties[i].item); + for (i = 0; i < layer->sortBy.nProperties; i++) + msFree(layer->sortBy.properties[i].item); msFree(layer->sortBy.properties); - if(&(layer->connectionoptions)) msFreeHashItems(&layer->connectionoptions); + if (&(layer->connectionoptions)) + msFreeHashItems(&layer->connectionoptions); return MS_SUCCESS; } @@ -3778,8 +4105,7 @@ int freeLayer(layerObj *layer) ** ** Returns a reference to the new classObj on success, NULL on error. */ -classObj *msGrowLayerClasses( layerObj *layer ) -{ +classObj *msGrowLayerClasses(layerObj *layer) { /* Do we need to increase the size of class[] by MS_CLASS_ALLOCSIZE? */ if (layer->numclasses == layer->maxclasses) { @@ -3789,542 +4115,657 @@ classObj *msGrowLayerClasses( layerObj *layer ) newsize = layer->maxclasses + MS_CLASS_ALLOCSIZE; /* Alloc/realloc classes */ - newClassPtr = (classObj**)realloc(layer->class, - newsize*sizeof(classObj*)); - MS_CHECK_ALLOC(newClassPtr, newsize*sizeof(classObj*), NULL); + newClassPtr = + (classObj **)realloc(layer->class, newsize * sizeof(classObj *)); + MS_CHECK_ALLOC(newClassPtr, newsize * sizeof(classObj *), NULL); layer->class = newClassPtr; layer->maxclasses = newsize; - for(i=layer->numclasses; imaxclasses; i++) { + for (i = layer->numclasses; i < layer->maxclasses; i++) { layer->class[i] = NULL; } } - if (layer->class[layer->numclasses]==NULL) { - layer->class[layer->numclasses]=(classObj*)calloc(1,sizeof(classObj)); + if (layer->class[layer->numclasses] == NULL) { + layer->class[layer->numclasses] = (classObj *)calloc(1, sizeof(classObj)); MS_CHECK_ALLOC(layer->class[layer->numclasses], sizeof(classObj), NULL); } return layer->class[layer->numclasses]; } -scaleTokenObj *msGrowLayerScaletokens( layerObj *layer ) -{ - layer->scaletokens = msSmallRealloc(layer->scaletokens,(layer->numscaletokens+1)*sizeof(scaleTokenObj)); - memset(&layer->scaletokens[layer->numscaletokens],0,sizeof(scaleTokenObj)); +scaleTokenObj *msGrowLayerScaletokens(layerObj *layer) { + layer->scaletokens = msSmallRealloc( + layer->scaletokens, (layer->numscaletokens + 1) * sizeof(scaleTokenObj)); + memset(&layer->scaletokens[layer->numscaletokens], 0, sizeof(scaleTokenObj)); return &layer->scaletokens[layer->numscaletokens]; } int loadScaletoken(scaleTokenObj *token, layerObj *layer) { (void)layer; - for(;;) { + for (;;) { int stop = 0; - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadScaletoken()"); - return(MS_FAILURE); - case(NAME): - if(getString(&token->name) == MS_FAILURE) return(MS_FAILURE); - break; - case(VALUES): - for(;;) { - if(stop) break; - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadScaletoken()"); - return(MS_FAILURE); - case(END): - stop = 1; - if(token->n_entries == 0) { - msSetError(MS_PARSEERR,"Scaletoken (line:%d) has no VALUES defined","loadScaleToken()",msyylineno); - return(MS_FAILURE); - } - token->tokens[token->n_entries-1].maxscale = DBL_MAX; - break; - case(MS_STRING): - /* we have a key */ - token->tokens = msSmallRealloc(token->tokens,(token->n_entries+1)*sizeof(scaleTokenEntryObj)); - - if(1 != sscanf(msyystring_buffer,"%lf",&token->tokens[token->n_entries].minscale)) { - msSetError(MS_PARSEERR, "failed to parse SCALETOKEN VALUE (%s):(line %d), expecting \"minscale\"", "loadScaletoken()", - msyystring_buffer,msyylineno); - return(MS_FAILURE); - } - if(token->n_entries == 0) { - /* check supplied value was 0*/ - if(token->tokens[0].minscale != 0) { - msSetError(MS_PARSEERR, "First SCALETOKEN VALUE (%s):(line %d) must be zero, expecting \"0\"", "loadScaletoken()", - msyystring_buffer,msyylineno); - return(MS_FAILURE); - } - } else { - /* set max scale of previous token */ - token->tokens[token->n_entries-1].maxscale = token->tokens[token->n_entries].minscale; - } - token->tokens[token->n_entries].value = NULL; - if(getString(&(token->tokens[token->n_entries].value)) == MS_FAILURE) return(MS_FAILURE); - token->n_entries++; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadScaletoken()", msyystring_buffer, msyylineno ); - return(MS_FAILURE); - } - } - break; - case(END): - if(!token->name || !*(token->name)) { - msSetError(MS_PARSEERR,"ScaleToken missing mandatory NAME entry (line %d)","loadScaleToken()",msyylineno); - return MS_FAILURE; - } - if(token->n_entries == 0) { - msSetError(MS_PARSEERR,"ScaleToken missing at least one VALUES entry (line %d)","loadScaleToken()",msyylineno); - return MS_FAILURE; + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadScaletoken()"); + return (MS_FAILURE); + case (NAME): + if (getString(&token->name) == MS_FAILURE) + return (MS_FAILURE); + break; + case (VALUES): + for (;;) { + if (stop) + break; + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadScaletoken()"); + return (MS_FAILURE); + case (END): + stop = 1; + if (token->n_entries == 0) { + msSetError(MS_PARSEERR, + "Scaletoken (line:%d) has no VALUES defined", + "loadScaleToken()", msyylineno); + return (MS_FAILURE); + } + token->tokens[token->n_entries - 1].maxscale = DBL_MAX; + break; + case (MS_STRING): + /* we have a key */ + token->tokens = + msSmallRealloc(token->tokens, (token->n_entries + 1) * + sizeof(scaleTokenEntryObj)); + + if (1 != sscanf(msyystring_buffer, "%lf", + &token->tokens[token->n_entries].minscale)) { + msSetError(MS_PARSEERR, + "failed to parse SCALETOKEN VALUE (%s):(line %d), " + "expecting \"minscale\"", + "loadScaletoken()", msyystring_buffer, msyylineno); + return (MS_FAILURE); + } + if (token->n_entries == 0) { + /* check supplied value was 0*/ + if (token->tokens[0].minscale != 0) { + msSetError(MS_PARSEERR, + "First SCALETOKEN VALUE (%s):(line %d) must be zero, " + "expecting \"0\"", + "loadScaletoken()", msyystring_buffer, msyylineno); + return (MS_FAILURE); + } + } else { + /* set max scale of previous token */ + token->tokens[token->n_entries - 1].maxscale = + token->tokens[token->n_entries].minscale; + } + token->tokens[token->n_entries].value = NULL; + if (getString(&(token->tokens[token->n_entries].value)) == MS_FAILURE) + return (MS_FAILURE); + token->n_entries++; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadScaletoken()", msyystring_buffer, msyylineno); + return (MS_FAILURE); } - return MS_SUCCESS; - default: - msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", "loadScaletoken()", msyystring_buffer, msyylineno ); - return(MS_FAILURE); + } + break; + case (END): + if (!token->name || !*(token->name)) { + msSetError(MS_PARSEERR, + "ScaleToken missing mandatory NAME entry (line %d)", + "loadScaleToken()", msyylineno); + return MS_FAILURE; + } + if (token->n_entries == 0) { + msSetError(MS_PARSEERR, + "ScaleToken missing at least one VALUES entry (line %d)", + "loadScaleToken()", msyylineno); + return MS_FAILURE; + } + return MS_SUCCESS; + default: + msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", + "loadScaletoken()", msyystring_buffer, msyylineno); + return (MS_FAILURE); } } /* next token*/ } int loadLayerCompositer(LayerCompositer *compositer) { - for(;;) { - switch(msyylex()) { - case COMPFILTER: { - CompositingFilter **filter = &compositer->filter; - while(*filter) { - filter = &((*filter)->next); - } - *filter = msSmallMalloc(sizeof(CompositingFilter)); - initCompositingFilter(*filter); - if(getString(&((*filter)->filter)) == MS_FAILURE) return(MS_FAILURE); + for (;;) { + switch (msyylex()) { + case COMPFILTER: { + CompositingFilter **filter = &compositer->filter; + while (*filter) { + filter = &((*filter)->next); } - break; - case COMPOP: { - char *compop=NULL; - if(getString(&compop) == MS_FAILURE) return(MS_FAILURE); - else if(!strcmp(compop,"clear")) - compositer->comp_op = MS_COMPOP_CLEAR; - else if(!strcmp(compop,"color-burn")) - compositer->comp_op = MS_COMPOP_COLOR_BURN; - else if(!strcmp(compop,"color-dodge")) - compositer->comp_op = MS_COMPOP_COLOR_DODGE; - else if(!strcmp(compop,"contrast")) - compositer->comp_op = MS_COMPOP_CONTRAST; - else if(!strcmp(compop,"darken")) - compositer->comp_op = MS_COMPOP_DARKEN; - else if(!strcmp(compop,"difference")) - compositer->comp_op = MS_COMPOP_DIFFERENCE; - else if(!strcmp(compop,"dst")) - compositer->comp_op = MS_COMPOP_DST; - else if(!strcmp(compop,"dst-atop")) - compositer->comp_op = MS_COMPOP_DST_ATOP; - else if(!strcmp(compop,"dst-in")) - compositer->comp_op = MS_COMPOP_DST_IN; - else if(!strcmp(compop,"dst-out")) - compositer->comp_op = MS_COMPOP_DST_OUT; - else if(!strcmp(compop,"dst-over")) - compositer->comp_op = MS_COMPOP_DST_OVER; - else if(!strcmp(compop,"exclusion")) - compositer->comp_op = MS_COMPOP_EXCLUSION; - else if(!strcmp(compop,"hard-light")) - compositer->comp_op = MS_COMPOP_HARD_LIGHT; - else if(!strcmp(compop,"invert")) - compositer->comp_op = MS_COMPOP_INVERT; - else if(!strcmp(compop,"invert-rgb")) - compositer->comp_op = MS_COMPOP_INVERT_RGB; - else if(!strcmp(compop,"lighten")) - compositer->comp_op = MS_COMPOP_LIGHTEN; - else if(!strcmp(compop,"minus")) - compositer->comp_op = MS_COMPOP_MINUS; - else if(!strcmp(compop,"multiply")) - compositer->comp_op = MS_COMPOP_MULTIPLY; - else if(!strcmp(compop,"overlay")) - compositer->comp_op = MS_COMPOP_OVERLAY; - else if(!strcmp(compop,"plus")) - compositer->comp_op = MS_COMPOP_PLUS; - else if(!strcmp(compop,"screen")) - compositer->comp_op = MS_COMPOP_SCREEN; - else if(!strcmp(compop,"soft-light")) - compositer->comp_op = MS_COMPOP_SOFT_LIGHT; - else if(!strcmp(compop,"src")) - compositer->comp_op = MS_COMPOP_SRC; - else if(!strcmp(compop,"src-atop")) - compositer->comp_op = MS_COMPOP_SRC_ATOP; - else if(!strcmp(compop,"src-in")) - compositer->comp_op = MS_COMPOP_SRC_IN; - else if(!strcmp(compop,"src-out")) - compositer->comp_op = MS_COMPOP_SRC_OUT; - else if(!strcmp(compop,"src-over")) - compositer->comp_op = MS_COMPOP_SRC_OVER; - else if(!strcmp(compop,"xor")) - compositer->comp_op = MS_COMPOP_XOR; - else { - msSetError(MS_PARSEERR,"Unknown COMPOP \"%s\"", "loadLayerCompositer()", compop); - free(compop); - return MS_FAILURE; - } + *filter = msSmallMalloc(sizeof(CompositingFilter)); + initCompositingFilter(*filter); + if (getString(&((*filter)->filter)) == MS_FAILURE) + return (MS_FAILURE); + } break; + case COMPOP: { + char *compop = NULL; + if (getString(&compop) == MS_FAILURE) + return (MS_FAILURE); + else if (!strcmp(compop, "clear")) + compositer->comp_op = MS_COMPOP_CLEAR; + else if (!strcmp(compop, "color-burn")) + compositer->comp_op = MS_COMPOP_COLOR_BURN; + else if (!strcmp(compop, "color-dodge")) + compositer->comp_op = MS_COMPOP_COLOR_DODGE; + else if (!strcmp(compop, "contrast")) + compositer->comp_op = MS_COMPOP_CONTRAST; + else if (!strcmp(compop, "darken")) + compositer->comp_op = MS_COMPOP_DARKEN; + else if (!strcmp(compop, "difference")) + compositer->comp_op = MS_COMPOP_DIFFERENCE; + else if (!strcmp(compop, "dst")) + compositer->comp_op = MS_COMPOP_DST; + else if (!strcmp(compop, "dst-atop")) + compositer->comp_op = MS_COMPOP_DST_ATOP; + else if (!strcmp(compop, "dst-in")) + compositer->comp_op = MS_COMPOP_DST_IN; + else if (!strcmp(compop, "dst-out")) + compositer->comp_op = MS_COMPOP_DST_OUT; + else if (!strcmp(compop, "dst-over")) + compositer->comp_op = MS_COMPOP_DST_OVER; + else if (!strcmp(compop, "exclusion")) + compositer->comp_op = MS_COMPOP_EXCLUSION; + else if (!strcmp(compop, "hard-light")) + compositer->comp_op = MS_COMPOP_HARD_LIGHT; + else if (!strcmp(compop, "invert")) + compositer->comp_op = MS_COMPOP_INVERT; + else if (!strcmp(compop, "invert-rgb")) + compositer->comp_op = MS_COMPOP_INVERT_RGB; + else if (!strcmp(compop, "lighten")) + compositer->comp_op = MS_COMPOP_LIGHTEN; + else if (!strcmp(compop, "minus")) + compositer->comp_op = MS_COMPOP_MINUS; + else if (!strcmp(compop, "multiply")) + compositer->comp_op = MS_COMPOP_MULTIPLY; + else if (!strcmp(compop, "overlay")) + compositer->comp_op = MS_COMPOP_OVERLAY; + else if (!strcmp(compop, "plus")) + compositer->comp_op = MS_COMPOP_PLUS; + else if (!strcmp(compop, "screen")) + compositer->comp_op = MS_COMPOP_SCREEN; + else if (!strcmp(compop, "soft-light")) + compositer->comp_op = MS_COMPOP_SOFT_LIGHT; + else if (!strcmp(compop, "src")) + compositer->comp_op = MS_COMPOP_SRC; + else if (!strcmp(compop, "src-atop")) + compositer->comp_op = MS_COMPOP_SRC_ATOP; + else if (!strcmp(compop, "src-in")) + compositer->comp_op = MS_COMPOP_SRC_IN; + else if (!strcmp(compop, "src-out")) + compositer->comp_op = MS_COMPOP_SRC_OUT; + else if (!strcmp(compop, "src-over")) + compositer->comp_op = MS_COMPOP_SRC_OVER; + else if (!strcmp(compop, "xor")) + compositer->comp_op = MS_COMPOP_XOR; + else { + msSetError(MS_PARSEERR, "Unknown COMPOP \"%s\"", + "loadLayerCompositer()", compop); free(compop); + return MS_FAILURE; } - break; - case END: - return MS_SUCCESS; - case OPACITY: - if (getInteger(&(compositer->opacity), MS_NUM_CHECK_RANGE, 0, 100) == -1) { - msSetError(MS_PARSEERR,"OPACITY must be between 0 and 100 (line %d)","loadLayerCompositer()",msyylineno); - return MS_FAILURE; - } - break; - default: - msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", "loadLayerCompositer()", msyystring_buffer, msyylineno ); - return(MS_FAILURE); + free(compop); + } break; + case END: + return MS_SUCCESS; + case OPACITY: + if (getInteger(&(compositer->opacity), MS_NUM_CHECK_RANGE, 0, 100) == + -1) { + msSetError(MS_PARSEERR, "OPACITY must be between 0 and 100 (line %d)", + "loadLayerCompositer()", msyylineno); + return MS_FAILURE; + } + break; + default: + msSetError(MS_IDENTERR, "Parsing error 2 near (%s):(line %d)", + "loadLayerCompositer()", msyystring_buffer, msyylineno); + return (MS_FAILURE); } } } -int loadLayer(layerObj *layer, mapObj *map) -{ +int loadLayer(layerObj *layer, mapObj *map) { int type; layer->map = (mapObj *)map; - for(;;) { - switch(msyylex()) { - case(BINDVALS): - if(loadHashTable(&(layer->bindvals)) != MS_SUCCESS) return(-1); - break; - case(CLASS): - if (msGrowLayerClasses(layer) == NULL) - return(-1); - initClass(layer->class[layer->numclasses]); - if(loadClass(layer->class[layer->numclasses], layer) == -1) - { - freeClass(layer->class[layer->numclasses]); - free(layer->class[layer->numclasses]); - layer->class[layer->numclasses] = NULL; - return(-1); - } - layer->numclasses++; - break; - case(CLUSTER): - if(loadCluster(&layer->cluster) == -1) return(-1); - break; - case(CLASSGROUP): - if(getString(&layer->classgroup) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(CLASSITEM): - if(getString(&layer->classitem) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(COMPOSITE): { - LayerCompositer *compositer = msSmallMalloc(sizeof(LayerCompositer)); - initLayerCompositer(compositer); - if(MS_FAILURE == loadLayerCompositer(compositer)) { - freeLayerCompositer(compositer); - return -1; - } - if(!layer->compositer) { - layer->compositer = compositer; - } else { - LayerCompositer *lctmp = layer->compositer; - while(lctmp->next) lctmp = lctmp->next; - lctmp->next = compositer; - } - break; + for (;;) { + switch (msyylex()) { + case (BINDVALS): + if (loadHashTable(&(layer->bindvals)) != MS_SUCCESS) + return (-1); + break; + case (CLASS): + if (msGrowLayerClasses(layer) == NULL) + return (-1); + initClass(layer->class[layer->numclasses]); + if (loadClass(layer->class[layer->numclasses], layer) == -1) { + freeClass(layer->class[layer->numclasses]); + free(layer->class[layer->numclasses]); + layer->class[layer->numclasses] = NULL; + return (-1); } - case(CONNECTION): - if(getString(&layer->connection) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(CONNECTIONTYPE): - if((type = getSymbol(13, MS_OGR, MS_POSTGIS, MS_WMS, MS_ORACLESPATIAL, MS_WFS, MS_GRATICULE, MS_PLUGIN, MS_UNION, MS_UVRASTER, MS_CONTOUR, MS_KERNELDENSITY, MS_IDW, MS_FLATGEOBUF)) == -1) return(-1); - layer->connectiontype = type; - break; - case(DATA): - if(getString(&layer->data) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(DEBUG): - if((layer->debug = getSymbol(3, MS_ON,MS_OFF, MS_NUMBER)) == -1) return(-1); - if(layer->debug == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid DEBUG level, must be between 0 and 5 (line %d)", "loadLayer()", msyylineno); - return(-1); - } - layer->debug = (int) msyynumber; - } - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadLayer()"); - return(-1); - break; - case(ENCODING): - if(getString(&layer->encoding) == MS_FAILURE) return(-1); - break; - case(END): - if((int)layer->type == -1) { - msSetError(MS_MISCERR, "Layer type not set.", "loadLayer()"); - return(-1); - } - - return(0); - break; - case(EXTENT): { - if(getDouble(&(layer->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(layer->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(layer->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(layer->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if (!MS_VALID_EXTENT(layer->extent)) { - msSetError(MS_MISCERR, "Given layer extent is invalid. Check that it is in the form: minx, miny, maxx, maxy", "loadLayer()"); - return(-1); - } - break; + layer->numclasses++; + break; + case (CLUSTER): + if (loadCluster(&layer->cluster) == -1) + return (-1); + break; + case (CLASSGROUP): + if (getString(&layer->classgroup) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (CLASSITEM): + if (getString(&layer->classitem) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (COMPOSITE): { + LayerCompositer *compositer = msSmallMalloc(sizeof(LayerCompositer)); + initLayerCompositer(compositer); + if (MS_FAILURE == loadLayerCompositer(compositer)) { + freeLayerCompositer(compositer); + return -1; } - case(FEATURE): - if((int)layer->type == -1) { - msSetError(MS_MISCERR, "Layer type must be set before defining inline features.", "loadLayer()"); - return(-1); + if (!layer->compositer) { + layer->compositer = compositer; + } else { + LayerCompositer *lctmp = layer->compositer; + while (lctmp->next) + lctmp = lctmp->next; + lctmp->next = compositer; + } + break; + } + case (CONNECTION): + if (getString(&layer->connection) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (CONNECTIONTYPE): + if ((type = getSymbol(13, MS_OGR, MS_POSTGIS, MS_WMS, MS_ORACLESPATIAL, + MS_WFS, MS_GRATICULE, MS_PLUGIN, MS_UNION, + MS_UVRASTER, MS_CONTOUR, MS_KERNELDENSITY, MS_IDW, + MS_FLATGEOBUF)) == -1) + return (-1); + layer->connectiontype = type; + break; + case (DATA): + if (getString(&layer->data) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (DEBUG): + if ((layer->debug = getSymbol(3, MS_ON, MS_OFF, MS_NUMBER)) == -1) + return (-1); + if (layer->debug == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid DEBUG level, must be between 0 and 5 (line %d)", + "loadLayer()", msyylineno); + return (-1); } + layer->debug = (int)msyynumber; + } + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadLayer()"); + return (-1); + break; + case (ENCODING): + if (getString(&layer->encoding) == MS_FAILURE) + return (-1); + break; + case (END): + if ((int)layer->type == -1) { + msSetError(MS_MISCERR, "Layer type not set.", "loadLayer()"); + return (-1); + } - if(layer->type == MS_LAYER_POLYGON) - type = MS_SHAPE_POLYGON; - else if(layer->type == MS_LAYER_LINE) - type = MS_SHAPE_LINE; - else - type = MS_SHAPE_POINT; + return (0); + break; + case (EXTENT): { + if (getDouble(&(layer->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(layer->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(layer->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(layer->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (!MS_VALID_EXTENT(layer->extent)) { + msSetError(MS_MISCERR, + "Given layer extent is invalid. Check that it is in the " + "form: minx, miny, maxx, maxy", + "loadLayer()"); + return (-1); + } + break; + } + case (FEATURE): + if ((int)layer->type == -1) { + msSetError(MS_MISCERR, + "Layer type must be set before defining inline features.", + "loadLayer()"); + return (-1); + } - layer->connectiontype = MS_INLINE; + if (layer->type == MS_LAYER_POLYGON) + type = MS_SHAPE_POLYGON; + else if (layer->type == MS_LAYER_LINE) + type = MS_SHAPE_LINE; + else + type = MS_SHAPE_POINT; - if(loadFeature(layer, type) == MS_FAILURE) return(-1); - break; - case(FILTER): - if(loadExpression(&(layer->filter)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ - break; - case(FILTERITEM): - if(getString(&layer->filteritem) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(FOOTER): - if(getString(&layer->footer) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(GRID): - layer->connectiontype = MS_GRATICULE; - if (layer->grid) { - freeGrid(layer->grid); - msFree(layer->grid); - } - layer->grid = (void *) malloc(sizeof(graticuleObj)); - MS_CHECK_ALLOC(layer->grid, sizeof(graticuleObj), -1); + layer->connectiontype = MS_INLINE; - initGrid(layer->grid); - loadGrid(layer); - break; - case(GROUP): - if(getString(&layer->group) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(GEOMTRANSFORM): { - int s; - if((s = getSymbol(1, MS_EXPRESSION)) == -1) return(MS_FAILURE); - /* handle expression case here for the moment */ - msFree(layer->_geomtransform.string); - layer->_geomtransform.string = msStrdup(msyystring_buffer); - layer->_geomtransform.type = MS_GEOMTRANSFORM_EXPRESSION; + if (loadFeature(layer, type) == MS_FAILURE) + return (-1); + break; + case (FILTER): + if (loadExpression(&(layer->filter)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + break; + case (FILTERITEM): + if (getString(&layer->filteritem) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (FOOTER): + if (getString(&layer->footer) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (GRID): + layer->connectiontype = MS_GRATICULE; + if (layer->grid) { + freeGrid(layer->grid); + msFree(layer->grid); } + layer->grid = (void *)malloc(sizeof(graticuleObj)); + MS_CHECK_ALLOC(layer->grid, sizeof(graticuleObj), -1); + + initGrid(layer->grid); + loadGrid(layer); break; - case(HEADER): - if(getString(&layer->header) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(JOIN): - if(layer->numjoins == MS_MAXJOINS) { /* no room */ - msSetError(MS_IDENTERR, "Maximum number of joins reached.", "loadLayer()"); - return(-1); - } + case (GROUP): + if (getString(&layer->group) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (GEOMTRANSFORM): { + int s; + if ((s = getSymbol(1, MS_EXPRESSION)) == -1) + return (MS_FAILURE); + /* handle expression case here for the moment */ + msFree(layer->_geomtransform.string); + layer->_geomtransform.string = msStrdup(msyystring_buffer); + layer->_geomtransform.type = MS_GEOMTRANSFORM_EXPRESSION; + } break; + case (HEADER): + if (getString(&layer->header) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (JOIN): + if (layer->numjoins == MS_MAXJOINS) { /* no room */ + msSetError(MS_IDENTERR, "Maximum number of joins reached.", + "loadLayer()"); + return (-1); + } - if(loadJoin(&(layer->joins[layer->numjoins])) == -1) { - freeJoin(&(layer->joins[layer->numjoins])); - return(-1); - } - layer->numjoins++; - break; - case(LABELCACHE): - if((layer->labelcache = getSymbol(2, MS_ON, MS_OFF)) == -1) return(-1); - break; - case(LABELITEM): - if(getString(&layer->labelitem) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(LABELMAXSCALE): - case(LABELMAXSCALEDENOM): - if(getDouble(&(layer->labelmaxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(LABELMINSCALE): - case(LABELMINSCALEDENOM): - if(getDouble(&(layer->labelminscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(LABELREQUIRES): - if(getString(&layer->labelrequires) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(LAYER): - break; /* for string loads */ - case(MASK): - if(getString(&layer->mask) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(MAXFEATURES): - if(getInteger(&(layer->maxfeatures), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MAXSCALE): - case(MAXSCALEDENOM): - if(getDouble(&(layer->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MAXGEOWIDTH): - if(getDouble(&(layer->maxgeowidth), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(METADATA): - if(loadHashTable(&(layer->metadata)) != MS_SUCCESS) return(-1); - break; - case(MINSCALE): - case(MINSCALEDENOM): - if(getDouble(&(layer->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MINGEOWIDTH): - if(getDouble(&(layer->mingeowidth), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MINFEATURESIZE): - if(getInteger(&(layer->minfeaturesize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(NAME): - if(getString(&layer->name) == MS_FAILURE) return(-1); - break; - case(OFFSITE): - if(loadColor(&(layer->offsite), NULL) != MS_SUCCESS) return(-1); - break; + if (loadJoin(&(layer->joins[layer->numjoins])) == -1) { + freeJoin(&(layer->joins[layer->numjoins])); + return (-1); + } + layer->numjoins++; + break; + case (LABELCACHE): + if ((layer->labelcache = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (LABELITEM): + if (getString(&layer->labelitem) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (LABELMAXSCALE): + case (LABELMAXSCALEDENOM): + if (getDouble(&(layer->labelmaxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == + -1) + return (-1); + break; + case (LABELMINSCALE): + case (LABELMINSCALEDENOM): + if (getDouble(&(layer->labelminscaledenom), MS_NUM_CHECK_GTE, 0, -1) == + -1) + return (-1); + break; + case (LABELREQUIRES): + if (getString(&layer->labelrequires) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (LAYER): + break; /* for string loads */ + case (MASK): + if (getString(&layer->mask) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (MAXFEATURES): + if (getInteger(&(layer->maxfeatures), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MAXSCALE): + case (MAXSCALEDENOM): + if (getDouble(&(layer->maxscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MAXGEOWIDTH): + if (getDouble(&(layer->maxgeowidth), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (METADATA): + if (loadHashTable(&(layer->metadata)) != MS_SUCCESS) + return (-1); + break; + case (MINSCALE): + case (MINSCALEDENOM): + if (getDouble(&(layer->minscaledenom), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MINGEOWIDTH): + if (getDouble(&(layer->mingeowidth), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MINFEATURESIZE): + if (getInteger(&(layer->minfeaturesize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (NAME): + if (getString(&layer->name) == MS_FAILURE) + return (-1); + break; + case (OFFSITE): + if (loadColor(&(layer->offsite), NULL) != MS_SUCCESS) + return (-1); + break; - case(CONNECTIONOPTIONS): - if(loadHashTable(&(layer->connectionoptions)) != MS_SUCCESS) return(-1); - break; - case(MS_PLUGIN): { - int rv; - if(map->config) { // value *must* represent a config key - char *value = NULL; - const char *plugin_library = NULL; - - if(getString(&value) == MS_FAILURE) return(-1); - plugin_library = msConfigGetPlugin(map->config, value); - msFree(value); - if(!plugin_library) { - msSetError(MS_MISCERR, "Plugin value not found in config file. See mapserver.org/mapfile/config.html for more information." , "loadLayer()"); - return(-1); - } - msFree(layer->plugin_library_original); - layer->plugin_library_original = strdup(plugin_library); - } else { - if(getString(&layer->plugin_library_original) == MS_FAILURE) return(-1); + case (CONNECTIONOPTIONS): + if (loadHashTable(&(layer->connectionoptions)) != MS_SUCCESS) + return (-1); + break; + case (MS_PLUGIN): { + int rv; + if (map->config) { // value *must* represent a config key + char *value = NULL; + const char *plugin_library = NULL; + + if (getString(&value) == MS_FAILURE) + return (-1); + plugin_library = msConfigGetPlugin(map->config, value); + msFree(value); + if (!plugin_library) { + msSetError(MS_MISCERR, + "Plugin value not found in config file. See " + "mapserver.org/mapfile/config.html for more information.", + "loadLayer()"); + return (-1); } - rv = msBuildPluginLibraryPath(&layer->plugin_library, layer->plugin_library_original, map); - if (rv == MS_FAILURE) return(-1); + msFree(layer->plugin_library_original); + layer->plugin_library_original = strdup(plugin_library); + } else { + if (getString(&layer->plugin_library_original) == MS_FAILURE) + return (-1); } + rv = msBuildPluginLibraryPath(&layer->plugin_library, + layer->plugin_library_original, map); + if (rv == MS_FAILURE) + return (-1); + } break; + case (PROCESSING): { + /* NOTE: processing array maintained as size+1 with NULL terminator. + This ensure that CSL (GDAL string list) functions can be + used on the list for easy processing. */ + char *value = NULL; + if (getString(&value) == MS_FAILURE) + return (-1); + msLayerAddProcessing(layer, value); + free(value); + value = NULL; + } break; + case (POSTLABELCACHE): + if ((layer->postlabelcache = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) + return (-1); + if (layer->postlabelcache) + layer->labelcache = MS_OFF; break; - case(PROCESSING): { - /* NOTE: processing array maintained as size+1 with NULL terminator. - This ensure that CSL (GDAL string list) functions can be - used on the list for easy processing. */ - char *value=NULL; - if(getString(&value) == MS_FAILURE) return(-1); - msLayerAddProcessing( layer, value ); - free(value); - value=NULL; + case (PROJECTION): + if (loadProjection(&(layer->projection)) == -1) + return (-1); + layer->project = MS_TRUE; + break; + case (REQUIRES): + if (getString(&layer->requires) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (SCALETOKEN): + if (msGrowLayerScaletokens(layer) == NULL) + return (-1); + initScaleToken(&layer->scaletokens[layer->numscaletokens]); + if (loadScaletoken(&layer->scaletokens[layer->numscaletokens], layer) == + -1) { + freeScaleToken(&layer->scaletokens[layer->numscaletokens]); + return (-1); } + layer->numscaletokens++; break; - case(POSTLABELCACHE): - if((layer->postlabelcache = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) return(-1); - if(layer->postlabelcache) - layer->labelcache = MS_OFF; - break; - case(PROJECTION): - if(loadProjection(&(layer->projection)) == -1) return(-1); - layer->project = MS_TRUE; - break; - case(REQUIRES): - if(getString(&layer->requires) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(SCALETOKEN): - if (msGrowLayerScaletokens(layer) == NULL) - return(-1); - initScaleToken(&layer->scaletokens[layer->numscaletokens]); - if(loadScaletoken(&layer->scaletokens[layer->numscaletokens], layer) == -1) { - freeScaleToken(&layer->scaletokens[layer->numscaletokens]); - return(-1); - } - layer->numscaletokens++; - break; - case(SIZEUNITS): - if((layer->sizeunits = getSymbol(8, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES,MS_DD,MS_PIXELS)) == -1) return(-1); - break; - case(STATUS): - if((layer->status = getSymbol(3, MS_ON,MS_OFF,MS_DEFAULT)) == -1) return(-1); - break; - case(STYLEITEM): - if(getString(&layer->styleitem) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(SYMBOLSCALE): - case(SYMBOLSCALEDENOM): - if(getDouble(&(layer->symbolscaledenom), MS_NUM_CHECK_GTE, 1, -1) == -1) return(-1); - break; - case(TEMPLATE): - if(getString(&layer->template) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(TILEINDEX): - if(getString(&layer->tileindex) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(TILEITEM): - if(getString(&layer->tileitem) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(TILESRS): - if(getString(&layer->tilesrs) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(TOLERANCE): - if(getDouble(&(layer->tolerance), MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(TOLERANCEUNITS): - if((layer->toleranceunits = getSymbol(8, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES,MS_DD,MS_PIXELS)) == -1) return(-1); - break; - case(TRANSFORM): - if((layer->transform = getSymbol(11, MS_TRUE,MS_FALSE, MS_UL,MS_UC,MS_UR,MS_CL,MS_CC,MS_CR,MS_LL,MS_LC,MS_LR)) == -1) return(-1); - break; - case(TYPE): - if((type = getSymbol(9, MS_LAYER_POINT,MS_LAYER_LINE,MS_LAYER_RASTER,MS_LAYER_POLYGON,MS_LAYER_ANNOTATION,MS_LAYER_QUERY,MS_LAYER_CIRCLE,MS_LAYER_CHART,TILEINDEX)) == -1) return(-1); - if(type == TILEINDEX) type = MS_LAYER_TILEINDEX; /* TILEINDEX is also a parameter */ - if(type == MS_LAYER_ANNOTATION) { - msSetError(MS_IDENTERR, "Annotation Layers have been removed. To obtain same functionality, use a layer with label->styles and no class->styles", "loadLayer()"); - return -1; - } - layer->type = type; - break; - case(UNITS): - if((layer->units = getSymbol(9, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES,MS_DD,MS_PIXELS,MS_PERCENTAGES)) == -1) return(-1); - break; - case(UTFDATA): - if(loadExpression(&(layer->utfdata)) == -1) return(-1); /* loadExpression() cleans up previously allocated expression */ - break; - case(UTFITEM): - if(getString(&layer->utfitem) == MS_FAILURE) return(-1); - break; - case(VALIDATION): - if(loadHashTable(&(layer->validation)) != MS_SUCCESS) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadLayer()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } + case (SIZEUNITS): + if ((layer->sizeunits = getSymbol( + 8, MS_INCHES, MS_FEET, MS_MILES, MS_METERS, MS_KILOMETERS, + MS_NAUTICALMILES, MS_DD, MS_PIXELS)) == -1) + return (-1); + break; + case (STATUS): + if ((layer->status = getSymbol(3, MS_ON, MS_OFF, MS_DEFAULT)) == -1) + return (-1); + break; + case (STYLEITEM): + if (getString(&layer->styleitem) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (SYMBOLSCALE): + case (SYMBOLSCALEDENOM): + if (getDouble(&(layer->symbolscaledenom), MS_NUM_CHECK_GTE, 1, -1) == -1) + return (-1); + break; + case (TEMPLATE): + if (getString(&layer->template) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (TILEINDEX): + if (getString(&layer->tileindex) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (TILEITEM): + if (getString(&layer->tileitem) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (TILESRS): + if (getString(&layer->tilesrs) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (TOLERANCE): + if (getDouble(&(layer->tolerance), MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (TOLERANCEUNITS): + if ((layer->toleranceunits = getSymbol( + 8, MS_INCHES, MS_FEET, MS_MILES, MS_METERS, MS_KILOMETERS, + MS_NAUTICALMILES, MS_DD, MS_PIXELS)) == -1) + return (-1); + break; + case (TRANSFORM): + if ((layer->transform = + getSymbol(11, MS_TRUE, MS_FALSE, MS_UL, MS_UC, MS_UR, MS_CL, + MS_CC, MS_CR, MS_LL, MS_LC, MS_LR)) == -1) + return (-1); + break; + case (TYPE): + if ((type = + getSymbol(9, MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_RASTER, + MS_LAYER_POLYGON, MS_LAYER_ANNOTATION, MS_LAYER_QUERY, + MS_LAYER_CIRCLE, MS_LAYER_CHART, TILEINDEX)) == -1) + return (-1); + if (type == TILEINDEX) + type = MS_LAYER_TILEINDEX; /* TILEINDEX is also a parameter */ + if (type == MS_LAYER_ANNOTATION) { + msSetError(MS_IDENTERR, + "Annotation Layers have been removed. To obtain same " + "functionality, use a layer with label->styles and no " + "class->styles", + "loadLayer()"); + return -1; + } + layer->type = type; + break; + case (UNITS): + if ((layer->units = getSymbol(9, MS_INCHES, MS_FEET, MS_MILES, MS_METERS, + MS_KILOMETERS, MS_NAUTICALMILES, MS_DD, + MS_PIXELS, MS_PERCENTAGES)) == -1) + return (-1); + break; + case (UTFDATA): + if (loadExpression(&(layer->utfdata)) == -1) + return (-1); /* loadExpression() cleans up previously allocated + expression */ + break; + case (UTFITEM): + if (getString(&layer->utfitem) == MS_FAILURE) + return (-1); + break; + case (VALIDATION): + if (loadHashTable(&(layer->validation)) != MS_SUCCESS) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadLayer()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } /* next token */ } -int msUpdateLayerFromString(layerObj *layer, char *string) -{ +int msUpdateLayerFromString(layerObj *layer, char *string) { int i; - if(!layer || !string) return MS_FAILURE; + if (!layer || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -4332,133 +4773,136 @@ int msUpdateLayerFromString(layerObj *layer, char *string) msyylineno = 1; /* start at line 1 */ - if(loadLayer(layer, layer->map) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadLayer(layer, layer->map) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); /* step through classes to resolve symbol names */ - for(i=0; inumclasses; i++) { - if(classResolveSymbolNames(layer->class[i]) != MS_SUCCESS) return MS_FAILURE; + for (i = 0; i < layer->numclasses; i++) { + if (classResolveSymbolNames(layer->class[i]) != MS_SUCCESS) + return MS_FAILURE; } return MS_SUCCESS; } -static void writeCompositingFilter(FILE *stream, int indent, CompositingFilter *filter) { - while(filter) { +static void writeCompositingFilter(FILE *stream, int indent, + CompositingFilter *filter) { + while (filter) { writeString(stream, indent, "COMPFILTER", "", filter->filter); filter = filter->next; } } -static void writeLayerCompositer(FILE *stream, int indent, LayerCompositer *compositor) { +static void writeLayerCompositer(FILE *stream, int indent, + LayerCompositer *compositor) { indent++; - while(compositor) { + while (compositor) { writeBlockBegin(stream, indent, "COMPOSITE"); writeCompositingFilter(stream, indent, compositor->filter); - if(compositor->comp_op != MS_COMPOP_SRC_OVER) { - switch(compositor->comp_op) { - case MS_COMPOP_CLEAR: - writeString(stream, indent, "COMPOP", NULL, "clear"); - break; - case MS_COMPOP_COLOR_BURN: - writeString(stream, indent, "COMPOP", NULL, "color-burn"); - break; - case MS_COMPOP_COLOR_DODGE: - writeString(stream, indent, "COMPOP", NULL, "color-dodge"); - break; - case MS_COMPOP_CONTRAST: - writeString(stream, indent, "COMPOP", NULL, "contrast"); - break; - case MS_COMPOP_DARKEN: - writeString(stream, indent, "COMPOP", NULL, "darken"); - break; - case MS_COMPOP_DIFFERENCE: - writeString(stream, indent, "COMPOP", NULL, "difference"); - break; - case MS_COMPOP_DST: - writeString(stream, indent, "COMPOP", NULL, "dst"); - break; - case MS_COMPOP_DST_ATOP: - writeString(stream, indent, "COMPOP", NULL, "dst-atop"); - break; - case MS_COMPOP_DST_IN: - writeString(stream, indent, "COMPOP", NULL, "dst-in"); - break; - case MS_COMPOP_DST_OUT: - writeString(stream, indent, "COMPOP", NULL, "dst-out"); - break; - case MS_COMPOP_DST_OVER: - writeString(stream, indent, "COMPOP", NULL, "dst-over"); - break; - case MS_COMPOP_EXCLUSION: - writeString(stream, indent, "COMPOP", NULL, "exclusion"); - break; - case MS_COMPOP_HARD_LIGHT: - writeString(stream, indent, "COMPOP", NULL, "hard-light"); - break; - case MS_COMPOP_INVERT: - writeString(stream, indent, "COMPOP", NULL, "invert"); - break; - case MS_COMPOP_INVERT_RGB: - writeString(stream, indent, "COMPOP", NULL, "invert-rgb"); - break; - case MS_COMPOP_LIGHTEN: - writeString(stream, indent, "COMPOP", NULL, "lighten"); - break; - case MS_COMPOP_MINUS: - writeString(stream, indent, "COMPOP", NULL, "minus"); - break; - case MS_COMPOP_MULTIPLY: - writeString(stream, indent, "COMPOP", NULL, "multiply"); - break; - case MS_COMPOP_OVERLAY: - writeString(stream, indent, "COMPOP", NULL, "overlay"); - break; - case MS_COMPOP_PLUS: - writeString(stream, indent, "COMPOP", NULL, "plus"); - break; - case MS_COMPOP_SCREEN: - writeString(stream, indent, "COMPOP", NULL, "screen"); - break; - case MS_COMPOP_SOFT_LIGHT: - writeString(stream, indent, "COMPOP", NULL, "soft-light"); - break; - case MS_COMPOP_SRC: - writeString(stream, indent, "COMPOP", NULL, "src"); - break; - case MS_COMPOP_SRC_ATOP: - writeString(stream, indent, "COMPOP", NULL, "src-atop"); - break; - case MS_COMPOP_SRC_IN: - writeString(stream, indent, "COMPOP", NULL, "src-in"); - break; - case MS_COMPOP_SRC_OUT: - writeString(stream, indent, "COMPOP", NULL, "src-out"); - break; - case MS_COMPOP_SRC_OVER: - writeString(stream, indent, "COMPOP", NULL, "src-over"); - break; - case MS_COMPOP_XOR: - writeString(stream, indent, "COMPOP", NULL, "xor"); - break; + if (compositor->comp_op != MS_COMPOP_SRC_OVER) { + switch (compositor->comp_op) { + case MS_COMPOP_CLEAR: + writeString(stream, indent, "COMPOP", NULL, "clear"); + break; + case MS_COMPOP_COLOR_BURN: + writeString(stream, indent, "COMPOP", NULL, "color-burn"); + break; + case MS_COMPOP_COLOR_DODGE: + writeString(stream, indent, "COMPOP", NULL, "color-dodge"); + break; + case MS_COMPOP_CONTRAST: + writeString(stream, indent, "COMPOP", NULL, "contrast"); + break; + case MS_COMPOP_DARKEN: + writeString(stream, indent, "COMPOP", NULL, "darken"); + break; + case MS_COMPOP_DIFFERENCE: + writeString(stream, indent, "COMPOP", NULL, "difference"); + break; + case MS_COMPOP_DST: + writeString(stream, indent, "COMPOP", NULL, "dst"); + break; + case MS_COMPOP_DST_ATOP: + writeString(stream, indent, "COMPOP", NULL, "dst-atop"); + break; + case MS_COMPOP_DST_IN: + writeString(stream, indent, "COMPOP", NULL, "dst-in"); + break; + case MS_COMPOP_DST_OUT: + writeString(stream, indent, "COMPOP", NULL, "dst-out"); + break; + case MS_COMPOP_DST_OVER: + writeString(stream, indent, "COMPOP", NULL, "dst-over"); + break; + case MS_COMPOP_EXCLUSION: + writeString(stream, indent, "COMPOP", NULL, "exclusion"); + break; + case MS_COMPOP_HARD_LIGHT: + writeString(stream, indent, "COMPOP", NULL, "hard-light"); + break; + case MS_COMPOP_INVERT: + writeString(stream, indent, "COMPOP", NULL, "invert"); + break; + case MS_COMPOP_INVERT_RGB: + writeString(stream, indent, "COMPOP", NULL, "invert-rgb"); + break; + case MS_COMPOP_LIGHTEN: + writeString(stream, indent, "COMPOP", NULL, "lighten"); + break; + case MS_COMPOP_MINUS: + writeString(stream, indent, "COMPOP", NULL, "minus"); + break; + case MS_COMPOP_MULTIPLY: + writeString(stream, indent, "COMPOP", NULL, "multiply"); + break; + case MS_COMPOP_OVERLAY: + writeString(stream, indent, "COMPOP", NULL, "overlay"); + break; + case MS_COMPOP_PLUS: + writeString(stream, indent, "COMPOP", NULL, "plus"); + break; + case MS_COMPOP_SCREEN: + writeString(stream, indent, "COMPOP", NULL, "screen"); + break; + case MS_COMPOP_SOFT_LIGHT: + writeString(stream, indent, "COMPOP", NULL, "soft-light"); + break; + case MS_COMPOP_SRC: + writeString(stream, indent, "COMPOP", NULL, "src"); + break; + case MS_COMPOP_SRC_ATOP: + writeString(stream, indent, "COMPOP", NULL, "src-atop"); + break; + case MS_COMPOP_SRC_IN: + writeString(stream, indent, "COMPOP", NULL, "src-in"); + break; + case MS_COMPOP_SRC_OUT: + writeString(stream, indent, "COMPOP", NULL, "src-out"); + break; + case MS_COMPOP_SRC_OVER: + writeString(stream, indent, "COMPOP", NULL, "src-over"); + break; + case MS_COMPOP_XOR: + writeString(stream, indent, "COMPOP", NULL, "xor"); + break; } } - writeNumber(stream,indent,"OPACITY",100,compositor->opacity); - writeBlockEnd(stream,indent,"COMPOSITE"); + writeNumber(stream, indent, "OPACITY", 100, compositor->opacity); + writeBlockEnd(stream, indent, "COMPOSITE"); compositor = compositor->next; } } -static void writeLayer(FILE *stream, int indent, layerObj *layer) -{ +static void writeLayer(FILE *stream, int indent, layerObj *layer) { int i; - featureListNodeObjPtr current=NULL; + featureListNodeObjPtr current = NULL; - if(layer->status == MS_DELETE) + if (layer->status == MS_DELETE) return; indent++; @@ -4470,10 +4914,17 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeCluster(stream, indent, &(layer->cluster)); writeLayerCompositer(stream, indent, layer->compositer); writeString(stream, indent, "CONNECTION", NULL, layer->connection); - writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 12, MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, "CONTOUR", MS_KERNELDENSITY, "KERNELDENSITY", MS_IDW, "IDW", MS_FLATGEOBUF, "FLATGEOBUF"); - writeHashTable(stream, indent, "CONNECTIONOPTIONS", &(layer->connectionoptions)); + writeKeyword(stream, indent, "CONNECTIONTYPE", layer->connectiontype, 12, + MS_OGR, "OGR", MS_POSTGIS, "POSTGIS", MS_WMS, "WMS", + MS_ORACLESPATIAL, "ORACLESPATIAL", MS_WFS, "WFS", MS_PLUGIN, + "PLUGIN", MS_UNION, "UNION", MS_UVRASTER, "UVRASTER", MS_CONTOUR, + "CONTOUR", MS_KERNELDENSITY, "KERNELDENSITY", MS_IDW, "IDW", + MS_FLATGEOBUF, "FLATGEOBUF"); + writeHashTable(stream, indent, "CONNECTIONOPTIONS", + &(layer->connectionoptions)); writeString(stream, indent, "DATA", NULL, layer->data); - writeNumber(stream, indent, "DEBUG", 0, layer->debug); /* is this right? see loadLayer() */ + writeNumber(stream, indent, "DEBUG", 0, + layer->debug); /* is this right? see loadLayer() */ writeString(stream, indent, "ENCODING", NULL, layer->encoding); writeExtent(stream, indent, "EXTENT", layer->extent); writeExpression(stream, indent, "FILTER", &(layer->filter)); @@ -4481,17 +4932,20 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeString(stream, indent, "FOOTER", NULL, layer->footer); writeString(stream, indent, "GROUP", NULL, layer->group); - if(layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) { + if (layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) { writeIndent(stream, indent + 1); fprintf(stream, "GEOMTRANSFORM (%s)\n", layer->_geomtransform.string); } writeString(stream, indent, "HEADER", NULL, layer->header); /* join - see below */ - writeKeyword(stream, indent, "LABELCACHE", layer->labelcache, 1, MS_OFF, "OFF"); + writeKeyword(stream, indent, "LABELCACHE", layer->labelcache, 1, MS_OFF, + "OFF"); writeString(stream, indent, "LABELITEM", NULL, layer->labelitem); - writeNumber(stream, indent, "LABELMAXSCALEDENOM", -1, layer->labelmaxscaledenom); - writeNumber(stream, indent, "LABELMINSCALEDENOM", -1, layer->labelminscaledenom); + writeNumber(stream, indent, "LABELMAXSCALEDENOM", -1, + layer->labelmaxscaledenom); + writeNumber(stream, indent, "LABELMINSCALEDENOM", -1, + layer->labelminscaledenom); writeString(stream, indent, "LABELREQUIRES", NULL, layer->labelrequires); writeNumber(stream, indent, "MAXFEATURES", -1, layer->maxfeatures); writeNumber(stream, indent, "MAXGEOWIDTH", -1, layer->maxgeowidth); @@ -4504,13 +4958,18 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeString(stream, indent, "NAME", NULL, layer->name); writeColor(stream, indent, "OFFSITE", NULL, &(layer->offsite)); writeString(stream, indent, "PLUGIN", NULL, layer->plugin_library_original); - writeKeyword(stream, indent, "POSTLABELCACHE", layer->postlabelcache, 1, MS_TRUE, "TRUE"); - for(i=0; inumprocessing; i++) + writeKeyword(stream, indent, "POSTLABELCACHE", layer->postlabelcache, 1, + MS_TRUE, "TRUE"); + for (i = 0; i < layer->numprocessing; i++) writeString(stream, indent, "PROCESSING", NULL, layer->processing[i]); writeProjection(stream, indent, &(layer->projection)); writeString(stream, indent, "REQUIRES", NULL, layer->requires); - writeKeyword(stream, indent, "SIZEUNITS", layer->sizeunits, 7, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD"); - writeKeyword(stream, indent, "STATUS", layer->status, 3, MS_ON, "ON", MS_OFF, "OFF", MS_DEFAULT, "DEFAULT"); + writeKeyword(stream, indent, "SIZEUNITS", layer->sizeunits, 7, MS_INCHES, + "INCHES", MS_FEET, "FEET", MS_MILES, "MILES", MS_METERS, + "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, + "NAUTICALMILES", MS_DD, "DD"); + writeKeyword(stream, indent, "STATUS", layer->status, 3, MS_ON, "ON", MS_OFF, + "OFF", MS_DEFAULT, "DEFAULT"); writeString(stream, indent, "STYLEITEM", NULL, layer->styleitem); writeNumber(stream, indent, "SYMBOLSCALEDENOM", -1, layer->symbolscaledenom); writeString(stream, indent, "TEMPLATE", NULL, layer->template); @@ -4518,24 +4977,40 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeString(stream, indent, "TILEITEM", NULL, layer->tileitem); writeString(stream, indent, "TILESRS", NULL, layer->tilesrs); writeNumber(stream, indent, "TOLERANCE", -1, layer->tolerance); - writeKeyword(stream, indent, "TOLERANCEUNITS", layer->toleranceunits, 7, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD"); - writeKeyword(stream, indent, "TRANSFORM", layer->transform, 10, MS_FALSE, "FALSE", MS_UL, "UL", MS_UC, "UC", MS_UR, "UR", MS_CL, "CL", MS_CC, "CC", MS_CR, "CR", MS_LL, "LL", MS_LC, "LC", MS_LR, "LR"); - writeKeyword(stream, indent, "TYPE", layer->type, 9, MS_LAYER_POINT, "POINT", MS_LAYER_LINE, "LINE", MS_LAYER_POLYGON, "POLYGON", MS_LAYER_RASTER, "RASTER", MS_LAYER_ANNOTATION, "ANNOTATION", MS_LAYER_QUERY, "QUERY", MS_LAYER_CIRCLE, "CIRCLE", MS_LAYER_TILEINDEX, "TILEINDEX", MS_LAYER_CHART, "CHART"); - writeKeyword(stream, indent, "UNITS", layer->units, 9, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD", MS_PIXELS, "PIXELS", MS_PERCENTAGES, "PERCENTATGES"); + writeKeyword(stream, indent, "TOLERANCEUNITS", layer->toleranceunits, 7, + MS_INCHES, "INCHES", MS_FEET, "FEET", MS_MILES, "MILES", + MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", + MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD"); + writeKeyword(stream, indent, "TRANSFORM", layer->transform, 10, MS_FALSE, + "FALSE", MS_UL, "UL", MS_UC, "UC", MS_UR, "UR", MS_CL, "CL", + MS_CC, "CC", MS_CR, "CR", MS_LL, "LL", MS_LC, "LC", MS_LR, "LR"); + writeKeyword(stream, indent, "TYPE", layer->type, 9, MS_LAYER_POINT, "POINT", + MS_LAYER_LINE, "LINE", MS_LAYER_POLYGON, "POLYGON", + MS_LAYER_RASTER, "RASTER", MS_LAYER_ANNOTATION, "ANNOTATION", + MS_LAYER_QUERY, "QUERY", MS_LAYER_CIRCLE, "CIRCLE", + MS_LAYER_TILEINDEX, "TILEINDEX", MS_LAYER_CHART, "CHART"); + writeKeyword(stream, indent, "UNITS", layer->units, 9, MS_INCHES, "INCHES", + MS_FEET, "FEET", MS_MILES, "MILES", MS_METERS, "METERS", + MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", + MS_DD, "DD", MS_PIXELS, "PIXELS", MS_PERCENTAGES, + "PERCENTATGES"); writeExpression(stream, indent, "UTFDATA", &(layer->utfdata)); writeString(stream, indent, "UTFITEM", NULL, layer->utfitem); writeHashTable(stream, indent, "VALIDATION", &(layer->validation)); /* write potentially multiply occuring objects last */ - for(i=0; inumscaletokens; i++) writeScaleToken(stream, indent, &(layer->scaletokens[i])); - for(i=0; inumjoins; i++) writeJoin(stream, indent, &(layer->joins[i])); - for(i=0; inumclasses; i++) writeClass(stream, indent, layer->class[i]); - - if( layer->grid && layer->connectiontype == MS_GRATICULE) + for (i = 0; i < layer->numscaletokens; i++) + writeScaleToken(stream, indent, &(layer->scaletokens[i])); + for (i = 0; i < layer->numjoins; i++) + writeJoin(stream, indent, &(layer->joins[i])); + for (i = 0; i < layer->numclasses; i++) + writeClass(stream, indent, layer->class[i]); + + if (layer->grid && layer->connectiontype == MS_GRATICULE) writeGrid(stream, indent, layer->grid); else { current = layer->features; - while(current != NULL) { + while (current != NULL) { writeFeature(stream, indent, &(current->shape)); current = current->next; } @@ -4545,9 +5020,8 @@ static void writeLayer(FILE *stream, int indent, layerObj *layer) writeLineFeed(stream); } -char* msWriteLayerToString(layerObj *layer) -{ - msIOContext context; +char *msWriteLayerToString(layerObj *layer) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -4558,23 +5032,23 @@ char* msWriteLayerToString(layerObj *layer) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeLayer(stdout, -1, layer); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize, load and free a referenceMapObj structure */ -void initReferenceMap(referenceMapObj *ref) -{ +void initReferenceMap(referenceMapObj *ref) { ref->height = ref->width = 0; - ref->extent.minx = ref->extent.miny = ref->extent.maxx = ref->extent.maxy = -1.0; + ref->extent.minx = ref->extent.miny = ref->extent.maxx = ref->extent.maxy = + -1.0; ref->image = NULL; MS_INIT_COLOR(ref->color, 255, 0, 0, 255); MS_INIT_COLOR(ref->outlinecolor, 0, 0, 0, 255); @@ -4587,103 +5061,124 @@ void initReferenceMap(referenceMapObj *ref) ref->map = NULL; } -void freeReferenceMap(referenceMapObj *ref) -{ +void freeReferenceMap(referenceMapObj *ref) { msFree(ref->image); msFree(ref->markername); } -int loadReferenceMap(referenceMapObj *ref, mapObj *map) -{ +int loadReferenceMap(referenceMapObj *ref, mapObj *map) { int state; ref->map = (mapObj *)map; - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadReferenceMap()"); - return(-1); - case(END): - if(!ref->image) { - msSetError(MS_MISCERR, "No image defined for the reference map.", "loadReferenceMap()"); - return(-1); - } - if(ref->width == 0 || ref->height == 0) { - msSetError(MS_MISCERR, "No image size defined for the reference map.", "loadReferenceMap()"); - return(-1); - } - return(0); - break; - case(COLOR): - if(loadColor(&(ref->color), NULL) != MS_SUCCESS) return(-1); - break; - case(EXTENT): - if(getDouble(&(ref->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(ref->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(ref->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if(getDouble(&(ref->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) return(-1); - if (!MS_VALID_EXTENT(ref->extent)) { - msSetError(MS_MISCERR, "Given reference extent is invalid. Check that it " \ - "is in the form: minx, miny, maxx, maxy", "loadReferenceMap()"); - return(-1); - } - break; - case(IMAGE): - if(getString(&ref->image) == MS_FAILURE) return(-1); - break; - case(OUTLINECOLOR): - if(loadColor(&(ref->outlinecolor), NULL) != MS_SUCCESS) return(-1); - break; - case(SIZE): - if(getInteger(&(ref->width), MS_NUM_CHECK_RANGE, 5, ref->map->maxsize) == -1) return(-1); // is 5 reasonable? - if(getInteger(&(ref->height), MS_NUM_CHECK_RANGE, 5, ref->map->maxsize) == -1) return(-1); - break; - case(STATUS): - if((ref->status = getSymbol(2, MS_ON,MS_OFF)) == -1) return(-1); - break; - case(MARKER): - if((state = getSymbol(2, MS_NUMBER,MS_STRING)) == -1) return(-1); + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadReferenceMap()"); + return (-1); + case (END): + if (!ref->image) { + msSetError(MS_MISCERR, "No image defined for the reference map.", + "loadReferenceMap()"); + return (-1); + } + if (ref->width == 0 || ref->height == 0) { + msSetError(MS_MISCERR, "No image size defined for the reference map.", + "loadReferenceMap()"); + return (-1); + } + return (0); + break; + case (COLOR): + if (loadColor(&(ref->color), NULL) != MS_SUCCESS) + return (-1); + break; + case (EXTENT): + if (getDouble(&(ref->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(ref->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(ref->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (getDouble(&(ref->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) + return (-1); + if (!MS_VALID_EXTENT(ref->extent)) { + msSetError(MS_MISCERR, + "Given reference extent is invalid. Check that it " + "is in the form: minx, miny, maxx, maxy", + "loadReferenceMap()"); + return (-1); + } + break; + case (IMAGE): + if (getString(&ref->image) == MS_FAILURE) + return (-1); + break; + case (OUTLINECOLOR): + if (loadColor(&(ref->outlinecolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (SIZE): + if (getInteger(&(ref->width), MS_NUM_CHECK_RANGE, 5, ref->map->maxsize) == + -1) + return (-1); // is 5 reasonable? + if (getInteger(&(ref->height), MS_NUM_CHECK_RANGE, 5, + ref->map->maxsize) == -1) + return (-1); + break; + case (STATUS): + if ((ref->status = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (MARKER): + if ((state = getSymbol(2, MS_NUMBER, MS_STRING)) == -1) + return (-1); - if(state == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid MARKER, must be greater than 0 (line %d)", "loadReferenceMap()", msyylineno); - return(-1); - } - ref->marker = (int) msyynumber; - } else { - if (ref->markername != NULL) - msFree(ref->markername); - ref->markername = msStrdup(msyystring_buffer); - } - break; - case(MARKERSIZE): - if(getInteger(&(ref->markersize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MINBOXSIZE): - if(getInteger(&(ref->minboxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(MAXBOXSIZE): - if(getInteger(&(ref->maxboxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return(-1); - break; - case(REFERENCE): - break; /* for string loads */ - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadReferenceMap()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ + if (state == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_GTE, 0, -1) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid MARKER, must be greater than 0 (line %d)", + "loadReferenceMap()", msyylineno); + return (-1); } + ref->marker = (int)msyynumber; + } else { + if (ref->markername != NULL) + msFree(ref->markername); + ref->markername = msStrdup(msyystring_buffer); + } + break; + case (MARKERSIZE): + if (getInteger(&(ref->markersize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MINBOXSIZE): + if (getInteger(&(ref->minboxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (MAXBOXSIZE): + if (getInteger(&(ref->maxboxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return (-1); + break; + case (REFERENCE): + break; /* for string loads */ + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadReferenceMap()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } /* next token */ } -int msUpdateReferenceMapFromString(referenceMapObj *ref, char *string) -{ - if(!ref || !string) return MS_FAILURE; +int msUpdateReferenceMapFromString(referenceMapObj *ref, char *string) { + if (!ref || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -4691,33 +5186,36 @@ int msUpdateReferenceMapFromString(referenceMapObj *ref, char *string) msyylineno = 1; /* start at line 1 */ - if(loadReferenceMap(ref, ref->map) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadReferenceMap(ref, ref->map) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeReferenceMap(FILE *stream, int indent, referenceMapObj *ref) -{ +static void writeReferenceMap(FILE *stream, int indent, referenceMapObj *ref) { colorObj c; - if(!ref->image) return; + if (!ref->image) + return; indent++; writeBlockBegin(stream, indent, "REFERENCE"); - MS_INIT_COLOR(c,255,0,0,255); + MS_INIT_COLOR(c, 255, 0, 0, 255); writeColor(stream, indent, "COLOR", &c, &(ref->color)); writeExtent(stream, indent, "EXTENT", ref->extent); writeString(stream, indent, "IMAGE", NULL, ref->image); - MS_INIT_COLOR(c,0,0,0,255); + MS_INIT_COLOR(c, 0, 0, 0, 255); writeColor(stream, indent, "OUTLINECOLOR", &c, &(ref->outlinecolor)); writeDimension(stream, indent, "SIZE", ref->width, ref->height, NULL, NULL); - writeKeyword(stream, indent, "STATUS", ref->status, 2, MS_ON, "ON", MS_OFF, "OFF"); - writeNumberOrString(stream, indent, "MARKER", 0, ref->marker, ref->markername); + writeKeyword(stream, indent, "STATUS", ref->status, 2, MS_ON, "ON", MS_OFF, + "OFF"); + writeNumberOrString(stream, indent, "MARKER", 0, ref->marker, + ref->markername); writeNumber(stream, indent, "MARKERSIZE", -1, ref->markersize); writeNumber(stream, indent, "MAXBOXSIZE", -1, ref->maxboxsize); writeNumber(stream, indent, "MINBOXSIZE", -1, ref->minboxsize); @@ -4725,9 +5223,8 @@ static void writeReferenceMap(FILE *stream, int indent, referenceMapObj *ref) writeLineFeed(stream); } -char* msWriteReferenceMapToString(referenceMapObj *ref) -{ - msIOContext context; +char *msWriteReferenceMapToString(referenceMapObj *ref) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -4738,20 +5235,19 @@ char* msWriteReferenceMapToString(referenceMapObj *ref) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeReferenceMap(stdout, -1, ref); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } #define MAX_FORMATOPTIONS 100 -static int loadOutputFormat(mapObj *map) -{ +static int loadOutputFormat(mapObj *map) { char *name = NULL; char *mimetype = NULL; char *driver = NULL; @@ -4759,173 +5255,179 @@ static int loadOutputFormat(mapObj *map) int imagemode = MS_NOOVERRIDE; int transparent = MS_NOOVERRIDE; char *formatoptions[MAX_FORMATOPTIONS]; - int numformatoptions = 0; + int numformatoptions = 0; char *value = NULL; - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadOutputFormat()"); - goto load_output_error; + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadOutputFormat()"); + goto load_output_error; - case(END): { - outputFormatObj *format; + case (END): { + outputFormatObj *format; - if( driver == NULL ) { - msSetError(MS_MISCERR, - "OUTPUTFORMAT clause lacks DRIVER keyword near (%s):(%d)", - "loadOutputFormat()", - msyystring_buffer, msyylineno ); - goto load_output_error; - } + if (driver == NULL) { + msSetError(MS_MISCERR, + "OUTPUTFORMAT clause lacks DRIVER keyword near (%s):(%d)", + "loadOutputFormat()", msyystring_buffer, msyylineno); + goto load_output_error; + } - format = msCreateDefaultOutputFormat( map, driver, name, NULL ); - if( format == NULL ) { - msSetError(MS_MISCERR, - "OUTPUTFORMAT (%s) clause references driver (%s), but this driver isn't configured.", - "loadOutputFormat()", name, driver ); - goto load_output_error; - } - msFree( name ); - name = NULL; - msFree( driver ); - driver = NULL; - - if( transparent != MS_NOOVERRIDE ) - format->transparent = transparent; - if( extension != NULL ) { - msFree( format->extension ); - format->extension = extension; - extension = NULL; - } - if( mimetype != NULL ) { - msFree( format->mimetype ); - format->mimetype = mimetype; - mimetype = NULL; + format = msCreateDefaultOutputFormat(map, driver, name, NULL); + if (format == NULL) { + msSetError(MS_MISCERR, + "OUTPUTFORMAT (%s) clause references driver (%s), but this " + "driver isn't configured.", + "loadOutputFormat()", name, driver); + goto load_output_error; + } + msFree(name); + name = NULL; + msFree(driver); + driver = NULL; + + if (transparent != MS_NOOVERRIDE) + format->transparent = transparent; + if (extension != NULL) { + msFree(format->extension); + format->extension = extension; + extension = NULL; + } + if (mimetype != NULL) { + msFree(format->mimetype); + format->mimetype = mimetype; + mimetype = NULL; + } + if (imagemode != MS_NOOVERRIDE) { + if (format->renderer != MS_RENDER_WITH_AGG || + imagemode != MS_IMAGEMODE_PC256) { + /* don't force to PC256 with agg, this can happen when using mapfile + * defined GD outputformats that are now falling back to agg/png8 + */ + format->imagemode = imagemode; } - if( imagemode != MS_NOOVERRIDE ) { - if(format->renderer != MS_RENDER_WITH_AGG || imagemode != MS_IMAGEMODE_PC256) { - /* don't force to PC256 with agg, this can happen when using mapfile defined GD - * outputformats that are now falling back to agg/png8 - */ - format->imagemode = imagemode; - } - if( transparent == MS_NOOVERRIDE ) { - if( imagemode == MS_IMAGEMODE_RGB ) - format->transparent = MS_FALSE; - else if( imagemode == MS_IMAGEMODE_RGBA ) - format->transparent = MS_TRUE; - } - if( format->imagemode == MS_IMAGEMODE_INT16 - || format->imagemode == MS_IMAGEMODE_FLOAT32 - || format->imagemode == MS_IMAGEMODE_BYTE ) - format->renderer = MS_RENDER_WITH_RAWDATA; + if (transparent == MS_NOOVERRIDE) { + if (imagemode == MS_IMAGEMODE_RGB) + format->transparent = MS_FALSE; + else if (imagemode == MS_IMAGEMODE_RGBA) + format->transparent = MS_TRUE; } - while(numformatoptions--) { - char *key = strchr(formatoptions[numformatoptions],'='); - if(!key || !*(key+1)) { - msSetError(MS_MISCERR,"Failed to parse FORMATOPTION, expecting \"KEY=VALUE\" syntax.","loadOutputFormat()"); - goto load_output_error; - } - *key = 0; - key++; - msSetOutputFormatOption(format,formatoptions[numformatoptions],key); - free(formatoptions[numformatoptions]); + if (format->imagemode == MS_IMAGEMODE_INT16 || + format->imagemode == MS_IMAGEMODE_FLOAT32 || + format->imagemode == MS_IMAGEMODE_BYTE) + format->renderer = MS_RENDER_WITH_RAWDATA; + } + while (numformatoptions--) { + char *key = strchr(formatoptions[numformatoptions], '='); + if (!key || !*(key + 1)) { + msSetError( + MS_MISCERR, + "Failed to parse FORMATOPTION, expecting \"KEY=VALUE\" syntax.", + "loadOutputFormat()"); + goto load_output_error; } + *key = 0; + key++; + msSetOutputFormatOption(format, formatoptions[numformatoptions], key); + free(formatoptions[numformatoptions]); + } - format->inmapfile = MS_TRUE; + format->inmapfile = MS_TRUE; - msOutputFormatValidate( format, MS_FALSE ); - return(0); + msOutputFormatValidate(format, MS_FALSE); + return (0); + } + case (NAME): + msFree(name); + if ((name = getToken()) == NULL) + goto load_output_error; + break; + case (MIMETYPE): + if (getString(&mimetype) == MS_FAILURE) + goto load_output_error; + break; + case (DRIVER): { + int s; + if ((s = getSymbol(2, MS_STRING, TEMPLATE)) == + -1) /* allow the template to be quoted or not in the mapfile */ + goto load_output_error; + free(driver); + if (s == MS_STRING) + driver = msStrdup(msyystring_buffer); + else + driver = msStrdup("TEMPLATE"); + } break; + case (EXTENSION): + if (getString(&extension) == MS_FAILURE) + goto load_output_error; + if (extension[0] == '.') { + char *temp = msStrdup(extension + 1); + free(extension); + extension = temp; } - case(NAME): - msFree( name ); - if((name = getToken()) == NULL) - goto load_output_error; - break; - case(MIMETYPE): - if(getString(&mimetype) == MS_FAILURE) - goto load_output_error; - break; - case(DRIVER): { - int s; - if((s = getSymbol(2, MS_STRING, TEMPLATE)) == -1) /* allow the template to be quoted or not in the mapfile */ - goto load_output_error; - free(driver); - if(s == MS_STRING) - driver = msStrdup(msyystring_buffer); - else - driver = msStrdup("TEMPLATE"); + break; + case (FORMATOPTION): + if (getString(&value) == MS_FAILURE) + goto load_output_error; + if (numformatoptions < MAX_FORMATOPTIONS) + formatoptions[numformatoptions++] = value; + value = NULL; + break; + case (IMAGEMODE): + value = getToken(); + if (strcasecmp(value, "PC256") == 0) + imagemode = MS_IMAGEMODE_PC256; + else if (strcasecmp(value, "RGB") == 0) + imagemode = MS_IMAGEMODE_RGB; + else if (strcasecmp(value, "RGBA") == 0) + imagemode = MS_IMAGEMODE_RGBA; + else if (strcasecmp(value, "INT16") == 0) + imagemode = MS_IMAGEMODE_INT16; + else if (strcasecmp(value, "FLOAT32") == 0) + imagemode = MS_IMAGEMODE_FLOAT32; + else if (strcasecmp(value, "BYTE") == 0) + imagemode = MS_IMAGEMODE_BYTE; + else if (strcasecmp(value, "FEATURE") == 0) + imagemode = MS_IMAGEMODE_FEATURE; + else { + msSetError(MS_IDENTERR, + "Parsing error near (%s):(line %d), expected PC256, RGB, " + "RGBA, FEATURE, BYTE, INT16, or FLOAT32 for IMAGEMODE.", + "loadOutputFormat()", msyystring_buffer, msyylineno); + goto load_output_error; } + free(value); + value = NULL; break; - case(EXTENSION): - if(getString(&extension) == MS_FAILURE) - goto load_output_error; - if( extension[0] == '.' ) { - char *temp = msStrdup(extension+1); - free( extension ); - extension = temp; - } - break; - case(FORMATOPTION): - if(getString(&value) == MS_FAILURE) - goto load_output_error; - if( numformatoptions < MAX_FORMATOPTIONS ) - formatoptions[numformatoptions++] = value; - value=NULL; - break; - case(IMAGEMODE): - value = getToken(); - if( strcasecmp(value,"PC256") == 0 ) - imagemode = MS_IMAGEMODE_PC256; - else if( strcasecmp(value,"RGB") == 0 ) - imagemode = MS_IMAGEMODE_RGB; - else if( strcasecmp(value,"RGBA") == 0) - imagemode = MS_IMAGEMODE_RGBA; - else if( strcasecmp(value,"INT16") == 0) - imagemode = MS_IMAGEMODE_INT16; - else if( strcasecmp(value,"FLOAT32") == 0) - imagemode = MS_IMAGEMODE_FLOAT32; - else if( strcasecmp(value,"BYTE") == 0) - imagemode = MS_IMAGEMODE_BYTE; - else if( strcasecmp(value,"FEATURE") == 0) - imagemode = MS_IMAGEMODE_FEATURE; - else { - msSetError(MS_IDENTERR, - "Parsing error near (%s):(line %d), expected PC256, RGB, RGBA, FEATURE, BYTE, INT16, or FLOAT32 for IMAGEMODE.", "loadOutputFormat()", - msyystring_buffer, msyylineno); - goto load_output_error; - } - free(value); - value=NULL; - break; - case(TRANSPARENT): - if((transparent = getSymbol(2, MS_ON,MS_OFF)) == -1) - goto load_output_error; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadOutputFormat()", - msyystring_buffer, msyylineno); + case (TRANSPARENT): + if ((transparent = getSymbol(2, MS_ON, MS_OFF)) == -1) goto load_output_error; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadOutputFormat()", msyystring_buffer, msyylineno); + goto load_output_error; } } /* next token */ load_output_error: - msFree( driver ); - msFree( extension ); - msFree( mimetype ); - msFree( name ); - msFree( value ); + msFree(driver); + msFree(extension); + msFree(mimetype); + msFree(name); + msFree(value); return -1; } /* ** utility function to write an output format structure to file */ -static void writeOutputformatobject(FILE *stream, int indent, outputFormatObj *outputformat) -{ +static void writeOutputformatobject(FILE *stream, int indent, + outputFormatObj *outputformat) { int i = 0; - if(!outputformat) return; + if (!outputformat) + return; indent++; writeBlockBegin(stream, indent, "OUTPUTFORMAT"); @@ -4933,26 +5435,32 @@ static void writeOutputformatobject(FILE *stream, int indent, outputFormatObj *o writeString(stream, indent, "MIMETYPE", NULL, outputformat->mimetype); writeString(stream, indent, "DRIVER", NULL, outputformat->driver); writeString(stream, indent, "EXTENSION", NULL, outputformat->extension); - writeKeyword(stream, indent, "IMAGEMODE", outputformat->imagemode, 7, MS_IMAGEMODE_PC256, "PC256", MS_IMAGEMODE_RGB, "RGB", MS_IMAGEMODE_RGBA, "RGBA", MS_IMAGEMODE_INT16, "INT16", MS_IMAGEMODE_FLOAT32, "FLOAT32", MS_IMAGEMODE_BYTE, "BYTE", MS_IMAGEMODE_FEATURE, "FEATURE"); - writeKeyword(stream, indent, "TRANSPARENT", outputformat->transparent, 2, MS_TRUE, "TRUE", MS_FALSE, "FALSE"); - for (i=0; inumformatoptions; i++) - writeString(stream, indent, "FORMATOPTION", NULL, outputformat->formatoptions[i]); + writeKeyword(stream, indent, "IMAGEMODE", outputformat->imagemode, 7, + MS_IMAGEMODE_PC256, "PC256", MS_IMAGEMODE_RGB, "RGB", + MS_IMAGEMODE_RGBA, "RGBA", MS_IMAGEMODE_INT16, "INT16", + MS_IMAGEMODE_FLOAT32, "FLOAT32", MS_IMAGEMODE_BYTE, "BYTE", + MS_IMAGEMODE_FEATURE, "FEATURE"); + writeKeyword(stream, indent, "TRANSPARENT", outputformat->transparent, 2, + MS_TRUE, "TRUE", MS_FALSE, "FALSE"); + for (i = 0; i < outputformat->numformatoptions; i++) + writeString(stream, indent, "FORMATOPTION", NULL, + outputformat->formatoptions[i]); writeBlockEnd(stream, indent, "OUTPUTFORMAT"); writeLineFeed(stream); } - /* ** Write the output formats to file */ -static void writeOutputformat(FILE *stream, int indent, mapObj *map) -{ - int i=0; - if(!map->outputformat) return; +static void writeOutputformat(FILE *stream, int indent, mapObj *map) { + int i = 0; + if (!map->outputformat) + return; writeOutputformatobject(stream, indent, map->outputformat); - for(i=0; inumoutputformats; i++) { - if(map->outputformatlist[i]->inmapfile == MS_TRUE && strcmp(map->outputformatlist[i]->name, map->outputformat->name) != 0) + for (i = 0; i < map->numoutputformats; i++) { + if (map->outputformatlist[i]->inmapfile == MS_TRUE && + strcmp(map->outputformatlist[i]->name, map->outputformat->name) != 0) writeOutputformatobject(stream, indent, map->outputformatlist[i]); } } @@ -4960,11 +5468,10 @@ static void writeOutputformat(FILE *stream, int indent, mapObj *map) /* ** Initialize, load and free a legendObj structure */ -void initLegend(legendObj *legend) -{ +void initLegend(legendObj *legend) { legend->height = legend->width = 0; - MS_INIT_COLOR(legend->imagecolor, 255,255,255,255); /* white */ - MS_INIT_COLOR(legend->outlinecolor, -1,-1,-1,255); + MS_INIT_COLOR(legend->imagecolor, 255, 255, 255, 255); /* white */ + MS_INIT_COLOR(legend->outlinecolor, -1, -1, -1, 255); initLabel(&legend->label); legend->label.position = MS_XY; /* override */ legend->keysizex = 20; @@ -4979,77 +5486,93 @@ void initLegend(legendObj *legend) legend->map = NULL; } -void freeLegend(legendObj *legend) -{ +void freeLegend(legendObj *legend) { if (legend->template) free(legend->template); freeLabel(&(legend->label)); } -int loadLegend(legendObj *legend, mapObj *map) -{ +int loadLegend(legendObj *legend, mapObj *map) { legend->map = (mapObj *)map; - for(;;) { - switch(msyylex()) { - case(EOF): - msSetError(MS_EOFERR, NULL, "loadLegend()"); - return(-1); - case(END): - legend->label.position = MS_XY; /* overrides go here */ - return(0); - break; - case(IMAGECOLOR): - if(loadColor(&(legend->imagecolor), NULL) != MS_SUCCESS) return(-1); - break; - case(KEYSIZE): - if(getInteger(&(legend->keysizex), MS_NUM_CHECK_RANGE, MS_LEGEND_KEYSIZE_MIN, MS_LEGEND_KEYSIZE_MAX) == -1) return(-1); - if(getInteger(&(legend->keysizey), MS_NUM_CHECK_RANGE, MS_LEGEND_KEYSIZE_MIN, MS_LEGEND_KEYSIZE_MAX) == -1) return(-1); - break; - case(KEYSPACING): - if(getInteger(&(legend->keyspacingx), MS_NUM_CHECK_RANGE, MS_LEGEND_KEYSPACING_MIN, MS_LEGEND_KEYSPACING_MAX) == -1) return(-1); - if(getInteger(&(legend->keyspacingy), MS_NUM_CHECK_RANGE, MS_LEGEND_KEYSPACING_MIN, MS_LEGEND_KEYSPACING_MAX) == -1) return(-1); - break; - case(LABEL): - if(loadLabel(&(legend->label)) == -1) return(-1); - legend->label.angle = 0; /* force */ - break; - case(LEGEND): - break; /* for string loads */ - case(OUTLINECOLOR): - if(loadColor(&(legend->outlinecolor), NULL) != MS_SUCCESS) return(-1); - break; - case(POSITION): - if((legend->position = getSymbol(6, MS_UL,MS_UR,MS_LL,MS_LR,MS_UC,MS_LC)) == -1) return(-1); - break; - case(POSTLABELCACHE): - if((legend->postlabelcache = getSymbol(2, MS_TRUE,MS_FALSE)) == -1) return(-1); - break; - case(STATUS): - if((legend->status = getSymbol(3, MS_ON,MS_OFF,MS_EMBED)) == -1) return(-1); - break; - case(TRANSPARENT): - if((legend->transparent = getSymbol(2, MS_ON,MS_OFF)) == -1) return(-1); - break; - case(TEMPLATE): - if(getString(&legend->template) == MS_FAILURE) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadLegend()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } + for (;;) { + switch (msyylex()) { + case (EOF): + msSetError(MS_EOFERR, NULL, "loadLegend()"); + return (-1); + case (END): + legend->label.position = MS_XY; /* overrides go here */ + return (0); + break; + case (IMAGECOLOR): + if (loadColor(&(legend->imagecolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (KEYSIZE): + if (getInteger(&(legend->keysizex), MS_NUM_CHECK_RANGE, + MS_LEGEND_KEYSIZE_MIN, MS_LEGEND_KEYSIZE_MAX) == -1) + return (-1); + if (getInteger(&(legend->keysizey), MS_NUM_CHECK_RANGE, + MS_LEGEND_KEYSIZE_MIN, MS_LEGEND_KEYSIZE_MAX) == -1) + return (-1); + break; + case (KEYSPACING): + if (getInteger(&(legend->keyspacingx), MS_NUM_CHECK_RANGE, + MS_LEGEND_KEYSPACING_MIN, MS_LEGEND_KEYSPACING_MAX) == -1) + return (-1); + if (getInteger(&(legend->keyspacingy), MS_NUM_CHECK_RANGE, + MS_LEGEND_KEYSPACING_MIN, MS_LEGEND_KEYSPACING_MAX) == -1) + return (-1); + break; + case (LABEL): + if (loadLabel(&(legend->label)) == -1) + return (-1); + legend->label.angle = 0; /* force */ + break; + case (LEGEND): + break; /* for string loads */ + case (OUTLINECOLOR): + if (loadColor(&(legend->outlinecolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (POSITION): + if ((legend->position = + getSymbol(6, MS_UL, MS_UR, MS_LL, MS_LR, MS_UC, MS_LC)) == -1) + return (-1); + break; + case (POSTLABELCACHE): + if ((legend->postlabelcache = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) + return (-1); + break; + case (STATUS): + if ((legend->status = getSymbol(3, MS_ON, MS_OFF, MS_EMBED)) == -1) + return (-1); + break; + case (TRANSPARENT): + if ((legend->transparent = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (TEMPLATE): + if (getString(&legend->template) == MS_FAILURE) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadLegend()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } /* next token */ } -int msUpdateLegendFromString(legendObj *legend, char *string) -{ - if(!legend || !string) return MS_FAILURE; +int msUpdateLegendFromString(legendObj *legend, char *string) { + if (!legend || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -5057,40 +5580,47 @@ int msUpdateLegendFromString(legendObj *legend, char *string) msyylineno = 1; /* start at line 1 */ - if(loadLegend(legend, legend->map) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadLegend(legend, legend->map) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeLegend(FILE *stream, int indent, legendObj *legend) -{ +static void writeLegend(FILE *stream, int indent, legendObj *legend) { colorObj c; indent++; writeBlockBegin(stream, indent, "LEGEND"); - MS_INIT_COLOR(c,255,255,255,255); + MS_INIT_COLOR(c, 255, 255, 255, 255); writeColor(stream, indent, "IMAGECOLOR", &c, &(legend->imagecolor)); - writeDimension(stream, indent, "KEYSIZE", legend->keysizex, legend->keysizey, NULL, NULL); - writeDimension(stream, indent, "KEYSPACING", legend->keyspacingx, legend->keyspacingy, NULL, NULL); + writeDimension(stream, indent, "KEYSIZE", legend->keysizex, legend->keysizey, + NULL, NULL); + writeDimension(stream, indent, "KEYSPACING", legend->keyspacingx, + legend->keyspacingy, NULL, NULL); writeLabel(stream, indent, &(legend->label)); writeColor(stream, indent, "OUTLINECOLOR", NULL, &(legend->outlinecolor)); - if(legend->status == MS_EMBED) writeKeyword(stream, indent, "POSITION", legend->position, 6, MS_LL, "LL", MS_UL, "UL", MS_UR, "UR", MS_LR, "LR", MS_UC, "UC", MS_LC, "LC"); - writeKeyword(stream, indent, "POSTLABELCACHE", legend->postlabelcache, 1, MS_TRUE, "TRUE"); - writeKeyword(stream, indent, "STATUS", legend->status, 3, MS_ON, "ON", MS_OFF, "OFF", MS_EMBED, "EMBED"); - writeKeyword(stream, indent, "TRANSPARENT", legend->transparent, 2, MS_TRUE, "TRUE", MS_FALSE, "FALSE"); + if (legend->status == MS_EMBED) + writeKeyword(stream, indent, "POSITION", legend->position, 6, MS_LL, "LL", + MS_UL, "UL", MS_UR, "UR", MS_LR, "LR", MS_UC, "UC", MS_LC, + "LC"); + writeKeyword(stream, indent, "POSTLABELCACHE", legend->postlabelcache, 1, + MS_TRUE, "TRUE"); + writeKeyword(stream, indent, "STATUS", legend->status, 3, MS_ON, "ON", MS_OFF, + "OFF", MS_EMBED, "EMBED"); + writeKeyword(stream, indent, "TRANSPARENT", legend->transparent, 2, MS_TRUE, + "TRUE", MS_FALSE, "FALSE"); writeString(stream, indent, "TEMPLATE", NULL, legend->template); writeBlockEnd(stream, indent, "LEGEND"); writeLineFeed(stream); } -char* msWriteLegendToString(legendObj *legend) -{ - msIOContext context; +char *msWriteLegendToString(legendObj *legend) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -5101,123 +5631,147 @@ char* msWriteLegendToString(legendObj *legend) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeLegend(stdout, -1, legend); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize, load and free a scalebarObj structure */ -void initScalebar(scalebarObj *scalebar) -{ - MS_INIT_COLOR(scalebar->imagecolor, -1,-1,-1,255); +void initScalebar(scalebarObj *scalebar) { + MS_INIT_COLOR(scalebar->imagecolor, -1, -1, -1, 255); scalebar->width = 200; scalebar->height = 3; scalebar->style = 0; /* only 2 styles at this point */ scalebar->intervals = 4; initLabel(&scalebar->label); scalebar->label.position = MS_XY; /* override */ - MS_INIT_COLOR(scalebar->backgroundcolor, -1,-1,-1,255); /* if not set, scalebar creation needs to set this to match the background color */ - MS_INIT_COLOR(scalebar->color, 0,0,0,255); /* default to black */ - MS_INIT_COLOR(scalebar->outlinecolor, -1,-1,-1,255); + MS_INIT_COLOR(scalebar->backgroundcolor, -1, -1, -1, + 255); /* if not set, scalebar creation needs to set this to + match the background color */ + MS_INIT_COLOR(scalebar->color, 0, 0, 0, 255); /* default to black */ + MS_INIT_COLOR(scalebar->outlinecolor, -1, -1, -1, 255); scalebar->units = MS_MILES; scalebar->status = MS_OFF; scalebar->position = MS_LL; scalebar->transparent = MS_NOOVERRIDE; /* no transparency */ - scalebar->postlabelcache = MS_FALSE; /* draw with labels */ + scalebar->postlabelcache = MS_FALSE; /* draw with labels */ scalebar->align = MS_ALIGN_CENTER; scalebar->offsetx = 0; scalebar->offsety = 0; } -void freeScalebar(scalebarObj *scalebar) -{ - freeLabel(&(scalebar->label)); -} +void freeScalebar(scalebarObj *scalebar) { freeLabel(&(scalebar->label)); } -int loadScalebar(scalebarObj *scalebar) -{ - for(;;) { - switch(msyylex()) { - case(ALIGN): - if((scalebar->align = getSymbol(3, MS_ALIGN_LEFT,MS_ALIGN_CENTER,MS_ALIGN_RIGHT)) == -1) return(-1); - break; - case(BACKGROUNDCOLOR): - if(loadColor(&(scalebar->backgroundcolor), NULL) != MS_SUCCESS) return(-1); - break; - case(COLOR): - if(loadColor(&(scalebar->color), NULL) != MS_SUCCESS) return(-1); - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadScalebar()"); - return(-1); - case(END): - return(0); - break; - case(IMAGECOLOR): - if(loadColor(&(scalebar->imagecolor), NULL) != MS_SUCCESS) return(-1); - break; - case(INTERVALS): - if(getInteger(&(scalebar->intervals), MS_NUM_CHECK_RANGE, MS_SCALEBAR_INTERVALS_MIN, MS_SCALEBAR_INTERVALS_MAX) == -1) return(-1); - break; - case(LABEL): - if(loadLabel(&(scalebar->label)) == -1) return(-1); - scalebar->label.angle = 0; - break; - case(OUTLINECOLOR): - if(loadColor(&(scalebar->outlinecolor), NULL) != MS_SUCCESS) return(-1); - break; - case(POSITION): - if((scalebar->position = getSymbol(6, MS_UL,MS_UR,MS_LL,MS_LR,MS_UC,MS_LC)) == -1) - return(-1); - break; - case(POSTLABELCACHE): - if((scalebar->postlabelcache = getSymbol(2, MS_TRUE,MS_FALSE)) == -1) return(-1); - break; - case(SCALEBAR): - break; /* for string loads */ - case(SIZE): - if(getInteger(&(scalebar->width), MS_NUM_CHECK_RANGE, MS_SCALEBAR_WIDTH_MIN, MS_SCALEBAR_WIDTH_MAX) == -1) return(-1); - if(getInteger(&(scalebar->height), MS_NUM_CHECK_RANGE, MS_SCALEBAR_HEIGHT_MIN, MS_SCALEBAR_HEIGHT_MAX) == -1) return(-1); - break; - case(STATUS): - if((scalebar->status = getSymbol(3, MS_ON,MS_OFF,MS_EMBED)) == -1) return(-1); - break; - case(STYLE): - if(getInteger(&(scalebar->style), MS_NUM_CHECK_RANGE, 0, 1) == -1) return(-1); // only 2 styles: 0 and 1 - break; - case(TRANSPARENT): - if((scalebar->transparent = getSymbol(2, MS_ON,MS_OFF)) == -1) return(-1); - break; - case(UNITS): - if((scalebar->units = getSymbol(6, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES)) == -1) return(-1); - break; - case(OFFSET): - if(getInteger(&(scalebar->offsetx), MS_NUM_CHECK_RANGE, MS_SCALEBAR_OFFSET_MIN, MS_SCALEBAR_OFFSET_MAX) == -1) return(-1); - if(getInteger(&(scalebar->offsety), MS_NUM_CHECK_RANGE, MS_SCALEBAR_OFFSET_MIN, MS_SCALEBAR_OFFSET_MAX) == -1) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadScalebar()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } +int loadScalebar(scalebarObj *scalebar) { + for (;;) { + switch (msyylex()) { + case (ALIGN): + if ((scalebar->align = getSymbol(3, MS_ALIGN_LEFT, MS_ALIGN_CENTER, + MS_ALIGN_RIGHT)) == -1) + return (-1); + break; + case (BACKGROUNDCOLOR): + if (loadColor(&(scalebar->backgroundcolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (COLOR): + if (loadColor(&(scalebar->color), NULL) != MS_SUCCESS) + return (-1); + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadScalebar()"); + return (-1); + case (END): + return (0); + break; + case (IMAGECOLOR): + if (loadColor(&(scalebar->imagecolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (INTERVALS): + if (getInteger(&(scalebar->intervals), MS_NUM_CHECK_RANGE, + MS_SCALEBAR_INTERVALS_MIN, + MS_SCALEBAR_INTERVALS_MAX) == -1) + return (-1); + break; + case (LABEL): + if (loadLabel(&(scalebar->label)) == -1) + return (-1); + scalebar->label.angle = 0; + break; + case (OUTLINECOLOR): + if (loadColor(&(scalebar->outlinecolor), NULL) != MS_SUCCESS) + return (-1); + break; + case (POSITION): + if ((scalebar->position = + getSymbol(6, MS_UL, MS_UR, MS_LL, MS_LR, MS_UC, MS_LC)) == -1) + return (-1); + break; + case (POSTLABELCACHE): + if ((scalebar->postlabelcache = getSymbol(2, MS_TRUE, MS_FALSE)) == -1) + return (-1); + break; + case (SCALEBAR): + break; /* for string loads */ + case (SIZE): + if (getInteger(&(scalebar->width), MS_NUM_CHECK_RANGE, + MS_SCALEBAR_WIDTH_MIN, MS_SCALEBAR_WIDTH_MAX) == -1) + return (-1); + if (getInteger(&(scalebar->height), MS_NUM_CHECK_RANGE, + MS_SCALEBAR_HEIGHT_MIN, MS_SCALEBAR_HEIGHT_MAX) == -1) + return (-1); + break; + case (STATUS): + if ((scalebar->status = getSymbol(3, MS_ON, MS_OFF, MS_EMBED)) == -1) + return (-1); + break; + case (STYLE): + if (getInteger(&(scalebar->style), MS_NUM_CHECK_RANGE, 0, 1) == -1) + return (-1); // only 2 styles: 0 and 1 + break; + case (TRANSPARENT): + if ((scalebar->transparent = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (UNITS): + if ((scalebar->units = + getSymbol(6, MS_INCHES, MS_FEET, MS_MILES, MS_METERS, + MS_KILOMETERS, MS_NAUTICALMILES)) == -1) + return (-1); + break; + case (OFFSET): + if (getInteger(&(scalebar->offsetx), MS_NUM_CHECK_RANGE, + MS_SCALEBAR_OFFSET_MIN, MS_SCALEBAR_OFFSET_MAX) == -1) + return (-1); + if (getInteger(&(scalebar->offsety), MS_NUM_CHECK_RANGE, + MS_SCALEBAR_OFFSET_MIN, MS_SCALEBAR_OFFSET_MAX) == -1) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadScalebar()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } /* next token */ } -int msUpdateScalebarFromString(scalebarObj *scalebar, char *string) -{ - if(!scalebar || !string) return MS_FAILURE; +int msUpdateScalebarFromString(scalebarObj *scalebar, char *string) { + if (!scalebar || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -5225,44 +5779,54 @@ int msUpdateScalebarFromString(scalebarObj *scalebar, char *string) msyylineno = 1; /* start at line 1 */ - if(loadScalebar(scalebar) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadScalebar(scalebar) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeScalebar(FILE *stream, int indent, scalebarObj *scalebar) -{ +static void writeScalebar(FILE *stream, int indent, scalebarObj *scalebar) { colorObj c; indent++; writeBlockBegin(stream, indent, "SCALEBAR"); - writeKeyword(stream, indent, "ALIGN", scalebar->align, 2, MS_ALIGN_LEFT, "LEFT", MS_ALIGN_RIGHT, "RIGHT"); - writeColor(stream, indent, "BACKGROUNDCOLOR", NULL, &(scalebar->backgroundcolor)); - MS_INIT_COLOR(c,0,0,0,255); + writeKeyword(stream, indent, "ALIGN", scalebar->align, 2, MS_ALIGN_LEFT, + "LEFT", MS_ALIGN_RIGHT, "RIGHT"); + writeColor(stream, indent, "BACKGROUNDCOLOR", NULL, + &(scalebar->backgroundcolor)); + MS_INIT_COLOR(c, 0, 0, 0, 255); writeColor(stream, indent, "COLOR", &c, &(scalebar->color)); writeColor(stream, indent, "IMAGECOLOR", NULL, &(scalebar->imagecolor)); writeNumber(stream, indent, "INTERVALS", -1, scalebar->intervals); writeLabel(stream, indent, &(scalebar->label)); writeColor(stream, indent, "OUTLINECOLOR", NULL, &(scalebar->outlinecolor)); - if(scalebar->status == MS_EMBED) writeKeyword(stream, indent, "POSITION", scalebar->position, 6, MS_LL, "LL", MS_UL, "UL", MS_UR, "UR", MS_LR, "LR", MS_UC, "UC", MS_LC, "LC"); - writeKeyword(stream, indent, "POSTLABELCACHE", scalebar->postlabelcache, 1, MS_TRUE, "TRUE"); - writeDimension(stream, indent, "SIZE", scalebar->width, scalebar->height, NULL, NULL); - writeKeyword(stream, indent, "STATUS", scalebar->status, 3, MS_ON, "ON", MS_OFF, "OFF", MS_EMBED, "EMBED"); + if (scalebar->status == MS_EMBED) + writeKeyword(stream, indent, "POSITION", scalebar->position, 6, MS_LL, "LL", + MS_UL, "UL", MS_UR, "UR", MS_LR, "LR", MS_UC, "UC", MS_LC, + "LC"); + writeKeyword(stream, indent, "POSTLABELCACHE", scalebar->postlabelcache, 1, + MS_TRUE, "TRUE"); + writeDimension(stream, indent, "SIZE", scalebar->width, scalebar->height, + NULL, NULL); + writeKeyword(stream, indent, "STATUS", scalebar->status, 3, MS_ON, "ON", + MS_OFF, "OFF", MS_EMBED, "EMBED"); writeNumber(stream, indent, "STYLE", 0, scalebar->style); - writeKeyword(stream, indent, "TRANSPARENT", scalebar->transparent, 2, MS_TRUE, "TRUE", MS_FALSE, "FALSE"); - writeKeyword(stream, indent, "UNITS", scalebar->units, 6, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES"); + writeKeyword(stream, indent, "TRANSPARENT", scalebar->transparent, 2, MS_TRUE, + "TRUE", MS_FALSE, "FALSE"); + writeKeyword(stream, indent, "UNITS", scalebar->units, 6, MS_INCHES, "INCHES", + MS_FEET, "FEET", MS_MILES, "MILES", MS_METERS, "METERS", + MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES"); writeBlockEnd(stream, indent, "SCALEBAR"); writeLineFeed(stream); } -char* msWriteScalebarToString(scalebarObj *scalebar) -{ - msIOContext context; +char *msWriteScalebarToString(scalebarObj *scalebar) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -5273,80 +5837,90 @@ char* msWriteScalebarToString(scalebarObj *scalebar) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeScalebar(stdout, -1, scalebar); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize a queryMapObj structure */ -void initQueryMap(queryMapObj *querymap) -{ +void initQueryMap(queryMapObj *querymap) { querymap->width = querymap->height = -1; querymap->style = MS_HILITE; querymap->status = MS_OFF; - MS_INIT_COLOR(querymap->color, 255,255,0,255); /* yellow */ + MS_INIT_COLOR(querymap->color, 255, 255, 0, 255); /* yellow */ } -int loadQueryMap(queryMapObj *querymap, mapObj *map) -{ +int loadQueryMap(queryMapObj *querymap, mapObj *map) { querymap->map = (mapObj *)map; - for(;;) { - switch(msyylex()) { - case(QUERYMAP): - break; /* for string loads */ - case(COLOR): - if(loadColor(&(querymap->color), NULL) != MS_SUCCESS) return MS_FAILURE; - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "loadQueryMap()"); - return(-1); - case(END): - return(0); - break; - case(SIZE): - /* - ** we do -1 (and avoid 0) here to maintain backwards compatability as older versions write "SIZE -1 -1" when saving a mapfile - */ - if(getInteger(&(querymap->width), MS_NUM_CHECK_RANGE, -1, querymap->map->maxsize) == -1 || querymap->width == 0) { - msSetError(MS_MISCERR, "Invalid SIZE value (line %d)", "loadQueryMap()", msyylineno); - return(-1); - } - if(getInteger(&(querymap->height), MS_NUM_CHECK_RANGE, -1, querymap->map->maxsize) == -1 || querymap->height == 0) { - msSetError(MS_MISCERR, "Invalid SIZE value (line %d)", "loadQueryMap()", msyylineno); - return(-1); - } - break; - case(STATUS): - if((querymap->status = getSymbol(2, MS_ON,MS_OFF)) == -1) return(-1); - break; - case(STYLE): - case(TYPE): - if((querymap->style = getSymbol(3, MS_NORMAL,MS_HILITE,MS_SELECTED)) == -1) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadQueryMap()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } + for (;;) { + switch (msyylex()) { + case (QUERYMAP): + break; /* for string loads */ + case (COLOR): + if (loadColor(&(querymap->color), NULL) != MS_SUCCESS) + return MS_FAILURE; + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "loadQueryMap()"); + return (-1); + case (END): + return (0); + break; + case (SIZE): + /* + ** we do -1 (and avoid 0) here to maintain backwards compatability as + *older versions write "SIZE -1 -1" when saving a mapfile + */ + if (getInteger(&(querymap->width), MS_NUM_CHECK_RANGE, -1, + querymap->map->maxsize) == -1 || + querymap->width == 0) { + msSetError(MS_MISCERR, "Invalid SIZE value (line %d)", "loadQueryMap()", + msyylineno); + return (-1); + } + if (getInteger(&(querymap->height), MS_NUM_CHECK_RANGE, -1, + querymap->map->maxsize) == -1 || + querymap->height == 0) { + msSetError(MS_MISCERR, "Invalid SIZE value (line %d)", "loadQueryMap()", + msyylineno); + return (-1); + } + break; + case (STATUS): + if ((querymap->status = getSymbol(2, MS_ON, MS_OFF)) == -1) + return (-1); + break; + case (STYLE): + case (TYPE): + if ((querymap->style = getSymbol(3, MS_NORMAL, MS_HILITE, MS_SELECTED)) == + -1) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadQueryMap()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } } -int msUpdateQueryMapFromString(queryMapObj *querymap, char *string) -{ - if(!querymap || !string) return MS_FAILURE; +int msUpdateQueryMapFromString(queryMapObj *querymap, char *string) { + if (!querymap || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -5354,35 +5928,38 @@ int msUpdateQueryMapFromString(queryMapObj *querymap, char *string) msyylineno = 1; /* start at line 1 */ - if(loadQueryMap(querymap, querymap->map) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadQueryMap(querymap, querymap->map) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; } -static void writeQueryMap(FILE *stream, int indent, queryMapObj *querymap) -{ +static void writeQueryMap(FILE *stream, int indent, queryMapObj *querymap) { colorObj c; indent++; writeBlockBegin(stream, indent, "QUERYMAP"); - MS_INIT_COLOR(c,255,255,0,255); - writeColor(stream, indent, "COLOR", &c, &(querymap->color)); - if(querymap->width != -1 && querymap->height != -1) // don't write SIZE if not explicitly set - writeDimension(stream, indent, "SIZE", querymap->width, querymap->height, NULL, NULL); - writeKeyword(stream, indent, "STATUS", querymap->status, 2, MS_ON, "ON", MS_OFF, "OFF"); - writeKeyword(stream, indent, "STYLE", querymap->style, 3, MS_NORMAL, "NORMAL", MS_HILITE, "HILITE", MS_SELECTED, "SELECTED"); + MS_INIT_COLOR(c, 255, 255, 0, 255); + writeColor(stream, indent, "COLOR", &c, &(querymap->color)); + if (querymap->width != -1 && + querymap->height != -1) // don't write SIZE if not explicitly set + writeDimension(stream, indent, "SIZE", querymap->width, querymap->height, + NULL, NULL); + writeKeyword(stream, indent, "STATUS", querymap->status, 2, MS_ON, "ON", + MS_OFF, "OFF"); + writeKeyword(stream, indent, "STYLE", querymap->style, 3, MS_NORMAL, "NORMAL", + MS_HILITE, "HILITE", MS_SELECTED, "SELECTED"); writeBlockEnd(stream, indent, "QUERYMAP"); writeLineFeed(stream); } -char* msWriteQueryMapToString(queryMapObj *querymap) -{ - msIOContext context; +char *msWriteQueryMapToString(queryMapObj *querymap) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -5393,24 +5970,23 @@ char* msWriteQueryMapToString(queryMapObj *querymap) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeQueryMap(stdout, -1, querymap); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } /* ** Initialize a webObj structure */ -void initWeb(webObj *web) -{ +void initWeb(webObj *web) { web->template = NULL; web->header = web->footer = NULL; - web->error = web->empty = NULL; + web->error = web->empty = NULL; web->mintemplate = web->maxtemplate = NULL; web->minscaledenom = web->maxscaledenom = -1; web->imagepath = msStrdup(""); @@ -5426,8 +6002,7 @@ void initWeb(webObj *web) web->browseformat = msStrdup("text/html"); } -void freeWeb(webObj *web) -{ +void freeWeb(webObj *web) { msFree(web->template); msFree(web->header); msFree(web->footer); @@ -5441,12 +6016,13 @@ void freeWeb(webObj *web) msFree(web->queryformat); msFree(web->legendformat); msFree(web->browseformat); - if(&(web->metadata)) msFreeHashItems(&(web->metadata)); - if(&(web->validation)) msFreeHashItems(&(web->validation)); + if (&(web->metadata)) + msFreeHashItems(&(web->metadata)); + if (&(web->validation)) + msFreeHashItems(&(web->validation)); } -static void writeWeb(FILE *stream, int indent, webObj *web) -{ +static void writeWeb(FILE *stream, int indent, webObj *web) { indent++; writeBlockBegin(stream, indent, "WEB"); writeString(stream, indent, "BROWSEFORMAT", "text/html", web->browseformat); @@ -5470,9 +6046,8 @@ static void writeWeb(FILE *stream, int indent, webObj *web) writeLineFeed(stream); } -char* msWriteWebToString(webObj *web) -{ - msIOContext context; +char *msWriteWebToString(webObj *web) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -5483,103 +6058,120 @@ char* msWriteWebToString(webObj *web) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeWeb(stdout, -1, web); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } -int loadWeb(webObj *web, mapObj *map) -{ +int loadWeb(webObj *web, mapObj *map) { web->map = (mapObj *)map; - for(;;) { - switch(msyylex()) { - case(BROWSEFORMAT): /* change to use validation in 6.0 */ - free(web->browseformat); - web->browseformat = NULL; /* there is a default */ - if(getString(&web->browseformat) == MS_FAILURE) return(-1); - break; - case(EMPTY): - if(getString(&web->empty) == MS_FAILURE) return(-1); - break; - case(WEB): - break; /* for string loads */ - case(EOF): - msSetError(MS_EOFERR, NULL, "loadWeb()"); - return(-1); - case(END): - return(0); - break; - case(ERROR): - if(getString(&web->error) == MS_FAILURE) return(-1); - break; - case(FOOTER): - if(getString(&web->footer) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(HEADER): - if(getString(&web->header) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(IMAGEPATH): - if(getString(&web->imagepath) == MS_FAILURE) return(-1); - break; - case(TEMPPATH): - if(getString(&web->temppath) == MS_FAILURE) return(-1); - break; - case(IMAGEURL): - if(getString(&web->imageurl) == MS_FAILURE) return(-1); - break; - case(LEGENDFORMAT): /* change to use validation in 6.0 */ - free(web->legendformat); - web->legendformat = NULL; /* there is a default */ - if(getString(&web->legendformat) == MS_FAILURE) return(-1); - break; - case(MAXSCALEDENOM): - if(getDouble(&web->maxscaledenom, MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MAXTEMPLATE): - if(getString(&web->maxtemplate) == MS_FAILURE) return(-1); - break; - case(METADATA): - if(loadHashTable(&(web->metadata)) != MS_SUCCESS) return(-1); - break; - case(MINSCALEDENOM): - if(getDouble(&web->minscaledenom, MS_NUM_CHECK_GTE, 0, -1) == -1) return(-1); - break; - case(MINTEMPLATE): - if(getString(&web->mintemplate) == MS_FAILURE) return(-1); - break; - case(QUERYFORMAT): /* change to use validation in 6.0 */ - free(web->queryformat); - web->queryformat = NULL; /* there is a default */ - if(getString(&web->queryformat) == MS_FAILURE) return(-1); - break; - case(TEMPLATE): - if(getString(&web->template) == MS_FAILURE) return(-1); /* getString() cleans up previously allocated string */ - break; - case(VALIDATION): - if(loadHashTable(&(web->validation)) != MS_SUCCESS) return(-1); - break; - default: - if(strlen(msyystring_buffer) > 0) { - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadWeb()", msyystring_buffer, msyylineno); - return(-1); - } else { - return(0); /* end of a string, not an error */ - } + for (;;) { + switch (msyylex()) { + case (BROWSEFORMAT): /* change to use validation in 6.0 */ + free(web->browseformat); + web->browseformat = NULL; /* there is a default */ + if (getString(&web->browseformat) == MS_FAILURE) + return (-1); + break; + case (EMPTY): + if (getString(&web->empty) == MS_FAILURE) + return (-1); + break; + case (WEB): + break; /* for string loads */ + case (EOF): + msSetError(MS_EOFERR, NULL, "loadWeb()"); + return (-1); + case (END): + return (0); + break; + case (ERROR): + if (getString(&web->error) == MS_FAILURE) + return (-1); + break; + case (FOOTER): + if (getString(&web->footer) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (HEADER): + if (getString(&web->header) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (IMAGEPATH): + if (getString(&web->imagepath) == MS_FAILURE) + return (-1); + break; + case (TEMPPATH): + if (getString(&web->temppath) == MS_FAILURE) + return (-1); + break; + case (IMAGEURL): + if (getString(&web->imageurl) == MS_FAILURE) + return (-1); + break; + case (LEGENDFORMAT): /* change to use validation in 6.0 */ + free(web->legendformat); + web->legendformat = NULL; /* there is a default */ + if (getString(&web->legendformat) == MS_FAILURE) + return (-1); + break; + case (MAXSCALEDENOM): + if (getDouble(&web->maxscaledenom, MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MAXTEMPLATE): + if (getString(&web->maxtemplate) == MS_FAILURE) + return (-1); + break; + case (METADATA): + if (loadHashTable(&(web->metadata)) != MS_SUCCESS) + return (-1); + break; + case (MINSCALEDENOM): + if (getDouble(&web->minscaledenom, MS_NUM_CHECK_GTE, 0, -1) == -1) + return (-1); + break; + case (MINTEMPLATE): + if (getString(&web->mintemplate) == MS_FAILURE) + return (-1); + break; + case (QUERYFORMAT): /* change to use validation in 6.0 */ + free(web->queryformat); + web->queryformat = NULL; /* there is a default */ + if (getString(&web->queryformat) == MS_FAILURE) + return (-1); + break; + case (TEMPLATE): + if (getString(&web->template) == MS_FAILURE) + return (-1); /* getString() cleans up previously allocated string */ + break; + case (VALIDATION): + if (loadHashTable(&(web->validation)) != MS_SUCCESS) + return (-1); + break; + default: + if (strlen(msyystring_buffer) > 0) { + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "loadWeb()", msyystring_buffer, msyylineno); + return (-1); + } else { + return (0); /* end of a string, not an error */ + } } } } -int msUpdateWebFromString(webObj *web, char *string) -{ - if(!web || !string) return MS_FAILURE; +int msUpdateWebFromString(webObj *web, char *string) { + if (!web || !string) + return MS_FAILURE; - msAcquireLock( TLOCK_PARSER ); + msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_STRING; msyystring = string; @@ -5587,11 +6179,12 @@ int msUpdateWebFromString(webObj *web, char *string) msyylineno = 1; /* start at line 1 */ - if(loadWeb(web, web->map) == -1) { - msReleaseLock( TLOCK_PARSER ); - return MS_FAILURE; /* parse error */; + if (loadWeb(web, web->map) == -1) { + msReleaseLock(TLOCK_PARSER); + return MS_FAILURE; /* parse error */ + ; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msyylex_destroy(); return MS_SUCCESS; @@ -5604,9 +6197,8 @@ int msUpdateWebFromString(webObj *web, char *string) ** lots of other init methods in this file. */ -int initMap(mapObj *map) -{ - int i=0; +int initMap(mapObj *map) { + int i = 0; MS_REFCNT_INIT(map); map->debug = (int)msGetGlobalDebugLevel(); @@ -5617,14 +6209,16 @@ int initMap(mapObj *map) map->numlayers = 0; map->maxlayers = 0; map->layers = NULL; - map->layerorder = NULL; /* used to modify the order in which the layers are drawn */ + map->layerorder = + NULL; /* used to modify the order in which the layers are drawn */ map->status = MS_ON; map->name = msStrdup("MS"); - map->extent.minx = map->extent.miny = map->extent.maxx = map->extent.maxy = -1.0; + map->extent.minx = map->extent.miny = map->extent.maxx = map->extent.maxy = + -1.0; map->scaledenom = -1.0; - map->resolution = MS_DEFAULT_RESOLUTION; /* pixels per inch */ + map->resolution = MS_DEFAULT_RESOLUTION; /* pixels per inch */ map->defresolution = MS_DEFAULT_RESOLUTION; /* pixels per inch */ map->height = map->width = -1; @@ -5639,7 +6233,7 @@ int initMap(mapObj *map) map->mappath = NULL; map->sldurl = NULL; - MS_INIT_COLOR(map->imagecolor, 255,255,255,255); /* white */ + MS_INIT_COLOR(map->imagecolor, 255, 255, 255, 255); /* white */ map->numoutputformats = 0; map->outputformatlist = NULL; @@ -5652,8 +6246,9 @@ int initMap(mapObj *map) map->palette.numcolors = 0; - for(i=0; ilabelcache.slots[i].labels = NULL; /* cache is initialize at draw time */ + for (i = 0; i < MS_MAX_LABEL_PRIORITY; i++) { + map->labelcache.slots[i].labels = + NULL; /* cache is initialize at draw time */ map->labelcache.slots[i].cachesize = 0; map->labelcache.slots[i].numlabels = 0; map->labelcache.slots[i].markers = NULL; @@ -5668,7 +6263,7 @@ int initMap(mapObj *map) initHashTable(&(map->fontset.fonts)); msInitSymbolSet(&map->symbolset); - map->symbolset.fontset = &(map->fontset); + map->symbolset.fontset = &(map->fontset); map->symbolset.map = map; initLegend(&map->legend); @@ -5679,10 +6274,10 @@ int initMap(mapObj *map) map->projContext = msProjectionContextGetFromPool(); - if(msInitProjection(&(map->projection)) == -1) - return(-1); - if(msInitProjection(&(map->latlon)) == -1) - return(-1); + if (msInitProjection(&(map->projection)) == -1) + return (-1); + if (msInitProjection(&(map->latlon)) == -1) + return (-1); msProjectionSetContext(&(map->projection), map->projContext); msProjectionSetContext(&(map->latlon), map->projContext); @@ -5690,8 +6285,10 @@ int initMap(mapObj *map) /* initialize a default "geographic" projection */ map->latlon.numargs = 2; map->latlon.args[0] = msStrdup("proj=latlong"); - map->latlon.args[1] = msStrdup("ellps=WGS84"); /* probably want a different ellipsoid */ - if(msProcessProjection(&(map->latlon)) == -1) return(-1); + map->latlon.args[1] = + msStrdup("ellps=WGS84"); /* probably want a different ellipsoid */ + if (msProcessProjection(&(map->latlon)) == -1) + return (-1); map->templatepattern = map->datapattern = NULL; @@ -5706,7 +6303,7 @@ int initMap(mapObj *map) map->config = NULL; - return(0); + return (0); } /* @@ -5721,8 +6318,7 @@ int initMap(mapObj *map) ** ** Returns a reference to the new layerObj on success, NULL on error. */ -layerObj *msGrowMapLayers( mapObj *map ) -{ +layerObj *msGrowMapLayers(mapObj *map) { /* Do we need to increase the size of layers/layerorder by * MS_LAYER_ALLOCSIZE? */ @@ -5734,50 +6330,47 @@ layerObj *msGrowMapLayers( mapObj *map ) newsize = map->maxlayers + MS_LAYER_ALLOCSIZE; /* Alloc/realloc layers */ - newLayersPtr = (layerObj**)realloc(map->layers, - newsize*sizeof(layerObj*)); - MS_CHECK_ALLOC(newLayersPtr, newsize*sizeof(layerObj*), NULL); + newLayersPtr = + (layerObj **)realloc(map->layers, newsize * sizeof(layerObj *)); + MS_CHECK_ALLOC(newLayersPtr, newsize * sizeof(layerObj *), NULL); map->layers = newLayersPtr; /* Alloc/realloc layerorder */ - newLayerorderPtr = (int *)realloc(map->layerorder, - newsize*sizeof(int)); - MS_CHECK_ALLOC(newLayerorderPtr, newsize*sizeof(int), NULL); + newLayerorderPtr = (int *)realloc(map->layerorder, newsize * sizeof(int)); + MS_CHECK_ALLOC(newLayerorderPtr, newsize * sizeof(int), NULL); map->layerorder = newLayerorderPtr; map->maxlayers = newsize; - for(i=map->numlayers; imaxlayers; i++) { + for (i = map->numlayers; i < map->maxlayers; i++) { map->layers[i] = NULL; map->layerorder[i] = 0; } } - if (map->layers[map->numlayers]==NULL) { - map->layers[map->numlayers]=(layerObj*)calloc(1,sizeof(layerObj)); + if (map->layers[map->numlayers] == NULL) { + map->layers[map->numlayers] = (layerObj *)calloc(1, sizeof(layerObj)); MS_CHECK_ALLOC(map->layers[map->numlayers], sizeof(layerObj), NULL); } return map->layers[map->numlayers]; } - -int msFreeLabelCacheSlot(labelCacheSlotObj *cacheslot) -{ +int msFreeLabelCacheSlot(labelCacheSlotObj *cacheslot) { int i, j; /* free the labels */ if (cacheslot->labels) { - for(i=0; inumlabels; i++) { + for (i = 0; i < cacheslot->numlabels; i++) { - for(j=0; jlabels[i].numtextsymbols; j++) { + for (j = 0; j < cacheslot->labels[i].numtextsymbols; j++) { freeTextSymbol(cacheslot->labels[i].textsymbols[j]); free(cacheslot->labels[i].textsymbols[j]); } msFree(cacheslot->labels[i].textsymbols); - if(cacheslot->labels[i].leaderline) { + if (cacheslot->labels[i].leaderline) { msFree(cacheslot->labels[i].leaderline->point); msFree(cacheslot->labels[i].leaderline); msFree(cacheslot->labels[i].leaderbbox); @@ -5794,14 +6387,13 @@ int msFreeLabelCacheSlot(labelCacheSlotObj *cacheslot) cacheslot->markercachesize = 0; cacheslot->nummarkers = 0; - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msFreeLabelCache(labelCacheObj *cache) -{ +int msFreeLabelCache(labelCacheObj *cache) { int p; - for(p=0; pslots[p])) != MS_SUCCESS) return MS_FAILURE; } @@ -5812,32 +6404,36 @@ int msFreeLabelCache(labelCacheObj *cache) return MS_SUCCESS; } -int msInitLabelCacheSlot(labelCacheSlotObj *cacheslot) -{ +int msInitLabelCacheSlot(labelCacheSlotObj *cacheslot) { - if(cacheslot->labels || cacheslot->markers) + if (cacheslot->labels || cacheslot->markers) msFreeLabelCacheSlot(cacheslot); - cacheslot->labels = (labelCacheMemberObj *)malloc(sizeof(labelCacheMemberObj)*MS_LABELCACHEINITSIZE); - MS_CHECK_ALLOC(cacheslot->labels, sizeof(labelCacheMemberObj)*MS_LABELCACHEINITSIZE, MS_FAILURE); + cacheslot->labels = (labelCacheMemberObj *)malloc( + sizeof(labelCacheMemberObj) * MS_LABELCACHEINITSIZE); + MS_CHECK_ALLOC(cacheslot->labels, + sizeof(labelCacheMemberObj) * MS_LABELCACHEINITSIZE, + MS_FAILURE); cacheslot->cachesize = MS_LABELCACHEINITSIZE; cacheslot->numlabels = 0; - cacheslot->markers = (markerCacheMemberObj *)malloc(sizeof(markerCacheMemberObj)*MS_LABELCACHEINITSIZE); - MS_CHECK_ALLOC(cacheslot->markers, sizeof(markerCacheMemberObj)*MS_LABELCACHEINITSIZE, MS_FAILURE); + cacheslot->markers = (markerCacheMemberObj *)malloc( + sizeof(markerCacheMemberObj) * MS_LABELCACHEINITSIZE); + MS_CHECK_ALLOC(cacheslot->markers, + sizeof(markerCacheMemberObj) * MS_LABELCACHEINITSIZE, + MS_FAILURE); cacheslot->markercachesize = MS_LABELCACHEINITSIZE; cacheslot->nummarkers = 0; - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msInitLabelCache(labelCacheObj *cache) -{ +int msInitLabelCache(labelCacheObj *cache) { int p; - for(p=0; pslots[p])) != MS_SUCCESS) return MS_FAILURE; } @@ -5848,8 +6444,7 @@ int msInitLabelCache(labelCacheObj *cache) return MS_SUCCESS; } -static void writeMap(FILE *stream, int indent, mapObj *map) -{ +static void writeMap(FILE *stream, int indent, mapObj *map) { int i; colorObj c; @@ -5860,7 +6455,7 @@ static void writeMap(FILE *stream, int indent, mapObj *map) writeNumber(stream, indent, "DEFRESOLUTION", 72.0, map->defresolution); writeExtent(stream, indent, "EXTENT", map->extent); writeString(stream, indent, "FONTSET", NULL, map->fontset.filename); - MS_INIT_COLOR(c,255,255,255,255); + MS_INIT_COLOR(c, 255, 255, 255, 255); writeColor(stream, indent, "IMAGECOLOR", &c, &(map->imagecolor)); writeString(stream, indent, "IMAGETYPE", NULL, map->imagetype); writeNumber(stream, indent, "MAXSIZE", MS_MAXIMAGESIZE_DEFAULT, map->maxsize); @@ -5868,16 +6463,21 @@ static void writeMap(FILE *stream, int indent, mapObj *map) writeNumber(stream, indent, "RESOLUTION", 72.0, map->resolution); writeString(stream, indent, "SHAPEPATH", NULL, map->shapepath); writeDimension(stream, indent, "SIZE", map->width, map->height, NULL, NULL); - writeKeyword(stream, indent, "STATUS", map->status, 2, MS_ON, "ON", MS_OFF, "OFF"); + writeKeyword(stream, indent, "STATUS", map->status, 2, MS_ON, "ON", MS_OFF, + "OFF"); writeString(stream, indent, "SYMBOLSET", NULL, map->symbolset.filename); - writeKeyword(stream, indent, "UNITS", map->units, 7, MS_INCHES, "INCHES", MS_FEET ,"FEET", MS_MILES, "MILES", MS_METERS, "METERS", MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", MS_DD, "DD"); + writeKeyword(stream, indent, "UNITS", map->units, 7, MS_INCHES, "INCHES", + MS_FEET, "FEET", MS_MILES, "MILES", MS_METERS, "METERS", + MS_KILOMETERS, "KILOMETERS", MS_NAUTICALMILES, "NAUTICALMILES", + MS_DD, "DD"); writeLineFeed(stream); writeOutputformat(stream, indent, map); /* write symbol with INLINE tag in mapfile */ - for(i=0; isymbolset.numsymbols; i++) { - if(map->symbolset.symbol[i]->inmapfile) writeSymbol(map->symbolset.symbol[i], stream); + for (i = 0; i < map->symbolset.numsymbols; i++) { + if (map->symbolset.symbol[i]->inmapfile) + writeSymbol(map->symbolset.symbol[i], stream); } writeProjection(stream, indent, &(map->projection)); @@ -5888,15 +6488,14 @@ static void writeMap(FILE *stream, int indent, mapObj *map) writeScalebar(stream, indent, &(map->scalebar)); writeWeb(stream, indent, &(map->web)); - for(i=0; inumlayers; i++) + for (i = 0; i < map->numlayers; i++) writeLayer(stream, indent, GET_LAYER(map, map->layerorder[i])); writeBlockEnd(stream, indent, "MAP"); } -char* msWriteMapToString(mapObj *map) -{ - msIOContext context; +char *msWriteMapToString(mapObj *map) { + msIOContext context; msIOBuffer buffer; context.label = NULL; @@ -5907,294 +6506,333 @@ char* msWriteMapToString(mapObj *map) buffer.data_len = 0; buffer.data_offset = 0; - msIO_installHandlers( NULL, &context, NULL ); + msIO_installHandlers(NULL, &context, NULL); writeMap(stdout, 0, map); - msIO_bufferWrite( &buffer, "", 1 ); + msIO_bufferWrite(&buffer, "", 1); - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); - return (char*)buffer.data; + return (char *)buffer.data; } -int msSaveMap(mapObj *map, char *filename) -{ +int msSaveMap(mapObj *map, char *filename) { FILE *stream; char szPath[MS_MAXPATHLEN]; - if(!map) { + if (!map) { msSetError(MS_MISCERR, "Map is undefined.", "msSaveMap()"); - return(-1); + return (-1); } - if(!filename) { + if (!filename) { msSetError(MS_MISCERR, "Filename is undefined.", "msSaveMap()"); - return(-1); + return (-1); } stream = fopen(msBuildPath(szPath, map->mappath, filename), "w"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "msSaveMap()", filename); - return(-1); + return (-1); } writeMap(stream, 0, map); fclose(stream); - return(0); + return (0); } -static void writeConfig(FILE *stream, int indent, configObj *config) -{ +static void writeConfig(FILE *stream, int indent, configObj *config) { writeBlockBegin(stream, indent, "CONFIG"); writeHashTable(stream, indent, "ENV", &(config->env)); writeHashTable(stream, indent, "MAPS", &(config->maps)); writeBlockEnd(stream, indent, "CONFIG"); } -int msSaveConfig(configObj *config, const char *filename) -{ +int msSaveConfig(configObj *config, const char *filename) { FILE *stream; - if(!config) { + if (!config) { msSetError(MS_MISCERR, "Config is undefined.", "msSaveConfigMap()"); - return(-1); + return (-1); } - if(!filename) { + if (!filename) { msSetError(MS_MISCERR, "Filename is undefined.", "msSaveConfigMap()"); - return(-1); + return (-1); } stream = fopen(filename, "w"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "msSaveConfig()", filename); - return(-1); + return (-1); } - writeConfig(stream,0,config); + writeConfig(stream, 0, config); fclose(stream); - return(0); + return (0); } -static int loadMapInternal(mapObj *map) -{ - int foundMapToken=MS_FALSE; +static int loadMapInternal(mapObj *map) { + int foundMapToken = MS_FALSE; int foundBomToken = MS_FALSE; int token; - for(;;) { + for (;;) { token = msyylex(); - if(!foundBomToken && token == BOM) { + if (!foundBomToken && token == BOM) { foundBomToken = MS_TRUE; - if(!foundMapToken) { + if (!foundMapToken) { continue; /*skip a leading bom*/ } } - if(!foundMapToken && token != MAP) { - msSetError(MS_IDENTERR, "First token must be MAP, this doesn't look like a mapfile.", "msLoadMap()"); - return(MS_FAILURE); + if (!foundMapToken && token != MAP) { + msSetError(MS_IDENTERR, + "First token must be MAP, this doesn't look like a mapfile.", + "msLoadMap()"); + return (MS_FAILURE); } - switch(token) { + switch (token) { - case(CONFIG): { - char *key=NULL, *value=NULL; + case (CONFIG): { + char *key = NULL, *value = NULL; - if( getString(&key) == MS_FAILURE ) - return MS_FAILURE; + if (getString(&key) == MS_FAILURE) + return MS_FAILURE; - if( getString(&value) == MS_FAILURE ) { - free(key); - return MS_FAILURE; - } + if (getString(&value) == MS_FAILURE) { + free(key); + return MS_FAILURE; + } - if (msSetConfigOption( map, key, value ) == MS_FAILURE) { - free(key); - free(value); - return MS_FAILURE; - } + if (msSetConfigOption(map, key, value) == MS_FAILURE) { + free(key); + free(value); + return MS_FAILURE; + } - free( key ); - free( value ); + free(key); + free(value); + } break; + case (DEBUG): + if ((map->debug = getSymbol(3, MS_ON, MS_OFF, MS_NUMBER)) == -1) + return MS_FAILURE; + if (map->debug == MS_NUMBER) { + if (msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { + msSetError(MS_MISCERR, + "Invalid DEBUG level, must be between 0 and 5 (line %d)", + "msLoadMap()", msyylineno); + return (-1); + } + map->debug = (int)msyynumber; } break; - case(DEBUG): - if((map->debug = getSymbol(3, MS_ON,MS_OFF, MS_NUMBER)) == -1) return MS_FAILURE; - if(map->debug == MS_NUMBER) { - if(msCheckNumber(msyynumber, MS_NUM_CHECK_RANGE, 0, 5) == MS_FAILURE) { - msSetError(MS_MISCERR, "Invalid DEBUG level, must be between 0 and 5 (line %d)", "msLoadMap()", msyylineno); - return(-1); - } - map->debug = (int) msyynumber; - } - break; - case(END): - if(msyyin) { - fclose(msyyin); - msyyin = NULL; - } - - /*** Make config options current ***/ - msApplyMapConfigOptions( map ); + case (END): + if (msyyin) { + fclose(msyyin); + msyyin = NULL; + } - /*** Compute rotated extent info if applicable ***/ - msMapComputeGeotransform( map ); + /*** Make config options current ***/ + msApplyMapConfigOptions(map); - /*** OUTPUTFORMAT related setup ***/ - if( msPostMapParseOutputFormatSetup( map ) == MS_FAILURE ) - return MS_FAILURE; + /*** Compute rotated extent info if applicable ***/ + msMapComputeGeotransform(map); - if(loadSymbolSet(&(map->symbolset), map) == -1) return MS_FAILURE; + /*** OUTPUTFORMAT related setup ***/ + if (msPostMapParseOutputFormatSetup(map) == MS_FAILURE) + return MS_FAILURE; - if (resolveSymbolNames(map) == MS_FAILURE) return MS_FAILURE; + if (loadSymbolSet(&(map->symbolset), map) == -1) + return MS_FAILURE; + if (resolveSymbolNames(map) == MS_FAILURE) + return MS_FAILURE; - if(msLoadFontSet(&(map->fontset), map) == -1) return MS_FAILURE; + if (msLoadFontSet(&(map->fontset), map) == -1) + return MS_FAILURE; - return MS_SUCCESS; - break; - case(EOF): - msSetError(MS_EOFERR, NULL, "msLoadMap()"); + return MS_SUCCESS; + break; + case (EOF): + msSetError(MS_EOFERR, NULL, "msLoadMap()"); + return MS_FAILURE; + case (EXTENT): { + if (getDouble(&(map->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return MS_FAILURE; + if (getDouble(&(map->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) + return MS_FAILURE; + if (getDouble(&(map->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) + return MS_FAILURE; + if (getDouble(&(map->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) + return MS_FAILURE; + if (!MS_VALID_EXTENT(map->extent)) { + msSetError(MS_MISCERR, + "Given map extent is invalid. Check that it " + "is in the form: minx, miny, maxx, maxy", + "loadMapInternal()"); return MS_FAILURE; - case(EXTENT): { - if(getDouble(&(map->extent.minx), MS_NUM_CHECK_NONE, -1, -1) == -1) return MS_FAILURE; - if(getDouble(&(map->extent.miny), MS_NUM_CHECK_NONE, -1, -1) == -1) return MS_FAILURE; - if(getDouble(&(map->extent.maxx), MS_NUM_CHECK_NONE, -1, -1) == -1) return MS_FAILURE; - if(getDouble(&(map->extent.maxy), MS_NUM_CHECK_NONE, -1, -1) == -1) return MS_FAILURE; - if (!MS_VALID_EXTENT(map->extent)) { - msSetError(MS_MISCERR, "Given map extent is invalid. Check that it " \ - "is in the form: minx, miny, maxx, maxy", "loadMapInternal()"); - return MS_FAILURE; - } } + } break; + case (ANGLE): { + double rotation_angle; + if (getDouble(&(rotation_angle), MS_NUM_CHECK_RANGE, -360, 360) == -1) + return MS_FAILURE; + msMapSetRotation(map, rotation_angle); + } break; + case (FONTSET): + if (getString(&map->fontset.filename) == MS_FAILURE) + return MS_FAILURE; + break; + case (IMAGECOLOR): + if (loadColor(&(map->imagecolor), NULL) != MS_SUCCESS) + return MS_FAILURE; + break; + case (IMAGETYPE): + msFree(map->imagetype); + map->imagetype = getToken(); + break; + case (LATLON): + if (loadProjection(&map->latlon) == -1) + return MS_FAILURE; + break; + case (LAYER): + if (msGrowMapLayers(map) == NULL) + return MS_FAILURE; + if (initLayer((GET_LAYER(map, map->numlayers)), map) == -1) + return MS_FAILURE; + if (loadLayer((GET_LAYER(map, map->numlayers)), map) == -1) + return MS_FAILURE; + GET_LAYER(map, map->numlayers)->index = + map->numlayers; /* save the index */ + /* Update the layer order list with the layer's index. */ + map->layerorder[map->numlayers] = map->numlayers; + map->numlayers++; + break; + case (OUTPUTFORMAT): + if (loadOutputFormat(map) == -1) + return MS_FAILURE; + break; + case (LEGEND): + if (loadLegend(&(map->legend), map) == -1) + return MS_FAILURE; + break; + case (MAP): + foundMapToken = MS_TRUE; + break; + case (MAXSIZE): + if (getInteger(&(map->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) + return MS_FAILURE; break; - case(ANGLE): { - double rotation_angle; - if(getDouble(&(rotation_angle), MS_NUM_CHECK_RANGE, -360, 360) == -1) return MS_FAILURE; - msMapSetRotation( map, rotation_angle ); + case (NAME): + free(map->name); + map->name = NULL; /* erase default */ + if (getString(&map->name) == MS_FAILURE) + return MS_FAILURE; + break; + case (PROJECTION): + if (loadProjection(&map->projection) == -1) + return MS_FAILURE; + break; + case (QUERYMAP): + if (loadQueryMap(&(map->querymap), map) == -1) + return MS_FAILURE; + break; + case (REFERENCE): + if (loadReferenceMap(&(map->reference), map) == -1) + return MS_FAILURE; + break; + case (RESOLUTION): + if (getDouble(&(map->resolution), MS_NUM_CHECK_RANGE, MS_RESOLUTION_MIN, + MS_RESOLUTION_MAX) == -1) + return MS_FAILURE; + break; + case (DEFRESOLUTION): + if (getDouble(&(map->defresolution), MS_NUM_CHECK_RANGE, + MS_RESOLUTION_MIN, MS_RESOLUTION_MAX) == -1) + return MS_FAILURE; + break; + case (SCALE): + case (SCALEDENOM): + if (getDouble(&(map->scaledenom), MS_NUM_CHECK_GTE, 1, -1) == -1) + return MS_FAILURE; + break; + case (SCALEBAR): + if (loadScalebar(&(map->scalebar)) == -1) + return MS_FAILURE; + break; + case (SHAPEPATH): + if (getString(&map->shapepath) == MS_FAILURE) + return MS_FAILURE; + break; + case (SIZE): + if (getInteger(&(map->width), MS_NUM_CHECK_RANGE, 1, map->maxsize) == -1) + return MS_FAILURE; + if (getInteger(&(map->height), MS_NUM_CHECK_RANGE, 1, map->maxsize) == -1) + return MS_FAILURE; + break; + case (STATUS): + if ((map->status = getSymbol(2, MS_ON, MS_OFF)) == -1) + return MS_FAILURE; + break; + case (SYMBOL): + if (msGrowSymbolSet(&(map->symbolset)) == NULL) + return MS_FAILURE; + if ((loadSymbol(map->symbolset.symbol[map->symbolset.numsymbols], + map->mappath) == -1)) { + msFreeSymbol(map->symbolset.symbol[map->symbolset.numsymbols]); + free(map->symbolset.symbol[map->symbolset.numsymbols]); + map->symbolset.symbol[map->symbolset.numsymbols] = NULL; + return MS_FAILURE; } + map->symbolset.symbol[map->symbolset.numsymbols]->inmapfile = MS_TRUE; + map->symbolset.numsymbols++; break; - case(FONTSET): - if(getString(&map->fontset.filename) == MS_FAILURE) return MS_FAILURE; - break; - case(IMAGECOLOR): - if(loadColor(&(map->imagecolor), NULL) != MS_SUCCESS) return MS_FAILURE; - break; - case(IMAGETYPE): - msFree(map->imagetype); - map->imagetype = getToken(); - break; - case(LATLON): - if(loadProjection(&map->latlon) == -1) return MS_FAILURE; - break; - case(LAYER): - if(msGrowMapLayers(map) == NULL) - return MS_FAILURE; - if(initLayer((GET_LAYER(map, map->numlayers)), map) == -1) return MS_FAILURE; - if(loadLayer((GET_LAYER(map, map->numlayers)), map) == -1) return MS_FAILURE; - GET_LAYER(map, map->numlayers)->index = map->numlayers; /* save the index */ - /* Update the layer order list with the layer's index. */ - map->layerorder[map->numlayers] = map->numlayers; - map->numlayers++; - break; - case(OUTPUTFORMAT): - if(loadOutputFormat(map) == -1) return MS_FAILURE; - break; - case(LEGEND): - if(loadLegend(&(map->legend), map) == -1) return MS_FAILURE; - break; - case(MAP): - foundMapToken = MS_TRUE; - break; - case(MAXSIZE): - if(getInteger(&(map->maxsize), MS_NUM_CHECK_GT, 0, -1) == -1) return MS_FAILURE; - break; - case(NAME): - free(map->name); - map->name = NULL; /* erase default */ - if(getString(&map->name) == MS_FAILURE) return MS_FAILURE; - break; - case(PROJECTION): - if(loadProjection(&map->projection) == -1) return MS_FAILURE; - break; - case(QUERYMAP): - if(loadQueryMap(&(map->querymap), map) == -1) return MS_FAILURE; - break; - case(REFERENCE): - if(loadReferenceMap(&(map->reference), map) == -1) return MS_FAILURE; - break; - case(RESOLUTION): - if(getDouble(&(map->resolution), MS_NUM_CHECK_RANGE, MS_RESOLUTION_MIN, MS_RESOLUTION_MAX) == -1) return MS_FAILURE; - break; - case(DEFRESOLUTION): - if(getDouble(&(map->defresolution), MS_NUM_CHECK_RANGE, MS_RESOLUTION_MIN, MS_RESOLUTION_MAX) == -1) return MS_FAILURE; - break; - case(SCALE): - case(SCALEDENOM): - if(getDouble(&(map->scaledenom), MS_NUM_CHECK_GTE, 1, -1) == -1) return MS_FAILURE; - break; - case(SCALEBAR): - if(loadScalebar(&(map->scalebar)) == -1) return MS_FAILURE; - break; - case(SHAPEPATH): - if(getString(&map->shapepath) == MS_FAILURE) return MS_FAILURE; - break; - case(SIZE): - if(getInteger(&(map->width), MS_NUM_CHECK_RANGE, 1, map->maxsize) == -1) return MS_FAILURE; - if(getInteger(&(map->height), MS_NUM_CHECK_RANGE, 1, map->maxsize) == -1) return MS_FAILURE; - break; - case(STATUS): - if((map->status = getSymbol(2, MS_ON,MS_OFF)) == -1) return MS_FAILURE; - break; - case(SYMBOL): - if(msGrowSymbolSet(&(map->symbolset)) == NULL) - return MS_FAILURE; - if((loadSymbol(map->symbolset.symbol[map->symbolset.numsymbols], map->mappath) == -1)) { - msFreeSymbol(map->symbolset.symbol[map->symbolset.numsymbols]); - free(map->symbolset.symbol[map->symbolset.numsymbols]); - map->symbolset.symbol[map->symbolset.numsymbols] = NULL; - return MS_FAILURE; - } - map->symbolset.symbol[map->symbolset.numsymbols]->inmapfile = MS_TRUE; - map->symbolset.numsymbols++; - break; - case(SYMBOLSET): - if(getString(&map->symbolset.filename) == MS_FAILURE) return MS_FAILURE; - break; - case(UNITS): - if((int)(map->units = getSymbol(7, MS_INCHES,MS_FEET,MS_MILES,MS_METERS,MS_KILOMETERS,MS_NAUTICALMILES,MS_DD)) == -1) return MS_FAILURE; - break; - case(WEB): - if(loadWeb(&(map->web), map) == -1) return MS_FAILURE; - break; - default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "msLoadMap()", msyystring_buffer, msyylineno); + case (SYMBOLSET): + if (getString(&map->symbolset.filename) == MS_FAILURE) + return MS_FAILURE; + break; + case (UNITS): + if ((int)(map->units = + getSymbol(7, MS_INCHES, MS_FEET, MS_MILES, MS_METERS, + MS_KILOMETERS, MS_NAUTICALMILES, MS_DD)) == -1) + return MS_FAILURE; + break; + case (WEB): + if (loadWeb(&(map->web), map) == -1) return MS_FAILURE; + break; + default: + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "msLoadMap()", msyystring_buffer, msyylineno); + return MS_FAILURE; } } /* next token */ } -static bool msGetCWD(char* szBuffer, size_t nBufferSize, const char* pszFunctionName) -{ - if(NULL == getcwd(szBuffer, nBufferSize)) { +static bool msGetCWD(char *szBuffer, size_t nBufferSize, + const char *pszFunctionName) { + if (NULL == getcwd(szBuffer, nBufferSize)) { #ifndef _WIN32 - if( errno == EACCES ) - msSetError(MS_MISCERR, - "getcwd() failed with EACCES: you may need to force the " - "current directory in the mapserver launcher " - "(e.g -d option of spawn-fcgi)", pszFunctionName); - else if( errno == ENAMETOOLONG ) - msSetError(MS_MISCERR, "getcwd() returned a too long path", - pszFunctionName); + if (errno == EACCES) + msSetError(MS_MISCERR, + "getcwd() failed with EACCES: you may need to force the " + "current directory in the mapserver launcher " + "(e.g -d option of spawn-fcgi)", + pszFunctionName); + else if (errno == ENAMETOOLONG) + msSetError(MS_MISCERR, "getcwd() returned a too long path", + pszFunctionName); else - msSetError(MS_MISCERR, "getcwd() failed with errno code %d", - pszFunctionName, errno); + msSetError(MS_MISCERR, "getcwd() failed with errno code %d", + pszFunctionName, errno); #else - msSetError(MS_MISCERR, "getcwd() returned a too long path", pszFunctionName); + msSetError(MS_MISCERR, "getcwd() returned a too long path", + pszFunctionName); #endif return FALSE; } @@ -6202,14 +6840,15 @@ static bool msGetCWD(char* szBuffer, size_t nBufferSize, const char* pszFunction } /* -** Sets up string-based mapfile loading and calls loadMapInternal to do the work. +** Sets up string-based mapfile loading and calls loadMapInternal to do the +*work. */ -mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *config) -{ +mapObj *msLoadMapFromString(char *buffer, char *new_mappath, + const configObj *config) { mapObj *map; struct mstimeval starttime = {0}, endtime = {0}; char szPath[MS_MAXPATHLEN], szCWDPath[MS_MAXPATHLEN]; - char *mappath=NULL; + char *mappath = NULL; int debuglevel; debuglevel = (int)msGetGlobalDebugLevel(); @@ -6219,25 +6858,26 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *co msGettimeofday(&starttime, NULL); } - if(!buffer) { + if (!buffer) { msSetError(MS_MISCERR, "No buffer to load.", "msLoadMapFromString()"); - return(NULL); + return (NULL); } /* ** Allocate mapObj structure */ - map = (mapObj *)calloc(sizeof(mapObj),1); + map = (mapObj *)calloc(sizeof(mapObj), 1); MS_CHECK_ALLOC(map, sizeof(mapObj), NULL); - if(initMap(map) == -1) { /* initialize this map */ + if (initMap(map) == -1) { /* initialize this map */ msFreeMap(map); - return(NULL); + return (NULL); } map->config = config; // create a read-only reference - - msAcquireLock( TLOCK_PARSER ); /* might need to move this lock a bit higher, yup (bug 2108) */ + + msAcquireLock(TLOCK_PARSER); /* might need to move this lock a bit higher, yup + (bug 2108) */ msyystate = MS_TOKENIZE_STRING; msyystring = buffer; @@ -6246,9 +6886,9 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *co msyylineno = 1; /* start at line 1 (do lines mean anything here?) */ /* If new_mappath is provided then use it, otherwise use the CWD */ - if(!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMapFromString()")) { + if (!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMapFromString()")) { msFreeMap(map); - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); } if (new_mappath) { mappath = msStrdup(new_mappath); @@ -6258,27 +6898,30 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *co msyybasepath = map->mappath; /* for INCLUDEs */ - if(loadMapInternal(map) != MS_SUCCESS) { + if (loadMapInternal(map) != MS_SUCCESS) { msFreeMap(map); - msReleaseLock( TLOCK_PARSER ); - if(mappath != NULL) free(mappath); + msReleaseLock(TLOCK_PARSER); + if (mappath != NULL) + free(mappath); return NULL; } - if (mappath != NULL) free(mappath); + if (mappath != NULL) + free(mappath); msyylex_destroy(); - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); if (debuglevel >= MS_DEBUGLEVEL_TUNING) { /* In debug mode, report time spent loading/parsing mapfile. */ msGettimeofday(&endtime, NULL); msDebug("msLoadMap(): %.3fs\n", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } - if (resolveSymbolNames(map) == MS_FAILURE) return NULL; + if (resolveSymbolNames(map) == MS_FAILURE) + return NULL; return map; } @@ -6286,10 +6929,10 @@ mapObj *msLoadMapFromString(char *buffer, char *new_mappath, const configObj *co /* ** Sets up file-based mapfile loading and calls loadMapInternal to do the work. */ -mapObj *msLoadMap(const char *filename, const char *new_mappath, const configObj *config) -{ +mapObj *msLoadMap(const char *filename, const char *new_mappath, + const configObj *config) { mapObj *map; - struct mstimeval starttime={0}, endtime={0}; + struct mstimeval starttime = {0}, endtime = {0}; char szPath[MS_MAXPATHLEN], szCWDPath[MS_MAXPATHLEN]; int debuglevel; @@ -6300,57 +6943,62 @@ mapObj *msLoadMap(const char *filename, const char *new_mappath, const configObj msGettimeofday(&starttime, NULL); } - if(!filename) { + if (!filename) { msSetError(MS_MISCERR, "Filename is undefined.", "msLoadMap()"); - return(NULL); + return (NULL); } - const char *ms_mapfile_pattern = CPLGetConfigOption("MS_MAPFILE_PATTERN", MS_DEFAULT_MAPFILE_PATTERN); - if(msEvalRegex(ms_mapfile_pattern, filename) != MS_TRUE) { - msSetError(MS_REGEXERR, "Filename validation failed." , "msLoadMap()"); - return(NULL); + const char *ms_mapfile_pattern = + CPLGetConfigOption("MS_MAPFILE_PATTERN", MS_DEFAULT_MAPFILE_PATTERN); + if (msEvalRegex(ms_mapfile_pattern, filename) != MS_TRUE) { + msSetError(MS_REGEXERR, "Filename validation failed.", "msLoadMap()"); + return (NULL); } /* ** Allocate mapObj structure */ - map = (mapObj *)calloc(sizeof(mapObj),1); + map = (mapObj *)calloc(sizeof(mapObj), 1); MS_CHECK_ALLOC(map, sizeof(mapObj), NULL); - if(initMap(map) == -1) { /* initialize this map */ + if (initMap(map) == -1) { /* initialize this map */ msFreeMap(map); - return(NULL); + return (NULL); } map->config = config; // create a read-only reference - msAcquireLock( TLOCK_PARSER ); /* Steve: might need to move this lock a bit higher; Umberto: done */ + msAcquireLock(TLOCK_PARSER); /* Steve: might need to move this lock a bit + higher; Umberto: done */ #ifdef USE_XMLMAPFILE /* If the mapfile is an xml mapfile, transform it */ - const char *ms_xmlmapfile_xslt = CPLGetConfigOption("MS_XMLMAPFILE_XSLT", NULL); + const char *ms_xmlmapfile_xslt = + CPLGetConfigOption("MS_XMLMAPFILE_XSLT", NULL); if (ms_xmlmapfile_xslt && (msEvalRegex(MS_DEFAULT_XMLMAPFILE_PATTERN, filename) == MS_TRUE)) { msyyin = tmpfile(); if (msyyin == NULL) { - msSetError(MS_IOERR, "tmpfile() failed to create temporary file", "msLoadMap()"); - msReleaseLock( TLOCK_PARSER ); + msSetError(MS_IOERR, "tmpfile() failed to create temporary file", + "msLoadMap()"); + msReleaseLock(TLOCK_PARSER); msFreeMap(map); return NULL; } - if (msTransformXmlMapfile(ms_xmlmapfile_xslt, filename, msyyin) != MS_SUCCESS) { + if (msTransformXmlMapfile(ms_xmlmapfile_xslt, filename, msyyin) != + MS_SUCCESS) { fclose(msyyin); msFreeMap(map); return NULL; } - fseek ( msyyin , 0 , SEEK_SET ); + fseek(msyyin, 0, SEEK_SET); } else { #endif - if((msyyin = fopen(filename,"r")) == NULL) { + if ((msyyin = fopen(filename, "r")) == NULL) { msSetError(MS_IOERR, "(%s)", "msLoadMap()", filename); - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); msFreeMap(map); return NULL; } @@ -6366,8 +7014,8 @@ mapObj *msLoadMap(const char *filename, const char *new_mappath, const configObj /* If new_mappath is provided then use it, otherwise use the location */ /* of the mapfile as the default path */ - if(!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMap()")) { - msReleaseLock( TLOCK_PARSER ); + if (!msGetCWD(szCWDPath, MS_MAXPATHLEN, "msLoadMap()")) { + msReleaseLock(TLOCK_PARSER); msFreeMap(map); return NULL; } @@ -6377,41 +7025,42 @@ mapObj *msLoadMap(const char *filename, const char *new_mappath, const configObj else { char *path = msGetPath(filename); map->mappath = msStrdup(msBuildPath(szPath, szCWDPath, path)); - free( path ); + free(path); } msyybasepath = map->mappath; /* for INCLUDEs */ - if(loadMapInternal(map) != MS_SUCCESS) { + if (loadMapInternal(map) != MS_SUCCESS) { msFreeMap(map); - msReleaseLock( TLOCK_PARSER ); - if( msyyin ) { + msReleaseLock(TLOCK_PARSER); + if (msyyin) { msyycleanup_includes(); fclose(msyyin); msyyin = NULL; } return NULL; } - msReleaseLock( TLOCK_PARSER ); + msReleaseLock(TLOCK_PARSER); if (debuglevel >= MS_DEBUGLEVEL_TUNING) { /* In debug mode, report time spent loading/parsing mapfile. */ msGettimeofday(&endtime, NULL); msDebug("msLoadMap(): %.3fs\n", - (endtime.tv_sec+endtime.tv_usec/1.0e6)- - (starttime.tv_sec+starttime.tv_usec/1.0e6) ); + (endtime.tv_sec + endtime.tv_usec / 1.0e6) - + (starttime.tv_sec + starttime.tv_usec / 1.0e6)); } return map; } -static void hashTableSubstituteString(hashTableObj *hash, const char *from, const char *to) { +static void hashTableSubstituteString(hashTableObj *hash, const char *from, + const char *to) { const char *key, *val; char *new_val; key = msFirstKeyFromHashTable(hash); - while(key != NULL) { + while (key != NULL) { val = msLookupHashTable(hash, key); - if(strcasestr(val, from)) { + if (strcasestr(val, from)) { new_val = msCaseReplaceSubstring(msStrdup(val), from, to); msInsertHashTable(hash, key, new_val); msFree(new_val); @@ -6420,66 +7069,81 @@ static void hashTableSubstituteString(hashTableObj *hash, const char *from, cons } } -static void classSubstituteString(classObj *class, const char *from, const char *to) { - if(class->expression.string) class->expression.string = msCaseReplaceSubstring(class->expression.string, from, to); - if(class->text.string) class->text.string = msCaseReplaceSubstring(class->text.string, from, to); - if(class->title) class->title = msCaseReplaceSubstring(class->title, from, to); +static void classSubstituteString(classObj *class, const char *from, + const char *to) { + if (class->expression.string) + class->expression.string = + msCaseReplaceSubstring(class->expression.string, from, to); + if (class->text.string) + class->text.string = msCaseReplaceSubstring(class->text.string, from, to); + if (class->title) + class->title = msCaseReplaceSubstring(class->title, from, to); } - -static void layerSubstituteString(layerObj *layer, const char *from, const char *to) -{ +static void layerSubstituteString(layerObj *layer, const char *from, + const char *to) { int c; - if(layer->data) layer->data = msCaseReplaceSubstring(layer->data, from, to); - if(layer->tileindex) layer->tileindex = msCaseReplaceSubstring(layer->tileindex, from, to); - if(layer->connection) layer->connection = msCaseReplaceSubstring(layer->connection, from, to); - if(layer->filter.string) layer->filter.string = msCaseReplaceSubstring(layer->filter.string, from, to); - if(layer->mask) layer->mask = msCaseReplaceSubstring(layer->mask, from, to); // new for 8.0 - - /* The bindvalues are most useful when able to substitute values from the URL */ + if (layer->data) + layer->data = msCaseReplaceSubstring(layer->data, from, to); + if (layer->tileindex) + layer->tileindex = msCaseReplaceSubstring(layer->tileindex, from, to); + if (layer->connection) + layer->connection = msCaseReplaceSubstring(layer->connection, from, to); + if (layer->filter.string) + layer->filter.string = + msCaseReplaceSubstring(layer->filter.string, from, to); + if (layer->mask) + layer->mask = msCaseReplaceSubstring(layer->mask, from, to); // new for 8.0 + + /* The bindvalues are most useful when able to substitute values from the URL + */ hashTableSubstituteString(&layer->bindvals, from, to); hashTableSubstituteString(&layer->metadata, from, to); - msLayerSubstituteProcessing( layer, from, to ); - for(c=0; cnumclasses;c++) { + msLayerSubstituteProcessing(layer, from, to); + for (c = 0; c < layer->numclasses; c++) { classSubstituteString(layer->class[c], from, to); } } static void mapSubstituteString(mapObj *map, const char *from, const char *to) { int l; - for(l=0;lnumlayers; l++) { - layerSubstituteString(GET_LAYER(map,l), from, to); + for (l = 0; l < map->numlayers; l++) { + layerSubstituteString(GET_LAYER(map, l), from, to); } /* output formats (#3751) */ - for(l=0; lnumoutputformats; l++) { + for (l = 0; l < map->numoutputformats; l++) { int o; - for(o=0; ooutputformatlist[l]->numformatoptions; o++) { - map->outputformatlist[l]->formatoptions[o] = msCaseReplaceSubstring(map->outputformatlist[l]->formatoptions[o], from, to); + for (o = 0; o < map->outputformatlist[l]->numformatoptions; o++) { + map->outputformatlist[l]->formatoptions[o] = msCaseReplaceSubstring( + map->outputformatlist[l]->formatoptions[o], from, to); } } hashTableSubstituteString(&map->web.metadata, from, to); - if(map->web.template) map->web.template = msCaseReplaceSubstring(map->web.template, from, to); + if (map->web.template) + map->web.template = msCaseReplaceSubstring(map->web.template, from, to); } -static void applyOutputFormatDefaultSubstitutions(outputFormatObj *format, const char *option, hashTableObj *table) -{ +static void applyOutputFormatDefaultSubstitutions(outputFormatObj *format, + const char *option, + hashTableObj *table) { const char *filename; filename = msGetOutputFormatOption(format, option, NULL); - if(filename && strlen(filename)>0) { + if (filename && strlen(filename) > 0) { char *tmpfilename = msStrdup(filename); const char *default_key = msFirstKeyFromHashTable(table); - while(default_key) { - if(!strncasecmp(default_key,"default_",8)) { + while (default_key) { + if (!strncasecmp(default_key, "default_", 8)) { char *new_filename = NULL; - size_t buffer_size = (strlen(default_key)-5); + size_t buffer_size = (strlen(default_key) - 5); char *tag = (char *)msSmallMalloc(buffer_size); snprintf(tag, buffer_size, "%%%s%%", &(default_key[8])); new_filename = msStrdup(tmpfilename); - new_filename = msCaseReplaceSubstring(new_filename, tag, msLookupHashTable(table, default_key)); + new_filename = msCaseReplaceSubstring( + new_filename, tag, msLookupHashTable(table, default_key)); free(tag); msSetOutputFormatOption(format, option, new_filename); @@ -6492,12 +7156,12 @@ static void applyOutputFormatDefaultSubstitutions(outputFormatObj *format, const return; } -static void applyClassDefaultSubstitutions(classObj *class, hashTableObj *table) -{ +static void applyClassDefaultSubstitutions(classObj *class, + hashTableObj *table) { const char *default_key = msFirstKeyFromHashTable(table); - while(default_key) { - if(!strncasecmp(default_key,"default_",8)) { - size_t buffer_size = (strlen(default_key)-5); + while (default_key) { + if (!strncasecmp(default_key, "default_", 8)) { + size_t buffer_size = (strlen(default_key) - 5); char *tag = (char *)msSmallMalloc(buffer_size); snprintf(tag, buffer_size, "%%%s%%", &(default_key[8])); @@ -6509,18 +7173,18 @@ static void applyClassDefaultSubstitutions(classObj *class, hashTableObj *table) return; } -static void applyLayerDefaultSubstitutions(layerObj *layer, hashTableObj *table) -{ +static void applyLayerDefaultSubstitutions(layerObj *layer, + hashTableObj *table) { int i; const char *default_key = msFirstKeyFromHashTable(table); - while(default_key) { - if(!strncasecmp(default_key,"default_",8)) { - size_t buffer_size = (strlen(default_key)-5); + while (default_key) { + if (!strncasecmp(default_key, "default_", 8)) { + size_t buffer_size = (strlen(default_key) - 5); const char *to = msLookupHashTable(table, default_key); char *tag = (char *)msSmallMalloc(buffer_size); snprintf(tag, buffer_size, "%%%s%%", &(default_key[8])); - for(i=0; inumclasses; i++) { + for (i = 0; i < layer->numclasses; i++) { classSubstituteString(layer->class[i], tag, to); } layerSubstituteString(layer, tag, to); @@ -6531,8 +7195,8 @@ static void applyLayerDefaultSubstitutions(layerObj *layer, hashTableObj *table) return; } -static void applyHashTableDefaultSubstitutions(hashTableObj *hashTab, hashTableObj *table) -{ +static void applyHashTableDefaultSubstitutions(hashTableObj *hashTab, + hashTableObj *table) { const char *default_key = msFirstKeyFromHashTable(table); while (default_key) { if (!strncasecmp(default_key, "default_", 8)) { @@ -6550,117 +7214,134 @@ static void applyHashTableDefaultSubstitutions(hashTableObj *hashTab, hashTableO } /* -** Loop through layer metadata for keys that have a default_%key% pattern to replace +** Loop through layer metadata for keys that have a default_%key% pattern to +*replace ** remaining %key% entries by their default value. */ -void msApplyDefaultSubstitutions(mapObj *map) -{ - int i,j; +void msApplyDefaultSubstitutions(mapObj *map) { + int i, j; /* output formats (#3751) */ - for(i=0; inumoutputformats; i++) { - applyOutputFormatDefaultSubstitutions(map->outputformatlist[i], "filename", &(map->web.validation)); - applyOutputFormatDefaultSubstitutions(map->outputformatlist[i], "JSONP", &(map->web.validation)); + for (i = 0; i < map->numoutputformats; i++) { + applyOutputFormatDefaultSubstitutions(map->outputformatlist[i], "filename", + &(map->web.validation)); + applyOutputFormatDefaultSubstitutions(map->outputformatlist[i], "JSONP", + &(map->web.validation)); } - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { layerObj *layer = GET_LAYER(map, i); - for(j=0; jnumclasses; j++) { /* class settings take precedence... */ + for (j = 0; j < layer->numclasses; + j++) { /* class settings take precedence... */ classObj *class = GET_CLASS(map, i, j); applyClassDefaultSubstitutions(class, &(class->validation)); } - applyLayerDefaultSubstitutions(layer, &(layer->validation)); /* ...then layer settings... */ - applyLayerDefaultSubstitutions(layer, &(map->web.validation)); /* ...and finally web settings */ + applyLayerDefaultSubstitutions( + layer, &(layer->validation)); /* ...then layer settings... */ + applyLayerDefaultSubstitutions( + layer, &(map->web.validation)); /* ...and finally web settings */ } - applyHashTableDefaultSubstitutions(&map->web.metadata, &(map->web.validation)); + applyHashTableDefaultSubstitutions(&map->web.metadata, + &(map->web.validation)); } -char *_get_param_value(const char *key, char **names, char **values, int npairs) -{ - if(npairs <= 0) return NULL; // bail, no point searching +char *_get_param_value(const char *key, char **names, char **values, + int npairs) { + if (npairs <= 0) + return NULL; // bail, no point searching - if(getenv(key)) { /* envirronment override */ + if (getenv(key)) { /* envirronment override */ return getenv(key); } - while(npairs) { + while (npairs) { npairs--; - if(strcasecmp(key, names[npairs]) == 0) { + if (strcasecmp(key, names[npairs]) == 0) { return values[npairs]; } } return NULL; } -void msApplySubstitutions(mapObj *map, char **names, char **values, int npairs) -{ +void msApplySubstitutions(mapObj *map, char **names, char **values, + int npairs) { int l; const char *key, *value, *validation; char *tag; - for(l=0; lnumlayers; l++) { + for (l = 0; l < map->numlayers; l++) { int c; - layerObj *lp = GET_LAYER(map,l); - for(c=0; cnumclasses; c++) { + layerObj *lp = GET_LAYER(map, l); + for (c = 0; c < lp->numclasses; c++) { classObj *cp = lp->class[c]; key = NULL; - while( (key = msNextKeyFromHashTable(&cp->validation, key)) ) { - value = _get_param_value(key,names,values,npairs); - if(!value) continue; /*parameter was not in url*/ + while ((key = msNextKeyFromHashTable(&cp->validation, key))) { + value = _get_param_value(key, names, values, npairs); + if (!value) + continue; /*parameter was not in url*/ validation = msLookupHashTable(&cp->validation, key); - if(msEvalRegex(validation, value)) { - /* we've found a substitution and it validates correctly, now let's apply it */ - tag = msSmallMalloc(strlen(key)+3); - sprintf(tag,"%%%s%%",key); - classSubstituteString(cp,tag,value); + if (msEvalRegex(validation, value)) { + /* we've found a substitution and it validates correctly, now let's + * apply it */ + tag = msSmallMalloc(strlen(key) + 3); + sprintf(tag, "%%%s%%", key); + classSubstituteString(cp, tag, value); free(tag); } else { - msSetError(MS_REGEXERR, "Parameter pattern validation failed." , "msApplySubstitutions()"); - if(map->debug || lp->debug) { - msDebug("layer (%s), class %d: failed to validate (%s=%s) for regex (%s)\n", lp->name, c, key, value, validation); + msSetError(MS_REGEXERR, "Parameter pattern validation failed.", + "msApplySubstitutions()"); + if (map->debug || lp->debug) { + msDebug("layer (%s), class %d: failed to validate (%s=%s) for " + "regex (%s)\n", + lp->name, c, key, value, validation); } } - } } key = NULL; - while( (key = msNextKeyFromHashTable(&lp->validation, key)) ) { - value = _get_param_value(key,names,values,npairs); - if(!value) continue; /*parameter was not in url*/ + while ((key = msNextKeyFromHashTable(&lp->validation, key))) { + value = _get_param_value(key, names, values, npairs); + if (!value) + continue; /*parameter was not in url*/ validation = msLookupHashTable(&lp->validation, key); - if(msEvalRegex(validation, value)) { - /* we've found a substitution and it validates correctly, now let's apply it */ - tag = msSmallMalloc(strlen(key)+3); - sprintf(tag,"%%%s%%",key); - layerSubstituteString(lp,tag,value); + if (msEvalRegex(validation, value)) { + /* we've found a substitution and it validates correctly, now let's + * apply it */ + tag = msSmallMalloc(strlen(key) + 3); + sprintf(tag, "%%%s%%", key); + layerSubstituteString(lp, tag, value); free(tag); } else { - msSetError(MS_REGEXERR, "Parameter pattern validation failed." , "msApplySubstitutions()"); - if(map->debug || lp->debug) { - msDebug("layer (%s): failed to validate (%s=%s) for regex (%s)\n", lp->name, key, value, validation); + msSetError(MS_REGEXERR, "Parameter pattern validation failed.", + "msApplySubstitutions()"); + if (map->debug || lp->debug) { + msDebug("layer (%s): failed to validate (%s=%s) for regex (%s)\n", + lp->name, key, value, validation); } } - } } key = NULL; - while( (key = msNextKeyFromHashTable(&map->web.validation, key)) ) { - value = _get_param_value(key,names,values,npairs); - if(!value) continue; /*parameter was not in url*/ + while ((key = msNextKeyFromHashTable(&map->web.validation, key))) { + value = _get_param_value(key, names, values, npairs); + if (!value) + continue; /*parameter was not in url*/ validation = msLookupHashTable(&map->web.validation, key); - if(msEvalRegex(validation, value)) { - /* we've found a substitution and it validates correctly, now let's apply it */ - tag = msSmallMalloc(strlen(key)+3); - sprintf(tag,"%%%s%%",key); - mapSubstituteString(map,tag,value); + if (msEvalRegex(validation, value)) { + /* we've found a substitution and it validates correctly, now let's apply + * it */ + tag = msSmallMalloc(strlen(key) + 3); + sprintf(tag, "%%%s%%", key); + mapSubstituteString(map, tag, value); free(tag); } else { - msSetError(MS_REGEXERR, "Parameter pattern validation failed." , "msApplySubstitutions()"); - if(map->debug) { - msDebug("failed to validate (%s=%s) for regex (%s)\n", key, value, validation); + msSetError(MS_REGEXERR, "Parameter pattern validation failed.", + "msApplySubstitutions()"); + if (map->debug) { + msDebug("failed to validate (%s=%s) for regex (%s)\n", key, value, + validation); } } - } } @@ -6670,15 +7351,14 @@ void msApplySubstitutions(mapObj *map, char **names, char **values, int npairs) ** ** The returned array should be freed using msFreeCharArray(). */ -static char **tokenizeMapInternal(char *filename, int *ret_numtokens) -{ +static char **tokenizeMapInternal(char *filename, int *ret_numtokens) { char **tokens = NULL; - int numtokens=0, numtokens_allocated=0; + int numtokens = 0, numtokens_allocated = 0; size_t buffer_size = 0; *ret_numtokens = 0; - if(!filename) { + if (!filename) { msSetError(MS_MISCERR, "Filename is undefined.", "msTokenizeMap()"); return NULL; } @@ -6686,18 +7366,20 @@ static char **tokenizeMapInternal(char *filename, int *ret_numtokens) /* ** Check map filename to make sure it's legal */ - const char *ms_mapfile_pattern = CPLGetConfigOption("MS_MAPFILE_PATTERN", MS_DEFAULT_MAPFILE_PATTERN); - if(msEvalRegex(ms_mapfile_pattern, filename) != MS_TRUE) { - msSetError(MS_REGEXERR, "Filename validation failed." , "msLoadMap()"); - return(NULL); + const char *ms_mapfile_pattern = + CPLGetConfigOption("MS_MAPFILE_PATTERN", MS_DEFAULT_MAPFILE_PATTERN); + if (msEvalRegex(ms_mapfile_pattern, filename) != MS_TRUE) { + msSetError(MS_REGEXERR, "Filename validation failed.", "msLoadMap()"); + return (NULL); } - if((msyyin = fopen(filename,"r")) == NULL) { + if ((msyyin = fopen(filename, "r")) == NULL) { msSetError(MS_IOERR, "(%s)", "msTokenizeMap()", filename); return NULL; } - msyystate = MS_TOKENIZE_FILE; /* restore lexer state to INITIAL, and do return comments */ + msyystate = MS_TOKENIZE_FILE; /* restore lexer state to INITIAL, and do return + comments */ msyylex(); msyyreturncomments = 1; /* want all tokens, including comments */ @@ -6706,60 +7388,62 @@ static char **tokenizeMapInternal(char *filename, int *ret_numtokens) numtokens = 0; numtokens_allocated = 256; - tokens = (char **) malloc(numtokens_allocated*sizeof(char*)); - if(tokens == NULL) { + tokens = (char **)malloc(numtokens_allocated * sizeof(char *)); + if (tokens == NULL) { msSetError(MS_MEMERR, NULL, "msTokenizeMap()"); fclose(msyyin); return NULL; } - for(;;) { + for (;;) { - if(numtokens_allocated <= numtokens) { - numtokens_allocated *= 2; /* double size of the array every time we reach the limit */ - char** tokensNew = (char **)realloc(tokens, numtokens_allocated*sizeof(char*)); - if(tokensNew == NULL) { + if (numtokens_allocated <= numtokens) { + numtokens_allocated *= + 2; /* double size of the array every time we reach the limit */ + char **tokensNew = + (char **)realloc(tokens, numtokens_allocated * sizeof(char *)); + if (tokensNew == NULL) { msSetError(MS_MEMERR, "Realloc() error.", "msTokenizeMap()"); fclose(msyyin); - for(int i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { lp = (GET_LAYER(map, i)); - /* If the vtable is null, then the layer is never accessed or used -> skip it + /* If the vtable is null, then the layer is never accessed or used -> skip + * it */ if (lp->vtable) { lp->vtable->LayerCloseConnection(lp); @@ -6801,47 +7484,42 @@ void msCloseConnections(mapObj *map) } } -void initResultCache(resultCacheObj *resultcache) -{ +void initResultCache(resultCacheObj *resultcache) { if (resultcache) { resultcache->results = NULL; resultcache->numresults = 0; resultcache->cachesize = 0; - resultcache->bounds.minx = resultcache->bounds.miny = resultcache->bounds.maxx = resultcache->bounds.maxy = -1; + resultcache->bounds.minx = resultcache->bounds.miny = + resultcache->bounds.maxx = resultcache->bounds.maxy = -1; resultcache->previousBounds = resultcache->bounds; } } -void cleanupResultCache(resultCacheObj *resultcache) -{ - if(resultcache) { - if(resultcache->results) - { - int i; - for( i = 0; i < resultcache->numresults; i++ ) - { - if( resultcache->results[i].shape ) - { - msFreeShape( resultcache->results[i].shape ); - msFree( resultcache->results[i].shape ); - } +void cleanupResultCache(resultCacheObj *resultcache) { + if (resultcache) { + if (resultcache->results) { + int i; + for (i = 0; i < resultcache->numresults; i++) { + if (resultcache->results[i].shape) { + msFreeShape(resultcache->results[i].shape); + msFree(resultcache->results[i].shape); } - free(resultcache->results); + } + free(resultcache->results); } resultcache->results = NULL; initResultCache(resultcache); } } - -static int resolveSymbolNames(mapObj* map) -{ +static int resolveSymbolNames(mapObj *map) { int i, j; /* step through layers and classes to resolve symbol names */ - for(i=0; inumlayers; i++) { - for(j=0; jnumclasses; j++) { - if(classResolveSymbolNames(GET_LAYER(map, i)->class[j]) != MS_SUCCESS) return MS_FAILURE; + for (i = 0; i < map->numlayers; i++) { + for (j = 0; j < GET_LAYER(map, i)->numclasses; j++) { + if (classResolveSymbolNames(GET_LAYER(map, i)->class[j]) != MS_SUCCESS) + return MS_FAILURE; } } diff --git a/mapfile.h b/mapfile.h index a527691486..d2a8990cea 100644 --- a/mapfile.h +++ b/mapfile.h @@ -27,12 +27,19 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #ifndef MAPFILE_H #define MAPFILE_H -enum MS_LEXER_STATES {MS_TOKENIZE_DEFAULT=0, MS_TOKENIZE_FILE, MS_TOKENIZE_STRING, MS_TOKENIZE_EXPRESSION, MS_TOKENIZE_VALUE, MS_TOKENIZE_NAME, MS_TOKENIZE_CONFIG}; -enum MS_TOKEN_SOURCES {MS_FILE_TOKENS=0, MS_STRING_TOKENS}; +enum MS_LEXER_STATES { + MS_TOKENIZE_DEFAULT = 0, + MS_TOKENIZE_FILE, + MS_TOKENIZE_STRING, + MS_TOKENIZE_EXPRESSION, + MS_TOKENIZE_VALUE, + MS_TOKENIZE_NAME, + MS_TOKENIZE_CONFIG +}; +enum MS_TOKEN_SOURCES { MS_FILE_TOKENS = 0, MS_STRING_TOKENS }; /* ** Keyword definitions for the mapfiles and symbolfiles (used by lexer) @@ -81,7 +88,6 @@ enum MS_TOKEN_SOURCES {MS_FILE_TOKENS=0, MS_STRING_TOKENS}; #define LOG 1043 #define MAP 1044 - #define MAXFEATURES 1047 #define MAXSCALE 1048 #define MAXSIZE 1049 @@ -190,10 +196,10 @@ enum MS_TOKEN_SOURCES {MS_FILE_TOKENS=0, MS_STRING_TOKENS}; #define MAXINTERVAL 1144 #define MININTERVAL 1145 #define MAXSUBDIVIDE 1146 -#define MINSUBDIVIDE 1147 -#define LABELFORMAT 1148 +#define MINSUBDIVIDE 1147 +#define LABELFORMAT 1148 -#define PROCESSING 1153 +#define PROCESSING 1153 /* The DEBUG macro is also used to request debugging output. Redefine for keyword purposes. */ @@ -308,7 +314,6 @@ enum MS_TOKEN_SOURCES {MS_FILE_TOKENS=0, MS_STRING_TOKENS}; #define COMPOP 1291 #define COMPFILTER 1292 - #define BOM 1300 /* rfc59 bindvals objects */ diff --git a/mapflatgeobuf.c b/mapflatgeobuf.c index e4c3cd92e0..6ef1a51ca0 100644 --- a/mapflatgeobuf.c +++ b/mapflatgeobuf.c @@ -39,66 +39,66 @@ #include #include -static void msFGBPassThroughFieldDefinitions(layerObj *layer, flatgeobuf_ctx *ctx) -{ +static void msFGBPassThroughFieldDefinitions(layerObj *layer, + flatgeobuf_ctx *ctx) { for (int i = 0; i < ctx->columns_len; i++) { char item[255]; char gml_width[32], gml_precision[32]; const char *gml_type = NULL; - const flatgeobuf_column* column = &(ctx->columns[i]); + const flatgeobuf_column *column = &(ctx->columns[i]); strncpy(item, column->name, 255 - 1); gml_width[0] = '\0'; gml_precision[0] = '\0'; - switch( column->type ) { - case flatgeobuf_column_type_byte: - case flatgeobuf_column_type_ubyte: - case flatgeobuf_column_type_bool: - case flatgeobuf_column_type_short: - case flatgeobuf_column_type_ushort: - case flatgeobuf_column_type_int: - case flatgeobuf_column_type_uint: - gml_type = "Integer"; - sprintf( gml_width, "%d", 4 ); - break; - case flatgeobuf_column_type_long: - case flatgeobuf_column_type_ulong: - gml_type = "Long"; - sprintf( gml_width, "%d", 8 ); - break; - case flatgeobuf_column_type_float: - case flatgeobuf_column_type_double: - gml_type = "Real"; - sprintf( gml_width, "%d", 8 ); - sprintf( gml_precision, "%d", 15 ); - break; - case flatgeobuf_column_type_string: - case flatgeobuf_column_type_json: - case flatgeobuf_column_type_datetime: - default: - gml_type = "Character"; - sprintf( gml_width, "%d", 4096 ); - break; + switch (column->type) { + case flatgeobuf_column_type_byte: + case flatgeobuf_column_type_ubyte: + case flatgeobuf_column_type_bool: + case flatgeobuf_column_type_short: + case flatgeobuf_column_type_ushort: + case flatgeobuf_column_type_int: + case flatgeobuf_column_type_uint: + gml_type = "Integer"; + sprintf(gml_width, "%d", 4); + break; + case flatgeobuf_column_type_long: + case flatgeobuf_column_type_ulong: + gml_type = "Long"; + sprintf(gml_width, "%d", 8); + break; + case flatgeobuf_column_type_float: + case flatgeobuf_column_type_double: + gml_type = "Real"; + sprintf(gml_width, "%d", 8); + sprintf(gml_precision, "%d", 15); + break; + case flatgeobuf_column_type_string: + case flatgeobuf_column_type_json: + case flatgeobuf_column_type_datetime: + default: + gml_type = "Character"; + sprintf(gml_width, "%d", 4096); + break; } - msUpdateGMLFieldMetadata(layer, item, gml_type, gml_width, gml_precision, 0); + msUpdateGMLFieldMetadata(layer, item, gml_type, gml_width, gml_precision, + 0); } } -void msFlatGeobufLayerFreeItemInfo(layerObj *layer) -{ +void msFlatGeobufLayerFreeItemInfo(layerObj *layer) { if (layer->iteminfo) { free(layer->iteminfo); layer->iteminfo = NULL; } } -int msFlatGeobufLayerInitItemInfo(layerObj *layer) -{ - if(!layer->layerinfo) { - msSetError(MS_FGBERR, "FlatGeobuf layer has not been opened.", "msFlatGeobufLayerInitItemInfo()"); +int msFlatGeobufLayerInitItemInfo(layerObj *layer) { + if (!layer->layerinfo) { + msSetError(MS_FGBERR, "FlatGeobuf layer has not been opened.", + "msFlatGeobufLayerInitItemInfo()"); return MS_FAILURE; } @@ -109,39 +109,38 @@ int msFlatGeobufLayerInitItemInfo(layerObj *layer) if (!ctx) return MS_FAILURE; - for (int j = 0; j < ctx->columns_len; j++) - { + for (int j = 0; j < ctx->columns_len; j++) { ctx->columns[j].itemindex = -1; - for (int i = 0; i < layer->numitems; i++) - { - if (strcasecmp(layer->items[i], ctx->columns[j].name) == 0) - { - ctx->columns[j].itemindex = i; - break; - } + for (int i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], ctx->columns[j].name) == 0) { + ctx->columns[j].itemindex = i; + break; + } } } return MS_SUCCESS; } -int msFlatGeobufLayerOpen(layerObj *layer) -{ +int msFlatGeobufLayerOpen(layerObj *layer) { char szPath[MS_MAXPATHLEN]; int ret; - if(layer->layerinfo) + if (layer->layerinfo) return MS_SUCCESS; - if (msCheckParentPointer(layer->map,"map") == MS_FAILURE) + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; flatgeobuf_ctx *ctx = flatgeobuf_init_ctx(); layer->layerinfo = ctx; - ctx->file = VSIFOpenL(msBuildPath(szPath, layer->map->mappath, layer->data), "rb"); + ctx->file = + VSIFOpenL(msBuildPath(szPath, layer->map->mappath, layer->data), "rb"); if (!ctx->file) - ctx->file = VSIFOpenL(msBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, layer->data), "rb"); + ctx->file = VSIFOpenL(msBuildPath3(szPath, layer->map->mappath, + layer->map->shapepath, layer->data), + "rb"); if (!ctx->file) { layer->layerinfo = NULL; flatgeobuf_free_ctx(ctx); @@ -164,7 +163,7 @@ int msFlatGeobufLayerOpen(layerObj *layer) if (layer->projection.numargs > 0 && EQUAL(layer->projection.args[0], "auto")) { - OGRSpatialReferenceH hSRS = OSRNewSpatialReference( NULL ); + OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL); char *pszWKT = NULL; if (ctx->srid > 0) { if (OSRImportFromEPSG(hSRS, ctx->srid) != OGRERR_NONE) { @@ -182,28 +181,29 @@ int msFlatGeobufLayerOpen(layerObj *layer) return MS_SUCCESS; } int bOK = MS_FALSE; - if (msOGCWKT2ProjectionObj(ctx->wkt ? ctx->wkt : pszWKT, &(layer->projection), layer->debug) == MS_SUCCESS) + if (msOGCWKT2ProjectionObj(ctx->wkt ? ctx->wkt : pszWKT, + &(layer->projection), + layer->debug) == MS_SUCCESS) bOK = MS_TRUE; CPLFree(pszWKT); OSRDestroySpatialReference(hSRS); - if( bOK != MS_TRUE ) - if( layer->debug || layer->map->debug ) - msDebug( "Unable to get SRS from FlatGeobuf '%s' for layer '%s'.\n", szPath, layer->name ); + if (bOK != MS_TRUE) + if (layer->debug || layer->map->debug) + msDebug("Unable to get SRS from FlatGeobuf '%s' for layer '%s'.\n", + szPath, layer->name); } return MS_SUCCESS; } -int msFlatGeobufLayerIsOpen(layerObj *layer) -{ - if(layer->layerinfo) +int msFlatGeobufLayerIsOpen(layerObj *layer) { + if (layer->layerinfo) return MS_TRUE; else return MS_FALSE; } -int msFlatGeobufLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msFlatGeobufLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)isQuery; flatgeobuf_ctx *ctx; ctx = layer->layerinfo; @@ -213,10 +213,11 @@ int msFlatGeobufLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) if (!ctx->has_extent || !ctx->index_node_size) return MS_SUCCESS; - if(msRectOverlap(&ctx->bounds, &rect) != MS_TRUE) + if (msRectOverlap(&ctx->bounds, &rect) != MS_TRUE) return MS_DONE; - if (msRectContained(&ctx->bounds, &rect) == MS_FALSE && ctx->index_node_size > 0) + if (msRectContained(&ctx->bounds, &rect) == MS_FALSE && + ctx->index_node_size > 0) flatgeobuf_index_search(ctx, &rect); else flatgeobuf_index_skip(ctx); @@ -224,8 +225,7 @@ int msFlatGeobufLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) return MS_SUCCESS; } -int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) -{ +int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) { flatgeobuf_ctx *ctx; ctx = layer->layerinfo; if (!ctx) @@ -236,9 +236,11 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) if (ctx->search_index >= ctx->search_result_len - 1) return MS_DONE; flatgeobuf_search_item item = ctx->search_result[ctx->search_index]; - if (VSIFSeekL(ctx->file, ctx->feature_offset + item.offset, SEEK_SET) == -1) { - msSetError(MS_FGBERR, "Unable to seek in file", "msFlatGeobufLayerNextShape"); - return MS_FAILURE; + if (VSIFSeekL(ctx->file, ctx->feature_offset + item.offset, SEEK_SET) == + -1) { + msSetError(MS_FGBERR, "Unable to seek in file", + "msFlatGeobufLayerNextShape"); + return MS_FAILURE; } ctx->offset = ctx->feature_offset + item.offset; ctx->search_index++; @@ -253,17 +255,17 @@ int msFlatGeobufLayerNextShape(layerObj *layer, shapeObj *shape) if (ctx->done) return MS_DONE; if (ctx->is_null_geom) { - msFreeCharArray(shape->values, shape->numvalues); - shape->values = NULL; + msFreeCharArray(shape->values, shape->numvalues); + shape->values = NULL; } - } while(ctx->is_null_geom); + } while (ctx->is_null_geom); return MS_SUCCESS; } -int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - +int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { + (void)shape; (void)record; flatgeobuf_ctx *ctx; @@ -271,15 +273,16 @@ int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *recor if (!ctx) return MS_FAILURE; long i = record->shapeindex; - if (i < 0 || (uint64_t) i >= ctx->features_count) { + if (i < 0 || (uint64_t)i >= ctx->features_count) { msSetError(MS_MISCERR, "Invalid feature id", "msFlatGeobufLayerGetShape"); return MS_FAILURE; } uint64_t offset; flatgeobuf_read_feature_offset(ctx, i, &offset); if (VSIFSeekL(ctx->file, ctx->feature_offset + offset, SEEK_SET) == -1) { - msSetError(MS_FGBERR, "Unable to seek in file", "msFlatGeobufLayerGetShape"); - return MS_FAILURE; + msSetError(MS_FGBERR, "Unable to seek in file", + "msFlatGeobufLayerGetShape"); + return MS_FAILURE; } int ret = flatgeobuf_decode_feature(ctx, layer, shape); if (ret == -1) @@ -287,8 +290,7 @@ int msFlatGeobufLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *recor return MS_SUCCESS; } -int msFlatGeobufLayerClose(layerObj *layer) -{ +int msFlatGeobufLayerClose(layerObj *layer) { flatgeobuf_ctx *ctx; ctx = layer->layerinfo; if (!ctx) @@ -299,8 +301,7 @@ int msFlatGeobufLayerClose(layerObj *layer) return MS_SUCCESS; } -int msFlatGeobufLayerGetItems(layerObj *layer) -{ +int msFlatGeobufLayerGetItems(layerObj *layer) { const char *value; flatgeobuf_ctx *ctx; ctx = layer->layerinfo; @@ -308,20 +309,19 @@ int msFlatGeobufLayerGetItems(layerObj *layer) return MS_FAILURE; layer->numitems = ctx->columns_len; - char **items = (char **) malloc(sizeof(char *) * ctx->columns_len); + char **items = (char **)malloc(sizeof(char *) * ctx->columns_len); for (int i = 0; i < ctx->columns_len; i++) items[i] = msStrdup(ctx->columns[i].name); layer->items = items; - if((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL - && strcasecmp(value,"auto") == 0 ) + if ((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL && + strcasecmp(value, "auto") == 0) msFGBPassThroughFieldDefinitions(layer, ctx); return msLayerInitItemInfo(layer); } -int msFlatGeobufLayerGetExtent(layerObj *layer, rectObj *extent) -{ +int msFlatGeobufLayerGetExtent(layerObj *layer, rectObj *extent) { flatgeobuf_ctx *ctx; ctx = layer->layerinfo; extent->minx = ctx->xmin; @@ -331,18 +331,17 @@ int msFlatGeobufLayerGetExtent(layerObj *layer, rectObj *extent) return MS_SUCCESS; } -int msFlatGeobufLayerSupportsCommonFilters(layerObj *layer) -{ +int msFlatGeobufLayerSupportsCommonFilters(layerObj *layer) { (void)layer; return MS_TRUE; } -int msFlatGeobufLayerInitializeVirtualTable(layerObj *layer) -{ +int msFlatGeobufLayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); - layer->vtable->LayerSupportsCommonFilters = msFlatGeobufLayerSupportsCommonFilters; + layer->vtable->LayerSupportsCommonFilters = + msFlatGeobufLayerSupportsCommonFilters; layer->vtable->LayerInitItemInfo = msFlatGeobufLayerInitItemInfo; layer->vtable->LayerFreeItemInfo = msFlatGeobufLayerFreeItemInfo; layer->vtable->LayerOpen = msFlatGeobufLayerOpen; diff --git a/mapgdal.cpp b/mapgdal.cpp index 66932fa7d5..b4544f36d2 100644 --- a/mapgdal.cpp +++ b/mapgdal.cpp @@ -32,28 +32,27 @@ #include "mapgdal.h" #include - #include "cpl_conv.h" #include "cpl_string.h" #include "ogr_srs_api.h" #include "gdal.h" -static int bGDALInitialized = 0; +static int bGDALInitialized = 0; /************************************************************************/ /* msGDALInitialize() */ /************************************************************************/ -void msGDALInitialize( void ) +void msGDALInitialize(void) { - if( !bGDALInitialized ) { - msAcquireLock( TLOCK_GDAL ); + if (!bGDALInitialized) { + msAcquireLock(TLOCK_GDAL); GDALAllRegister(); - CPLPushErrorHandler( CPLQuietErrorHandler ); - msReleaseLock( TLOCK_GDAL ); + CPLPushErrorHandler(CPLQuietErrorHandler); + msReleaseLock(TLOCK_GDAL); bGDALInitialized = 1; } @@ -63,42 +62,42 @@ void msGDALInitialize( void ) /* msGDALCleanup() */ /************************************************************************/ -void msGDALCleanup( void ) +void msGDALCleanup(void) { - if( bGDALInitialized ) { + if (bGDALInitialized) { int iRepeat = 5; - /* - ** Cleanup any unreferenced but open datasets as will tend - ** to exist due to deferred close requests. We are careful - ** to only close one file at a time before refecting the - ** list as closing some datasets may cause others to be - ** closed (subdatasets in a VRT for instance). - */ + /* + ** Cleanup any unreferenced but open datasets as will tend + ** to exist due to deferred close requests. We are careful + ** to only close one file at a time before refecting the + ** list as closing some datasets may cause others to be + ** closed (subdatasets in a VRT for instance). + */ GDALDatasetH *pahDSList = NULL; int nDSCount = 0; int bDidSomething; - msAcquireLock( TLOCK_GDAL ); + msAcquireLock(TLOCK_GDAL); do { - int i; - GDALGetOpenDatasets( &pahDSList, &nDSCount ); - bDidSomething = FALSE; - for( i = 0; i < nDSCount && !bDidSomething; i++ ) { - if( GDALReferenceDataset( pahDSList[i] ) == 1 ) { - GDALClose( pahDSList[i] ); - bDidSomething = TRUE; - } else - GDALDereferenceDataset( pahDSList[i] ); - } - } while( bDidSomething ); + int i; + GDALGetOpenDatasets(&pahDSList, &nDSCount); + bDidSomething = FALSE; + for (i = 0; i < nDSCount && !bDidSomething; i++) { + if (GDALReferenceDataset(pahDSList[i]) == 1) { + GDALClose(pahDSList[i]); + bDidSomething = TRUE; + } else + GDALDereferenceDataset(pahDSList[i]); + } + } while (bDidSomething); - while( iRepeat-- ) + while (iRepeat--) CPLPopErrorHandler(); - msReleaseLock( TLOCK_GDAL ); + msReleaseLock(TLOCK_GDAL); bGDALInitialized = 0; } @@ -111,62 +110,61 @@ void msGDALCleanup( void ) /* things are clean before we start, and after we are done. */ /************************************************************************/ -void msCleanVSIDir( const char *pszDir ) +void msCleanVSIDir(const char *pszDir) { - char **papszFiles = CPLReadDir( pszDir ); - int i, nFileCount = CSLCount( papszFiles ); + char **papszFiles = CPLReadDir(pszDir); + int i, nFileCount = CSLCount(papszFiles); - for( i = 0; i < nFileCount; i++ ) { - if( strcasecmp(papszFiles[i],".") == 0 - || strcasecmp(papszFiles[i],"..") == 0 ) + for (i = 0; i < nFileCount; i++) { + if (strcasecmp(papszFiles[i], ".") == 0 || + strcasecmp(papszFiles[i], "..") == 0) continue; - VSIUnlink( CPLFormFilename(pszDir, papszFiles[i], NULL) ); + VSIUnlink(CPLFormFilename(pszDir, papszFiles[i], NULL)); } - CSLDestroy( papszFiles ); + CSLDestroy(papszFiles); } /************************************************************************/ /* msSaveImageGDAL() */ /************************************************************************/ -int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) +int msSaveImageGDAL(mapObj *map, imageObj *image, const char *filenameIn) { - int bFileIsTemporary = MS_FALSE; + int bFileIsTemporary = MS_FALSE; GDALDatasetH hMemDS, hOutputDS; - GDALDriverH hMemDriver, hOutputDriver; - int nBands = 1; - int iLine; + GDALDriverH hMemDriver, hOutputDriver; + int nBands = 1; + int iLine; outputFormatObj *format = image->format; rasterBufferObj rb; GDALDataType eDataType = GDT_Byte; int bUseXmp = MS_FALSE; - const char *filename = NULL; - char *filenameToFree = NULL; - const char *gdal_driver_shortname = format->driver+5; + const char *filename = NULL; + char *filenameToFree = NULL; + const char *gdal_driver_shortname = format->driver + 5; msGDALInitialize(); - memset(&rb,0,sizeof(rasterBufferObj)); + memset(&rb, 0, sizeof(rasterBufferObj)); #ifdef USE_EXEMPI - if( map != NULL ) { + if (map != NULL) { bUseXmp = msXmpPresent(map); } #endif - /* -------------------------------------------------------------------- */ /* Identify the proposed output driver. */ /* -------------------------------------------------------------------- */ - msAcquireLock( TLOCK_GDAL ); - hOutputDriver = GDALGetDriverByName( gdal_driver_shortname ); - if( hOutputDriver == NULL ) { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "Failed to find %s driver.", - "msSaveImageGDAL()", gdal_driver_shortname ); + msAcquireLock(TLOCK_GDAL); + hOutputDriver = GDALGetDriverByName(gdal_driver_shortname); + if (hOutputDriver == NULL) { + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "Failed to find %s driver.", "msSaveImageGDAL()", + gdal_driver_shortname); return MS_FAILURE; } @@ -177,27 +175,26 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* memory, otherwise we try to put it in a reasonable temporary */ /* file location. */ /* -------------------------------------------------------------------- */ - if( filenameIn == NULL ) { + if (filenameIn == NULL) { const char *pszExtension = format->extension; - if( pszExtension == NULL ) + if (pszExtension == NULL) pszExtension = "img.tmp"; - if( bUseXmp == MS_FALSE && - msGDALDriverSupportsVirtualIOOutput(hOutputDriver) ) { - msCleanVSIDir( "/vsimem/msout" ); - filenameToFree = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension ); + if (bUseXmp == MS_FALSE && + msGDALDriverSupportsVirtualIOOutput(hOutputDriver)) { + msCleanVSIDir("/vsimem/msout"); + filenameToFree = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension); } - if( filenameToFree == NULL && map != NULL) - filenameToFree = msTmpFile(map, map->mappath,NULL,pszExtension); - else if( filenameToFree == NULL ) { - filenameToFree = msTmpFile(map, NULL, NULL, pszExtension ); + if (filenameToFree == NULL && map != NULL) + filenameToFree = msTmpFile(map, map->mappath, NULL, pszExtension); + else if (filenameToFree == NULL) { + filenameToFree = msTmpFile(map, NULL, NULL, pszExtension); } filename = filenameToFree; bFileIsTemporary = MS_TRUE; - } - else { + } else { filename = filenameIn; } @@ -206,35 +203,38 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* dataset. */ /* -------------------------------------------------------------------- */ - if( format->imagemode == MS_IMAGEMODE_RGB ) { + if (format->imagemode == MS_IMAGEMODE_RGB) { nBands = 3; - assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); - if(MS_UNLIKELY(MS_FAILURE == format->vtable->getRasterBufferHandle(image,&rb))) { - msReleaseLock( TLOCK_GDAL ); - msFree( filenameToFree ); + assert(MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer); + if (MS_UNLIKELY(MS_FAILURE == + format->vtable->getRasterBufferHandle(image, &rb))) { + msReleaseLock(TLOCK_GDAL); + msFree(filenameToFree); return MS_FAILURE; } - } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { + } else if (format->imagemode == MS_IMAGEMODE_RGBA) { nBands = 4; - assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); - if(MS_UNLIKELY(MS_FAILURE == format->vtable->getRasterBufferHandle(image,&rb))) { - msReleaseLock( TLOCK_GDAL ); - msFree( filenameToFree ); + assert(MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer); + if (MS_UNLIKELY(MS_FAILURE == + format->vtable->getRasterBufferHandle(image, &rb))) { + msReleaseLock(TLOCK_GDAL); + msFree(filenameToFree); return MS_FAILURE; } - } else if( format->imagemode == MS_IMAGEMODE_INT16 ) { + } else if (format->imagemode == MS_IMAGEMODE_INT16) { nBands = format->bands; eDataType = GDT_Int16; - } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { + } else if (format->imagemode == MS_IMAGEMODE_FLOAT32) { nBands = format->bands; eDataType = GDT_Float32; - } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { + } else if (format->imagemode == MS_IMAGEMODE_BYTE) { nBands = format->bands; eDataType = GDT_Byte; } else { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MEMERR, "Unknown format. This is a bug.", "msSaveImageGDAL()"); - msFree( filenameToFree ); + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MEMERR, "Unknown format. This is a bug.", + "msSaveImageGDAL()"); + msFree(filenameToFree); return MS_FAILURE; } @@ -242,118 +242,117 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* Create a memory dataset which we can use as a source for a */ /* CreateCopy(). */ /* -------------------------------------------------------------------- */ - hMemDriver = GDALGetDriverByName( "MEM" ); - if( hMemDriver == NULL ) { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "Failed to find MEM driver.", - "msSaveImageGDAL()" ); - msFree( filenameToFree ); + hMemDriver = GDALGetDriverByName("MEM"); + if (hMemDriver == NULL) { + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "Failed to find MEM driver.", "msSaveImageGDAL()"); + msFree(filenameToFree); return MS_FAILURE; } - hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp", - image->width, image->height, nBands, - eDataType, NULL ); - if( hMemDS == NULL ) { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "Failed to create MEM dataset.", - "msSaveImageGDAL()" ); - msFree( filenameToFree ); + hMemDS = GDALCreate(hMemDriver, "msSaveImageGDAL_temp", image->width, + image->height, nBands, eDataType, NULL); + if (hMemDS == NULL) { + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "Failed to create MEM dataset.", + "msSaveImageGDAL()"); + msFree(filenameToFree); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy the gd image into the memory dataset. */ /* -------------------------------------------------------------------- */ - for( iLine = 0; iLine < image->height; iLine++ ) { + for (iLine = 0; iLine < image->height; iLine++) { int iBand; - for( iBand = 0; iBand < nBands; iBand++ ) { + for (iBand = 0; iBand < nBands; iBand++) { CPLErr eErr; - GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); - - if( format->imagemode == MS_IMAGEMODE_INT16 ) { - eErr = GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, - image->img.raw_16bit + iLine * image->width - + iBand * image->width * image->height, - image->width, 1, GDT_Int16, 2, 0 ); - - } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { - eErr = GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, - image->img.raw_float + iLine * image->width - + iBand * image->width * image->height, - image->width, 1, GDT_Float32, 4, 0 ); - } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { - eErr = GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, - image->img.raw_byte + iLine * image->width - + iBand * image->width * image->height, - image->width, 1, GDT_Byte, 1, 0 ); + GDALRasterBandH hBand = GDALGetRasterBand(hMemDS, iBand + 1); + + if (format->imagemode == MS_IMAGEMODE_INT16) { + eErr = GDALRasterIO(hBand, GF_Write, 0, iLine, image->width, 1, + image->img.raw_16bit + iLine * image->width + + iBand * image->width * image->height, + image->width, 1, GDT_Int16, 2, 0); + + } else if (format->imagemode == MS_IMAGEMODE_FLOAT32) { + eErr = GDALRasterIO(hBand, GF_Write, 0, iLine, image->width, 1, + image->img.raw_float + iLine * image->width + + iBand * image->width * image->height, + image->width, 1, GDT_Float32, 4, 0); + } else if (format->imagemode == MS_IMAGEMODE_BYTE) { + eErr = GDALRasterIO(hBand, GF_Write, 0, iLine, image->width, 1, + image->img.raw_byte + iLine * image->width + + iBand * image->width * image->height, + image->width, 1, GDT_Byte, 1, 0); } else { GByte *pabyData; unsigned char *pixptr = NULL; - assert( rb.type == MS_BUFFER_BYTE_RGBA ); - switch(iBand) { - case 0: - pixptr = rb.data.rgba.r; - break; - case 1: - pixptr = rb.data.rgba.g; - break; - case 2: - pixptr = rb.data.rgba.b; - break; - case 3: - pixptr = rb.data.rgba.a; - break; + assert(rb.type == MS_BUFFER_BYTE_RGBA); + switch (iBand) { + case 0: + pixptr = rb.data.rgba.r; + break; + case 1: + pixptr = rb.data.rgba.g; + break; + case 2: + pixptr = rb.data.rgba.b; + break; + case 3: + pixptr = rb.data.rgba.a; + break; } assert(pixptr); - if( pixptr == NULL ) { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "Missing RGB or A buffer.\n", - "msSaveImageGDAL()" ); + if (pixptr == NULL) { + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "Missing RGB or A buffer.\n", + "msSaveImageGDAL()"); GDALClose(hMemDS); - msFree( filenameToFree ); + msFree(filenameToFree); return MS_FAILURE; } - pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step); + pabyData = (GByte *)(pixptr + iLine * rb.data.rgba.row_step); - if( rb.data.rgba.a == NULL || iBand == 3 ) { - eErr = GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, - pabyData, image->width, 1, GDT_Byte, - rb.data.rgba.pixel_step, 0 ); + if (rb.data.rgba.a == NULL || iBand == 3) { + eErr = GDALRasterIO(hBand, GF_Write, 0, iLine, image->width, 1, + pabyData, image->width, 1, GDT_Byte, + rb.data.rgba.pixel_step, 0); } else { /* We need to un-pre-multiple RGB by alpha. */ - GByte *pabyUPM = (GByte*) malloc(image->width); - GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step); + GByte *pabyUPM = (GByte *)malloc(image->width); + GByte *pabyAlpha = + (GByte *)(rb.data.rgba.a + iLine * rb.data.rgba.row_step); int i; - for( i = 0; i < image->width; i++ ) { - int alpha = pabyAlpha[i*rb.data.rgba.pixel_step]; + for (i = 0; i < image->width; i++) { + int alpha = pabyAlpha[i * rb.data.rgba.pixel_step]; - if( alpha == 0 ) + if (alpha == 0) pabyUPM[i] = 0; else { - int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha; + int result = + (pabyData[i * rb.data.rgba.pixel_step] * 255) / alpha; - if( result > 255 ) + if (result > 255) result = 255; pabyUPM[i] = result; } } - eErr = GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, - pabyUPM, image->width, 1, GDT_Byte, 1, 0 ); - free( pabyUPM ); + eErr = GDALRasterIO(hBand, GF_Write, 0, iLine, image->width, 1, + pabyUPM, image->width, 1, GDT_Byte, 1, 0); + free(pabyUPM); } } - if( eErr != CE_None ) { - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "GDALRasterIO() failed.\n", - "msSaveImageGDAL()" ); - GDALClose(hMemDS); - msFree( filenameToFree ); - return MS_FAILURE; + if (eErr != CE_None) { + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "GDALRasterIO() failed.\n", "msSaveImageGDAL()"); + GDALClose(hMemDS); + msFree(filenameToFree); + return MS_FAILURE; } } } @@ -361,118 +360,107 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* -------------------------------------------------------------------- */ /* Attach the palette if appropriate. */ /* -------------------------------------------------------------------- */ - if( format->imagemode == MS_IMAGEMODE_RGB ) { - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); - } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); - GDALSetRasterColorInterpretation( - GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand ); - } + if (format->imagemode == MS_IMAGEMODE_RGB) { + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 1), GCI_RedBand); + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 2), + GCI_GreenBand); + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 3), + GCI_BlueBand); + } else if (format->imagemode == MS_IMAGEMODE_RGBA) { + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 1), GCI_RedBand); + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 2), + GCI_GreenBand); + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 3), + GCI_BlueBand); + GDALSetRasterColorInterpretation(GDALGetRasterBand(hMemDS, 4), + GCI_AlphaBand); + } /* -------------------------------------------------------------------- */ /* Assign the projection and coordinate system to the memory */ /* dataset. */ /* -------------------------------------------------------------------- */ - if( map != NULL ) { + if (map != NULL) { char *pszWKT; - GDALSetGeoTransform( hMemDS, map->gt.geotransform ); + GDALSetGeoTransform(hMemDS, map->gt.geotransform); - pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); - if( pszWKT != NULL ) { - GDALSetProjection( hMemDS, pszWKT ); - msFree( pszWKT ); + pszWKT = msProjectionObj2OGCWKT(&(map->projection)); + if (pszWKT != NULL) { + GDALSetProjection(hMemDS, pszWKT); + msFree(pszWKT); } } /* -------------------------------------------------------------------- */ /* Possibly assign a nodata value. */ /* -------------------------------------------------------------------- */ - const char *nullvalue = msGetOutputFormatOption(format,"NULLVALUE",NULL); - if( nullvalue != NULL ) { + const char *nullvalue = msGetOutputFormatOption(format, "NULLVALUE", NULL); + if (nullvalue != NULL) { const double dfNullValue = atof(nullvalue); - for( int iBand = 0; iBand < nBands; iBand++ ) { - GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); - GDALSetRasterNoDataValue( hBand, dfNullValue ); + for (int iBand = 0; iBand < nBands; iBand++) { + GDALRasterBandH hBand = GDALGetRasterBand(hMemDS, iBand + 1); + GDALSetRasterNoDataValue(hBand, dfNullValue); } } /* -------------------------------------------------------------------- */ /* Try to save resolution in the output file. */ /* -------------------------------------------------------------------- */ - if( image->resolution > 0 ) { + if (image->resolution > 0) { char res[30]; - sprintf( res, "%lf", image->resolution ); - GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL ); - GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL ); - GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL ); + sprintf(res, "%lf", image->resolution); + GDALSetMetadataItem(hMemDS, "TIFFTAG_XRESOLUTION", res, NULL); + GDALSetMetadataItem(hMemDS, "TIFFTAG_YRESOLUTION", res, NULL); + GDALSetMetadataItem(hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL); } /* -------------------------------------------------------------------- */ /* Separate creation options from metadata items. */ /* -------------------------------------------------------------------- */ - std::vector apszCreationOptions; - for( int i = 0; i < format->numformatoptions; i++ ) - { - char* option = format->formatoptions[i]; + std::vector apszCreationOptions; + for (int i = 0; i < format->numformatoptions; i++) { + char *option = format->formatoptions[i]; // MDI stands for MetaDataItem - if( STARTS_WITH(option, "mdi_") ) - { - const char* option_without_band = option + strlen("mdi_"); + if (STARTS_WITH(option, "mdi_")) { + const char *option_without_band = option + strlen("mdi_"); GDALMajorObjectH hObject = (GDALMajorObjectH)hMemDS; - if( STARTS_WITH(option_without_band, "BAND_") ) - { + if (STARTS_WITH(option_without_band, "BAND_")) { int nBandNumber = atoi(option_without_band + strlen("BAND_")); - if( nBandNumber > 0 && nBandNumber <= nBands ) - { - const char* pszAfterBand = strchr(option_without_band + strlen("BAND_"), '_'); - if( pszAfterBand != NULL ) - { - hObject = (GDALMajorObjectH)GDALGetRasterBand(hMemDS, nBandNumber); - option_without_band = pszAfterBand + 1; + if (nBandNumber > 0 && nBandNumber <= nBands) { + const char *pszAfterBand = + strchr(option_without_band + strlen("BAND_"), '_'); + if (pszAfterBand != NULL) { + hObject = (GDALMajorObjectH)GDALGetRasterBand(hMemDS, nBandNumber); + option_without_band = pszAfterBand + 1; } - } - else { - msDebug("Invalid band number %d in metadata item option %s", nBandNumber, option); + } else { + msDebug("Invalid band number %d in metadata item option %s", + nBandNumber, option); } } - if( hObject ) { + if (hObject) { std::string osDomain(option_without_band); size_t nUnderscorePos = osDomain.find('_'); - if( nUnderscorePos != std::string::npos ) { + if (nUnderscorePos != std::string::npos) { std::string osKeyValue = osDomain.substr(nUnderscorePos + 1); osDomain.resize(nUnderscorePos); - if( osDomain == "default" ) - osDomain.clear(); + if (osDomain == "default") + osDomain.clear(); size_t nEqualPos = osKeyValue.find('='); - if( nEqualPos != std::string::npos ) - { - GDALSetMetadataItem(hObject, - osKeyValue.substr(0, nEqualPos).c_str(), - osKeyValue.substr(nEqualPos + 1).c_str(), - osDomain.c_str()); + if (nEqualPos != std::string::npos) { + GDALSetMetadataItem( + hObject, osKeyValue.substr(0, nEqualPos).c_str(), + osKeyValue.substr(nEqualPos + 1).c_str(), osDomain.c_str()); } - } - else { + } else { msDebug("Invalid format in metadata item option %s", option); } } - } - else - { + } else { apszCreationOptions.emplace_back(option); } } @@ -482,38 +470,35 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* Create a disk image in the selected output format from the */ /* memory image. */ /* -------------------------------------------------------------------- */ - hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE, - &apszCreationOptions[0], NULL, NULL ); - + hOutputDS = GDALCreateCopy(hOutputDriver, filename, hMemDS, FALSE, + &apszCreationOptions[0], NULL, NULL); - if( hOutputDS == NULL ) { - GDALClose( hMemDS ); - msReleaseLock( TLOCK_GDAL ); - msSetError( MS_MISCERR, "Failed to create output %s file.\n%s", - "msSaveImageGDAL()", format->driver+5, - CPLGetLastErrorMsg() ); - msFree( filenameToFree ); + if (hOutputDS == NULL) { + GDALClose(hMemDS); + msReleaseLock(TLOCK_GDAL); + msSetError(MS_MISCERR, "Failed to create output %s file.\n%s", + "msSaveImageGDAL()", format->driver + 5, CPLGetLastErrorMsg()); + msFree(filenameToFree); return MS_FAILURE; } /* closing the memory DS also frees all associated resources. */ - GDALClose( hMemDS ); - - GDALClose( hOutputDS ); - msReleaseLock( TLOCK_GDAL ); + GDALClose(hMemDS); + GDALClose(hOutputDS); + msReleaseLock(TLOCK_GDAL); /* -------------------------------------------------------------------- */ /* Are we writing license info into the image? */ /* If so, add it to the temp file on disk now. */ /* -------------------------------------------------------------------- */ #ifdef USE_EXEMPI - if ( bUseXmp == MS_TRUE ) { - if( msXmpWrite(map, filename) == MS_FAILURE ) { + if (bUseXmp == MS_TRUE) { + if (msXmpWrite(map, filename) == MS_FAILURE) { /* Something bad happened. */ - msSetError( MS_MISCERR, "XMP write to %s failed.\n", - "msSaveImageGDAL()", filename); - msFree( filenameToFree ); + msSetError(MS_MISCERR, "XMP write to %s failed.\n", "msSaveImageGDAL()", + filename); + msFree(filenameToFree); return MS_FAILURE; } } @@ -523,39 +508,36 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* Is this supposed to be a temporary file? If so, stream to */ /* stdout and delete the file. */ /* -------------------------------------------------------------------- */ - if( bFileIsTemporary ) { + if (bFileIsTemporary) { VSILFILE *fp; unsigned char block[4000]; int bytes_read; - if( msIO_needBinaryStdout() == MS_FAILURE ) - { - msFree( filenameToFree ); + if (msIO_needBinaryStdout() == MS_FAILURE) { + msFree(filenameToFree); return MS_FAILURE; } /* We aren't sure how far back GDAL exports the VSI*L API, so we only use it if we suspect we need it. But we do need it if holding temporary file in memory. */ - fp = VSIFOpenL( filename, "rb" ); - if( fp == NULL ) { - msSetError( MS_MISCERR, - "Failed to open %s for streaming to stdout.", - "msSaveImageGDAL()", filename ); - msFree( filenameToFree ); + fp = VSIFOpenL(filename, "rb"); + if (fp == NULL) { + msSetError(MS_MISCERR, "Failed to open %s for streaming to stdout.", + "msSaveImageGDAL()", filename); + msFree(filenameToFree); return MS_FAILURE; } - while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 ) - msIO_fwrite( block, 1, bytes_read, stdout ); - - VSIFCloseL( fp ); + while ((bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0) + msIO_fwrite(block, 1, bytes_read, stdout); - VSIUnlink( filename ); - msCleanVSIDir( "/vsimem/msout" ); + VSIFCloseL(fp); + VSIUnlink(filename); + msCleanVSIDir("/vsimem/msout"); } - msFree( filenameToFree ); + msFree(filenameToFree); return MS_SUCCESS; } @@ -564,7 +546,7 @@ int msSaveImageGDAL( mapObj *map, imageObj *image, const char *filenameIn ) /* msInitGDALOutputFormat() */ /************************************************************************/ -int msInitDefaultGDALOutputFormat( outputFormatObj *format ) +int msInitDefaultGDALOutputFormat(outputFormatObj *format) { GDALDriverH hDriver; @@ -576,17 +558,17 @@ int msInitDefaultGDALOutputFormat( outputFormatObj *format ) /* be pretty threadsafe so don't bother acquiring the GDAL */ /* lock. */ /* -------------------------------------------------------------------- */ - hDriver = GDALGetDriverByName( format->driver+5 ); - if( hDriver == NULL ) { - msSetError( MS_MISCERR, "No GDAL driver named `%s' available.", - "msInitGDALOutputFormat()", format->driver+5 ); + hDriver = GDALGetDriverByName(format->driver + 5); + if (hDriver == NULL) { + msSetError(MS_MISCERR, "No GDAL driver named `%s' available.", + "msInitGDALOutputFormat()", format->driver + 5); return MS_FAILURE; } - if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL - && GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) == NULL ) { - msSetError( MS_MISCERR, "GDAL `%s' driver does not support output.", - "msInitGDALOutputFormat()", format->driver+5 ); + if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) == NULL && + GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL) == NULL) { + msSetError(MS_MISCERR, "GDAL `%s' driver does not support output.", + "msInitGDALOutputFormat()", format->driver + 5); return MS_FAILURE; } @@ -596,28 +578,29 @@ int msInitDefaultGDALOutputFormat( outputFormatObj *format ) format->imagemode = MS_IMAGEMODE_RGB; format->renderer = MS_RENDER_WITH_AGG; - if( GDALGetMetadataItem( hDriver, GDAL_DMD_MIMETYPE, NULL ) != NULL ) + if (GDALGetMetadataItem(hDriver, GDAL_DMD_MIMETYPE, NULL) != NULL) format->mimetype = - msStrdup(GDALGetMetadataItem(hDriver,GDAL_DMD_MIMETYPE,NULL)); - if( GDALGetMetadataItem( hDriver, GDAL_DMD_EXTENSION, NULL ) != NULL ) + msStrdup(GDALGetMetadataItem(hDriver, GDAL_DMD_MIMETYPE, NULL)); + if (GDALGetMetadataItem(hDriver, GDAL_DMD_EXTENSION, NULL) != NULL) format->extension = - msStrdup(GDALGetMetadataItem(hDriver,GDAL_DMD_EXTENSION,NULL)); + msStrdup(GDALGetMetadataItem(hDriver, GDAL_DMD_EXTENSION, NULL)); return MS_SUCCESS; } -char** msGetStringListFromHashTable(hashTableObj* table) -{ +char **msGetStringListFromHashTable(hashTableObj *table) { struct hashObj *tp = NULL; int i; - char** papszRet = NULL; + char **papszRet = NULL; - if(!table) return NULL; - if(msHashIsEmpty(table)) return NULL; + if (!table) + return NULL; + if (msHashIsEmpty(table)) + return NULL; - for (i=0; iitems[i] != NULL) { - for (tp=table->items[i]; tp!=NULL; tp=tp->next) { + for (tp = table->items[i]; tp != NULL; tp = tp->next) { papszRet = CSLSetNameValue(papszRet, tp->key, tp->data); } } @@ -625,7 +608,6 @@ char** msGetStringListFromHashTable(hashTableObj* table) return papszRet; } - /************************************************************************/ /* msProjectionObj2OGCWKT() */ /* */ @@ -637,59 +619,59 @@ char** msGetStringListFromHashTable(hashTableObj* table) /* returned string should be freed with msFree(). */ /************************************************************************/ -char *msProjectionObj2OGCWKT( projectionObj *projection ) +char *msProjectionObj2OGCWKT(projectionObj *projection) { OGRSpatialReferenceH hSRS; - char *pszWKT=NULL, *pszProj4, *pszInitEpsg=NULL; - int nLength = 0, i; + char *pszWKT = NULL, *pszProj4, *pszInitEpsg = NULL; + int nLength = 0, i; OGRErr eErr; - if( projection->proj == NULL ) + if (projection->proj == NULL) return NULL; - hSRS = OSRNewSpatialReference( NULL ); + hSRS = OSRNewSpatialReference(NULL); /* -------------------------------------------------------------------- */ /* Look for an EPSG-like projection argument */ /* -------------------------------------------------------------------- */ - if( projection->numargs == 1 && - (pszInitEpsg = strcasestr(projection->args[0],"init=epsg:"))) { - int nEpsgCode = atoi(pszInitEpsg + strlen("init=epsg:")); - eErr = OSRImportFromEPSG(hSRS, nEpsgCode); + if (projection->numargs == 1 && + (pszInitEpsg = strcasestr(projection->args[0], "init=epsg:"))) { + int nEpsgCode = atoi(pszInitEpsg + strlen("init=epsg:")); + eErr = OSRImportFromEPSG(hSRS, nEpsgCode); } else { /* -------------------------------------------------------------------- */ /* Form arguments into a full Proj.4 definition string. */ /* -------------------------------------------------------------------- */ - for( i = 0; i < projection->numargs; i++ ) + for (i = 0; i < projection->numargs; i++) nLength += strlen(projection->args[i]) + 2; - pszProj4 = (char *) CPLMalloc(nLength+2); + pszProj4 = (char *)CPLMalloc(nLength + 2); pszProj4[0] = '\0'; - for( i = 0; i < projection->numargs; i++ ) { - strcat( pszProj4, "+" ); - strcat( pszProj4, projection->args[i] ); - strcat( pszProj4, " " ); + for (i = 0; i < projection->numargs; i++) { + strcat(pszProj4, "+"); + strcat(pszProj4, projection->args[i]); + strcat(pszProj4, " "); } /* -------------------------------------------------------------------- */ /* Ingest the string into OGRSpatialReference. */ /* -------------------------------------------------------------------- */ - eErr = OSRImportFromProj4( hSRS, pszProj4 ); - CPLFree( pszProj4 ); + eErr = OSRImportFromProj4(hSRS, pszProj4); + CPLFree(pszProj4); } /* -------------------------------------------------------------------- */ /* Export as a WKT string. */ /* -------------------------------------------------------------------- */ - if( eErr == OGRERR_NONE ) - OSRExportToWkt( hSRS, &pszWKT ); + if (eErr == OGRERR_NONE) + OSRExportToWkt(hSRS, &pszWKT); - OSRDestroySpatialReference( hSRS ); + OSRDestroySpatialReference(hSRS); - if( pszWKT ) { + if (pszWKT) { char *pszWKT2 = msStrdup(pszWKT); - CPLFree( pszWKT ); + CPLFree(pszWKT); return pszWKT2; } else @@ -700,11 +682,10 @@ char *msProjectionObj2OGCWKT( projectionObj *projection ) /* msGDALDriverSupportsVirtualIOOutput() */ /************************************************************************/ -int msGDALDriverSupportsVirtualIOOutput( GDALDriverH hDriver ) -{ - /* We need special testing here for the netCDF driver, since recent */ - /* GDAL versions advertize VirtualIO support, but this is only for the */ - /* read-side of the driver, not the write-side. */ - return GDALGetMetadataItem( hDriver, GDAL_DCAP_VIRTUALIO, NULL ) != NULL && - !EQUAL(GDALGetDescription(hDriver), "netCDF"); +int msGDALDriverSupportsVirtualIOOutput(GDALDriverH hDriver) { + /* We need special testing here for the netCDF driver, since recent */ + /* GDAL versions advertize VirtualIO support, but this is only for the */ + /* read-side of the driver, not the write-side. */ + return GDALGetMetadataItem(hDriver, GDAL_DCAP_VIRTUALIO, NULL) != NULL && + !EQUAL(GDALGetDescription(hDriver), "netCDF"); } diff --git a/mapgdal.h b/mapgdal.h index 45ec7eb26b..211b90c2ff 100644 --- a/mapgdal.h +++ b/mapgdal.h @@ -37,7 +37,7 @@ extern "C" { #endif -int msGDALDriverSupportsVirtualIOOutput( GDALDriverH hDriver ); +int msGDALDriverSupportsVirtualIOOutput(GDALDriverH hDriver); #ifdef __cplusplus } diff --git a/mapgeomtransform.c b/mapgeomtransform.c index 03b3199095..f64d5d5943 100644 --- a/mapgeomtransform.c +++ b/mapgeomtransform.c @@ -32,8 +32,7 @@ extern int yyparse(parseObj *p); -void msStyleSetGeomTransform(styleObj *s, char *transform) -{ +void msStyleSetGeomTransform(styleObj *s, char *transform) { msFree(s->_geomtransform.string); if (!transform) { s->_geomtransform.type = MS_GEOMTRANSFORM_NONE; @@ -41,71 +40,65 @@ void msStyleSetGeomTransform(styleObj *s, char *transform) return; } s->_geomtransform.string = msStrdup(transform); - if(!strncasecmp("start",transform,5)) { + if (!strncasecmp("start", transform, 5)) { s->_geomtransform.type = MS_GEOMTRANSFORM_START; - } else if(!strncasecmp("end",transform,3)) { + } else if (!strncasecmp("end", transform, 3)) { s->_geomtransform.type = MS_GEOMTRANSFORM_END; - } else if(!strncasecmp("vertices",transform,8)) { + } else if (!strncasecmp("vertices", transform, 8)) { s->_geomtransform.type = MS_GEOMTRANSFORM_VERTICES; - } else if(!strncasecmp("bbox",transform,4)) { + } else if (!strncasecmp("bbox", transform, 4)) { s->_geomtransform.type = MS_GEOMTRANSFORM_BBOX; - } else if(!strncasecmp("labelpnt",transform,8)) { + } else if (!strncasecmp("labelpnt", transform, 8)) { s->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOINT; - } else if(!strncasecmp("labelpoly",transform,9)) { + } else if (!strncasecmp("labelpoly", transform, 9)) { s->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOLY; - } else if(!strncasecmp("labelcenter",transform,11)) { + } else if (!strncasecmp("labelcenter", transform, 11)) { s->_geomtransform.type = MS_GEOMTRANSFORM_LABELCENTER; - } else if(!strncasecmp("centroid",transform,8)) { + } else if (!strncasecmp("centroid", transform, 8)) { s->_geomtransform.type = MS_GEOMTRANSFORM_CENTROID; } else { s->_geomtransform.type = MS_GEOMTRANSFORM_NONE; - msSetError(MS_MISCERR,"unknown transform expression","msStyleSetGeomTransform()"); + msSetError(MS_MISCERR, "unknown transform expression", + "msStyleSetGeomTransform()"); msFree(s->_geomtransform.string); s->_geomtransform.string = NULL; } } - /* * return a copy of the geometry transform expression * returned char* must be freed by the caller */ -char *msStyleGetGeomTransform(styleObj *s) -{ +char *msStyleGetGeomTransform(styleObj *s) { return msStrdup(s->_geomtransform.string); } - -double calcOrientation(pointObj *p1, pointObj *p2) -{ +double calcOrientation(pointObj *p1, pointObj *p2) { double theta; - theta = atan2(p2->x - p1->x,p2->y - p1->y); - return MS_RAD_TO_DEG*(theta-MS_PI2); + theta = atan2(p2->x - p1->x, p2->y - p1->y); + return MS_RAD_TO_DEG * (theta - MS_PI2); } -double calcMidAngle(pointObj *p1, pointObj *p2, pointObj *p3) -{ +double calcMidAngle(pointObj *p1, pointObj *p2, pointObj *p3) { pointObj p1n; double dx12, dy12, dx23, dy23, l12, l23; - /* We treat both segments as vector 1-2 and vector 2-3 and - * compute their dx,dy and length + /* We treat both segments as vector 1-2 and vector 2-3 and + * compute their dx,dy and length */ dx12 = p2->x - p1->x; dy12 = p2->y - p1->y; - l12 = sqrt(dx12*dx12 + dy12*dy12); + l12 = sqrt(dx12 * dx12 + dy12 * dy12); dx23 = p3->x - p2->x; dy23 = p3->y - p2->y; - l23 = sqrt(dx23*dx23 + dy23*dy23); + l23 = sqrt(dx23 * dx23 + dy23 * dy23); /* Normalize length of vector 1-2 to same as length of vector 2-3 */ - if (l12 > 0.0) - { - p1n.x = p2->x - dx12*(l23/l12); - p1n.y = p2->y - dy12*(l23/l12); - } - else - p1n = *p2; /* segment 1-2 is 0-length, use segment 2-3 for orientation */ + if (l12 > 0.0) { + p1n.x = p2->x - dx12 * (l23 / l12); + p1n.y = p2->y - dy12 * (l23 / l12); + } else + p1n = *p2; /* segment 1-2 is 0-length, use segment 2-3 for orientation */ /* Return the orientation defined by the sum of the normalized vectors */ return calcOrientation(&p1n, p3); @@ -116,133 +109,139 @@ double calcMidAngle(pointObj *p1, pointObj *p2, pointObj *p3) * - transform the original shapeobj * - use the styleObj to render the transformed shapeobj */ -int msDrawTransformedShape(mapObj *map, imageObj *image, shapeObj *shape, styleObj *style, double scalefactor) -{ +int msDrawTransformedShape(mapObj *map, imageObj *image, shapeObj *shape, + styleObj *style, double scalefactor) { int type = style->_geomtransform.type; - int i,j,status = MS_SUCCESS; - switch(type) { - case MS_GEOMTRANSFORM_END: /*render point on last vertex only*/ - for(j=0; jnumlines; j++) { - lineObj *line = &(shape->line[j]); - pointObj *p = &(line->point[line->numpoints-1]); - if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) - continue; - if(style->autoangle==MS_TRUE && line->numpoints>1) { - style->angle = calcOrientation(&(line->point[line->numpoints-2]),p); - } - status = msDrawMarkerSymbol(map,image,p,style,scalefactor); - } - break; - case MS_GEOMTRANSFORM_START: /*render point on first vertex only*/ - for(j=0; jnumlines; j++) { - lineObj *line = &(shape->line[j]); - pointObj *p = &(line->point[0]); - /*skip if outside image*/ - if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) - continue; - if(style->autoangle==MS_TRUE && line->numpoints>1) { - style->angle = calcOrientation(p,&(line->point[1])); - } - status = msDrawMarkerSymbol(map,image,p,style,scalefactor); + int i, j, status = MS_SUCCESS; + switch (type) { + case MS_GEOMTRANSFORM_END: /*render point on last vertex only*/ + for (j = 0; j < shape->numlines; j++) { + lineObj *line = &(shape->line[j]); + pointObj *p = &(line->point[line->numpoints - 1]); + if (p->x < 0 || p->x > image->width || p->y < 0 || p->y > image->height) + continue; + if (style->autoangle == MS_TRUE && line->numpoints > 1) { + style->angle = calcOrientation(&(line->point[line->numpoints - 2]), p); } - break; - case MS_GEOMTRANSFORM_VERTICES: - for(j=0; jnumlines; j++) { - lineObj *line = &(shape->line[j]); - for(i=1; inumpoints-1; i++) { - pointObj *p = &(line->point[i]); - /*skip points outside image*/ - if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) - continue; - if(style->autoangle==MS_TRUE) { - style->angle = calcMidAngle(&(line->point[i-1]),&(line->point[i]),&(line->point[i+1])); - } - status = msDrawMarkerSymbol(map,image,p,style,scalefactor); - } + status = msDrawMarkerSymbol(map, image, p, style, scalefactor); + } + break; + case MS_GEOMTRANSFORM_START: /*render point on first vertex only*/ + for (j = 0; j < shape->numlines; j++) { + lineObj *line = &(shape->line[j]); + pointObj *p = &(line->point[0]); + /*skip if outside image*/ + if (p->x < 0 || p->x > image->width || p->y < 0 || p->y > image->height) + continue; + if (style->autoangle == MS_TRUE && line->numpoints > 1) { + style->angle = calcOrientation(p, &(line->point[1])); } - break; - case MS_GEOMTRANSFORM_BBOX: { - shapeObj bbox; - lineObj bbox_line; - pointObj bbox_points[5]; - int padding = MS_MAX(style->width,style->size)+3; /* so clipped shape does not extent into image */ - - /*create a shapeObj representing the bounding box (clipped by the image size)*/ - bbox.numlines = 1; - bbox.line = &bbox_line; - bbox.line->numpoints = 5; - bbox.line->point = bbox_points; - - msComputeBounds(shape); - bbox_points[0].x=bbox_points[4].x=bbox_points[1].x = - (shape->bounds.minx < -padding) ? -padding : shape->bounds.minx; - /* cppcheck-suppress unreadVariable */ - bbox_points[2].x=bbox_points[3].x = - (shape->bounds.maxx > image->width+padding) ? image->width+padding : shape->bounds.maxx; - bbox_points[0].y=bbox_points[4].y=bbox_points[3].y = - (shape->bounds.miny < -padding) ? -padding : shape->bounds.miny; - /* cppcheck-suppress unreadVariable */ - bbox_points[1].y=bbox_points[2].y = - (shape->bounds.maxy > image->height+padding) ? image->height+padding : shape->bounds.maxy; - status = msDrawShadeSymbol(map, image, &bbox, style, scalefactor); + status = msDrawMarkerSymbol(map, image, p, style, scalefactor); } break; - case MS_GEOMTRANSFORM_CENTROID: { - double unused; /*used by centroid function*/ - pointObj centroid; - if(MS_SUCCESS == msGetPolygonCentroid(shape,¢roid,&unused,&unused)) { - status = msDrawMarkerSymbol(map,image,¢roid,style,scalefactor); + case MS_GEOMTRANSFORM_VERTICES: + for (j = 0; j < shape->numlines; j++) { + lineObj *line = &(shape->line[j]); + for (i = 1; i < line->numpoints - 1; i++) { + pointObj *p = &(line->point[i]); + /*skip points outside image*/ + if (p->x < 0 || p->x > image->width || p->y < 0 || p->y > image->height) + continue; + if (style->autoangle == MS_TRUE) { + style->angle = calcMidAngle(&(line->point[i - 1]), &(line->point[i]), + &(line->point[i + 1])); + } + status = msDrawMarkerSymbol(map, image, p, style, scalefactor); } } break; - case MS_GEOMTRANSFORM_EXPRESSION: { - int status; - shapeObj *tmpshp; - parseObj p; + case MS_GEOMTRANSFORM_BBOX: { + shapeObj bbox; + lineObj bbox_line; + pointObj bbox_points[5]; + int padding = MS_MAX(style->width, style->size) + + 3; /* so clipped shape does not extent into image */ - p.shape = shape; /* set a few parser globals (hence the lock) */ - p.expr = &(style->_geomtransform); + /*create a shapeObj representing the bounding box (clipped by the image + * size)*/ + bbox.numlines = 1; + bbox.line = &bbox_line; + bbox.line->numpoints = 5; + bbox.line->point = bbox_points; - if(p.expr->tokens == NULL) { /* this could happen if drawing originates from legend code (#5193) */ - status = msTokenizeExpression(p.expr, NULL, NULL); - if(status != MS_SUCCESS) { - msSetError(MS_MISCERR, "Unable to tokenize expression.", "msDrawTransformedShape()"); - return MS_FAILURE; - } - } + msComputeBounds(shape); + bbox_points[0].x = bbox_points[4].x = bbox_points[1].x = + (shape->bounds.minx < -padding) ? -padding : shape->bounds.minx; + /* cppcheck-suppress unreadVariable */ + bbox_points[2].x = bbox_points[3].x = + (shape->bounds.maxx > image->width + padding) ? image->width + padding + : shape->bounds.maxx; + bbox_points[0].y = bbox_points[4].y = bbox_points[3].y = + (shape->bounds.miny < -padding) ? -padding : shape->bounds.miny; + /* cppcheck-suppress unreadVariable */ + bbox_points[1].y = bbox_points[2].y = + (shape->bounds.maxy > image->height + padding) ? image->height + padding + : shape->bounds.maxy; + status = msDrawShadeSymbol(map, image, &bbox, style, scalefactor); + } break; + case MS_GEOMTRANSFORM_CENTROID: { + double unused; /*used by centroid function*/ + pointObj centroid; + if (MS_SUCCESS == + msGetPolygonCentroid(shape, ¢roid, &unused, &unused)) { + status = msDrawMarkerSymbol(map, image, ¢roid, style, scalefactor); + } + } break; + case MS_GEOMTRANSFORM_EXPRESSION: { + int status; + shapeObj *tmpshp; + parseObj p; - p.expr->curtoken = p.expr->tokens; /* reset */ - p.type = MS_PARSE_TYPE_SHAPE; + p.shape = shape; /* set a few parser globals (hence the lock) */ + p.expr = &(style->_geomtransform); - status = yyparse(&p); - if (status != 0) { - msSetError(MS_PARSEERR, "Failed to process shape expression: %s", "msDrawTransformedShape", style->_geomtransform.string); + if (p.expr->tokens == NULL) { /* this could happen if drawing originates + from legend code (#5193) */ + status = msTokenizeExpression(p.expr, NULL, NULL); + if (status != MS_SUCCESS) { + msSetError(MS_MISCERR, "Unable to tokenize expression.", + "msDrawTransformedShape()"); return MS_FAILURE; } - tmpshp = p.result.shpval; + } - switch (tmpshp->type) { - case MS_SHAPE_POINT: - case MS_SHAPE_POLYGON: - /* cppcheck-suppress unreadVariable */ - status = msDrawShadeSymbol(map, image, tmpshp, style, scalefactor); - break; - case MS_SHAPE_LINE: - /* cppcheck-suppress unreadVariable */ - status = msDrawLineSymbol(map, image, tmpshp, style, scalefactor); - break; - } + p.expr->curtoken = p.expr->tokens; /* reset */ + p.type = MS_PARSE_TYPE_SHAPE; - msFreeShape(tmpshp); - msFree(tmpshp); + status = yyparse(&p); + if (status != 0) { + msSetError(MS_PARSEERR, "Failed to process shape expression: %s", + "msDrawTransformedShape", style->_geomtransform.string); + return MS_FAILURE; } - break; - case MS_GEOMTRANSFORM_LABELPOINT: - case MS_GEOMTRANSFORM_LABELPOLY: + tmpshp = p.result.shpval; + + switch (tmpshp->type) { + case MS_SHAPE_POINT: + case MS_SHAPE_POLYGON: + /* cppcheck-suppress unreadVariable */ + status = msDrawShadeSymbol(map, image, tmpshp, style, scalefactor); break; - default: - msSetError(MS_MISCERR, "unknown geomtransform", "msDrawTransformedShape()"); - return MS_FAILURE; + case MS_SHAPE_LINE: + /* cppcheck-suppress unreadVariable */ + status = msDrawLineSymbol(map, image, tmpshp, style, scalefactor); + break; + } + + msFreeShape(tmpshp); + msFree(tmpshp); + } break; + case MS_GEOMTRANSFORM_LABELPOINT: + case MS_GEOMTRANSFORM_LABELPOLY: + break; + default: + msSetError(MS_MISCERR, "unknown geomtransform", "msDrawTransformedShape()"); + return MS_FAILURE; } return status; } @@ -251,70 +250,71 @@ int msDrawTransformedShape(mapObj *map, imageObj *image, shapeObj *shape, styleO * RFC89 implementation: * - transform directly the shapeobj */ -int msGeomTransformShape(mapObj *map, layerObj *layer, shapeObj *shape) -{ +int msGeomTransformShape(mapObj *map, layerObj *layer, shapeObj *shape) { int i; - expressionObj *e = &layer->_geomtransform; + expressionObj *e = &layer->_geomtransform; #ifdef USE_V8_MAPSCRIPT if (!map->v8context) { msV8CreateContext(map); - if (!map->v8context) - { - msSetError(MS_V8ERR, "Unable to create v8 context.", "msGeomTransformShape()"); + if (!map->v8context) { + msSetError(MS_V8ERR, "Unable to create v8 context.", + "msGeomTransformShape()"); return MS_FAILURE; } } msV8ContextSetLayer(map, layer); #endif - - switch(e->type) { - case MS_GEOMTRANSFORM_EXPRESSION: { - int status; - shapeObj *tmpshp; - parseObj p; - - p.shape = shape; /* set a few parser globals (hence the lock) */ - p.expr = e; - p.expr->curtoken = p.expr->tokens; /* reset */ - p.type = MS_PARSE_TYPE_SHAPE; - p.dblval = map->cellsize * (msInchesPerUnit(map->units,0)/msInchesPerUnit(layer->units,0)); - p.dblval2 = 0; - /* data_cellsize is only set with contour layer */ - if (layer->connectiontype == MS_CONTOUR) - { - const char *value = msLookupHashTable(&layer->metadata, "__data_cellsize__"); - if (value) - p.dblval2 = atof(value); - } - - status = yyparse(&p); - if (status != 0) { - msSetError(MS_PARSEERR, "Failed to process shape expression: %s", "msGeomTransformShape()", e->string); - return MS_FAILURE; - } - - tmpshp = p.result.shpval; - for (i= 0; i < shape->numlines; i++) - free(shape->line[i].point); - shape->numlines = 0; - if (shape->line) free(shape->line); - shape->line = NULL; - shape->type = tmpshp->type; /* might have been a change (e.g. centerline) */ + switch (e->type) { + case MS_GEOMTRANSFORM_EXPRESSION: { + int status; + shapeObj *tmpshp; + parseObj p; - for(i=0; inumlines; i++) - msAddLine(shape, &(tmpshp->line[i])); /* copy each line */ - - msFreeShape(tmpshp); - msFree(tmpshp); + p.shape = shape; /* set a few parser globals (hence the lock) */ + p.expr = e; + p.expr->curtoken = p.expr->tokens; /* reset */ + p.type = MS_PARSE_TYPE_SHAPE; + p.dblval = map->cellsize * (msInchesPerUnit(map->units, 0) / + msInchesPerUnit(layer->units, 0)); + p.dblval2 = 0; + /* data_cellsize is only set with contour layer */ + if (layer->connectiontype == MS_CONTOUR) { + const char *value = + msLookupHashTable(&layer->metadata, "__data_cellsize__"); + if (value) + p.dblval2 = atof(value); } - break; - default: - msSetError(MS_MISCERR, "unknown geomtransform", "msGeomTransformShape()"); + + status = yyparse(&p); + if (status != 0) { + msSetError(MS_PARSEERR, "Failed to process shape expression: %s", + "msGeomTransformShape()", e->string); return MS_FAILURE; + } + + tmpshp = p.result.shpval; + + for (i = 0; i < shape->numlines; i++) + free(shape->line[i].point); + shape->numlines = 0; + if (shape->line) + free(shape->line); + shape->line = NULL; + shape->type = tmpshp->type; /* might have been a change (e.g. centerline) */ + + for (i = 0; i < tmpshp->numlines; i++) + msAddLine(shape, &(tmpshp->line[i])); /* copy each line */ + + msFreeShape(tmpshp); + msFree(tmpshp); + } break; + default: + msSetError(MS_MISCERR, "unknown geomtransform", "msGeomTransformShape()"); + return MS_FAILURE; } - + return MS_SUCCESS; } diff --git a/mapgeomutil.cpp b/mapgeomutil.cpp index 7792599f03..b4f0bfa014 100644 --- a/mapgeomutil.cpp +++ b/mapgeomutil.cpp @@ -31,31 +31,32 @@ #include "renderers/agg/include/agg_arc.h" #include "renderers/agg/include/agg_basics.h" - - -shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, double endAngle, int isSlice) -{ - static int allocated_size=100; - shapeObj *shape = (shapeObj*)calloc(1,sizeof(shapeObj)); +shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, + double endAngle, int isSlice) { + static int allocated_size = 100; + shapeObj *shape = (shapeObj *)calloc(1, sizeof(shapeObj)); MS_CHECK_ALLOC(shape, sizeof(shapeObj), NULL); - mapserver::arc arc ( x0, y0,radius,radius, startAngle*MS_DEG_TO_RAD, endAngle*MS_DEG_TO_RAD,true ); - arc.approximation_scale ( 1 ); + mapserver::arc arc(x0, y0, radius, radius, startAngle * MS_DEG_TO_RAD, + endAngle * MS_DEG_TO_RAD, true); + arc.approximation_scale(1); arc.rewind(1); msInitShape(shape); - lineObj *line = (lineObj*)calloc(1,sizeof(lineObj)); + lineObj *line = (lineObj *)calloc(1, sizeof(lineObj)); if (!line) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , - __FILE__, __LINE__, (unsigned int)sizeof(lineObj)); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msRasterizeArc()", __FILE__, __LINE__, + (unsigned int)sizeof(lineObj)); free(shape); return NULL; } shape->line = line; shape->numlines = 1; - line->point = (pointObj*)calloc(allocated_size,sizeof(pointObj)); + line->point = (pointObj *)calloc(allocated_size, sizeof(pointObj)); if (!line->point) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , - __FILE__, __LINE__, (unsigned int)(allocated_size*sizeof(pointObj))); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msRasterizeArc()", __FILE__, __LINE__, + (unsigned int)(allocated_size * sizeof(pointObj))); free(line); free(shape); return NULL; @@ -63,21 +64,23 @@ shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, line->numpoints = 0; - double x,y; + double x, y; - //first segment from center to first point of arc - if(isSlice) { + // first segment from center to first point of arc + if (isSlice) { line->point[0].x = x0; line->point[0].y = y0; line->numpoints = 1; } - while(arc.vertex(&x,&y) != mapserver::path_cmd_stop) { - if(line->numpoints == allocated_size) { + while (arc.vertex(&x, &y) != mapserver::path_cmd_stop) { + if (line->numpoints == allocated_size) { allocated_size *= 2; - line->point = (pointObj*)realloc(line->point, allocated_size * sizeof(pointObj)); + line->point = + (pointObj *)realloc(line->point, allocated_size * sizeof(pointObj)); if (!line->point) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , - __FILE__, __LINE__, (unsigned int)(allocated_size * sizeof(pointObj))); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "msRasterizeArc()", __FILE__, __LINE__, + (unsigned int)(allocated_size * sizeof(pointObj))); free(line); free(shape); return NULL; @@ -88,12 +91,13 @@ shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, line->numpoints++; } - //make sure the shape is closed - if(line->point[line->numpoints-1].x != line->point[0].x || - line->point[line->numpoints-1].y != line->point[0].y) { - if(line->numpoints == allocated_size) { + // make sure the shape is closed + if (line->point[line->numpoints - 1].x != line->point[0].x || + line->point[line->numpoints - 1].y != line->point[0].y) { + if (line->numpoints == allocated_size) { allocated_size *= 2; - line->point = (pointObj*)msSmallRealloc(line->point, allocated_size * sizeof(pointObj)); + line->point = (pointObj *)msSmallRealloc( + line->point, allocated_size * sizeof(pointObj)); } line->point[line->numpoints].x = line->point[0].x; line->point[line->numpoints].y = line->point[0].y; @@ -102,6 +106,3 @@ shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, return shape; } - - - diff --git a/mapgeos.c b/mapgeos.c index 29146f25c0..14b33aa84e 100644 --- a/mapgeos.c +++ b/mapgeos.c @@ -41,27 +41,25 @@ /* ** Error handling... */ -static void msGEOSError(const char *format, ...) -{ +static void msGEOSError(const char *format, ...) { va_list args; - va_start (args, format); - msSetError(MS_GEOSERR, format, "msGEOSError()", args); /* just pass along to MapServer error handling */ + va_start(args, format); + msSetError(MS_GEOSERR, format, "msGEOSError()", + args); /* just pass along to MapServer error handling */ va_end(args); return; } -static void msGEOSNotice(const char *fmt, ...) -{ +static void msGEOSNotice(const char *fmt, ...) { (void)fmt; /* do nothing with notices at this point */ } #ifndef USE_THREAD static GEOSContextHandle_t geos_handle; -static inline GEOSContextHandle_t msGetGeosContextHandle() -{ +static inline GEOSContextHandle_t msGetGeosContextHandle() { return geos_handle; } @@ -69,37 +67,37 @@ static inline GEOSContextHandle_t msGetGeosContextHandle() #include "mapthread.h" typedef struct geos_thread_info { struct geos_thread_info *next; - void* thread_id; - GEOSContextHandle_t geos_handle; + void *thread_id; + GEOSContextHandle_t geos_handle; } geos_thread_info_t; static geos_thread_info_t *geos_list = NULL; -static GEOSContextHandle_t msGetGeosContextHandle() -{ +static GEOSContextHandle_t msGetGeosContextHandle() { geos_thread_info_t *link; GEOSContextHandle_t ret_obj; - void* thread_id; + void *thread_id; - msAcquireLock( TLOCK_GEOS ); + msAcquireLock(TLOCK_GEOS); thread_id = msGetThreadId(); /* find link for this thread */ - for( link = geos_list; - link != NULL && link->thread_id != thread_id - && link->next != NULL && link->next->thread_id != thread_id; - link = link->next ) {} + for (link = geos_list; + link != NULL && link->thread_id != thread_id && link->next != NULL && + link->next->thread_id != thread_id; + link = link->next) { + } /* If the target thread link is already at the head of the list were ok */ - if( geos_list != NULL && geos_list->thread_id == thread_id ) { + if (geos_list != NULL && geos_list->thread_id == thread_id) { } /* We don't have one ... initialize one. */ - else if( link == NULL || link->next == NULL ) { + else if (link == NULL || link->next == NULL) { geos_thread_info_t *new_link; - new_link = (geos_thread_info_t *) malloc(sizeof(geos_thread_info_t)); + new_link = (geos_thread_info_t *)malloc(sizeof(geos_thread_info_t)); new_link->next = geos_list; new_link->thread_id = thread_id; new_link->geos_handle = initGEOS_r(msGEOSNotice, msGEOSError); @@ -118,7 +116,7 @@ static GEOSContextHandle_t msGetGeosContextHandle() ret_obj = geos_list->geos_handle; - msReleaseLock( TLOCK_GEOS ); + msReleaseLock(TLOCK_GEOS); return ret_obj; } @@ -127,214 +125,231 @@ static GEOSContextHandle_t msGetGeosContextHandle() /* ** Setup/Cleanup wrappers */ -void msGEOSSetup() -{ +void msGEOSSetup() { #ifndef USE_THREAD geos_handle = initGEOS_r(msGEOSNotice, msGEOSError); #endif } -void msGEOSCleanup() -{ +void msGEOSCleanup() { #ifndef USE_THREAD finishGEOS_r(geos_handle); geos_handle = NULL; #else geos_thread_info_t *link; - msAcquireLock( TLOCK_GEOS ); - for( link = geos_list; link != NULL;) { + msAcquireLock(TLOCK_GEOS); + for (link = geos_list; link != NULL;) { geos_thread_info_t *cur = link; link = link->next; finishGEOS_r(cur->geos_handle); free(cur); } geos_list = NULL; - msReleaseLock( TLOCK_GEOS ); + msReleaseLock(TLOCK_GEOS); #endif } /* ** Translation functions */ -static GEOSGeom msGEOSShape2Geometry_point(pointObj *point) -{ +static GEOSGeom msGEOSShape2Geometry_point(pointObj *point) { GEOSCoordSeq coords; GEOSGeom g; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!point) return NULL; + if (!point) + return NULL; - coords = GEOSCoordSeq_create_r(handle,1, 2); /* todo handle z's */ - if(!coords) return NULL; + coords = GEOSCoordSeq_create_r(handle, 1, 2); /* todo handle z's */ + if (!coords) + return NULL; - GEOSCoordSeq_setX_r(handle,coords, 0, point->x); - GEOSCoordSeq_setY_r(handle,coords, 0, point->y); + GEOSCoordSeq_setX_r(handle, coords, 0, point->x); + GEOSCoordSeq_setY_r(handle, coords, 0, point->y); /* GEOSCoordSeq_setY(coords, 0, point->z); */ - g = GEOSGeom_createPoint_r(handle,coords); /* g owns the coordinate in coords */ + g = GEOSGeom_createPoint_r(handle, + coords); /* g owns the coordinate in coords */ return g; } -static GEOSGeom msGEOSShape2Geometry_multipoint(lineObj *multipoint) -{ +static GEOSGeom msGEOSShape2Geometry_multipoint(lineObj *multipoint) { int i; GEOSGeom g; GEOSGeom *points; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!multipoint) return NULL; + if (!multipoint) + return NULL; - points = malloc(multipoint->numpoints*sizeof(GEOSGeom)); - if(!points) return NULL; + points = malloc(multipoint->numpoints * sizeof(GEOSGeom)); + if (!points) + return NULL; - for(i=0; inumpoints; i++) + for (i = 0; i < multipoint->numpoints; i++) points[i] = msGEOSShape2Geometry_point(&(multipoint->point[i])); - g = GEOSGeom_createCollection_r(handle,GEOS_MULTIPOINT, points, multipoint->numpoints); + g = GEOSGeom_createCollection_r(handle, GEOS_MULTIPOINT, points, + multipoint->numpoints); free(points); return g; } -static GEOSGeom msGEOSShape2Geometry_line(lineObj *line) -{ +static GEOSGeom msGEOSShape2Geometry_line(lineObj *line) { int i; GEOSGeom g; GEOSCoordSeq coords; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!line) return NULL; + if (!line) + return NULL; - coords = GEOSCoordSeq_create_r(handle,line->numpoints, 2); /* todo handle z's */ - if(!coords) return NULL; + coords = + GEOSCoordSeq_create_r(handle, line->numpoints, 2); /* todo handle z's */ + if (!coords) + return NULL; - for(i=0; inumpoints; i++) { - GEOSCoordSeq_setX_r(handle,coords, i, line->point[i].x); - GEOSCoordSeq_setY_r(handle,coords, i, line->point[i].y); + for (i = 0; i < line->numpoints; i++) { + GEOSCoordSeq_setX_r(handle, coords, i, line->point[i].x); + GEOSCoordSeq_setY_r(handle, coords, i, line->point[i].y); /* GEOSCoordSeq_setZ(coords, i, line->point[i].z); */ } - g = GEOSGeom_createLineString_r(handle,coords); /* g owns the coordinates in coords */ + g = GEOSGeom_createLineString_r( + handle, coords); /* g owns the coordinates in coords */ return g; } -static GEOSGeom msGEOSShape2Geometry_multiline(shapeObj *multiline) -{ +static GEOSGeom msGEOSShape2Geometry_multiline(shapeObj *multiline) { int i; GEOSGeom g; GEOSGeom *lines; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!multiline) return NULL; + if (!multiline) + return NULL; - lines = malloc(multiline->numlines*sizeof(GEOSGeom)); - if(!lines) return NULL; + lines = malloc(multiline->numlines * sizeof(GEOSGeom)); + if (!lines) + return NULL; - for(i=0; inumlines; i++) + for (i = 0; i < multiline->numlines; i++) lines[i] = msGEOSShape2Geometry_line(&(multiline->line[i])); - g = GEOSGeom_createCollection_r(handle,GEOS_MULTILINESTRING, lines, multiline->numlines); + g = GEOSGeom_createCollection_r(handle, GEOS_MULTILINESTRING, lines, + multiline->numlines); free(lines); return g; } -static GEOSGeom msGEOSShape2Geometry_simplepolygon(shapeObj *shape, int r, int *outerList) -{ +static GEOSGeom msGEOSShape2Geometry_simplepolygon(shapeObj *shape, int r, + int *outerList) { int i, j, k; GEOSCoordSeq coords; GEOSGeom g; GEOSGeom outerRing; - GEOSGeom *innerRings=NULL; - int numInnerRings=0, *innerList; + GEOSGeom *innerRings = NULL; + int numInnerRings = 0, *innerList; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape || !outerList) return NULL; + if (!shape || !outerList) + return NULL; /* build the outer shell */ - coords = GEOSCoordSeq_create_r(handle,shape->line[r].numpoints, 2); /* todo handle z's */ - if(!coords) return NULL; + coords = GEOSCoordSeq_create_r(handle, shape->line[r].numpoints, + 2); /* todo handle z's */ + if (!coords) + return NULL; - for(i=0; iline[r].numpoints; i++) { - GEOSCoordSeq_setX_r(handle,coords, i, shape->line[r].point[i].x); - GEOSCoordSeq_setY_r(handle,coords, i, shape->line[r].point[i].y); + for (i = 0; i < shape->line[r].numpoints; i++) { + GEOSCoordSeq_setX_r(handle, coords, i, shape->line[r].point[i].x); + GEOSCoordSeq_setY_r(handle, coords, i, shape->line[r].point[i].y); /* GEOSCoordSeq_setZ(coords, i, shape->line[r].point[i].z); */ } - outerRing = GEOSGeom_createLinearRing_r(handle,coords); /* outerRing owns the coordinates in coords */ + outerRing = GEOSGeom_createLinearRing_r( + handle, coords); /* outerRing owns the coordinates in coords */ /* build the holes */ innerList = msGetInnerList(shape, r, outerList); - for(j=0; jnumlines; j++) - if(innerList[j] == MS_TRUE) numInnerRings++; + for (j = 0; j < shape->numlines; j++) + if (innerList[j] == MS_TRUE) + numInnerRings++; - if(numInnerRings > 0) { + if (numInnerRings > 0) { k = 0; /* inner ring counter */ - innerRings = msSmallMalloc(numInnerRings*sizeof(GEOSGeom)); + innerRings = msSmallMalloc(numInnerRings * sizeof(GEOSGeom)); - for(j=0; jnumlines; j++) { - if(innerList[j] == MS_FALSE) continue; + for (j = 0; j < shape->numlines; j++) { + if (innerList[j] == MS_FALSE) + continue; - coords = GEOSCoordSeq_create_r(handle,shape->line[j].numpoints, 2); /* todo handle z's */ - if(!coords) { + coords = GEOSCoordSeq_create_r(handle, shape->line[j].numpoints, + 2); /* todo handle z's */ + if (!coords) { free(innerRings); free(innerList); return NULL; /* todo, this will leak memory (shell + allocated holes) */ } - for(i=0; iline[j].numpoints; i++) { - GEOSCoordSeq_setX_r(handle,coords, i, shape->line[j].point[i].x); - GEOSCoordSeq_setY_r(handle,coords, i, shape->line[j].point[i].y); + for (i = 0; i < shape->line[j].numpoints; i++) { + GEOSCoordSeq_setX_r(handle, coords, i, shape->line[j].point[i].x); + GEOSCoordSeq_setY_r(handle, coords, i, shape->line[j].point[i].y); /* GEOSCoordSeq_setZ(coords, i, shape->line[j].point[i].z); */ } - innerRings[k] = GEOSGeom_createLinearRing_r(handle,coords); /* innerRings[k] owns the coordinates in coords */ + innerRings[k] = GEOSGeom_createLinearRing_r( + handle, coords); /* innerRings[k] owns the coordinates in coords */ k++; } } - g = GEOSGeom_createPolygon_r(handle,outerRing, innerRings, numInnerRings); + g = GEOSGeom_createPolygon_r(handle, outerRing, innerRings, numInnerRings); - free(innerList); /* clean up */ + free(innerList); /* clean up */ free(innerRings); /* clean up */ return g; } -static GEOSGeom msGEOSShape2Geometry_polygon(shapeObj *shape) -{ +static GEOSGeom msGEOSShape2Geometry_polygon(shapeObj *shape) { int i, j; GEOSGeom *polygons; - int *outerList, numOuterRings=0, lastOuterRing=0; + int *outerList, numOuterRings = 0, lastOuterRing = 0; GEOSGeom g; GEOSContextHandle_t handle = msGetGeosContextHandle(); outerList = msGetOuterList(shape); - for(i=0; inumlines; i++) { - if(outerList[i] == MS_TRUE) { + for (i = 0; i < shape->numlines; i++) { + if (outerList[i] == MS_TRUE) { numOuterRings++; lastOuterRing = i; /* save for the simple case */ } } - if(numOuterRings == 1) { + if (numOuterRings == 1) { g = msGEOSShape2Geometry_simplepolygon(shape, lastOuterRing, outerList); } else { /* a true multipolygon */ - polygons = msSmallMalloc(numOuterRings*sizeof(GEOSGeom)); + polygons = msSmallMalloc(numOuterRings * sizeof(GEOSGeom)); j = 0; /* part counter */ - for(i=0; inumlines; i++) { - if(outerList[i] == MS_FALSE) continue; - polygons[j] = msGEOSShape2Geometry_simplepolygon(shape, i, outerList); /* TODO: account for NULL return values */ + for (i = 0; i < shape->numlines; i++) { + if (outerList[i] == MS_FALSE) + continue; + polygons[j] = msGEOSShape2Geometry_simplepolygon( + shape, i, outerList); /* TODO: account for NULL return values */ j++; } - g = GEOSGeom_createCollection_r(handle,GEOS_MULTIPOLYGON, polygons, numOuterRings); + g = GEOSGeom_createCollection_r(handle, GEOS_MULTIPOLYGON, polygons, + numOuterRings); free(polygons); } @@ -342,65 +357,69 @@ static GEOSGeom msGEOSShape2Geometry_polygon(shapeObj *shape) return g; } -GEOSGeom msGEOSShape2Geometry(shapeObj *shape) -{ - if(!shape) +GEOSGeom msGEOSShape2Geometry(shapeObj *shape) { + if (!shape) return NULL; /* a NULL shape generates a NULL geometry */ - switch(shape->type) { - case MS_SHAPE_POINT: - if(shape->numlines == 0 || shape->line[0].numpoints == 0) /* not enough info for a point */ - return NULL; - - if(shape->line[0].numpoints == 1) /* simple point */ - return msGEOSShape2Geometry_point(&(shape->line[0].point[0])); - else /* multi-point */ - return msGEOSShape2Geometry_multipoint(&(shape->line[0])); - break; - case MS_SHAPE_LINE: - if(shape->numlines == 0 || shape->line[0].numpoints < 2) /* not enough info for a line */ - return NULL; - - if(shape->numlines == 1) /* simple line */ - return msGEOSShape2Geometry_line(&(shape->line[0])); - else /* multi-line */ - return msGEOSShape2Geometry_multiline(shape); - break; - case MS_SHAPE_POLYGON: - if(shape->numlines == 0 || shape->line[0].numpoints < 4) /* not enough info for a polygon (first=last) */ - return NULL; - - return msGEOSShape2Geometry_polygon(shape); /* simple and multipolygon cases are addressed */ - break; - default: - break; + switch (shape->type) { + case MS_SHAPE_POINT: + if (shape->numlines == 0 || + shape->line[0].numpoints == 0) /* not enough info for a point */ + return NULL; + + if (shape->line[0].numpoints == 1) /* simple point */ + return msGEOSShape2Geometry_point(&(shape->line[0].point[0])); + else /* multi-point */ + return msGEOSShape2Geometry_multipoint(&(shape->line[0])); + break; + case MS_SHAPE_LINE: + if (shape->numlines == 0 || + shape->line[0].numpoints < 2) /* not enough info for a line */ + return NULL; + + if (shape->numlines == 1) /* simple line */ + return msGEOSShape2Geometry_line(&(shape->line[0])); + else /* multi-line */ + return msGEOSShape2Geometry_multiline(shape); + break; + case MS_SHAPE_POLYGON: + if (shape->numlines == 0 || + shape->line[0].numpoints < + 4) /* not enough info for a polygon (first=last) */ + return NULL; + + return msGEOSShape2Geometry_polygon( + shape); /* simple and multipolygon cases are addressed */ + break; + default: + break; } return NULL; /* should not get here */ } -static shapeObj *msGEOSGeometry2Shape_point(GEOSGeom g) -{ +static shapeObj *msGEOSGeometry2Shape_point(GEOSGeom g) { GEOSCoordSeq coords; - shapeObj *shape=NULL; + shapeObj *shape = NULL; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!g) return NULL; + if (!g) + return NULL; - shape = (shapeObj *) malloc(sizeof(shapeObj)); + shape = (shapeObj *)malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POINT; - shape->line = (lineObj *) malloc(sizeof(lineObj)); + shape->line = (lineObj *)malloc(sizeof(lineObj)); shape->numlines = 1; - shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)); + shape->line[0].point = (pointObj *)malloc(sizeof(pointObj)); shape->line[0].numpoints = 1; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; - coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq_r(handle,g); + coords = (GEOSCoordSeq)GEOSGeom_getCoordSeq_r(handle, g); - GEOSCoordSeq_getX_r(handle,coords, 0, &(shape->line[0].point[0].x)); - GEOSCoordSeq_getY_r(handle,coords, 0, &(shape->line[0].point[0].y)); + GEOSCoordSeq_getX_r(handle, coords, 0, &(shape->line[0].point[0].x)); + GEOSCoordSeq_getY_r(handle, coords, 0, &(shape->line[0].point[0].y)); /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[0].z)); */ shape->bounds.minx = shape->bounds.maxx = shape->line[0].point[0].x; @@ -409,35 +428,35 @@ static shapeObj *msGEOSGeometry2Shape_point(GEOSGeom g) return shape; } -static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g) -{ +static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g) { int i; int numPoints; GEOSCoordSeq coords; GEOSGeom point; - shapeObj *shape=NULL; + shapeObj *shape = NULL; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!g) return NULL; - numPoints = GEOSGetNumGeometries_r(handle,g); /* each geometry has 1 point */ + if (!g) + return NULL; + numPoints = GEOSGetNumGeometries_r(handle, g); /* each geometry has 1 point */ - shape = (shapeObj *) malloc(sizeof(shapeObj)); + shape = (shapeObj *)malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POINT; - shape->line = (lineObj *) malloc(sizeof(lineObj)); + shape->line = (lineObj *)malloc(sizeof(lineObj)); shape->numlines = 1; - shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints); + shape->line[0].point = (pointObj *)malloc(sizeof(pointObj) * numPoints); shape->line[0].numpoints = numPoints; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; - for(i=0; iline[0].point[i].x)); - GEOSCoordSeq_getY_r(handle,coords, 0, &(shape->line[0].point[i].y)); + GEOSCoordSeq_getX_r(handle, coords, 0, &(shape->line[0].point[i].x)); + GEOSCoordSeq_getY_r(handle, coords, 0, &(shape->line[0].point[i].y)); /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[i].z)); */ } @@ -446,32 +465,32 @@ static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g) return shape; } -static shapeObj *msGEOSGeometry2Shape_line(GEOSGeom g) -{ - shapeObj *shape=NULL; +static shapeObj *msGEOSGeometry2Shape_line(GEOSGeom g) { + shapeObj *shape = NULL; GEOSContextHandle_t handle = msGetGeosContextHandle(); int i; int numPoints; GEOSCoordSeq coords; - if(!g) return NULL; - numPoints = GEOSGetNumCoordinates_r(handle,g); - coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq_r(handle,g); + if (!g) + return NULL; + numPoints = GEOSGetNumCoordinates_r(handle, g); + coords = (GEOSCoordSeq)GEOSGeom_getCoordSeq_r(handle, g); - shape = (shapeObj *) malloc(sizeof(shapeObj)); + shape = (shapeObj *)malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_LINE; - shape->line = (lineObj *) malloc(sizeof(lineObj)); + shape->line = (lineObj *)malloc(sizeof(lineObj)); shape->numlines = 1; - shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints); + shape->line[0].point = (pointObj *)malloc(sizeof(pointObj) * numPoints); shape->line[0].numpoints = numPoints; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; - for(i=0; iline[0].point[i].x)); - GEOSCoordSeq_getY_r(handle,coords, i, &(shape->line[0].point[i].y)); + for (i = 0; i < numPoints; i++) { + GEOSCoordSeq_getX_r(handle, coords, i, &(shape->line[0].point[i].x)); + GEOSCoordSeq_getY_r(handle, coords, i, &(shape->line[0].point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(shape->line[0].point[i].z)); */ } @@ -480,29 +499,31 @@ static shapeObj *msGEOSGeometry2Shape_line(GEOSGeom g) return shape; } -static void msGEOSGeometry2Shape_multiline_part(GEOSContextHandle_t handle, GEOSGeom part, shapeObj *shape) { +static void msGEOSGeometry2Shape_multiline_part(GEOSContextHandle_t handle, + GEOSGeom part, + shapeObj *shape) { int i; int type, numGeometries, numPoints; GEOSCoordSeq coords; lineObj line; - - type = GEOSGeomTypeId_r(handle,part); + + type = GEOSGeomTypeId_r(handle, part); if (type == GEOS_MULTILINESTRING) { - numGeometries = GEOSGetNumGeometries_r(handle,part); + numGeometries = GEOSGetNumGeometries_r(handle, part); - for(i=0; itype = MS_SHAPE_LINE; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; - for(i=0; itype = MS_SHAPE_POLYGON; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; /* exterior ring */ - ring = (GEOSGeom) GEOSGetExteriorRing_r(handle,g); - numPoints = GEOSGetNumCoordinates_r(handle,ring); - coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq_r(handle,ring); + ring = (GEOSGeom)GEOSGetExteriorRing_r(handle, g); + numPoints = GEOSGetNumCoordinates_r(handle, ring); + coords = (GEOSCoordSeq)GEOSGeom_getCoordSeq_r(handle, ring); - line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); + line.point = (pointObj *)malloc(sizeof(pointObj) * numPoints); line.numpoints = numPoints; - for(i=0; itype = MS_SHAPE_POLYGON; - shape->geometry = (GEOSGeom) g; + shape->geometry = (GEOSGeom)g; - for(k=0; ktype = MS_SHAPE_LINE; - shape->geometry = (GEOSGeom) g; - - const int numGeoms = GEOSGetNumGeometries_r(handle,g); - for(int i = 0; i < numGeoms; i++) { /* for each geometry */ - shapeObj* shape2 = msGEOSGeometry2Shape((GEOSGeom)GEOSGetGeometryN_r(handle,g, i)); - if (shape2) { - for (int j = 0; j < shape2->numlines; j++) - msAddLineDirectly(shape, &shape2->line[j]); - shape2->numlines = 0; - shape2->geometry = NULL; /* not owned */ - msFreeShape(shape2); - } + type = GEOSGeomTypeId_r(handle, g); + switch (type) { + case GEOS_POINT: + return msGEOSGeometry2Shape_point(g); + break; + case GEOS_MULTIPOINT: + return msGEOSGeometry2Shape_multipoint(g); + break; + case GEOS_LINESTRING: + return msGEOSGeometry2Shape_line(g); + break; + case GEOS_MULTILINESTRING: + return msGEOSGeometry2Shape_multiline(g); + break; + case GEOS_POLYGON: + return msGEOSGeometry2Shape_polygon(g); + break; + case GEOS_MULTIPOLYGON: + return msGEOSGeometry2Shape_multipolygon(g); + break; + case GEOS_GEOMETRYCOLLECTION: + if (!GEOSisEmpty_r(handle, g)) { + shapeObj *shape = (shapeObj *)malloc(sizeof(shapeObj)); + msInitShape(shape); + shape->type = MS_SHAPE_LINE; + shape->geometry = (GEOSGeom)g; + + const int numGeoms = GEOSGetNumGeometries_r(handle, g); + for (int i = 0; i < numGeoms; i++) { /* for each geometry */ + shapeObj *shape2 = + msGEOSGeometry2Shape((GEOSGeom)GEOSGetGeometryN_r(handle, g, i)); + if (shape2) { + for (int j = 0; j < shape2->numlines; j++) + msAddLineDirectly(shape, &shape2->line[j]); + shape2->numlines = 0; + shape2->geometry = NULL; /* not owned */ + msFreeShape(shape2); } - msComputeBounds(shape); - return shape; } - break; - default: - msSetError(MS_GEOSERR, "Unsupported GEOS geometry type (%d).", "msGEOSGeometry2Shape()", type); + msComputeBounds(shape); + return shape; + } + break; + default: + msSetError(MS_GEOSERR, "Unsupported GEOS geometry type (%d).", + "msGEOSGeometry2Shape()", type); } return NULL; } @@ -722,20 +745,20 @@ shapeObj *msGEOSGeometry2Shape(GEOSGeom g) ** Maintenence functions exposed to MapServer/MapScript. */ -void msGEOSFreeGeometry(shapeObj *shape) -{ +void msGEOSFreeGeometry(shapeObj *shape) { #ifdef USE_GEOS - GEOSGeom g=NULL; + GEOSGeom g = NULL; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape || !shape->geometry) + if (!shape || !shape->geometry) return; - g = (GEOSGeom) shape->geometry; - GEOSGeom_destroy_r(handle,g); + g = (GEOSGeom)shape->geometry; + GEOSGeom_destroy_r(handle, g); shape->geometry = NULL; #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSFreeGEOSGeom()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSFreeGEOSGeom()"); return; #endif } @@ -743,59 +766,61 @@ void msGEOSFreeGeometry(shapeObj *shape) /* ** WKT input and output functions */ -shapeObj *msGEOSShapeFromWKT(const char *wkt) -{ +shapeObj *msGEOSShapeFromWKT(const char *wkt) { #ifdef USE_GEOS GEOSGeom g; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!wkt) + if (!wkt) return NULL; - g = GEOSGeomFromWKT_r(handle,wkt); - if(!g) { - msSetError(MS_GEOSERR, "Error reading WKT geometry \"%s\".", "msGEOSShapeFromWKT()", wkt); + g = GEOSGeomFromWKT_r(handle, wkt); + if (!g) { + msSetError(MS_GEOSERR, "Error reading WKT geometry \"%s\".", + "msGEOSShapeFromWKT()", wkt); return NULL; } else { return msGEOSGeometry2Shape(g); } #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSShapeFromWKT()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSShapeFromWKT()"); return NULL; #endif } /* Return should be freed with msGEOSFreeWKT */ -char *msGEOSShapeToWKT(shapeObj *shape) -{ +char *msGEOSShapeToWKT(shapeObj *shape) { #ifdef USE_GEOS GEOSGeom g; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) + if (!shape) return NULL; /* if we have a geometry, we should update it*/ msGEOSFreeGeometry(shape); - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g = (GEOSGeom) shape->geometry; - if(!g) return NULL; + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g = (GEOSGeom)shape->geometry; + if (!g) + return NULL; - return GEOSGeomToWKT_r(handle,g); + return GEOSGeomToWKT_r(handle, g); #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSShapeToWKT()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSShapeToWKT()"); return NULL; #endif } -void msGEOSFreeWKT(char* pszGEOSWKT) -{ +void msGEOSFreeWKT(char *pszGEOSWKT) { #ifdef USE_GEOS GEOSContextHandle_t handle = msGetGeosContextHandle(); -#if GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 2) - GEOSFree_r(handle,pszGEOSWKT); +#if GEOS_VERSION_MAJOR > 3 || \ + (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 2) + GEOSFree_r(handle, pszGEOSWKT); #endif #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSFreeWKT()"); @@ -803,12 +828,13 @@ void msGEOSFreeWKT(char* pszGEOSWKT) } shapeObj *msGEOSOffsetCurve(shapeObj *p, double offset) { -#if defined USE_GEOS && (GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 3)) +#if defined USE_GEOS && (GEOS_VERSION_MAJOR > 3 || \ + (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 3)) int typeChanged = 0; GEOSGeom g1, g2 = NULL; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!p) + if (!p) return NULL; /* @@ -816,40 +842,41 @@ shapeObj *msGEOSOffsetCurve(shapeObj *p, double offset) { * works with lines, naturally. In order to allow offsets for a MapServer * polygonObj, it has to be processed as line and afterwards reverted. */ - if(p->type == MS_SHAPE_POLYGON) { + if (p->type == MS_SHAPE_POLYGON) { p->type = MS_SHAPE_LINE; typeChanged = 1; msGEOSFreeGeometry(p); } - if(typeChanged || !p->geometry) - p->geometry = (GEOSGeom) msGEOSShape2Geometry(p); - - g1 = (GEOSGeom) p->geometry; - if(!g1) return NULL; - - if (GEOSGeomTypeId_r(handle,g1) == GEOS_MULTILINESTRING) - { - GEOSGeom *lines = malloc(p->numlines*sizeof(GEOSGeom)); - if (!lines) return NULL; - for(int i=0; inumlines; i++) - { - lines[i] = GEOSOffsetCurve_r(handle, GEOSGetGeometryN_r(handle,g1,i), - offset, 4, GEOSBUF_JOIN_MITRE, fabs(offset*1.5)); + if (typeChanged || !p->geometry) + p->geometry = (GEOSGeom)msGEOSShape2Geometry(p); + + g1 = (GEOSGeom)p->geometry; + if (!g1) + return NULL; + + if (GEOSGeomTypeId_r(handle, g1) == GEOS_MULTILINESTRING) { + GEOSGeom *lines = malloc(p->numlines * sizeof(GEOSGeom)); + if (!lines) + return NULL; + for (int i = 0; i < p->numlines; i++) { + lines[i] = + GEOSOffsetCurve_r(handle, GEOSGetGeometryN_r(handle, g1, i), offset, + 4, GEOSBUF_JOIN_MITRE, fabs(offset * 1.5)); } - g2 = GEOSGeom_createCollection_r(handle,GEOS_MULTILINESTRING, lines, p->numlines); + g2 = GEOSGeom_createCollection_r(handle, GEOS_MULTILINESTRING, lines, + p->numlines); free(lines); - } - else - { - g2 = GEOSOffsetCurve_r(handle,g1, offset, 4, GEOSBUF_JOIN_MITRE, fabs(offset*1.5)); + } else { + g2 = GEOSOffsetCurve_r(handle, g1, offset, 4, GEOSBUF_JOIN_MITRE, + fabs(offset * 1.5)); } /* * Undo change of geometry type. We won't re-create the geos gemotry here, * it's up to each geos function to create it. */ - if(typeChanged) { + if (typeChanged) { msGEOSFreeGeometry(p); p->type = MS_SHAPE_POLYGON; } @@ -859,7 +886,8 @@ shapeObj *msGEOSOffsetCurve(shapeObj *p, double offset) { return NULL; #else - msSetError(MS_GEOSERR, "GEOS Offset Curve support is not available.", "msGEOSingleSidedBuffer()"); + msSetError(MS_GEOSERR, "GEOS Offset Curve support is not available.", + "msGEOSingleSidedBuffer()"); return NULL; #endif } @@ -868,22 +896,22 @@ shapeObj *msGEOSOffsetCurve(shapeObj *p, double offset) { ** Analytical functions exposed to MapServer/MapScript. */ -shapeObj *msGEOSBuffer(shapeObj *shape, double width) -{ +shapeObj *msGEOSBuffer(shapeObj *shape, double width) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) + if (!shape) return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSBuffer_r(handle,g1, width, 30); + g2 = GEOSBuffer_r(handle, g1, width, 30); return msGEOSGeometry2Shape(g2); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSBuffer()"); @@ -891,87 +919,92 @@ shapeObj *msGEOSBuffer(shapeObj *shape, double width) #endif } -shapeObj *msGEOSSimplify(shapeObj *shape, double tolerance) -{ +shapeObj *msGEOSSimplify(shapeObj *shape, double tolerance) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) + if (!shape) return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSSimplify_r(handle,g1, tolerance); + g2 = GEOSSimplify_r(handle, g1, tolerance); return msGEOSGeometry2Shape(g2); #else - msSetError(MS_GEOSERR, "GEOS Simplify support is not available.", "msGEOSSimplify()"); + msSetError(MS_GEOSERR, "GEOS Simplify support is not available.", + "msGEOSSimplify()"); return NULL; #endif } -shapeObj *msGEOSTopologyPreservingSimplify(shapeObj *shape, double tolerance) -{ +shapeObj *msGEOSTopologyPreservingSimplify(shapeObj *shape, double tolerance) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) + if (!shape) return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSTopologyPreserveSimplify_r(handle,g1, tolerance); + g2 = GEOSTopologyPreserveSimplify_r(handle, g1, tolerance); return msGEOSGeometry2Shape(g2); #else - msSetError(MS_GEOSERR, "GEOS Simplify support is not available.", "msGEOSTopologyPreservingSimplify()"); + msSetError(MS_GEOSERR, "GEOS Simplify support is not available.", + "msGEOSTopologyPreservingSimplify()"); return NULL; #endif } -shapeObj *msGEOSConvexHull(shapeObj *shape) -{ +shapeObj *msGEOSConvexHull(shapeObj *shape) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return NULL; + if (!shape) + return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSConvexHull_r(handle,g1); + g2 = GEOSConvexHull_r(handle, g1); return msGEOSGeometry2Shape(g2); #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSConvexHull()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSConvexHull()"); return NULL; #endif } -shapeObj *msGEOSBoundary(shapeObj *shape) -{ +shapeObj *msGEOSBoundary(shapeObj *shape) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return NULL; + if (!shape) + return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSBoundary_r(handle,g1); + g2 = GEOSBoundary_r(handle, g1); return msGEOSGeometry2Shape(g2); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSBoundary()"); @@ -979,61 +1012,65 @@ shapeObj *msGEOSBoundary(shapeObj *shape) #endif } -pointObj *msGEOSGetCentroid(shapeObj *shape) -{ +pointObj *msGEOSGetCentroid(shapeObj *shape) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSCoordSeq coords; pointObj *point; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return NULL; + if (!shape) + return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; - g2 = GEOSGetCentroid_r(handle,g1); - if (!g2) return NULL; + g2 = GEOSGetCentroid_r(handle, g1); + if (!g2) + return NULL; - point = (pointObj *) malloc(sizeof(pointObj)); + point = (pointObj *)malloc(sizeof(pointObj)); - coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq_r(handle,g2); + coords = (GEOSCoordSeq)GEOSGeom_getCoordSeq_r(handle, g2); - GEOSCoordSeq_getX_r(handle,coords, 0, &(point->x)); - GEOSCoordSeq_getY_r(handle,coords, 0, &(point->y)); + GEOSCoordSeq_getX_r(handle, coords, 0, &(point->x)); + GEOSCoordSeq_getY_r(handle, coords, 0, &(point->y)); /* GEOSCoordSeq_getZ(coords, 0, &(point->z)); */ GEOSGeom_destroy_r(handle, g2); return point; #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSGetCentroid()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSGetCentroid()"); return NULL; #endif } -shapeObj *msGEOSUnion(shapeObj *shape1, shapeObj *shape2) -{ +shapeObj *msGEOSUnion(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2, g3; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return NULL; - if(!shape1->geometry) /* if no geometry for the shape then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return NULL; + if (!shape1->geometry) /* if no geometry for the shape then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return NULL; - if(!shape2->geometry) /* if no geometry for the shape then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return NULL; + if (!shape2->geometry) /* if no geometry for the shape then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return NULL; - g3 = GEOSUnion_r(handle,g1, g2); + g3 = GEOSUnion_r(handle, g1, g2); return msGEOSGeometry2Shape(g3); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSUnion()"); @@ -1041,100 +1078,108 @@ shapeObj *msGEOSUnion(shapeObj *shape1, shapeObj *shape2) #endif } -shapeObj *msGEOSIntersection(shapeObj *shape1, shapeObj *shape2) -{ +shapeObj *msGEOSIntersection(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2, g3; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return NULL; - if(!shape1->geometry) /* if no geometry for the shape then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return NULL; + if (!shape1->geometry) /* if no geometry for the shape then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return NULL; - if(!shape2->geometry) /* if no geometry for the shape then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return NULL; + if (!shape2->geometry) /* if no geometry for the shape then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return NULL; - g3 = GEOSIntersection_r(handle,g1, g2); + g3 = GEOSIntersection_r(handle, g1, g2); return msGEOSGeometry2Shape(g3); #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSIntersection()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSIntersection()"); return NULL; #endif } -shapeObj *msGEOSDifference(shapeObj *shape1, shapeObj *shape2) -{ +shapeObj *msGEOSDifference(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2, g3; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return NULL; - if(!shape1->geometry) /* if no geometry for the shape then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return NULL; + if (!shape1->geometry) /* if no geometry for the shape then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return NULL; - if(!shape2->geometry) /* if no geometry for the shape then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return NULL; + if (!shape2->geometry) /* if no geometry for the shape then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return NULL; - g3 = GEOSDifference_r(handle,g1, g2); + g3 = GEOSDifference_r(handle, g1, g2); return msGEOSGeometry2Shape(g3); #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSDifference()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSDifference()"); return NULL; #endif } -shapeObj *msGEOSSymDifference(shapeObj *shape1, shapeObj *shape2) -{ +shapeObj *msGEOSSymDifference(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2, g3; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return NULL; - if(!shape1->geometry) /* if no geometry for the shape then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return NULL; + if (!shape1->geometry) /* if no geometry for the shape then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return NULL; - if(!shape2->geometry) /* if no geometry for the shape then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return NULL; + if (!shape2->geometry) /* if no geometry for the shape then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return NULL; - g3 = GEOSSymDifference_r(handle,g1, g2); + g3 = GEOSSymDifference_r(handle, g1, g2); return msGEOSGeometry2Shape(g3); #else - msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSSymDifference()"); + msSetError(MS_GEOSERR, "GEOS support is not available.", + "msGEOSSymDifference()"); return NULL; #endif } -shapeObj *msGEOSLineMerge(shapeObj *shape) -{ +shapeObj *msGEOSLineMerge(shapeObj *shape) { #ifdef USE_GEOS GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return NULL; - if(shape->type != MS_SHAPE_LINE) return NULL; + if (!shape) + return NULL; + if (shape->type != MS_SHAPE_LINE) + return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; g2 = GEOSLineMerge_r(handle, g1); return msGEOSGeometry2Shape(g2); @@ -1144,52 +1189,64 @@ shapeObj *msGEOSLineMerge(shapeObj *shape) #endif } -shapeObj *msGEOSVoronoiDiagram(shapeObj *shape, double tolerance, int onlyEdges) -{ -#if defined(USE_GEOS) && (GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 5)) +shapeObj *msGEOSVoronoiDiagram(shapeObj *shape, double tolerance, + int onlyEdges) { +#if defined(USE_GEOS) && \ + (GEOS_VERSION_MAJOR > 3 || \ + (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 5)) GEOSGeom g1, g2; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return NULL; + if (!shape) + return NULL; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g1 = (GEOSGeom) shape->geometry; - if(!g1) return NULL; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g1 = (GEOSGeom)shape->geometry; + if (!g1) + return NULL; g2 = GEOSVoronoiDiagram_r(handle, g1, NULL, tolerance, onlyEdges); return msGEOSGeometry2Shape(g2); #else - msSetError(MS_GEOSERR, "GEOS support is not available or GEOS version is not 3.5 or higher.", "msGEOSVoronoiDiagram()"); + msSetError( + MS_GEOSERR, + "GEOS support is not available or GEOS version is not 3.5 or higher.", + "msGEOSVoronoiDiagram()"); return NULL; #endif } -static int keepEdge(lineObj *segment, shapeObj *polygon) -{ - int i,j; - - if(segment->numpoints<2) return MS_FALSE; - if(msIntersectPointPolygon(&segment->point[0], polygon) != MS_TRUE) return MS_FALSE; - if(msIntersectPointPolygon(&segment->point[1], polygon) != MS_TRUE) return MS_FALSE; - - for(i=0; inumlines; i++) - for(j=1; jline[i].numpoints; j++) - if(msIntersectSegments(&(segment->point[0]), &(segment->point[1]), &(polygon->line[i].point[j-1]), &(polygon->line[i].point[j])) == MS_TRUE) - return(MS_FALSE); +static int keepEdge(lineObj *segment, shapeObj *polygon) { + int i, j; - return(MS_TRUE); + if (segment->numpoints < 2) + return MS_FALSE; + if (msIntersectPointPolygon(&segment->point[0], polygon) != MS_TRUE) + return MS_FALSE; + if (msIntersectPointPolygon(&segment->point[1], polygon) != MS_TRUE) + return MS_FALSE; + + for (i = 0; i < polygon->numlines; i++) + for (j = 1; j < polygon->line[i].numpoints; j++) + if (msIntersectSegments(&(segment->point[0]), &(segment->point[1]), + &(polygon->line[i].point[j - 1]), + &(polygon->line[i].point[j])) == MS_TRUE) + return (MS_FALSE); + + return (MS_TRUE); } -#define ARE_SAME_POINTS(a,b) (((a).x!=(b).x || (a).y!=(b).y)?MS_FALSE:MS_TRUE) +#define ARE_SAME_POINTS(a, b) \ + (((a).x != (b).x || (a).y != (b).y) ? MS_FALSE : MS_TRUE) -// returns the index of the node, we use z to store a count of points at the same coordinate -static int buildNodes(multipointObj *nodes, pointObj *point) -{ +// returns the index of the node, we use z to store a count of points at the +// same coordinate +static int buildNodes(multipointObj *nodes, pointObj *point) { int i; - for(i=0; inumpoints; i++) { - if(ARE_SAME_POINTS(nodes->point[i], *point)) { // found it + for (i = 0; i < nodes->numpoints; i++) { + if (ARE_SAME_POINTS(nodes->point[i], *point)) { // found it nodes->point[i].z++; return i; } @@ -1204,60 +1261,70 @@ static int buildNodes(multipointObj *nodes, pointObj *point) return i; } -shapeObj *msGEOSCenterline(shapeObj *shape) -{ -#if defined(USE_GEOS) && (GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 5)) +shapeObj *msGEOSCenterline(shapeObj *shape) { +#if defined(USE_GEOS) && \ + (GEOS_VERSION_MAJOR > 3 || \ + (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 5)) int i; - shapeObj *shape2=NULL; + shapeObj *shape2 = NULL; multipointObj nodes; graphObj *graph; - int *path=NULL; // array of node indexes - int path_size=0; - double path_dist=-1, max_path_dist=-1; + int *path = NULL; // array of node indexes + int path_size = 0; + double path_dist = -1, max_path_dist = -1; - if(!shape) return NULL; - if(shape->type != MS_SHAPE_POLYGON) { - msSetError(MS_GEOSERR, "Centerlines can only be computed for polygon shapes.", "msGEOSCenterline()"); + if (!shape) + return NULL; + if (shape->type != MS_SHAPE_POLYGON) { + msSetError(MS_GEOSERR, + "Centerlines can only be computed for polygon shapes.", + "msGEOSCenterline()"); return NULL; } shape2 = msGEOSVoronoiDiagram(shape, 0.0, MS_TRUE); - if(!shape2) { - msSetError(MS_GEOSERR, "Voronoi diagram generation failed.", "msGEOSCenterline()"); + if (!shape2) { + msSetError(MS_GEOSERR, "Voronoi diagram generation failed.", + "msGEOSCenterline()"); return NULL; } // process the edges and build a graph representation - nodes.point = (pointObj *) malloc(shape2->numlines*sizeof(pointObj)*2); + nodes.point = (pointObj *)malloc(shape2->numlines * sizeof(pointObj) * 2); nodes.numpoints = 0; - if(!nodes.point) { + if (!nodes.point) { msFreeShape(shape2); free(shape2); return NULL; } - graph = msCreateGraph(shape2->numlines*2); - if(!graph) { + graph = msCreateGraph(shape2->numlines * 2); + if (!graph) { msFreeShape(shape2); free(shape2); free(nodes.point); return NULL; } - for(i=0; inumlines; i++) { - if(keepEdge(&shape2->line[i], shape) == MS_TRUE) { + for (i = 0; i < shape2->numlines; i++) { + if (keepEdge(&shape2->line[i], shape) == MS_TRUE) { int src = buildNodes(&nodes, &shape2->line[i].point[0]); int dest = buildNodes(&nodes, &shape2->line[i].point[1]); - msGraphAddEdge(graph, src, dest, msDistancePointToPoint(&shape2->line[i].point[0], &shape2->line[i].point[1])); + msGraphAddEdge(graph, src, dest, + msDistancePointToPoint(&shape2->line[i].point[0], + &shape2->line[i].point[1])); } } - msFreeShape(shape2); // done with voronoi geometry, shape2 is still allocated though, just empty + msFreeShape(shape2); // done with voronoi geometry, shape2 is still allocated + // though, just empty shape2->type = MS_SHAPE_LINE; // will fill with centerline - if(nodes.numpoints == 0) { - msSetError(MS_GEOSERR, "Centerline generation failed, try densifying the shapes.", "msGEOSCenterline()"); + if (nodes.numpoints == 0) { + msSetError(MS_GEOSERR, + "Centerline generation failed, try densifying the shapes.", + "msGEOSCenterline()"); free(shape2); msFreeGraph(graph); free(nodes.point); @@ -1265,20 +1332,23 @@ shapeObj *msGEOSCenterline(shapeObj *shape) } // step through edge nodes (z=1) - for(i=0; i max_path_dist) { + int *tmp_path = NULL; + int tmp_path_size = 0; + double tmp_path_dist = -1; + + if (i == path[path_size - 1]) + continue; // skip, graph is bi-directional so it can't be any longer + tmp_path = msGraphGetLongestShortestPath(graph, i, &tmp_path_size, + &tmp_path_dist); + if (tmp_path_dist > max_path_dist) { free(path); path = tmp_path; path_size = tmp_path_size; @@ -1292,15 +1362,16 @@ shapeObj *msGEOSCenterline(shapeObj *shape) msFreeGraph(graph); // done with graph // transform the path into a shape - if(!path) { - msSetError(MS_GEOSERR, "Centerline generation failed.", "msGEOSCenterline()"); + if (!path) { + msSetError(MS_GEOSERR, "Centerline generation failed.", + "msGEOSCenterline()"); free(shape2); free(nodes.point); return NULL; } else { lineObj line; - line.point = (pointObj *) malloc(path_size*sizeof(pointObj)); - if(!line.point) { + line.point = (pointObj *)malloc(path_size * sizeof(pointObj)); + if (!line.point) { free(shape2); free(path); free(nodes.point); @@ -1308,7 +1379,7 @@ shapeObj *msGEOSCenterline(shapeObj *shape) } line.numpoints = path_size; - for(i=0; igeometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); g1 = shape1->geometry; - if(!g1) return -1; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); g2 = shape2->geometry; - if(!g2) return -1; + if (!g2) + return -1; - result = GEOSContains_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSContains_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSContains()"); return -1; @@ -1363,28 +1438,29 @@ int msGEOSContains(shapeObj *shape1, shapeObj *shape2) /* ** Does shape1 overlap shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSOverlaps(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSOverlaps(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); g1 = shape1->geometry; - if(!g1) return -1; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); g2 = shape2->geometry; - if(!g2) return -1; + if (!g2) + return -1; - result = GEOSOverlaps_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSOverlaps_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSOverlaps()"); return -1; @@ -1394,28 +1470,29 @@ int msGEOSOverlaps(shapeObj *shape1, shapeObj *shape2) /* ** Is shape1 within shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSWithin(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSWithin(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); g1 = shape1->geometry; - if(!g1) return -1; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); g2 = shape2->geometry; - if(!g2) return -1; + if (!g2) + return -1; - result = GEOSWithin_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSWithin_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSWithin()"); return -1; @@ -1425,28 +1502,29 @@ int msGEOSWithin(shapeObj *shape1, shapeObj *shape2) /* ** Does shape1 cross shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSCrosses(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSCrosses(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); g1 = shape1->geometry; - if(!g1) return -1; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); g2 = shape2->geometry; - if(!g2) return -1; + if (!g2) + return -1; - result = GEOSCrosses_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSCrosses_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSCrosses()"); return -1; @@ -1456,49 +1534,50 @@ int msGEOSCrosses(shapeObj *shape1, shapeObj *shape2) /* ** Does shape1 intersect shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSIntersects(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSIntersects(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return -1; + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return -1; + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return -1; - result = GEOSIntersects_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSIntersects_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - switch(shape1->type) { /* todo: deal with point shapes */ - case(MS_SHAPE_LINE): - switch(shape2->type) { - case(MS_SHAPE_LINE): - return msIntersectPolylines(shape1, shape2); - case(MS_SHAPE_POLYGON): - return msIntersectPolylinePolygon(shape1, shape2); - } - break; - case(MS_SHAPE_POLYGON): - switch(shape2->type) { - case(MS_SHAPE_LINE): - return msIntersectPolylinePolygon(shape2, shape1); - case(MS_SHAPE_POLYGON): - return msIntersectPolygons(shape1, shape2); - } - break; + switch (shape1->type) { /* todo: deal with point shapes */ + case (MS_SHAPE_LINE): + switch (shape2->type) { + case (MS_SHAPE_LINE): + return msIntersectPolylines(shape1, shape2); + case (MS_SHAPE_POLYGON): + return msIntersectPolylinePolygon(shape1, shape2); + } + break; + case (MS_SHAPE_POLYGON): + switch (shape2->type) { + case (MS_SHAPE_LINE): + return msIntersectPolylinePolygon(shape2, shape1); + case (MS_SHAPE_POLYGON): + return msIntersectPolygons(shape1, shape2); + } + break; } return -1; @@ -1508,28 +1587,29 @@ int msGEOSIntersects(shapeObj *shape1, shapeObj *shape2) /* ** Does shape1 touch shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSTouches(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSTouches(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return -1; + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return -1; + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return -1; - result = GEOSTouches_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSTouches_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSTouches()"); return -1; @@ -1539,28 +1619,29 @@ int msGEOSTouches(shapeObj *shape1, shapeObj *shape2) /* ** Does shape1 equal shape2, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSEquals(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSEquals(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return -1; + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return -1; + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return -1; - result = GEOSEquals_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSEquals_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSEquals()"); return -1; @@ -1570,28 +1651,29 @@ int msGEOSEquals(shapeObj *shape1, shapeObj *shape2) /* ** Are shape1 and shape2 disjoint, returns MS_TRUE/MS_FALSE or -1 for an error. */ -int msGEOSDisjoint(shapeObj *shape1, shapeObj *shape2) -{ +int msGEOSDisjoint(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return -1; + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return -1; + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return -1; - result = GEOSDisjoint_r(handle,g1, g2); - return ((result==2) ? -1 : result); + result = GEOSDisjoint_r(handle, g1, g2); + return ((result == 2) ? -1 : result); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSDisjoint()"); return -1; @@ -1601,25 +1683,30 @@ int msGEOSDisjoint(shapeObj *shape1, shapeObj *shape2) /* ** Useful misc. functions that return -1 on failure. */ -double msGEOSArea(shapeObj *shape) -{ -#if defined(USE_GEOS) && defined(GEOS_CAPI_VERSION_MAJOR) && defined(GEOS_CAPI_VERSION_MINOR) && (GEOS_CAPI_VERSION_MAJOR > 1 || GEOS_CAPI_VERSION_MINOR >= 1) +double msGEOSArea(shapeObj *shape) { +#if defined(USE_GEOS) && defined(GEOS_CAPI_VERSION_MAJOR) && \ + defined(GEOS_CAPI_VERSION_MINOR) && \ + (GEOS_CAPI_VERSION_MAJOR > 1 || GEOS_CAPI_VERSION_MINOR >= 1) GEOSGeom g; double area; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return -1; + if (!shape) + return -1; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g = (GEOSGeom) shape->geometry; - if(!g) return -1; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g = (GEOSGeom)shape->geometry; + if (!g) + return -1; - result = GEOSArea_r(handle,g, &area); - return ((result==0) ? -1 : area); + result = GEOSArea_r(handle, g, &area); + return ((result == 0) ? -1 : area); #elif defined(USE_GEOS) - msSetError(MS_GEOSERR, "GEOS support enabled, but old version lacks GEOSArea().", "msGEOSArea()"); + msSetError(MS_GEOSERR, + "GEOS support enabled, but old version lacks GEOSArea().", + "msGEOSArea()"); return -1; #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSArea()"); @@ -1627,26 +1714,31 @@ double msGEOSArea(shapeObj *shape) #endif } -double msGEOSLength(shapeObj *shape) -{ -#if defined(USE_GEOS) && defined(GEOS_CAPI_VERSION_MAJOR) && defined(GEOS_CAPI_VERSION_MINOR) && (GEOS_CAPI_VERSION_MAJOR > 1 || GEOS_CAPI_VERSION_MINOR >= 1) +double msGEOSLength(shapeObj *shape) { +#if defined(USE_GEOS) && defined(GEOS_CAPI_VERSION_MAJOR) && \ + defined(GEOS_CAPI_VERSION_MINOR) && \ + (GEOS_CAPI_VERSION_MAJOR > 1 || GEOS_CAPI_VERSION_MINOR >= 1) GEOSGeom g; double length; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape) return -1; + if (!shape) + return -1; - if(!shape->geometry) /* if no geometry for the shape then build one */ - shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); - g = (GEOSGeom) shape->geometry; - if(!g) return -1; + if (!shape->geometry) /* if no geometry for the shape then build one */ + shape->geometry = (GEOSGeom)msGEOSShape2Geometry(shape); + g = (GEOSGeom)shape->geometry; + if (!g) + return -1; - result = GEOSLength_r(handle,g, &length); - return ((result==0) ? -1 : length); + result = GEOSLength_r(handle, g, &length); + return ((result == 0) ? -1 : length); #elif defined(USE_GEOS) - msSetError(MS_GEOSERR, "GEOS support enabled, but old version lacks GEOSLength().", "msGEOSLength()"); + msSetError(MS_GEOSERR, + "GEOS support enabled, but old version lacks GEOSLength().", + "msGEOSLength()"); return -1; #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSLength()"); @@ -1654,30 +1746,32 @@ double msGEOSLength(shapeObj *shape) #endif } -double msGEOSDistance(shapeObj *shape1, shapeObj *shape2) -{ +double msGEOSDistance(shapeObj *shape1, shapeObj *shape2) { #ifdef USE_GEOS GEOSGeom g1, g2; double distance; int result; GEOSContextHandle_t handle = msGetGeosContextHandle(); - if(!shape1 || !shape2) + if (!shape1 || !shape2) return -1; - if(!shape1->geometry) /* if no geometry for shape1 then build one */ - shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1); - g1 = (GEOSGeom) shape1->geometry; - if(!g1) return -1; + if (!shape1->geometry) /* if no geometry for shape1 then build one */ + shape1->geometry = (GEOSGeom)msGEOSShape2Geometry(shape1); + g1 = (GEOSGeom)shape1->geometry; + if (!g1) + return -1; - if(!shape2->geometry) /* if no geometry for shape2 then build one */ - shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2); - g2 = (GEOSGeom) shape2->geometry; - if(!g2) return -1; + if (!shape2->geometry) /* if no geometry for shape2 then build one */ + shape2->geometry = (GEOSGeom)msGEOSShape2Geometry(shape2); + g2 = (GEOSGeom)shape2->geometry; + if (!g2) + return -1; - result = GEOSDistance_r(handle,g1, g2, &distance); - return ((result==0) ? -1 : distance); + result = GEOSDistance_r(handle, g1, g2, &distance); + return ((result == 0) ? -1 : distance); #else - return msDistanceShapeToShape(shape1, shape2); /* fall back on brute force method (for MapScript) */ + return msDistanceShapeToShape( + shape1, shape2); /* fall back on brute force method (for MapScript) */ #endif } diff --git a/mapgml.c b/mapgml.c index 3b9739f6c9..a0828cd339 100644 --- a/mapgml.c +++ b/mapgml.c @@ -33,38 +33,42 @@ #include "mapgml.h" #include "maptime.h" +/* Use only mapgml.c if WMS or WFS is available (with minor exceptions at end) + */ -/* Use only mapgml.c if WMS or WFS is available (with minor exceptions at end) */ - -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) -static int msGMLGeometryLookup(gmlGeometryListObj *geometryList, const char *type); +static int msGMLGeometryLookup(gmlGeometryListObj *geometryList, + const char *type); /* ** Functions that write the feature boundary geometry (i.e. a rectObj). */ /* GML 2.1.2 */ -static int gmlWriteBounds_GML2(FILE *stream, rectObj *rect, - const char *srsname, const char *tab, - const char *pszTopPrefix) -{ +static int gmlWriteBounds_GML2(FILE *stream, rectObj *rect, const char *srsname, + const char *tab, const char *pszTopPrefix) { char *srsname_encoded; - if(!stream) return(MS_FAILURE); - if(!rect) return(MS_FAILURE); - if(!tab) return(MS_FAILURE); + if (!stream) + return (MS_FAILURE); + if (!rect) + return (MS_FAILURE); + if (!tab) + return (MS_FAILURE); msIO_fprintf(stream, "%s<%s:boundedBy>\n", tab, pszTopPrefix); - if(srsname) { + if (srsname) { srsname_encoded = msEncodeHTMLEntities(srsname); - msIO_fprintf(stream, "%s\t\n", tab, srsname_encoded); + msIO_fprintf(stream, "%s\t\n", tab, + srsname_encoded); msFree(srsname_encoded); } else msIO_fprintf(stream, "%s\t\n", tab); msIO_fprintf(stream, "%s\t\t", tab); - msIO_fprintf(stream, "%.6f,%.6f %.6f,%.6f", rect->minx, rect->miny, rect->maxx, rect->maxy ); + msIO_fprintf(stream, "%.6f,%.6f %.6f,%.6f", rect->minx, rect->miny, + rect->maxx, rect->maxy); msIO_fprintf(stream, "\n"); msIO_fprintf(stream, "%s\t\n", tab); msIO_fprintf(stream, "%s\n", tab, pszTopPrefix); @@ -73,26 +77,30 @@ static int gmlWriteBounds_GML2(FILE *stream, rectObj *rect, } /* GML 3.1 or GML 3.2 (MapServer limits GML encoding to the level 0 profile) */ -static int gmlWriteBounds_GML3(FILE *stream, rectObj *rect, - const char *srsname, const char *tab, - const char *pszTopPrefix) -{ +static int gmlWriteBounds_GML3(FILE *stream, rectObj *rect, const char *srsname, + const char *tab, const char *pszTopPrefix) { char *srsname_encoded; - if(!stream) return(MS_FAILURE); - if(!rect) return(MS_FAILURE); - if(!tab) return(MS_FAILURE); + if (!stream) + return (MS_FAILURE); + if (!rect) + return (MS_FAILURE); + if (!tab) + return (MS_FAILURE); msIO_fprintf(stream, "%s<%s:boundedBy>\n", tab, pszTopPrefix); - if(srsname) { + if (srsname) { srsname_encoded = msEncodeHTMLEntities(srsname); - msIO_fprintf(stream, "%s\t\n", tab, srsname_encoded); + msIO_fprintf(stream, "%s\t\n", tab, + srsname_encoded); msFree(srsname_encoded); } else msIO_fprintf(stream, "%s\t\n", tab); - msIO_fprintf(stream, "%s\t\t%.6f %.6f\n", tab, rect->minx, rect->miny); - msIO_fprintf(stream, "%s\t\t%.6f %.6f\n", tab, rect->maxx, rect->maxy); + msIO_fprintf(stream, "%s\t\t%.6f %.6f\n", + tab, rect->minx, rect->miny); + msIO_fprintf(stream, "%s\t\t%.6f %.6f\n", + tab, rect->maxx, rect->maxy); msIO_fprintf(stream, "%s\t\n", tab); msIO_fprintf(stream, "%s\n", tab, pszTopPrefix); @@ -101,26 +109,26 @@ static int gmlWriteBounds_GML3(FILE *stream, rectObj *rect, } static void gmlStartGeometryContainer(FILE *stream, const char *name, - const char *namespace, const char *tab) -{ - const char *tag_name=OWS_GML_DEFAULT_GEOMETRY_NAME; + const char *namespace, const char *tab) { + const char *tag_name = OWS_GML_DEFAULT_GEOMETRY_NAME; - if(name) tag_name = name; + if (name) + tag_name = name; - if(namespace) + if (namespace) msIO_fprintf(stream, "%s<%s:%s>\n", tab, namespace, tag_name); else msIO_fprintf(stream, "%s<%s>\n", tab, tag_name); } static void gmlEndGeometryContainer(FILE *stream, const char *name, - const char *namespace, const char *tab) -{ - const char *tag_name=OWS_GML_DEFAULT_GEOMETRY_NAME; + const char *namespace, const char *tab) { + const char *tag_name = OWS_GML_DEFAULT_GEOMETRY_NAME; - if(name) tag_name = name; + if (name) + tag_name = name; - if(namespace) + if (namespace) msIO_fprintf(stream, "%s\n", tab, namespace, tag_name); else msIO_fprintf(stream, "%s\n", tab, tag_name); @@ -130,677 +138,840 @@ static void gmlEndGeometryContainer(FILE *stream, const char *name, static int gmlWriteGeometry_GML2(FILE *stream, gmlGeometryListObj *geometryList, shapeObj *shape, const char *srsname, const char *namespace, const char *tab, - int nSRSDimension, int geometry_precision) -{ + int nSRSDimension, int geometry_precision) { int i, j, k; - int *innerlist, *outerlist=NULL, numouters; + int *innerlist, *outerlist = NULL, numouters; char *srsname_encoded = NULL; int geometry_aggregate_index, geometry_simple_index; char *geometry_aggregate_name = NULL, *geometry_simple_name = NULL; - if(!stream) return(MS_FAILURE); - if(!shape) return(MS_FAILURE); - if(!tab) return(MS_FAILURE); - if(!geometryList) return(MS_FAILURE); + if (!stream) + return (MS_FAILURE); + if (!shape) + return (MS_FAILURE); + if (!tab) + return (MS_FAILURE); + if (!geometryList) + return (MS_FAILURE); - if(shape->numlines <= 0) return(MS_SUCCESS); /* empty shape, nothing to output */ + if (shape->numlines <= 0) + return (MS_SUCCESS); /* empty shape, nothing to output */ - if(srsname) + if (srsname) srsname_encoded = msEncodeHTMLEntities(srsname); /* feature geometry */ - switch(shape->type) { - case(MS_SHAPE_POINT): - geometry_simple_index = msGMLGeometryLookup(geometryList, "point"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipoint"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; - - if((geometry_simple_index != -1 && shape->line[0].numpoints == 1 && shape->numlines == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->line[0].numpoints == 1 && shape->numlines == 1)) { /* write a Point(s) */ - - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - - /* Point */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); - else - msIO_fprintf(stream, "%s\n", tab); - - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%s %.*f,%.*f,%.*f\n", - tab, geometry_precision,shape->line[i].point[j].x, geometry_precision,shape->line[i].point[j].y, geometry_precision,shape->line[i].point[j].z); - else - /* fall-through */ + switch (shape->type) { + case (MS_SHAPE_POINT): + geometry_simple_index = msGMLGeometryLookup(geometryList, "point"); + geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipoint"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + if ((geometry_simple_index != -1 && shape->line[0].numpoints == 1 && + shape->numlines == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && shape->line[0].numpoints == 1 && + shape->numlines == 1)) { /* write a Point(s) */ + + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, + tab); + + /* Point */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); + else + msIO_fprintf(stream, "%s\n", tab); + + if (nSRSDimension == 3) + msIO_fprintf( + stream, + "%s %.*f,%.*f,%.*f\n", tab, + geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y, + geometry_precision, shape->line[i].point[j].z); + else + /* fall-through */ - msIO_fprintf(stream, "%s %.*f,%.*f\n", tab, geometry_precision,shape->line[i].point[j].x, geometry_precision,shape->line[i].point[j].y); + msIO_fprintf(stream, + "%s %.*f,%.*f\n", + tab, geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y); - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s\n", tab); - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - } + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); + } + } + } else if ((geometry_aggregate_index != -1) || + (geometryList->numgeometries == 0)) { /* write a MultiPoint */ + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + /* MultiPoint */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); + else + msIO_fprintf(stream, "%s\n", tab); + + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + if (nSRSDimension == 3) + msIO_fprintf( + stream, + "%s %.*f,%.*f,%.*f\n", + tab, geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y, + geometry_precision, shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf( + stream, "%s %f,%f\n", + tab, shape->line[i].point[j].x, shape->line[i].point[j].y); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); } - } else if((geometry_aggregate_index != -1) || (geometryList->numgeometries == 0)) { /* write a MultiPoint */ - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } - /* MultiPoint */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); + msIO_fprintf(stream, "%s\n", tab); + + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } + + break; + case (MS_SHAPE_LINE): + geometry_simple_index = msGMLGeometryLookup(geometryList, "line"); + geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multiline"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + if ((geometry_simple_index != -1 && shape->numlines == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && + shape->numlines == 1)) { /* write a LineStrings(s) */ + for (i = 0; i < shape->numlines; i++) { + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); + + /* LineString */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); else - msIO_fprintf(stream, "%s\n", tab); - - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%s %.*f,%.*f,%.*f\n", - tab, geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, - geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%s %f,%f\n", tab, shape->line[i].point[j].x, shape->line[i].point[j].y); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - } + msIO_fprintf(stream, "%s\n", tab); + + msIO_fprintf(stream, "%s ", tab); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); } + msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s\n", tab); - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); } - - break; - case(MS_SHAPE_LINE): - geometry_simple_index = msGMLGeometryLookup(geometryList, "line"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multiline"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; - - if((geometry_simple_index != -1 && shape->numlines == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->numlines == 1)) { /* write a LineStrings(s) */ - for(i=0; inumlines; i++) { - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - - /* LineString */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); + } else if (geometry_aggregate_index != -1 || + (geometryList->numgeometries == 0)) { /* write a MultiCurve */ + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + /* MultiLineString */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); + else + msIO_fprintf(stream, "%s\n", tab); + + for (j = 0; j < shape->numlines; j++) { + msIO_fprintf(stream, "%s \n", + tab); /* no srsname at this point */ + msIO_fprintf(stream, "%s \n", + tab); /* no srsname at this point */ + + msIO_fprintf(stream, "%s ", tab); + for (i = 0; i < shape->line[j].numpoints; i++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[j].point[i].x, geometry_precision, + shape->line[j].point[i].y, geometry_precision, + shape->line[j].point[i].z); else - msIO_fprintf(stream, "%s\n", tab); - - msIO_fprintf(stream, "%s ", tab); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision,shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, - geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); - } - msIO_fprintf(stream, "\n"); + /* fall-through */ + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[j].point[i].x, geometry_precision, + shape->line[j].point[i].y); + } + msIO_fprintf(stream, "\n"); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + } - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s\n", tab); - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - } - } else if(geometry_aggregate_index != -1 || (geometryList->numgeometries == 0)) { /* write a MultiCurve */ - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } - /* MultiLineString */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); + break; + case ( + MS_SHAPE_POLYGON): /* this gets nasty, since our shapes are so flexible */ + geometry_simple_index = msGMLGeometryLookup(geometryList, "polygon"); + geometry_aggregate_index = + msGMLGeometryLookup(geometryList, "multipolygon"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + /* get a list of outter rings for this polygon */ + outerlist = msGetOuterList(shape); + + numouters = 0; + for (i = 0; i < shape->numlines; i++) + if (outerlist[i] == MS_TRUE) + numouters++; + + if ((geometry_simple_index != -1 && numouters == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && + shape->numlines == 1)) { /* write a Polygon(s) */ + for (i = 0; i < shape->numlines; i++) { + if (outerlist[i] == MS_FALSE) + break; /* skip non-outer rings, each outer ring is a new polygon */ + + /* get a list of inner rings for this polygon */ + innerlist = msGetInnerList(shape, i, outerlist); + + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); + + /* Polygon */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); else - msIO_fprintf(stream, "%s\n", tab); - - for(j=0; jnumlines; j++) { - msIO_fprintf(stream, "%s \n", tab); /* no srsname at this point */ - msIO_fprintf(stream, "%s \n", tab); /* no srsname at this point */ - - msIO_fprintf(stream, "%s ", tab); - for(i=0; iline[j].numpoints; i++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, shape->line[j].point[i].x, geometry_precision, shape->line[j].point[i].y, - geometry_precision, shape->line[j].point[i].z); - else + msIO_fprintf(stream, "%s\n", tab); + + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + msIO_fprintf(stream, "%s ", tab); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); + } + msIO_fprintf(stream, "\n"); + + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + for (k = 0; k < shape->numlines; + k++) { /* now step through all the inner rings */ + if (innerlist[k] == MS_TRUE) { + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + msIO_fprintf(stream, "%s ", tab); + for (j = 0; j < shape->line[k].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y, geometry_precision, + shape->line[k].point[j].z); + else /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, shape->line[j].point[i].x, geometry_precision, shape->line[j].point[i].y); + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y); + } + msIO_fprintf(stream, "\n"); + + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); } - msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); } - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s\n", tab); + free(innerlist); - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); } + free(outerlist); + outerlist = NULL; + } else if (geometry_aggregate_index != -1 || + (geometryList->numgeometries == 0)) { /* write a MultiPolygon */ + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + /* MultiPolygon */ + if (srsname_encoded) + msIO_fprintf(stream, "%s\n", tab, + srsname_encoded); + else + msIO_fprintf(stream, "%s\n", tab); - break; - case(MS_SHAPE_POLYGON): /* this gets nasty, since our shapes are so flexible */ - geometry_simple_index = msGMLGeometryLookup(geometryList, "polygon"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipolygon"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; - - /* get a list of outter rings for this polygon */ - outerlist = msGetOuterList(shape); - - numouters = 0; - for(i=0; inumlines; i++) - if(outerlist[i] == MS_TRUE) numouters++; - - if((geometry_simple_index != -1 && numouters == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->numlines == 1)) { /* write a Polygon(s) */ - for(i=0; inumlines; i++) { - if(outerlist[i] == MS_FALSE) break; /* skip non-outer rings, each outer ring is a new polygon */ - - /* get a list of inner rings for this polygon */ + for (i = 0; i < shape->numlines; i++) { /* step through the outer rings */ + if (outerlist[i] == MS_TRUE) { innerlist = msGetInnerList(shape, i, outerlist); - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - - /* Polygon */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); - else - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s ", tab); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, - geometry_precision, shape->line[i].point[j].z); + msIO_fprintf(stream, "%s ", tab); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); else - /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); + /* fall-through */ + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); } msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - for(k=0; knumlines; k++) { /* now step through all the inner rings */ - if(innerlist[k] == MS_TRUE) { - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + for (k = 0; k < shape->numlines; + k++) { /* now step through all the inner rings */ + if (innerlist[k] == MS_TRUE) { + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s ", tab); - for(j=0; jline[k].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y, - geometry_precision,shape->line[k].point[j].z); + msIO_fprintf(stream, "%s ", tab); + for (j = 0; j < shape->line[k].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y, geometry_precision, + shape->line[k].point[j].z); else /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ",geometry_precision, shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y); + msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y); } msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); } } - msIO_fprintf(stream, "%s\n", tab); - free(innerlist); - - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - } - free(outerlist); - outerlist = NULL; - } else if(geometry_aggregate_index != -1 || (geometryList->numgeometries == 0)) { /* write a MultiPolygon */ - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - - /* MultiPolygon */ - if(srsname_encoded) - msIO_fprintf(stream, "%s\n", tab, srsname_encoded); - else - msIO_fprintf(stream, "%s\n", tab); - - for(i=0; inumlines; i++) { /* step through the outer rings */ - if(outerlist[i] == MS_TRUE) { - innerlist = msGetInnerList(shape, i, outerlist); - - msIO_fprintf(stream, "%s\n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, - geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); - } - msIO_fprintf(stream, "\n"); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - for(k=0; knumlines; k++) { /* now step through all the inner rings */ - if(innerlist[k] == MS_TRUE) { - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab); - for(j=0; jline[k].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f,%.*f,%.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y, - geometry_precision,shape->line[k].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f,%.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y); - } - msIO_fprintf(stream, "\n"); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - } - } - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s\n", tab); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s\n", tab); - free(innerlist); - } + free(innerlist); } - msIO_fprintf(stream, "%s\n", tab); + } + msIO_fprintf(stream, "%s\n", tab); - free(outerlist); - outerlist = NULL; + free(outerlist); + outerlist = NULL; - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); - } + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } - break; - default: - break; + break; + default: + break; } /* clean-up */ msFree(srsname_encoded); msFree(outerlist); - return(MS_SUCCESS); + return (MS_SUCCESS); } -static char* gmlCreateGeomId(OWSGMLVersion nGMLVersion, const char* pszFID, int* p_id) -{ - char* pszGMLId; - if( nGMLVersion == OWS_GML32 ) - { - pszGMLId = (char*) msSmallMalloc( strlen(pszFID) + 1 + strlen(" gml:id=\"\"") + 10 ); - sprintf(pszGMLId, " gml:id=\"%s.%d\"", pszFID, *p_id); - (*p_id) ++; - } - else - pszGMLId = msStrdup(""); - return pszGMLId; +static char *gmlCreateGeomId(OWSGMLVersion nGMLVersion, const char *pszFID, + int *p_id) { + char *pszGMLId; + if (nGMLVersion == OWS_GML32) { + pszGMLId = + (char *)msSmallMalloc(strlen(pszFID) + 1 + strlen(" gml:id=\"\"") + 10); + sprintf(pszGMLId, " gml:id=\"%s.%d\"", pszFID, *p_id); + (*p_id)++; + } else + pszGMLId = msStrdup(""); + return pszGMLId; } /* GML 3.1 or GML 3.2 (MapServer limits GML encoding to the level 0 profile) */ -static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList, shapeObj *shape, - const char *srsname, const char *namespace, const char *tab, +static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList, + shapeObj *shape, const char *srsname, + const char *namespace, const char *tab, const char *pszFID, OWSGMLVersion nGMLVersion, - int nSRSDimension, int geometry_precision) -{ + int nSRSDimension, int geometry_precision) { int i, j, k, id = 1; - int *innerlist, *outerlist=NULL, numouters; + int *innerlist, *outerlist = NULL, numouters; char *srsname_encoded = NULL; - char* pszGMLId; + char *pszGMLId; int geometry_aggregate_index, geometry_simple_index; char *geometry_aggregate_name = NULL, *geometry_simple_name = NULL; - if(!stream) return(MS_FAILURE); - if(!shape) return(MS_FAILURE); - if(!tab) return(MS_FAILURE); - if(!geometryList) return(MS_FAILURE); + if (!stream) + return (MS_FAILURE); + if (!shape) + return (MS_FAILURE); + if (!tab) + return (MS_FAILURE); + if (!geometryList) + return (MS_FAILURE); - if(shape->numlines <= 0) return(MS_SUCCESS); /* empty shape, nothing to output */ + if (shape->numlines <= 0) + return (MS_SUCCESS); /* empty shape, nothing to output */ - if(srsname) + if (srsname) srsname_encoded = msEncodeHTMLEntities(srsname); /* feature geometry */ - switch(shape->type) { - case(MS_SHAPE_POINT): - geometry_simple_index = msGMLGeometryLookup(geometryList, "point"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipoint"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; - - if((geometry_simple_index != -1 && shape->line[0].numpoints == 1 && shape->numlines == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->line[0].numpoints == 1 && shape->numlines == 1)) { /* write a Point(s) */ - - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - - /* Point */ - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); - else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); + switch (shape->type) { + case (MS_SHAPE_POINT): + geometry_simple_index = msGMLGeometryLookup(geometryList, "point"); + geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipoint"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + if ((geometry_simple_index != -1 && shape->line[0].numpoints == 1 && + shape->numlines == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && shape->line[0].numpoints == 1 && + shape->numlines == 1)) { /* write a Point(s) */ + + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, + tab); + + /* Point */ + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); + else + msIO_fprintf(stream, "%s \n", tab, pszGMLId); + + if (nSRSDimension == 3) + msIO_fprintf( + stream, + "%s %.*f %.*f %.*f\n", + tab, geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y, + geometry_precision, shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%s %.*f %.*f\n", tab, + geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y); - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%s %.*f %.*f %.*f\n", tab, geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%s %.*f %.*f\n", tab, geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); + msIO_fprintf(stream, "%s \n", tab); + + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); + msFree(pszGMLId); + } + } + } else if ((geometry_aggregate_index != -1) || + (geometryList->numgeometries == 0)) { /* write a MultiPoint */ + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + /* MultiPoint */ + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); + else + msIO_fprintf(stream, "%s \n", tab, pszGMLId); - msIO_fprintf(stream, "%s \n", tab); + msFree(pszGMLId); - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - msFree(pszGMLId); - } + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + msIO_fprintf(stream, "%s \n", tab); + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + msIO_fprintf(stream, "%s \n", tab, pszGMLId); + if (nSRSDimension == 3) + msIO_fprintf(stream, + "%s %.*f %.*f " + "%.*f\n", + tab, geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y, + geometry_precision, shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%s %.*f %.*f\n", + tab, geometry_precision, shape->line[i].point[j].x, + geometry_precision, shape->line[i].point[j].y); + msIO_fprintf(stream, "%s \n", tab); + msFree(pszGMLId); + msIO_fprintf(stream, "%s \n", tab); } - } else if((geometry_aggregate_index != -1) || (geometryList->numgeometries == 0)) { /* write a MultiPoint */ - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } - /* MultiPoint */ - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); - else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); + msIO_fprintf(stream, "%s \n", tab); + + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } + break; + case (MS_SHAPE_LINE): + geometry_simple_index = msGMLGeometryLookup(geometryList, "line"); + geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multiline"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + if ((geometry_simple_index != -1 && shape->numlines == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && + shape->numlines == 1)) { /* write a LineStrings(s) */ + for (i = 0; i < shape->numlines; i++) { + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); + + /* LineString (should be Curve?) */ + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); + else + msIO_fprintf(stream, "%s \n", tab, pszGMLId); msFree(pszGMLId); - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - msIO_fprintf(stream, "%s \n", tab); - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - msIO_fprintf(stream, "%s \n", tab, pszGMLId); - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%s %.*f %.*f %.*f\n", tab, geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%s %.*f %.*f\n", tab, geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); - msIO_fprintf(stream, "%s \n", tab); - msFree(pszGMLId); - msIO_fprintf(stream, "%s \n", tab); - } + msIO_fprintf(stream, "%s ", tab, + nSRSDimension); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); } + msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); } + } else if (geometry_aggregate_index != -1 || + (geometryList->numgeometries == 0)) { /* write a MultiCurve */ + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + /* MultiCurve */ + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); + else + msIO_fprintf(stream, "%s \n", tab, pszGMLId); + msFree(pszGMLId); - break; - case(MS_SHAPE_LINE): - geometry_simple_index = msGMLGeometryLookup(geometryList, "line"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multiline"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; - - if((geometry_simple_index != -1 && shape->numlines == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->numlines == 1)) { /* write a LineStrings(s) */ - for(i=0; inumlines; i++) { - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); + for (i = 0; i < shape->numlines; i++) { + msIO_fprintf(stream, "%s \n", tab); + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + msIO_fprintf(stream, "%s \n", tab, + pszGMLId); /* no srsname at this point */ + msFree(pszGMLId); - /* LineString (should be Curve?) */ - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); + msIO_fprintf(stream, "%s ", tab, + nSRSDimension); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); - msFree(pszGMLId); + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); + } - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); - } - msIO_fprintf(stream, "\n"); + msIO_fprintf(stream, "\n"); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + } - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - } - } else if(geometry_aggregate_index != -1 || (geometryList->numgeometries == 0)) { /* write a MultiCurve */ - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } + + break; + case ( + MS_SHAPE_POLYGON): /* this gets nasty, since our shapes are so flexible */ + geometry_simple_index = msGMLGeometryLookup(geometryList, "polygon"); + geometry_aggregate_index = + msGMLGeometryLookup(geometryList, "multipolygon"); + if (geometry_simple_index >= 0) + geometry_simple_name = + geometryList->geometries[geometry_simple_index].name; + if (geometry_aggregate_index >= 0) + geometry_aggregate_name = + geometryList->geometries[geometry_aggregate_index].name; + + /* get a list of outter rings for this polygon */ + outerlist = msGetOuterList(shape); + + numouters = 0; + for (i = 0; i < shape->numlines; i++) + if (outerlist[i] == MS_TRUE) + numouters++; + + if ((geometry_simple_index != -1 && numouters == 1) || + (geometry_simple_index != -1 && geometry_aggregate_index == -1) || + (geometryList->numgeometries == 0 && + shape->numlines == 1)) { /* write a Polygon(s) */ + for (i = 0; i < shape->numlines; i++) { + if (outerlist[i] == MS_FALSE) + break; /* skip non-outer rings, each outer ring is a new polygon */ + + /* get a list of inner rings for this polygon */ + innerlist = msGetInnerList(shape, i, outerlist); + + gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - /* MultiCurve */ pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); + + /* Polygon (should be Surface?) */ + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); + msIO_fprintf(stream, "%s \n", tab, pszGMLId); msFree(pszGMLId); - for(i=0; inumlines; i++) { - msIO_fprintf(stream, "%s \n", tab); - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - msIO_fprintf(stream, "%s \n", tab, pszGMLId); /* no srsname at this point */ - msFree(pszGMLId); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + msIO_fprintf(stream, "%s ", tab, + nSRSDimension); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); + } - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, geometry_precision, shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); - } + msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - } + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + for (k = 0; k < shape->numlines; + k++) { /* now step through all the inner rings */ + if (innerlist[k] == MS_TRUE) { + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); - } + msIO_fprintf(stream, "%s ", + tab, nSRSDimension); + for (j = 0; j < shape->line[k].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y, geometry_precision, + shape->line[k].point[j].z); + else + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y); + } + + msIO_fprintf(stream, "\n"); - break; - case(MS_SHAPE_POLYGON): /* this gets nasty, since our shapes are so flexible */ - geometry_simple_index = msGMLGeometryLookup(geometryList, "polygon"); - geometry_aggregate_index = msGMLGeometryLookup(geometryList, "multipolygon"); - if(geometry_simple_index >= 0) geometry_simple_name = geometryList->geometries[geometry_simple_index].name; - if(geometry_aggregate_index >= 0) geometry_aggregate_name = geometryList->geometries[geometry_aggregate_index].name; + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + } + } - /* get a list of outter rings for this polygon */ - outerlist = msGetOuterList(shape); + msIO_fprintf(stream, "%s \n", tab); + free(innerlist); - numouters = 0; - for(i=0; inumlines; i++) - if(outerlist[i] == MS_TRUE) numouters++; + gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); + } + free(outerlist); + outerlist = NULL; + } else if (geometry_aggregate_index != -1 || + (geometryList->numgeometries == 0)) { /* write a MultiSurface */ + gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, + tab); + + pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); + + /* MultiSurface */ + if (srsname_encoded) + msIO_fprintf(stream, "%s \n", tab, + pszGMLId, srsname_encoded); + else + msIO_fprintf(stream, "%s \n", tab, pszGMLId); + msFree(pszGMLId); - if((geometry_simple_index != -1 && numouters == 1) || - (geometry_simple_index != -1 && geometry_aggregate_index == -1) || - (geometryList->numgeometries == 0 && shape->numlines == 1)) { /* write a Polygon(s) */ - for(i=0; inumlines; i++) { - if(outerlist[i] == MS_FALSE) break; /* skip non-outer rings, each outer ring is a new polygon */ + for (i = 0; i < shape->numlines; i++) { /* step through the outer rings */ + if (outerlist[i] == MS_TRUE) { + msIO_fprintf(stream, "%s \n", tab); /* get a list of inner rings for this polygon */ innerlist = msGetInnerList(shape, i, outerlist); - gmlStartGeometryContainer(stream, geometry_simple_name, namespace, tab); - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - /* Polygon (should be Surface?) */ - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); - else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); + msIO_fprintf(stream, "%s \n", tab, pszGMLId); msFree(pszGMLId); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y, geometry_precision, shape->line[i].point[j].z); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + msIO_fprintf(stream, + "%s ", tab, + nSRSDimension); + for (j = 0; j < shape->line[i].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y, geometry_precision, + shape->line[i].point[j].z); else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, shape->line[i].point[j].x, geometry_precision, shape->line[i].point[j].y); + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[i].point[j].x, geometry_precision, + shape->line[i].point[j].y); } msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - for(k=0; knumlines; k++) { /* now step through all the inner rings */ - if(innerlist[k] == MS_TRUE) { - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[k].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y, geometry_precision,shape->line[k].point[j].z); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + for (k = 0; k < shape->numlines; + k++) { /* now step through all the inner rings */ + if (innerlist[k] == MS_TRUE) { + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + + msIO_fprintf(stream, + "%s ", + tab, nSRSDimension); + for (j = 0; j < shape->line[k].numpoints; j++) { + if (nSRSDimension == 3) + msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y, geometry_precision, + shape->line[k].point[j].z); else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y); + /* fall-through */ + msIO_fprintf(stream, "%.*f %.*f ", geometry_precision, + shape->line[k].point[j].x, geometry_precision, + shape->line[k].point[j].y); } - msIO_fprintf(stream, "\n"); - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); } } - msIO_fprintf(stream, "%s \n", tab); - free(innerlist); - - gmlEndGeometryContainer(stream, geometry_simple_name, namespace, tab); - } - free(outerlist); - outerlist = NULL; - } else if(geometry_aggregate_index != -1 || (geometryList->numgeometries == 0)) { /* write a MultiSurface */ - gmlStartGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - - /* MultiSurface */ - if(srsname_encoded) - msIO_fprintf(stream, "%s \n", tab, pszGMLId, srsname_encoded); - else - msIO_fprintf(stream, "%s \n", tab, pszGMLId); - msFree(pszGMLId); - - for(i=0; inumlines; i++) { /* step through the outer rings */ - if(outerlist[i] == MS_TRUE) { - msIO_fprintf(stream, "%s \n", tab); + msIO_fprintf(stream, "%s \n", tab); - /* get a list of inner rings for this polygon */ - innerlist = msGetInnerList(shape, i, outerlist); - - pszGMLId = gmlCreateGeomId(nGMLVersion, pszFID, &id); - - msIO_fprintf(stream, "%s \n", tab, pszGMLId); - msFree(pszGMLId); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[i].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision,shape->line[i].point[j].x, geometry_precision,shape->line[i].point[j].y, geometry_precision,shape->line[i].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision,shape->line[i].point[j].x, geometry_precision,shape->line[i].point[j].y); - } - - msIO_fprintf(stream, "\n"); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - for(k=0; knumlines; k++) { /* now step through all the inner rings */ - if(innerlist[k] == MS_TRUE) { - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - - msIO_fprintf(stream, "%s ", tab, nSRSDimension); - for(j=0; jline[k].numpoints; j++) - { - if( nSRSDimension == 3 ) - msIO_fprintf(stream, "%.*f %.*f %.*f ", geometry_precision, shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y, geometry_precision,shape->line[k].point[j].z); - else - /* fall-through */ - msIO_fprintf(stream, "%.*f %.*f ", geometry_precision,shape->line[k].point[j].x, geometry_precision,shape->line[k].point[j].y); - } - msIO_fprintf(stream, "\n"); - - msIO_fprintf(stream, "%s \n", tab); - msIO_fprintf(stream, "%s \n", tab); - } - } - - msIO_fprintf(stream, "%s \n", tab); - - free(innerlist); - msIO_fprintf(stream, "%s \n", tab); - } + free(innerlist); + msIO_fprintf(stream, "%s \n", tab); } - msIO_fprintf(stream, "%s \n", tab); + } + msIO_fprintf(stream, "%s \n", tab); - free(outerlist); - outerlist = NULL; + free(outerlist); + outerlist = NULL; - gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); - } else { - msIO_fprintf(stream, "\n"); - } + gmlEndGeometryContainer(stream, geometry_aggregate_name, namespace, tab); + } else { + msIO_fprintf(stream, "\n"); + } - break; - default: - break; + break; + default: + break; } /* clean-up */ msFree(outerlist); msFree(srsname_encoded); - return(MS_SUCCESS); + return (MS_SUCCESS); } /* @@ -808,113 +979,125 @@ static int gmlWriteGeometry_GML3(FILE *stream, gmlGeometryListObj *geometryList, */ static int gmlWriteBounds(FILE *stream, OWSGMLVersion format, rectObj *rect, const char *srsname, const char *tab, - const char *pszTopPrefix) -{ - switch(format) { - case(OWS_GML2): - return gmlWriteBounds_GML2(stream, rect, srsname, tab, pszTopPrefix); - break; - case(OWS_GML3): - case(OWS_GML32): - return gmlWriteBounds_GML3(stream, rect, srsname, tab, pszTopPrefix); - break; - default: - msSetError(MS_IOERR, "Unsupported GML format.", "gmlWriteBounds()"); + const char *pszTopPrefix) { + switch (format) { + case (OWS_GML2): + return gmlWriteBounds_GML2(stream, rect, srsname, tab, pszTopPrefix); + break; + case (OWS_GML3): + case (OWS_GML32): + return gmlWriteBounds_GML3(stream, rect, srsname, tab, pszTopPrefix); + break; + default: + msSetError(MS_IOERR, "Unsupported GML format.", "gmlWriteBounds()"); } - return(MS_FAILURE); + return (MS_FAILURE); } static int gmlWriteGeometry(FILE *stream, gmlGeometryListObj *geometryList, OWSGMLVersion format, shapeObj *shape, const char *srsname, const char *namespace, - const char *tab, const char* pszFID, int nSRSDimension, int geometry_precision) -{ - switch(format) { - case(OWS_GML2): - return gmlWriteGeometry_GML2(stream, geometryList, shape, srsname, namespace, tab, nSRSDimension, geometry_precision); - break; - case(OWS_GML3): - case(OWS_GML32): - return gmlWriteGeometry_GML3(stream, geometryList, shape, srsname, namespace, tab, pszFID, format, nSRSDimension, geometry_precision); - break; - default: - msSetError(MS_IOERR, "Unsupported GML format.", "gmlWriteGeometry()"); + const char *tab, const char *pszFID, + int nSRSDimension, int geometry_precision) { + switch (format) { + case (OWS_GML2): + return gmlWriteGeometry_GML2(stream, geometryList, shape, srsname, + namespace, tab, nSRSDimension, + geometry_precision); + break; + case (OWS_GML3): + case (OWS_GML32): + return gmlWriteGeometry_GML3(stream, geometryList, shape, srsname, + namespace, tab, pszFID, format, nSRSDimension, + geometry_precision); + break; + default: + msSetError(MS_IOERR, "Unsupported GML format.", "gmlWriteGeometry()"); } - return(MS_FAILURE); + return (MS_FAILURE); } /* ** GML specific metadata handling functions. */ -int msItemInGroups(const char *name, gmlGroupListObj *groupList) -{ +int msItemInGroups(const char *name, gmlGroupListObj *groupList) { int i, j; gmlGroupObj *group; - if(!groupList) return MS_FALSE; /* no groups */ + if (!groupList) + return MS_FALSE; /* no groups */ - for(i=0; inumgroups; i++) { + for (i = 0; i < groupList->numgroups; i++) { group = &(groupList->groups[i]); - for(j=0; jnumitems; j++) { - if(strcasecmp(name, group->items[j]) == 0) return MS_TRUE; + for (j = 0; j < group->numitems; j++) { + if (strcasecmp(name, group->items[j]) == 0) + return MS_TRUE; } } return MS_FALSE; } -static int msGMLGeometryLookup(gmlGeometryListObj *geometryList, const char *type) -{ +static int msGMLGeometryLookup(gmlGeometryListObj *geometryList, + const char *type) { int i; - if(!geometryList || !type) return -1; /* nothing to look for */ + if (!geometryList || !type) + return -1; /* nothing to look for */ - for(i=0; inumgeometries; i++) - if(geometryList->geometries[i].type && (strcasecmp(geometryList->geometries[i].type, type) == 0)) + for (i = 0; i < geometryList->numgeometries; i++) + if (geometryList->geometries[i].type && + (strcasecmp(geometryList->geometries[i].type, type) == 0)) return i; - if( geometryList->numgeometries == 1 && geometryList->geometries[0].type == NULL ) + if (geometryList->numgeometries == 1 && + geometryList->geometries[0].type == NULL) return 0; return -1; /* not found */ } -gmlGeometryListObj *msGMLGetGeometries(layerObj *layer, const char *metadata_namespaces, int bWithDefaultGeom) -{ +gmlGeometryListObj *msGMLGetGeometries(layerObj *layer, + const char *metadata_namespaces, + int bWithDefaultGeom) { int i; - const char *value=NULL; + const char *value = NULL; char tag[64]; - char **names=NULL; - int numnames=0; + char **names = NULL; + int numnames = 0; - gmlGeometryListObj *geometryList=NULL; - gmlGeometryObj *geometry=NULL; + gmlGeometryListObj *geometryList = NULL; + gmlGeometryObj *geometry = NULL; /* allocate memory and initialize the item collection */ - geometryList = (gmlGeometryListObj *) malloc(sizeof(gmlGeometryListObj)); - MS_CHECK_ALLOC(geometryList, sizeof(gmlGeometryListObj), NULL) ; + geometryList = (gmlGeometryListObj *)malloc(sizeof(gmlGeometryListObj)); + MS_CHECK_ALLOC(geometryList, sizeof(gmlGeometryListObj), NULL); geometryList->geometries = NULL; geometryList->numgeometries = 0; - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "geometries")) != NULL) { + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "geometries")) != NULL) { names = msStringSplit(value, ',', &numnames); /* allocation an array of gmlGeometryObj's */ geometryList->numgeometries = numnames; - geometryList->geometries = (gmlGeometryObj *) malloc(sizeof(gmlGeometryObj)*geometryList->numgeometries); - if (geometryList->geometries == NULL) { - msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", "msGMLGetGeometries()", - (unsigned int)(sizeof(gmlGeometryObj)*geometryList->numgeometries)); + geometryList->geometries = (gmlGeometryObj *)malloc( + sizeof(gmlGeometryObj) * geometryList->numgeometries); + if (geometryList->geometries == NULL) { + msSetError( + MS_MEMERR, "Out of memory allocating %u bytes.\n", + "msGMLGetGeometries()", + (unsigned int)(sizeof(gmlGeometryObj) * geometryList->numgeometries)); free(geometryList); return NULL; } - for(i=0; inumgeometries; i++) { + for (i = 0; i < geometryList->numgeometries; i++) { geometry = &(geometryList->geometries[i]); geometry->name = msStrdup(names[i]); /* initialize a few things */ @@ -923,31 +1106,33 @@ gmlGeometryListObj *msGMLGetGeometries(layerObj *layer, const char *metadata_nam geometry->occurmax = 1; snprintf(tag, 64, "%s_type", names[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) geometry->type = msStrdup(value); /* TODO: validate input value */ snprintf(tag, 64, "%s_occurances", names[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) { + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) { char **occur; int numoccur; occur = msStringSplit(value, ',', &numoccur); - if(numoccur == 2) { /* continue (TODO: throw an error if != 2) */ + if (numoccur == 2) { /* continue (TODO: throw an error if != 2) */ geometry->occurmin = atof(occur[0]); - if(strcasecmp(occur[1], "UNBOUNDED") == 0) + if (strcasecmp(occur[1], "UNBOUNDED") == 0) geometry->occurmax = OWS_GML_OCCUR_UNBOUNDED; else geometry->occurmax = atof(occur[1]); } - msFreeCharArray(occur,numoccur); + msFreeCharArray(occur, numoccur); } } msFreeCharArray(names, numnames); - } - else if( bWithDefaultGeom ) { + } else if (bWithDefaultGeom) { geometryList->numgeometries = 1; - geometryList->geometries = (gmlGeometryObj *) calloc(1, sizeof(gmlGeometryObj)); + geometryList->geometries = + (gmlGeometryObj *)calloc(1, sizeof(gmlGeometryObj)); geometryList->geometries[0].name = msStrdup(OWS_GML_DEFAULT_GEOMETRY_NAME); geometryList->geometries[0].type = NULL; geometryList->geometries[0].occurmin = 0; @@ -957,13 +1142,13 @@ gmlGeometryListObj *msGMLGetGeometries(layerObj *layer, const char *metadata_nam return geometryList; } -void msGMLFreeGeometries(gmlGeometryListObj *geometryList) -{ +void msGMLFreeGeometries(gmlGeometryListObj *geometryList) { int i; - if(!geometryList) return; + if (!geometryList) + return; - for(i=0; inumgeometries; i++) { + for (i = 0; i < geometryList->numgeometries; i++) { msFree(geometryList->geometries[i].name); msFree(geometryList->geometries[i].type); } @@ -972,143 +1157,143 @@ void msGMLFreeGeometries(gmlGeometryListObj *geometryList) free(geometryList); } -static void msGMLWriteItem(FILE *stream, gmlItemObj *item, - const char *value, const char *namespace, - const char *tab, - OWSGMLVersion outputformat, - const char *pszFID) -{ +static void msGMLWriteItem(FILE *stream, gmlItemObj *item, const char *value, + const char *namespace, const char *tab, + OWSGMLVersion outputformat, const char *pszFID) { char *encoded_value = NULL, *tag_name; int add_namespace = MS_TRUE; char gmlid[256]; gmlid[0] = 0; - if(!stream || !item) return; - if(!item->visible) return; + if (!stream || !item) + return; + if (!item->visible) + return; - if(!namespace) add_namespace = MS_FALSE; + if (!namespace) + add_namespace = MS_FALSE; - if(item->alias) + if (item->alias) tag_name = item->alias; else tag_name = item->name; - if(strchr(tag_name, ':') != NULL) add_namespace = MS_FALSE; - - if( item->type && (EQUAL(item->type, "Date") || - EQUAL(item->type, "DateTime") || - EQUAL(item->type, "Time")) ) { - struct tm tm; - if( msParseTime(value, &tm) == MS_TRUE ) { - const char* pszStartTag = ""; - const char* pszEndTag = ""; - - encoded_value = (char*) msSmallMalloc(256); - if( outputformat == OWS_GML32 ) { - if( pszFID != NULL ) - snprintf(gmlid, 256, " gml:id=\"%s.%s\"", pszFID, tag_name); - pszStartTag = ""; - pszEndTag = ""; - } + if (strchr(tag_name, ':') != NULL) + add_namespace = MS_FALSE; + + if (item->type && + (EQUAL(item->type, "Date") || EQUAL(item->type, "DateTime") || + EQUAL(item->type, "Time"))) { + struct tm tm; + if (msParseTime(value, &tm) == MS_TRUE) { + const char *pszStartTag = ""; + const char *pszEndTag = ""; + + encoded_value = (char *)msSmallMalloc(256); + if (outputformat == OWS_GML32) { + if (pszFID != NULL) + snprintf(gmlid, 256, " gml:id=\"%s.%s\"", pszFID, tag_name); + pszStartTag = ""; + pszEndTag = ""; + } - if( EQUAL(item->type, "Date") ) - snprintf(encoded_value, 256, "%s%04d-%02d-%02d%s", - pszStartTag, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - pszEndTag); - else if( EQUAL(item->type, "Time") ) - snprintf(encoded_value, 256, "%s%02d:%02d:%02dZ%s", - pszStartTag, - tm.tm_hour, tm.tm_min, tm.tm_sec, - pszEndTag); - else - { - // Detected date time already formatted as YYYY-MM-DDTHH:mm:SS+ab:cd - // because msParseTime() can't handle time zones. - if( strlen(value) == 4+1+2+1+2+1+2+1+2+1+2+1+2+1+2 && - value[4] == '-' && value[7] == '-' && value[10] == 'T' && - value[13] == ':' && value[16] == ':' && - (value[19] == '+' || value[19] == '-') && - value[22] == ':' ) - { - snprintf(encoded_value, 256, "%s%s%s", - pszStartTag, value, pszEndTag); - } - else - { - snprintf(encoded_value, 256, "%s%04d-%02d-%02dT%02d:%02d:%02dZ%s", - pszStartTag, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, pszEndTag); - } - } + if (EQUAL(item->type, "Date")) + snprintf(encoded_value, 256, "%s%04d-%02d-%02d%s", pszStartTag, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, pszEndTag); + else if (EQUAL(item->type, "Time")) + snprintf(encoded_value, 256, "%s%02d:%02d:%02dZ%s", pszStartTag, + tm.tm_hour, tm.tm_min, tm.tm_sec, pszEndTag); + else { + // Detected date time already formatted as YYYY-MM-DDTHH:mm:SS+ab:cd + // because msParseTime() can't handle time zones. + if (strlen(value) == + 4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 && + value[4] == '-' && value[7] == '-' && value[10] == 'T' && + value[13] == ':' && value[16] == ':' && + (value[19] == '+' || value[19] == '-') && value[22] == ':') { + snprintf(encoded_value, 256, "%s%s%s", pszStartTag, value, pszEndTag); + } else { + snprintf(encoded_value, 256, "%s%04d-%02d-%02dT%02d:%02d:%02dZ%s", + pszStartTag, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, pszEndTag); + } } + } } - if( encoded_value == NULL ) - { - if(item->encode == MS_TRUE) + if (encoded_value == NULL) { + if (item->encode == MS_TRUE) encoded_value = msEncodeHTMLEntities(value); else encoded_value = msStrdup(value); } - if(!item->template) { /* build the tag from pieces */ + if (!item->template) { /* build the tag from pieces */ - if(add_namespace == MS_TRUE && msIsXMLTagValid(tag_name) == MS_FALSE) - msIO_fprintf(stream, "\n", tag_name); + if (add_namespace == MS_TRUE && msIsXMLTagValid(tag_name) == MS_FALSE) + msIO_fprintf(stream, + "\n", + tag_name); - if(add_namespace == MS_TRUE) - msIO_fprintf(stream, "%s<%s:%s%s>%s\n", tab, namespace, tag_name, gmlid, encoded_value, namespace, tag_name); + if (add_namespace == MS_TRUE) + msIO_fprintf(stream, "%s<%s:%s%s>%s\n", tab, namespace, tag_name, + gmlid, encoded_value, namespace, tag_name); else - msIO_fprintf(stream, "%s<%s%s>%s\n", tab, tag_name, gmlid, encoded_value, tag_name); + msIO_fprintf(stream, "%s<%s%s>%s\n", tab, tag_name, gmlid, + encoded_value, tag_name); } else { char *tag = NULL; tag = msStrdup(item->template); tag = msReplaceSubstring(tag, "$value", encoded_value); - if(namespace) tag = msReplaceSubstring(tag, "$namespace", namespace); + if (namespace) + tag = msReplaceSubstring(tag, "$namespace", namespace); msIO_fprintf(stream, "%s%s\n", tab, tag); free(tag); } - free( encoded_value ); + free(encoded_value); return; } -gmlNamespaceListObj *msGMLGetNamespaces(webObj *web, const char *metadata_namespaces) -{ +gmlNamespaceListObj *msGMLGetNamespaces(webObj *web, + const char *metadata_namespaces) { int i; - const char *value=NULL; + const char *value = NULL; char tag[64]; - char **prefixes=NULL; - int numprefixes=0; + char **prefixes = NULL; + int numprefixes = 0; - gmlNamespaceListObj *namespaceList=NULL; - gmlNamespaceObj *namespace=NULL; + gmlNamespaceListObj *namespaceList = NULL; + gmlNamespaceObj *namespace = NULL; /* allocate the collection */ - namespaceList = (gmlNamespaceListObj *) malloc(sizeof(gmlNamespaceListObj)); - MS_CHECK_ALLOC(namespaceList, sizeof(gmlNamespaceListObj), NULL) ; + namespaceList = (gmlNamespaceListObj *)malloc(sizeof(gmlNamespaceListObj)); + MS_CHECK_ALLOC(namespaceList, sizeof(gmlNamespaceListObj), NULL); namespaceList->namespaces = NULL; namespaceList->numnamespaces = 0; /* list of namespaces (TODO: make this automatic by parsing metadata) */ - if((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, "external_namespace_prefixes")) != NULL) { + if ((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, + "external_namespace_prefixes")) != NULL) { prefixes = msStringSplit(value, ',', &numprefixes); /* allocation an array of gmlNamespaceObj's */ namespaceList->numnamespaces = numprefixes; - namespaceList->namespaces = (gmlNamespaceObj *) malloc(sizeof(gmlNamespaceObj)*namespaceList->numnamespaces); + namespaceList->namespaces = (gmlNamespaceObj *)malloc( + sizeof(gmlNamespaceObj) * namespaceList->numnamespaces); if (namespaceList->namespaces == NULL) { - msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", "msGMLGetNamespaces()", - (unsigned int)(sizeof(gmlNamespaceObj)*namespaceList->numnamespaces)); + msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", + "msGMLGetNamespaces()", + (unsigned int)(sizeof(gmlNamespaceObj) * + namespaceList->numnamespaces)); free(namespaceList); return NULL; } - for(i=0; inumnamespaces; i++) { + for (i = 0; i < namespaceList->numnamespaces; i++) { namespace = &(namespaceList->namespaces[i]); namespace->prefix = msStrdup(prefixes[i]); /* initialize a few things */ @@ -1116,12 +1301,14 @@ gmlNamespaceListObj *msGMLGetNamespaces(webObj *web, const char *metadata_namesp namespace->schemalocation = NULL; snprintf(tag, 64, "%s_uri", namespace->prefix); - if((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, tag)) != NULL) - namespace->uri = msStrdup(value); + if ((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, + tag)) != NULL) + namespace->uri = msStrdup(value); snprintf(tag, 64, "%s_schema_location", namespace->prefix); - if((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, tag)) != NULL) - namespace->schemalocation = msStrdup(value); + if ((value = msOWSLookupMetadata(&(web->metadata), metadata_namespaces, + tag)) != NULL) + namespace->schemalocation = msStrdup(value); } msFreeCharArray(prefixes, numprefixes); @@ -1130,13 +1317,13 @@ gmlNamespaceListObj *msGMLGetNamespaces(webObj *web, const char *metadata_namesp return namespaceList; } -void msGMLFreeNamespaces(gmlNamespaceListObj *namespaceList) -{ +void msGMLFreeNamespaces(gmlNamespaceListObj *namespaceList) { int i; - if(!namespaceList) return; + if (!namespaceList) + return; - for(i=0; inumnamespaces; i++) { + for (i = 0; i < namespaceList->numnamespaces; i++) { msFree(namespaceList->namespaces[i].prefix); msFree(namespaceList->namespaces[i].uri); msFree(namespaceList->namespaces[i].schemalocation); @@ -1145,40 +1332,43 @@ void msGMLFreeNamespaces(gmlNamespaceListObj *namespaceList) free(namespaceList); } -gmlConstantListObj *msGMLGetConstants(layerObj *layer, const char *metadata_namespaces) -{ +gmlConstantListObj *msGMLGetConstants(layerObj *layer, + const char *metadata_namespaces) { int i; - const char *value=NULL; + const char *value = NULL; char tag[64]; - char **names=NULL; - int numnames=0; + char **names = NULL; + int numnames = 0; - gmlConstantListObj *constantList=NULL; - gmlConstantObj *constant=NULL; + gmlConstantListObj *constantList = NULL; + gmlConstantObj *constant = NULL; /* allocate the collection */ - constantList = (gmlConstantListObj *) malloc(sizeof(gmlConstantListObj)); + constantList = (gmlConstantListObj *)malloc(sizeof(gmlConstantListObj)); MS_CHECK_ALLOC(constantList, sizeof(gmlConstantListObj), NULL); constantList->constants = NULL; constantList->numconstants = 0; /* list of constants (TODO: make this automatic by parsing metadata) */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "constants")) != NULL) { + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "constants")) != NULL) { names = msStringSplit(value, ',', &numnames); /* allocation an array of gmlConstantObj's */ constantList->numconstants = numnames; - constantList->constants = (gmlConstantObj *) malloc(sizeof(gmlConstantObj)*constantList->numconstants); + constantList->constants = (gmlConstantObj *)malloc( + sizeof(gmlConstantObj) * constantList->numconstants); if (constantList->constants == NULL) { - msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", "msGMLGetConstants()", - (unsigned int)(sizeof(gmlConstantObj)*constantList->numconstants)); + msSetError( + MS_MEMERR, "Out of memory allocating %u bytes.\n", + "msGMLGetConstants()", + (unsigned int)(sizeof(gmlConstantObj) * constantList->numconstants)); free(constantList); return NULL; } - - for(i=0; inumconstants; i++) { + for (i = 0; i < constantList->numconstants; i++) { constant = &(constantList->constants[i]); constant->name = msStrdup(names[i]); /* initialize a few things */ @@ -1186,11 +1376,13 @@ gmlConstantListObj *msGMLGetConstants(layerObj *layer, const char *metadata_name constant->type = NULL; snprintf(tag, 64, "%s_value", constant->name); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) constant->value = msStrdup(value); snprintf(tag, 64, "%s_type", constant->name); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) constant->type = msStrdup(value); } @@ -1200,13 +1392,13 @@ gmlConstantListObj *msGMLGetConstants(layerObj *layer, const char *metadata_name return constantList; } -void msGMLFreeConstants(gmlConstantListObj *constantList) -{ +void msGMLFreeConstants(gmlConstantListObj *constantList) { int i; - if(!constantList) return; + if (!constantList) + return; - for(i=0; inumconstants; i++) { + for (i = 0; i < constantList->numconstants; i++) { msFree(constantList->constants[i].name); msFree(constantList->constants[i].value); msFree(constantList->constants[i].type); @@ -1215,79 +1407,89 @@ void msGMLFreeConstants(gmlConstantListObj *constantList) free(constantList); } -static void msGMLWriteConstant(FILE *stream, gmlConstantObj *constant, const char *namespace, const char *tab) -{ +static void msGMLWriteConstant(FILE *stream, gmlConstantObj *constant, + const char *namespace, const char *tab) { int add_namespace = MS_TRUE; - if(!stream || !constant) return; - if(!constant->value) return; - - if(!namespace) add_namespace = MS_FALSE; - if(strchr(constant->name, ':') != NULL) add_namespace = MS_FALSE; - - if(add_namespace == MS_TRUE && msIsXMLTagValid(constant->name) == MS_FALSE) - msIO_fprintf(stream, "\n", constant->name); - - if(add_namespace == MS_TRUE) - msIO_fprintf(stream, "%s<%s:%s>%s\n", tab, namespace, constant->name, constant->value, namespace, constant->name); + if (!stream || !constant) + return; + if (!constant->value) + return; + + if (!namespace) + add_namespace = MS_FALSE; + if (strchr(constant->name, ':') != NULL) + add_namespace = MS_FALSE; + + if (add_namespace == MS_TRUE && msIsXMLTagValid(constant->name) == MS_FALSE) + msIO_fprintf( + stream, + "\n", + constant->name); + + if (add_namespace == MS_TRUE) + msIO_fprintf(stream, "%s<%s:%s>%s\n", tab, namespace, + constant->name, constant->value, namespace, constant->name); else - msIO_fprintf(stream, "%s<%s>%s\n", tab, constant->name, constant->value, constant->name); + msIO_fprintf(stream, "%s<%s>%s\n", tab, constant->name, + constant->value, constant->name); return; } -static void msGMLWriteGroup(FILE *stream, - gmlGroupObj *group, shapeObj *shape, +static void msGMLWriteGroup(FILE *stream, gmlGroupObj *group, shapeObj *shape, gmlItemListObj *itemList, gmlConstantListObj *constantList, const char *namespace, const char *tab, - OWSGMLVersion outputformat, - const char *pszFID) -{ - int i,j; + OWSGMLVersion outputformat, const char *pszFID) { + int i, j; int add_namespace = MS_TRUE; char *itemtab; - gmlItemObj *item=NULL; - gmlConstantObj *constant=NULL; + gmlItemObj *item = NULL; + gmlConstantObj *constant = NULL; - if(!stream || !group) return; + if (!stream || !group) + return; /* setup the item/constant tab */ - itemtab = (char *) msSmallMalloc(sizeof(char)*strlen(tab)+3); + itemtab = (char *)msSmallMalloc(sizeof(char) * strlen(tab) + 3); sprintf(itemtab, "%s ", tab); - if(!namespace || strchr(group->name, ':') != NULL) add_namespace = MS_FALSE; + if (!namespace || strchr(group->name, ':') != NULL) + add_namespace = MS_FALSE; /* start the group */ - if(add_namespace == MS_TRUE) + if (add_namespace == MS_TRUE) msIO_fprintf(stream, "%s<%s:%s>\n", tab, namespace, group->name); else msIO_fprintf(stream, "%s<%s>\n", tab, group->name); /* now the items/constants in the group */ - for(i=0; inumitems; i++) { - for(j=0; jnumconstants; j++) { + for (i = 0; i < group->numitems; i++) { + for (j = 0; j < constantList->numconstants; j++) { constant = &(constantList->constants[j]); - if(strcasecmp(constant->name, group->items[i]) == 0) { + if (strcasecmp(constant->name, group->items[i]) == 0) { msGMLWriteConstant(stream, constant, namespace, itemtab); break; } } - if(j != constantList->numconstants) continue; /* found this one */ - for(j=0; jnumitems; j++) { + if (j != constantList->numconstants) + continue; /* found this one */ + for (j = 0; j < itemList->numitems; j++) { item = &(itemList->items[j]); - if(strcasecmp(item->name, group->items[i]) == 0) { + if (strcasecmp(item->name, group->items[i]) == 0) { /* the number of items matches the number of values exactly */ - msGMLWriteItem(stream, item, shape->values[j], namespace, itemtab, outputformat, pszFID); + msGMLWriteItem(stream, item, shape->values[j], namespace, itemtab, + outputformat, pszFID); break; } } } /* end the group */ - if(add_namespace == MS_TRUE) + if (add_namespace == MS_TRUE) msIO_fprintf(stream, "%s\n", tab, namespace, group->name); else msIO_fprintf(stream, "%s\n", tab, group->name); @@ -1298,40 +1500,43 @@ static void msGMLWriteGroup(FILE *stream, } #endif -gmlGroupListObj *msGMLGetGroups(layerObj *layer, const char *metadata_namespaces) -{ +gmlGroupListObj *msGMLGetGroups(layerObj *layer, + const char *metadata_namespaces) { int i; - const char *value=NULL; + const char *value = NULL; char tag[64]; - char **names=NULL; - int numnames=0; + char **names = NULL; + int numnames = 0; - gmlGroupListObj *groupList=NULL; - gmlGroupObj *group=NULL; + gmlGroupListObj *groupList = NULL; + gmlGroupObj *group = NULL; /* allocate the collection */ - groupList = (gmlGroupListObj *) malloc(sizeof(gmlGroupListObj)); - MS_CHECK_ALLOC(groupList, sizeof(gmlGroupListObj), NULL) ; + groupList = (gmlGroupListObj *)malloc(sizeof(gmlGroupListObj)); + MS_CHECK_ALLOC(groupList, sizeof(gmlGroupListObj), NULL); groupList->groups = NULL; groupList->numgroups = 0; /* list of groups (TODO: make this automatic by parsing metadata) */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "groups")) != NULL && - value[0] != '\0' ) { + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "groups")) != NULL && + value[0] != '\0') { names = msStringSplit(value, ',', &numnames); /* allocation an array of gmlGroupObj's */ groupList->numgroups = numnames; - groupList->groups = (gmlGroupObj *) malloc(sizeof(gmlGroupObj)*groupList->numgroups); + groupList->groups = + (gmlGroupObj *)malloc(sizeof(gmlGroupObj) * groupList->numgroups); if (groupList->groups == NULL) { - msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", "msGMLGetGroups()", - (unsigned int)(sizeof(gmlGroupObj)*groupList->numgroups)); + msSetError(MS_MEMERR, "Out of memory allocating %u bytes.\n", + "msGMLGetGroups()", + (unsigned int)(sizeof(gmlGroupObj) * groupList->numgroups)); free(groupList); return NULL; } - for(i=0; inumgroups; i++) { + for (i = 0; i < groupList->numgroups; i++) { group = &(groupList->groups[i]); group->name = msStrdup(names[i]); /* initialize a few things */ @@ -1340,11 +1545,13 @@ gmlGroupListObj *msGMLGetGroups(layerObj *layer, const char *metadata_namespaces group->type = NULL; snprintf(tag, 64, "%s_group", group->name); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) group->items = msStringSplit(value, ',', &group->numitems); snprintf(tag, 64, "%s_type", group->name); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) group->type = msStrdup(value); } @@ -1354,13 +1561,13 @@ gmlGroupListObj *msGMLGetGroups(layerObj *layer, const char *metadata_namespaces return groupList; } -void msGMLFreeGroups(gmlGroupListObj *groupList) -{ +void msGMLFreeGroups(gmlGroupListObj *groupList) { int i; - if(!groupList) return; + if (!groupList) + return; - for(i=0; inumgroups; i++) { + for (i = 0; i < groupList->numgroups; i++) { msFree(groupList->groups[i].name); msFreeCharArray(groupList->groups[i].items, groupList->groups[i].numitems); msFree(groupList->groups[i].type); @@ -1371,87 +1578,104 @@ void msGMLFreeGroups(gmlGroupListObj *groupList) } /* Dump GML query results for WMS GetFeatureInfo */ -int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) -{ +int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) { #if defined(USE_WMS_SVR) int status; - int i,j,k; - layerObj *lp=NULL; + int i, j, k; + layerObj *lp = NULL; shapeObj shape; FILE *stream_to_free = NULL; - FILE *stream=stdout; /* defaults to stdout */ + FILE *stream = stdout; /* defaults to stdout */ char szPath[MS_MAXPATHLEN]; char *value; char *pszMapSRS = NULL; - gmlGroupListObj *groupList=NULL; - gmlItemListObj *itemList=NULL; - gmlConstantListObj *constantList=NULL; - gmlGeometryListObj *geometryList=NULL; - gmlItemObj *item=NULL; - gmlConstantObj *constant=NULL; + gmlGroupListObj *groupList = NULL; + gmlItemListObj *itemList = NULL; + gmlConstantListObj *constantList = NULL; + gmlGeometryListObj *geometryList = NULL; + gmlItemObj *item = NULL; + gmlConstantObj *constant = NULL; msInitShape(&shape); - if(filename && strlen(filename) > 0) { /* deal with the filename if present */ + if (filename && + strlen(filename) > 0) { /* deal with the filename if present */ stream_to_free = fopen(msBuildPath(szPath, map->mappath, filename), "w"); - if(!stream_to_free) { + if (!stream_to_free) { msSetError(MS_IOERR, "(%s)", "msGMLWriteQuery()", filename); - return(MS_FAILURE); + return (MS_FAILURE); } stream = stream_to_free; } msIO_fprintf(stream, "\n\n"); - msOWSPrintValidateMetadata(stream, &(map->web.metadata), namespaces, "rootname", OWS_NOERR, "<%s ", "msGMLOutput"); + msOWSPrintValidateMetadata(stream, &(map->web.metadata), namespaces, + "rootname", OWS_NOERR, "<%s ", "msGMLOutput"); - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "uri", OWS_NOERR, "xmlns=\"%s\"", NULL); - msIO_fprintf(stream, "\n\t xmlns:gml=\"http://www.opengis.net/gml\"" ); + msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "uri", + OWS_NOERR, "xmlns=\"%s\"", NULL); + msIO_fprintf(stream, "\n\t xmlns:gml=\"http://www.opengis.net/gml\""); msIO_fprintf(stream, "\n\t xmlns:xlink=\"http://www.w3.org/1999/xlink\""); - msIO_fprintf(stream, "\n\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "schema", OWS_NOERR, "\n\t xsi:schemaLocation=\"%s\"", NULL); + msIO_fprintf(stream, + "\n\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); + msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "schema", + OWS_NOERR, "\n\t xsi:schemaLocation=\"%s\"", NULL); msIO_fprintf(stream, ">\n"); /* a schema *should* be required */ - msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, "description", OWS_NOERR, "\t%s\n", NULL); + msOWSPrintEncodeMetadata(stream, &(map->web.metadata), namespaces, + "description", OWS_NOERR, + "\t%s\n", NULL); - /* Look up map SRS. We need an EPSG code for GML, if not then we get null and we'll fall back on the layer's SRS */ + /* Look up map SRS. We need an EPSG code for GML, if not then we get null and + * we'll fall back on the layer's SRS */ msOWSGetEPSGProj(&(map->projection), NULL, namespaces, MS_TRUE, &pszMapSRS); /* step through the layers looking for query results */ - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { char *pszOutputSRS = NULL; int nSRSDimension = 2; - const char* geomtype; + const char *geomtype; lp = (GET_LAYER(map, map->layerorder[i])); - if(lp->resultcache && lp->resultcache->numresults > 0) { /* found results */ + if (lp->resultcache && + lp->resultcache->numresults > 0) { /* found results */ - reprojectionObj* reprojector = NULL; + reprojectionObj *reprojector = NULL; - /* Determine output SRS, if map has none, then try using layer's native SRS */ + /* Determine output SRS, if map has none, then try using layer's native + * SRS */ if ((pszOutputSRS = pszMapSRS) == NULL) { - msOWSGetEPSGProj(&(lp->projection), NULL, namespaces, MS_TRUE, &pszOutputSRS); + msOWSGetEPSGProj(&(lp->projection), NULL, namespaces, MS_TRUE, + &pszOutputSRS); if (pszOutputSRS == NULL) { - msSetError(MS_WMSERR, "No valid EPSG code in map or layer projection for GML output", "msGMLWriteQuery()"); - continue; /* No EPSG code, cannot output this layer */ + msSetError( + MS_WMSERR, + "No valid EPSG code in map or layer projection for GML output", + "msGMLWriteQuery()"); + continue; /* No EPSG code, cannot output this layer */ } } /* start this collection (layer) */ /* if no layer name provided fall back on the layer name + "_layer" */ - value = (char*) msSmallMalloc(strlen(lp->name)+7); + value = (char *)msSmallMalloc(strlen(lp->name) + 7); sprintf(value, "%s_layer", lp->name); - msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, "layername", OWS_NOERR, "\t<%s>\n", value); + msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, + "layername", OWS_NOERR, "\t<%s>\n", value); msFree(value); - value = (char *) msOWSLookupMetadata(&(lp->metadata), "OM", "title"); + value = (char *)msOWSLookupMetadata(&(lp->metadata), "OM", "title"); if (value) { - msOWSPrintEncodeMetadata(stream, &(lp->metadata), namespaces, "title", OWS_NOERR, "\t%s\n", value); + msOWSPrintEncodeMetadata(stream, &(lp->metadata), namespaces, "title", + OWS_NOERR, "\t%s\n", + value); } geomtype = msOWSLookupMetadata(&(lp->metadata), "OFG", "geomtype"); - if( geomtype != NULL && (strstr(geomtype, "25d") != NULL || strstr(geomtype, "25D") != NULL) ) { + if (geomtype != NULL && (strstr(geomtype, "25d") != NULL || + strstr(geomtype, "25D") != NULL)) { nSRSDimension = 3; } @@ -1460,87 +1684,111 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) constantList = msGMLGetConstants(lp, namespaces); groupList = msGMLGetGroups(lp, namespaces); geometryList = msGMLGetGeometries(lp, namespaces, MS_FALSE); - if (itemList == NULL || constantList == NULL || groupList == NULL || geometryList == NULL) { - msSetError(MS_MISCERR, "Unable to populate item and group metadata structures", "msGMLWriteQuery()"); - if(stream_to_free != NULL) fclose(stream_to_free); + if (itemList == NULL || constantList == NULL || groupList == NULL || + geometryList == NULL) { + msSetError(MS_MISCERR, + "Unable to populate item and group metadata structures", + "msGMLWriteQuery()"); + if (stream_to_free != NULL) + fclose(stream_to_free); return MS_FAILURE; } - if(pszOutputSRS == pszMapSRS && msProjectionsDiffer(&(lp->projection), &(map->projection))) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { + if (pszOutputSRS == pszMapSRS && + msProjectionsDiffer(&(lp->projection), &(map->projection))) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { msGMLFreeGroups(groupList); msGMLFreeConstants(constantList); msGMLFreeItems(itemList); msGMLFreeGeometries(geometryList); msFree(pszOutputSRS); - if(stream_to_free != NULL) fclose(stream_to_free); + if (stream_to_free != NULL) + fclose(stream_to_free); return MS_FAILURE; } } - for(j=0; jresultcache->numresults; j++) { + for (j = 0; j < lp->resultcache->numresults; j++) { status = msLayerGetShape(lp, &shape, &(lp->resultcache->results[j])); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msGMLFreeGroups(groupList); msGMLFreeConstants(constantList); msGMLFreeItems(itemList); msGMLFreeGeometries(geometryList); msProjectDestroyReprojector(reprojector); msFree(pszOutputSRS); - if(stream_to_free != NULL) fclose(stream_to_free); + if (stream_to_free != NULL) + fclose(stream_to_free); return MS_FAILURE; } - /* project the shape into the map projection (if necessary), note that this projects the bounds as well */ - if(reprojector) { + /* project the shape into the map projection (if necessary), note that + * this projects the bounds as well */ + if (reprojector) { status = msProjectShapeEx(reprojector, &shape); - if(status != MS_SUCCESS) { - msIO_fprintf(stream, "\n",msGetErrorString(",")); + if (status != MS_SUCCESS) { + msIO_fprintf(stream, + "\n", + msGetErrorString(",")); msFreeShape(&shape); continue; } } /* start this feature */ - /* specify a feature name, if nothing provided fall back on the layer name + "_feature" */ - value = (char*) msSmallMalloc(strlen(lp->name)+9); + /* specify a feature name, if nothing provided fall back on the layer + * name + "_feature" */ + value = (char *)msSmallMalloc(strlen(lp->name) + 9); sprintf(value, "%s_feature", lp->name); - msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, "featurename", OWS_NOERR, "\t\t<%s>\n", value); + msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, + "featurename", OWS_NOERR, "\t\t<%s>\n", + value); msFree(value); - /* Write the feature geometry and bounding box unless 'none' was requested. */ - /* Default to bbox only if nothing specified and output full geometry only if explicitly requested */ - if(!(geometryList && geometryList->numgeometries == 1 && strcasecmp(geometryList->geometries[0].name, "none") == 0)) { - gmlWriteBounds(stream, OWS_GML2, &(shape.bounds), pszOutputSRS, "\t\t\t", "gml"); - if (geometryList && geometryList->numgeometries > 0 ) - gmlWriteGeometry(stream, geometryList, OWS_GML2, &(shape), pszOutputSRS, NULL, "\t\t\t", "", nSRSDimension, 6); + /* Write the feature geometry and bounding box unless 'none' was + * requested. */ + /* Default to bbox only if nothing specified and output full geometry + * only if explicitly requested */ + if (!(geometryList && geometryList->numgeometries == 1 && + strcasecmp(geometryList->geometries[0].name, "none") == 0)) { + gmlWriteBounds(stream, OWS_GML2, &(shape.bounds), pszOutputSRS, + "\t\t\t", "gml"); + if (geometryList && geometryList->numgeometries > 0) + gmlWriteGeometry(stream, geometryList, OWS_GML2, &(shape), + pszOutputSRS, NULL, "\t\t\t", "", nSRSDimension, + 6); } /* write any item/values */ - for(k=0; knumitems; k++) { + for (k = 0; k < itemList->numitems; k++) { item = &(itemList->items[k]); - if(msItemInGroups(item->name, groupList) == MS_FALSE) - msGMLWriteItem(stream, item, shape.values[k], NULL, "\t\t\t", OWS_GML2, NULL); + if (msItemInGroups(item->name, groupList) == MS_FALSE) + msGMLWriteItem(stream, item, shape.values[k], NULL, "\t\t\t", + OWS_GML2, NULL); } /* write any constants */ - for(k=0; knumconstants; k++) { + for (k = 0; k < constantList->numconstants; k++) { constant = &(constantList->constants[k]); - if(msItemInGroups(constant->name, groupList) == MS_FALSE) + if (msItemInGroups(constant->name, groupList) == MS_FALSE) msGMLWriteConstant(stream, constant, NULL, "\t\t\t"); } /* write any groups */ - for(k=0; knumgroups; k++) - msGMLWriteGroup(stream, &(groupList->groups[k]), &shape, itemList, constantList, NULL, "\t\t\t", OWS_GML2, NULL); + for (k = 0; k < groupList->numgroups; k++) + msGMLWriteGroup(stream, &(groupList->groups[k]), &shape, itemList, + constantList, NULL, "\t\t\t", OWS_GML2, NULL); /* end this feature */ /* specify a feature name if nothing provided */ /* fall back on the layer name + "Feature" */ - value = (char*) msSmallMalloc(strlen(lp->name)+9); + value = (char *)msSmallMalloc(strlen(lp->name) + 9); sprintf(value, "%s_feature", lp->name); - msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, "featurename", OWS_NOERR, "\t\t\n", value); + msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, + "featurename", OWS_NOERR, "\t\t\n", + value); msFree(value); msFreeShape(&shape); /* init too */ @@ -1550,9 +1798,10 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) /* end this collection (layer) */ /* if no layer name provided fall back on the layer name + "_layer" */ - value = (char*) msSmallMalloc(strlen(lp->name)+7); + value = (char *)msSmallMalloc(strlen(lp->name) + 7); sprintf(value, "%s_layer", lp->name); - msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, "layername", OWS_NOERR, "\t\n", value); + msOWSPrintValidateMetadata(stream, &(lp->metadata), namespaces, + "layername", OWS_NOERR, "\t\n", value); msFree(value); msGMLFreeGroups(groupList); @@ -1562,18 +1811,20 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) /* msLayerClose(lp); */ } - if(pszOutputSRS!=pszMapSRS) { + if (pszOutputSRS != pszMapSRS) { msFree(pszOutputSRS); } } /* next layer */ /* end this document */ - msOWSPrintValidateMetadata(stream, &(map->web.metadata), namespaces, "rootname", OWS_NOERR, "\n", "msGMLOutput"); + msOWSPrintValidateMetadata(stream, &(map->web.metadata), namespaces, + "rootname", OWS_NOERR, "\n", "msGMLOutput"); - if(stream_to_free != NULL) fclose(stream_to_free); + if (stream_to_free != NULL) + fclose(stream_to_free); msFree(pszMapSRS); - return(MS_SUCCESS); + return (MS_SUCCESS); #else /* Stub for mapscript */ msSetError(MS_MISCERR, "WMS server support not enabled", "msGMLWriteQuery()"); @@ -1583,39 +1834,37 @@ int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces) #ifdef USE_WFS_SVR void msGMLWriteWFSBounds(mapObj *map, FILE *stream, const char *tab, - OWSGMLVersion outputformat, int nWFSVersion, int bUseURN) -{ - rectObj resultBounds = {-1.0,-1.0,-1.0,-1.0}; + OWSGMLVersion outputformat, int nWFSVersion, + int bUseURN) { + rectObj resultBounds = {-1.0, -1.0, -1.0, -1.0}; /*add a check to see if the map projection is set to be north-east*/ int bSwapAxis = msIsAxisInvertedProj(&(map->projection)); /* Need to start with BBOX of the whole resultset */ if (msGetQueryResultBounds(map, &resultBounds) > 0) { - char* srs = NULL; + char *srs = NULL; if (bSwapAxis) { double tmp; tmp = resultBounds.minx; - resultBounds.minx = resultBounds.miny; + resultBounds.minx = resultBounds.miny; resultBounds.miny = tmp; tmp = resultBounds.maxx; - resultBounds.maxx = resultBounds.maxy; + resultBounds.maxx = resultBounds.maxy; resultBounds.maxy = tmp; - - } - if( bUseURN ) - { - srs = msOWSGetProjURN(&(map->projection), NULL, "FGO", MS_TRUE); - if (!srs) - srs = msOWSGetProjURN(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE); } - else - { - msOWSGetEPSGProj(&(map->projection), NULL, "FGO", MS_TRUE, &srs); - if (!srs) - msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE, &srs); + if (bUseURN) { + srs = msOWSGetProjURN(&(map->projection), NULL, "FGO", MS_TRUE); + if (!srs) + srs = msOWSGetProjURN(&(map->projection), &(map->web.metadata), "FGO", + MS_TRUE); + } else { + msOWSGetEPSGProj(&(map->projection), NULL, "FGO", MS_TRUE, &srs); + if (!srs) + msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", + MS_TRUE, &srs); } gmlWriteBounds(stream, outputformat, &resultBounds, srs, tab, @@ -1631,24 +1880,24 @@ void msGMLWriteWFSBounds(mapObj *map, FILE *stream, const char *tab, ** ** Similar to msGMLWriteQuery() but tuned for use with WFS */ -int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_prefix, +int msGMLWriteWFSQuery(mapObj *map, FILE *stream, + const char *default_namespace_prefix, OWSGMLVersion outputformat, int nWFSVersion, int bUseURN, - int bGetPropertyValueRequest) -{ + int bGetPropertyValueRequest) { #ifdef USE_WFS_SVR int status; - int i,j,k; - layerObj *lp=NULL; + int i, j, k; + layerObj *lp = NULL; shapeObj shape; - gmlGroupListObj *groupList=NULL; - gmlItemListObj *itemList=NULL; - gmlConstantListObj *constantList=NULL; - gmlGeometryListObj *geometryList=NULL; - gmlItemObj *item=NULL; - gmlConstantObj *constant=NULL; + gmlGroupListObj *groupList = NULL; + gmlItemListObj *itemList = NULL; + gmlConstantListObj *constantList = NULL; + gmlGeometryListObj *geometryList = NULL; + gmlItemObj *item = NULL; + gmlConstantObj *constant = NULL; - const char *namespace_prefix=NULL; + const char *namespace_prefix = NULL; int bSwapAxis; msInitShape(&shape); @@ -1658,218 +1907,240 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_ /* Need to start with BBOX of the whole resultset */ if (!bGetPropertyValueRequest) { - msGMLWriteWFSBounds(map, stream, " ", outputformat, nWFSVersion, bUseURN); + msGMLWriteWFSBounds(map, stream, " ", outputformat, nWFSVersion, + bUseURN); } /* step through the layers looking for query results */ - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { lp = GET_LAYER(map, map->layerorder[i]); - if(lp->resultcache && lp->resultcache->numresults > 0) { /* found results */ + if (lp->resultcache && + lp->resultcache->numresults > 0) { /* found results */ char *layerName; const char *value; - int featureIdIndex=-1; /* no feature id */ - char* srs = NULL; + int featureIdIndex = -1; /* no feature id */ + char *srs = NULL; int bOutputGMLIdOnly = MS_FALSE; int nSRSDimension = 2; - const char* geomtype; - reprojectionObj* reprojector = NULL; + const char *geomtype; + reprojectionObj *reprojector = NULL; int geometry_precision = 6; /* setup namespace, a layer can override the default */ - namespace_prefix = msOWSLookupMetadata(&(lp->metadata), "OFG", "namespace_prefix"); - if(!namespace_prefix) namespace_prefix = default_namespace_prefix; + namespace_prefix = + msOWSLookupMetadata(&(lp->metadata), "OFG", "namespace_prefix"); + if (!namespace_prefix) + namespace_prefix = default_namespace_prefix; geomtype = msOWSLookupMetadata(&(lp->metadata), "OFG", "geomtype"); - if( geomtype != NULL && (strstr(geomtype, "25d") != NULL || strstr(geomtype, "25D") != NULL) ) - { - nSRSDimension = 3; + if (geomtype != NULL && (strstr(geomtype, "25d") != NULL || + strstr(geomtype, "25D") != NULL)) { + nSRSDimension = 3; } value = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); - if(value) { /* find the featureid amongst the items for this layer */ - for(j=0; jnumitems; j++) { - if(strcasecmp(lp->items[j], value) == 0) { /* found it */ + if (value) { /* find the featureid amongst the items for this layer */ + for (j = 0; j < lp->numitems; j++) { + if (strcasecmp(lp->items[j], value) == 0) { /* found it */ featureIdIndex = j; break; } } - /* Produce a warning if a featureid was set but the corresponding item is not found. */ + /* Produce a warning if a featureid was set but the corresponding item + * is not found. */ if (featureIdIndex == -1) - msIO_fprintf(stream, "\n", value, lp->name); - } - else if( outputformat == OWS_GML32 ) - msIO_fprintf(stream, "\n", lp->name); + msIO_fprintf(stream, + "\n", + value, lp->name); + } else if (outputformat == OWS_GML32) + msIO_fprintf(stream, + "\n", + lp->name); /* populate item and group metadata structures */ itemList = msGMLGetItems(lp, "G"); constantList = msGMLGetConstants(lp, "G"); groupList = msGMLGetGroups(lp, "G"); geometryList = msGMLGetGeometries(lp, "GFO", MS_FALSE); - if (itemList == NULL || constantList == NULL || groupList == NULL || geometryList == NULL) { - msSetError(MS_MISCERR, "Unable to populate item and group metadata structures", "msGMLWriteWFSQuery()"); + if (itemList == NULL || constantList == NULL || groupList == NULL || + geometryList == NULL) { + msSetError(MS_MISCERR, + "Unable to populate item and group metadata structures", + "msGMLWriteWFSQuery()"); return MS_FAILURE; } - if( bGetPropertyValueRequest ) - { - const char* value = msOWSLookupMetadata(&(lp->metadata), "G", "include_items"); - if( value != NULL && strcmp(value, "@gml:id") == 0 ) - bOutputGMLIdOnly = MS_TRUE; + if (bGetPropertyValueRequest) { + const char *value = + msOWSLookupMetadata(&(lp->metadata), "G", "include_items"); + if (value != NULL && strcmp(value, "@gml:id") == 0) + bOutputGMLIdOnly = MS_TRUE; } if (namespace_prefix) { - layerName = (char *) msSmallMalloc(strlen(namespace_prefix)+strlen(lp->name)+2); + layerName = (char *)msSmallMalloc(strlen(namespace_prefix) + + strlen(lp->name) + 2); sprintf(layerName, "%s:%s", namespace_prefix, lp->name); } else { layerName = msStrdup(lp->name); } - if( bUseURN ) - { - srs = msOWSGetProjURN(&(map->projection), NULL, "FGO", MS_TRUE); - if (!srs) - srs = msOWSGetProjURN(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE); - if (!srs) - srs = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FGO", MS_TRUE); - } - else - { - msOWSGetEPSGProj(&(map->projection), NULL, "FGO", MS_TRUE, &srs); - if (!srs) - msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", MS_TRUE, &srs); - if (!srs) - msOWSGetEPSGProj(&(lp->projection), &(lp->metadata), "FGO", MS_TRUE, &srs); + if (bUseURN) { + srs = msOWSGetProjURN(&(map->projection), NULL, "FGO", MS_TRUE); + if (!srs) + srs = msOWSGetProjURN(&(map->projection), &(map->web.metadata), "FGO", + MS_TRUE); + if (!srs) + srs = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FGO", + MS_TRUE); + } else { + msOWSGetEPSGProj(&(map->projection), NULL, "FGO", MS_TRUE, &srs); + if (!srs) + msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "FGO", + MS_TRUE, &srs); + if (!srs) + msOWSGetEPSGProj(&(lp->projection), &(lp->metadata), "FGO", MS_TRUE, + &srs); } - if(msProjectionsDiffer(&(lp->projection), &(map->projection))) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msGMLFreeGroups(groupList); - msGMLFreeConstants(constantList); - msGMLFreeItems(itemList); - msGMLFreeGeometries(geometryList); - msFree(layerName); - msFree(srs); - return MS_FAILURE; + if (msProjectionsDiffer(&(lp->projection), &(map->projection))) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { + msGMLFreeGroups(groupList); + msGMLFreeConstants(constantList); + msGMLFreeItems(itemList); + msGMLFreeGeometries(geometryList); + msFree(layerName); + msFree(srs); + return MS_FAILURE; } } - for(j=0; jresultcache->numresults; j++) { - char* pszFID; + for (j = 0; j < lp->resultcache->numresults; j++) { + char *pszFID; - if( lp->resultcache->results[j].shape ) - { - /* msDebug("Using cached shape %ld\n", lp->resultcache->results[j].shapeindex); */ - msCopyShape(lp->resultcache->results[j].shape, &shape); - } - else - { - status = msLayerGetShape(lp, &shape, &(lp->resultcache->results[j])); - if(status != MS_SUCCESS) { - msGMLFreeGroups(groupList); - msGMLFreeConstants(constantList); - msGMLFreeItems(itemList); - msGMLFreeGeometries(geometryList); - msFree(layerName); - msProjectDestroyReprojector(reprojector); - msFree(srs); - return(status); - } + if (lp->resultcache->results[j].shape) { + /* msDebug("Using cached shape %ld\n", + * lp->resultcache->results[j].shapeindex); */ + msCopyShape(lp->resultcache->results[j].shape, &shape); + } else { + status = msLayerGetShape(lp, &shape, &(lp->resultcache->results[j])); + if (status != MS_SUCCESS) { + msGMLFreeGroups(groupList); + msGMLFreeConstants(constantList); + msGMLFreeItems(itemList); + msGMLFreeGeometries(geometryList); + msFree(layerName); + msProjectDestroyReprojector(reprojector); + msFree(srs); + return (status); + } } - /* project the shape into the map projection (if necessary), note that this projects the bounds as well */ - if(reprojector) + /* project the shape into the map projection (if necessary), note that + * this projects the bounds as well */ + if (reprojector) msProjectShapeEx(reprojector, &shape); - if(featureIdIndex != -1) { - pszFID = (char*) msSmallMalloc( strlen(lp->name) + 1 + strlen(shape.values[featureIdIndex]) + 1 ); - sprintf(pszFID, "%s.%s", lp->name, shape.values[featureIdIndex]); - } - else - pszFID = msStrdup(""); - - - if( bOutputGMLIdOnly ) - { - msIO_fprintf(stream, " %s\n", pszFID); - msFree(pszFID); - msFreeShape(&shape); /* init too */ - continue; + if (featureIdIndex != -1) { + pszFID = (char *)msSmallMalloc( + strlen(lp->name) + 1 + strlen(shape.values[featureIdIndex]) + 1); + sprintf(pszFID, "%s.%s", lp->name, shape.values[featureIdIndex]); + } else + pszFID = msStrdup(""); + + if (bOutputGMLIdOnly) { + msIO_fprintf(stream, " %s\n", pszFID); + msFree(pszFID); + msFreeShape(&shape); /* init too */ + continue; } /* ** start this feature */ - if( nWFSVersion == OWS_2_0_0 ) - msIO_fprintf(stream, " \n"); + if (nWFSVersion == OWS_2_0_0) + msIO_fprintf(stream, " \n"); else - msIO_fprintf(stream, " \n"); - if(msIsXMLTagValid(layerName) == MS_FALSE) - msIO_fprintf(stream, "\n", layerName); - if(featureIdIndex != -1) { - if( !bGetPropertyValueRequest ) - { - if(outputformat == OWS_GML2) - msIO_fprintf(stream, " <%s fid=\"%s\">\n", layerName, pszFID); - else /* OWS_GML3 or OWS_GML32 */ - msIO_fprintf(stream, " <%s gml:id=\"%s\">\n", layerName, pszFID); - } + msIO_fprintf(stream, " \n"); + if (msIsXMLTagValid(layerName) == MS_FALSE) + msIO_fprintf(stream, + "\n", + layerName); + if (featureIdIndex != -1) { + if (!bGetPropertyValueRequest) { + if (outputformat == OWS_GML2) + msIO_fprintf(stream, " <%s fid=\"%s\">\n", layerName, + pszFID); + else /* OWS_GML3 or OWS_GML32 */ + msIO_fprintf(stream, " <%s gml:id=\"%s\">\n", layerName, + pszFID); + } } else { - if( !bGetPropertyValueRequest ) - msIO_fprintf(stream, " <%s>\n", layerName); + if (!bGetPropertyValueRequest) + msIO_fprintf(stream, " <%s>\n", layerName); } if (bSwapAxis) msAxisSwapShape(&shape); /* write the feature geometry and bounding box */ - if(!(geometryList && geometryList->numgeometries == 1 && - strcasecmp(geometryList->geometries[0].name, "none") == 0)) { - if( !bGetPropertyValueRequest ) - gmlWriteBounds(stream, outputformat, &(shape.bounds), srs, " ", "gml"); - - if(msOWSLookupMetadata(&(lp->metadata), "F", "geometry_precision")){ - geometry_precision=atoi(msOWSLookupMetadata(&(lp->metadata), "F", "geometry_precision")); - } else if(msOWSLookupMetadata(&map->web.metadata, "F", "geometry_precision")){ - geometry_precision=atoi(msOWSLookupMetadata(&map->web.metadata, "F", "geometry_precision")); + if (!(geometryList && geometryList->numgeometries == 1 && + strcasecmp(geometryList->geometries[0].name, "none") == 0)) { + if (!bGetPropertyValueRequest) + gmlWriteBounds(stream, outputformat, &(shape.bounds), srs, + " ", "gml"); + + if (msOWSLookupMetadata(&(lp->metadata), "F", "geometry_precision")) { + geometry_precision = atoi(msOWSLookupMetadata( + &(lp->metadata), "F", "geometry_precision")); + } else if (msOWSLookupMetadata(&map->web.metadata, "F", + "geometry_precision")) { + geometry_precision = atoi(msOWSLookupMetadata( + &map->web.metadata, "F", "geometry_precision")); } gmlWriteGeometry(stream, geometryList, outputformat, &(shape), srs, - namespace_prefix, " ", pszFID, nSRSDimension,geometry_precision); + namespace_prefix, " ", pszFID, nSRSDimension, + geometry_precision); } /* write any item/values */ - for(k=0; knumitems; k++) { + for (k = 0; k < itemList->numitems; k++) { item = &(itemList->items[k]); - if(msItemInGroups(item->name, groupList) == MS_FALSE) + if (msItemInGroups(item->name, groupList) == MS_FALSE) msGMLWriteItem(stream, item, shape.values[k], namespace_prefix, " ", outputformat, pszFID); } /* write any constants */ - for(k=0; knumconstants; k++) { + for (k = 0; k < constantList->numconstants; k++) { constant = &(constantList->constants[k]); - if(msItemInGroups(constant->name, groupList) == MS_FALSE) + if (msItemInGroups(constant->name, groupList) == MS_FALSE) msGMLWriteConstant(stream, constant, namespace_prefix, " "); } /* write any groups */ - for(k=0; knumgroups; k++) + for (k = 0; k < groupList->numgroups; k++) msGMLWriteGroup(stream, &(groupList->groups[k]), &shape, itemList, - constantList, namespace_prefix, " ", outputformat, pszFID); + constantList, namespace_prefix, " ", + outputformat, pszFID); - if( !bGetPropertyValueRequest ) - /* end this feature */ - msIO_fprintf(stream, " \n", layerName); + if (!bGetPropertyValueRequest) + /* end this feature */ + msIO_fprintf(stream, " \n", layerName); - if( nWFSVersion == OWS_2_0_0 ) + if (nWFSVersion == OWS_2_0_0) msIO_fprintf(stream, " \n"); else msIO_fprintf(stream, " \n"); - msFree(pszFID); pszFID = NULL; msFreeShape(&shape); /* init too */ @@ -1892,15 +2163,15 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_ } /* next layer */ - return(MS_SUCCESS); + return (MS_SUCCESS); -#else /* Stub for mapscript */ - msSetError(MS_MISCERR, "WFS server support not enabled", "msGMLWriteWFSQuery()"); +#else /* Stub for mapscript */ + msSetError(MS_MISCERR, "WFS server support not enabled", + "msGMLWriteWFSQuery()"); return MS_FAILURE; #endif /* USE_WFS_SVR */ } - #ifdef USE_LIBXML2 /** @@ -1920,8 +2191,8 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *default_namespace_ * */ -xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, double maxy, const char *psEpsg) -{ +xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, + double maxy, const char *psEpsg) { xmlNodePtr psNode = NULL, psSubNode = NULL; char *pszTmp = NULL; char *pszTmp2 = NULL; @@ -1931,8 +2202,8 @@ xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, psSubNode = xmlNewChild(psNode, NULL, BAD_CAST "Envelope", NULL); if (psEpsg) { - const size_t bufferSize = strlen(psEpsg)+1; - pszEpsg = (char*) msSmallMalloc(bufferSize); + const size_t bufferSize = strlen(psEpsg) + 1; + pszEpsg = (char *)msSmallMalloc(bufferSize); snprintf(pszEpsg, bufferSize, "%s", psEpsg); msStringToLower(pszEpsg); pszTmp = msStringConcatenate(pszTmp, "urn:ogc:crs:"); @@ -1955,7 +2226,7 @@ xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, pszTmp = msDoubleToString(maxx, MS_TRUE); pszTmp = msStringConcatenate(pszTmp, " "); - pszTmp2 = msDoubleToString(maxy,MS_TRUE); + pszTmp2 = msDoubleToString(maxy, MS_TRUE); pszTmp = msStringConcatenate(pszTmp, pszTmp2); xmlNewChild(psSubNode, NULL, BAD_CAST "upperCorner", BAD_CAST pszTmp); free(pszTmp); @@ -1979,9 +2250,9 @@ xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, * */ -xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, double x, double y) -{ - +xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, + double x, double y) { + xmlNodePtr psNode = xmlNewNode(psNs, BAD_CAST "Point"); if (id) { @@ -1989,8 +2260,8 @@ xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, dou } if (psSrsName) { - const size_t bufferSize = strlen(psSrsName)+1; - char* pszSrsName = (char *) msSmallMalloc(bufferSize); + const size_t bufferSize = strlen(psSrsName) + 1; + char *pszSrsName = (char *)msSmallMalloc(bufferSize); snprintf(pszSrsName, bufferSize, "%s", psSrsName); msStringToLower(pszSrsName); char *pszTmp = NULL; @@ -2005,9 +2276,9 @@ xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, dou free(pszTmp); } - char* pszTmp = msDoubleToString(x, MS_TRUE); + char *pszTmp = msDoubleToString(x, MS_TRUE); pszTmp = msStringConcatenate(pszTmp, " "); - char* pszTmp2 = msDoubleToString(y, MS_TRUE); + char *pszTmp2 = msDoubleToString(y, MS_TRUE); pszTmp = msStringConcatenate(pszTmp, pszTmp2); xmlNewChild(psNode, NULL, BAD_CAST "pos", BAD_CAST pszTmp); @@ -2029,9 +2300,8 @@ xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, dou * */ -xmlNodePtr msGML3TimePeriod(xmlNsPtr psNs, char *pszStart, char *pszEnd) -{ - xmlNodePtr psNode=NULL; +xmlNodePtr msGML3TimePeriod(xmlNsPtr psNs, char *pszStart, char *pszEnd) { + xmlNodePtr psNode = NULL; psNode = xmlNewNode(psNs, BAD_CAST "TimePeriod"); xmlNewChild(psNode, NULL, BAD_CAST "beginPosition", BAD_CAST pszStart); @@ -2056,9 +2326,8 @@ xmlNodePtr msGML3TimePeriod(xmlNsPtr psNs, char *pszStart, char *pszEnd) * */ -xmlNodePtr msGML3TimeInstant(xmlNsPtr psNs, char *pszTime) -{ - xmlNodePtr psNode=NULL; +xmlNodePtr msGML3TimeInstant(xmlNsPtr psNs, char *pszTime) { + xmlNodePtr psNode = NULL; psNode = xmlNewNode(psNs, BAD_CAST "TimeInstant"); xmlNewChild(psNode, NULL, BAD_CAST "timePosition", BAD_CAST pszTime); @@ -2067,83 +2336,93 @@ xmlNodePtr msGML3TimeInstant(xmlNsPtr psNs, char *pszTime) #endif /* USE_LIBXML2 */ - /************************************************************************/ /* The following functions are enabled in all cases, even if */ /* WMS and WFS are not available. */ /************************************************************************/ -gmlItemListObj *msGMLGetItems(layerObj *layer, const char *metadata_namespaces) -{ - int i,j; +gmlItemListObj *msGMLGetItems(layerObj *layer, + const char *metadata_namespaces) { + int i, j; - char **xmlitems=NULL; - int numxmlitems=0; + char **xmlitems = NULL; + int numxmlitems = 0; - char **incitems=NULL; - int numincitems=0; + char **incitems = NULL; + int numincitems = 0; - char **excitems=NULL; - int numexcitems=0; + char **excitems = NULL; + int numexcitems = 0; - char **optionalitems=NULL; - int numoptionalitems=0; + char **optionalitems = NULL; + int numoptionalitems = 0; - char **mandatoryitems=NULL; - int nummandatoryitems=0; + char **mandatoryitems = NULL; + int nummandatoryitems = 0; - char **defaultitems=NULL; - int numdefaultitems=0; + char **defaultitems = NULL; + int numdefaultitems = 0; - const char *value=NULL; + const char *value = NULL; char tag[64]; - gmlItemListObj *itemList=NULL; - gmlItemObj *item=NULL; + gmlItemListObj *itemList = NULL; + gmlItemObj *item = NULL; /* get a list of items that might be included in output */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "include_items")) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "include_items")) != NULL) incitems = msStringSplit(value, ',', &numincitems); /* get a list of items that should be excluded in output */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "exclude_items")) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "exclude_items")) != NULL) excitems = msStringSplit(value, ',', &numexcitems); /* get a list of items that should not be XML encoded */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "xml_items")) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "xml_items")) != NULL) xmlitems = msStringSplit(value, ',', &numxmlitems); - /* get a list of items that should be indicated as optional in DescribeFeatureType */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "optional_items")) != NULL) + /* get a list of items that should be indicated as optional in + * DescribeFeatureType */ + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "optional_items")) != NULL) optionalitems = msStringSplit(value, ',', &numoptionalitems); - /* get a list of items that should be indicated as mandatory in DescribeFeatureType */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "mandatory_items")) != NULL) + /* get a list of items that should be indicated as mandatory in + * DescribeFeatureType */ + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "mandatory_items")) != NULL) mandatoryitems = msStringSplit(value, ',', &nummandatoryitems); /* get a list of items that should be presented by default in GetFeature */ - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, "default_items")) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + "default_items")) != NULL) defaultitems = msStringSplit(value, ',', &numdefaultitems); /* allocate memory and iinitialize the item collection */ - itemList = (gmlItemListObj *) malloc(sizeof(gmlItemListObj)); - if(itemList == NULL) { - msSetError(MS_MEMERR, "Error allocating a collection GML item structures.", "msGMLGetItems()"); + itemList = (gmlItemListObj *)malloc(sizeof(gmlItemListObj)); + if (itemList == NULL) { + msSetError(MS_MEMERR, "Error allocating a collection GML item structures.", + "msGMLGetItems()"); return NULL; } itemList->numitems = layer->numitems; - itemList->items = (gmlItemObj *) malloc(sizeof(gmlItemObj)*itemList->numitems); - if(!itemList->items) { - msSetError(MS_MEMERR, "Error allocating a collection GML item structures.", "msGMLGetItems()"); + itemList->items = + (gmlItemObj *)malloc(sizeof(gmlItemObj) * itemList->numitems); + if (!itemList->items) { + msSetError(MS_MEMERR, "Error allocating a collection GML item structures.", + "msGMLGetItems()"); free(itemList); return NULL; } - for(i=0; inumitems; i++) { + for (i = 0; i < layer->numitems; i++) { item = &(itemList->items[i]); - item->name = msStrdup(layer->items[i]); /* initialize the item */ + item->name = msStrdup(layer->items[i]); /* initialize the item */ item->alias = NULL; item->type = NULL; item->template = NULL; @@ -2155,73 +2434,78 @@ gmlItemListObj *msGMLGetItems(layerObj *layer, const char *metadata_namespaces) item->minOccurs = 0; /* check visibility, included items first... */ - if(numincitems == 1 && strcasecmp("all", incitems[0]) == 0) { + if (numincitems == 1 && strcasecmp("all", incitems[0]) == 0) { item->visible = MS_TRUE; } else { - for(j=0; jitems[i], incitems[j]) == 0) + for (j = 0; j < numincitems; j++) { + if (strcasecmp(layer->items[i], incitems[j]) == 0) item->visible = MS_TRUE; } } /* ...and now excluded items */ - for(j=0; jitems[i], excitems[j]) == 0) + for (j = 0; j < numexcitems; j++) { + if (strcasecmp(layer->items[i], excitems[j]) == 0) item->visible = MS_FALSE; } /* check encoding */ - for(j=0; jitems[i], xmlitems[j]) == 0) + for (j = 0; j < numxmlitems; j++) { + if (strcasecmp(layer->items[i], xmlitems[j]) == 0) item->encode = MS_FALSE; } /* check optional */ - if(numoptionalitems == 1 && strcasecmp("all", optionalitems[0]) == 0) { + if (numoptionalitems == 1 && strcasecmp("all", optionalitems[0]) == 0) { item->minOccurs = 0; - } else if( numoptionalitems > 0) { + } else if (numoptionalitems > 0) { item->minOccurs = 1; - for(j=0; jitems[i], optionalitems[j]) == 0) + for (j = 0; j < numoptionalitems; j++) { + if (strcasecmp(layer->items[i], optionalitems[j]) == 0) item->minOccurs = 0; } } /* check mandatory */ - if(nummandatoryitems == 1 && strcasecmp("all", mandatoryitems[0]) == 0) { + if (nummandatoryitems == 1 && strcasecmp("all", mandatoryitems[0]) == 0) { item->minOccurs = 1; - } else if( nummandatoryitems > 0) { + } else if (nummandatoryitems > 0) { item->minOccurs = 0; - for(j=0; jitems[i], mandatoryitems[j]) == 0) + for (j = 0; j < nummandatoryitems; j++) { + if (strcasecmp(layer->items[i], mandatoryitems[j]) == 0) item->minOccurs = 1; } } /* check default */ - for(j=0; jitems[i], defaultitems[j]) == 0) + for (j = 0; j < numdefaultitems; j++) { + if (strcasecmp(layer->items[i], defaultitems[j]) == 0) item->outputByDefault = 1; } snprintf(tag, sizeof(tag), "%s_alias", layer->items[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) item->alias = msStrdup(value); snprintf(tag, sizeof(tag), "%s_type", layer->items[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) item->type = msStrdup(value); snprintf(tag, sizeof(tag), "%s_template", layer->items[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) item->template = msStrdup(value); snprintf(tag, sizeof(tag), "%s_width", layer->items[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) item->width = atoi(value); snprintf(tag, sizeof(tag), "%s_precision", layer->items[i]); - if((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, tag)) != NULL) + if ((value = msOWSLookupMetadata(&(layer->metadata), metadata_namespaces, + tag)) != NULL) item->precision = atoi(value); } @@ -2235,20 +2519,20 @@ gmlItemListObj *msGMLGetItems(layerObj *layer, const char *metadata_namespaces) return itemList; } -void msGMLFreeItems(gmlItemListObj *itemList) -{ +void msGMLFreeItems(gmlItemListObj *itemList) { int i; - if(!itemList) return; + if (!itemList) + return; - for(i=0; inumitems; i++) { + for (i = 0; i < itemList->numitems; i++) { msFree(itemList->items[i].name); msFree(itemList->items[i].alias); msFree(itemList->items[i].type); msFree(itemList->items[i].template); } - if( itemList->items != NULL ) + if (itemList->items != NULL) free(itemList->items); free(itemList); diff --git a/mapgml.h b/mapgml.h index 1bff8db780..c5cebd83d9 100644 --- a/mapgml.h +++ b/mapgml.h @@ -28,18 +28,19 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #ifndef MAPGML_H #define MAPGML_H #ifdef USE_LIBXML2 -#include -#include +#include +#include -xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, double maxy, const char *psEpsg); +xmlNodePtr msGML3BoundedBy(xmlNsPtr psNs, double minx, double miny, double maxx, + double maxy, const char *psEpsg); xmlNodePtr msGML3TimePeriod(xmlNsPtr psNs, char *pszStart, char *pszEnd); xmlNodePtr msGML3TimeInstant(xmlNsPtr psNs, char *timeInstant); -xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, double x, double y); +xmlNodePtr msGML3Point(xmlNsPtr psNs, const char *psSrsName, const char *id, + double x, double y); #endif /* USE_LIBXML2 */ diff --git a/mapgraph.cpp b/mapgraph.cpp index 0601081649..e578bd951b 100644 --- a/mapgraph.cpp +++ b/mapgraph.cpp @@ -31,17 +31,18 @@ #include "mapgraph.h" #include // for std::swap -graphObj *msCreateGraph(signed int numnodes) -{ - graphObj *graph=nullptr; +graphObj *msCreateGraph(signed int numnodes) { + graphObj *graph = nullptr; - if(numnodes <= 0) return nullptr; + if (numnodes <= 0) + return nullptr; - graph = (graphObj *) malloc(sizeof(graphObj)); - if(!graph) return nullptr; + graph = (graphObj *)malloc(sizeof(graphObj)); + if (!graph) + return nullptr; - graph->head = (graphNodeObj **) calloc(numnodes, sizeof(graphNodeObj*)); - if(!graph->head) { + graph->head = (graphNodeObj **)calloc(numnodes, sizeof(graphNodeObj *)); + if (!graph->head) { free(graph); return nullptr; } @@ -50,14 +51,14 @@ graphObj *msCreateGraph(signed int numnodes) return graph; } -void msFreeGraph(graphObj *graph) -{ - if(!graph) return; +void msFreeGraph(graphObj *graph) { + if (!graph) + return; - graphNodeObj *tmp=nullptr; - - for(int i=0; inumnodes; i++) { - while(graph->head[i] != nullptr) { + graphNodeObj *tmp = nullptr; + + for (int i = 0; i < graph->numnodes; i++) { + while (graph->head[i] != nullptr) { tmp = graph->head[i]; graph->head[i] = graph->head[i]->next; free(tmp); @@ -68,15 +69,16 @@ void msFreeGraph(graphObj *graph) free(graph); } -int msGraphAddEdge(graphObj *graph, int src, int dest, double weight) -{ - graphNodeObj *node=nullptr; +int msGraphAddEdge(graphObj *graph, int src, int dest, double weight) { + graphNodeObj *node = nullptr; - if(!graph) return MS_FAILURE; + if (!graph) + return MS_FAILURE; // src -> dest - node = (graphNodeObj *) malloc(sizeof(graphNodeObj)); - if(!node) return MS_FAILURE; + node = (graphNodeObj *)malloc(sizeof(graphNodeObj)); + if (!node) + return MS_FAILURE; node->dest = dest; node->weight = weight; @@ -84,8 +86,9 @@ int msGraphAddEdge(graphObj *graph, int src, int dest, double weight) graph->head[src] = node; // dest -> src - node = (graphNodeObj *) malloc(sizeof(graphNodeObj)); - if(!node) return MS_FAILURE; + node = (graphNodeObj *)malloc(sizeof(graphNodeObj)); + if (!node) + return MS_FAILURE; node->dest = src; node->weight = weight; @@ -95,15 +98,15 @@ int msGraphAddEdge(graphObj *graph, int src, int dest, double weight) return MS_SUCCESS; } -void msPrintGraph(graphObj *graph) -{ +void msPrintGraph(graphObj *graph) { int i; - if(!graph) return; + if (!graph) + return; - for(i=0; inumnodes; i++) { + for (i = 0; i < graph->numnodes; i++) { graphNodeObj *node = graph->head[i]; - if(node != nullptr) { + if (node != nullptr) { do { msDebug("%d -> %d (%.6f)\t", i, node->dest, node->weight); node = node->next; @@ -116,7 +119,8 @@ void msPrintGraph(graphObj *graph) /* ** Derived from an number web resources including: ** -** https://www.geeksforgeeks.org/dijkstras-algorithm-for-adjacency-list-representation-greedy-algo-8/ +** +*https://www.geeksforgeeks.org/dijkstras-algorithm-for-adjacency-list-representation-greedy-algo-8/ ** https://youtube.com/watch?v=pSqmAO-m7Lk ** https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm ** @@ -135,41 +139,42 @@ typedef struct { minHeapNodeObj **nodes; } minHeapObj; -static minHeapNodeObj *newMinHeapNode(int idx, double dist) -{ - minHeapNodeObj *node = (minHeapNodeObj *) malloc(sizeof(minHeapNodeObj)); - if(!node) return nullptr; +static minHeapNodeObj *newMinHeapNode(int idx, double dist) { + minHeapNodeObj *node = (minHeapNodeObj *)malloc(sizeof(minHeapNodeObj)); + if (!node) + return nullptr; node->idx = idx; node->dist = dist; return node; } -static void freeMinHeap(minHeapObj *minHeap) -{ - if(!minHeap) return; +static void freeMinHeap(minHeapObj *minHeap) { + if (!minHeap) + return; free(minHeap->pos); - for(int i=0; isize; i++) { + for (int i = 0; i < minHeap->size; i++) { free(minHeap->nodes[i]); } free(minHeap->nodes); free(minHeap); } -static minHeapObj *createMinHeap(signed int capacity) -{ - minHeapObj *minHeap = (minHeapObj *) malloc(sizeof(minHeapObj)); - if(!minHeap) return nullptr; +static minHeapObj *createMinHeap(signed int capacity) { + minHeapObj *minHeap = (minHeapObj *)malloc(sizeof(minHeapObj)); + if (!minHeap) + return nullptr; - minHeap->pos = (int *) malloc(capacity * sizeof(int)); - if(!minHeap->pos) { + minHeap->pos = (int *)malloc(capacity * sizeof(int)); + if (!minHeap->pos) { free(minHeap); return nullptr; } minHeap->size = 0; minHeap->capacity = capacity; - minHeap->nodes = (minHeapNodeObj **) malloc(capacity * sizeof(minHeapNodeObj *)); - if(!minHeap->nodes) { + minHeap->nodes = + (minHeapNodeObj **)malloc(capacity * sizeof(minHeapNodeObj *)); + if (!minHeap->nodes) { free(minHeap->pos); free(minHeap); return nullptr; @@ -177,79 +182,75 @@ static minHeapObj *createMinHeap(signed int capacity) return minHeap; } -static void minHeapify(minHeapObj *minHeap, int idx) -{ +static void minHeapify(minHeapObj *minHeap, int idx) { int smallest = idx; - const int left = 2*idx + 1; - const int right = 2*idx + 2; - - if (left < minHeap->size && minHeap->nodes[left]->dist < minHeap->nodes[smallest]->dist) + const int left = 2 * idx + 1; + const int right = 2 * idx + 2; + + if (left < minHeap->size && + minHeap->nodes[left]->dist < minHeap->nodes[smallest]->dist) smallest = left; - - if (right < minHeap->size && minHeap->nodes[right]->dist < minHeap->nodes[smallest]->dist) + + if (right < minHeap->size && + minHeap->nodes[right]->dist < minHeap->nodes[smallest]->dist) smallest = right; - + if (smallest != idx) { minHeapNodeObj *smallestNode = minHeap->nodes[smallest]; minHeapNodeObj *idxNode = minHeap->nodes[idx]; - + minHeap->pos[smallestNode->idx] = idx; // swap positions minHeap->pos[idxNode->idx] = smallest; - + std::swap(minHeap->nodes[smallest], minHeap->nodes[idx]); // swap nodes minHeapify(minHeap, smallest); } } -static bool isEmpty(const minHeapObj *minHeap) -{ - return minHeap->size == 0; -} +static bool isEmpty(const minHeapObj *minHeap) { return minHeap->size == 0; } + +static minHeapNodeObj *extractMin(minHeapObj *minHeap) { + if (isEmpty(minHeap)) + return nullptr; -static minHeapNodeObj *extractMin(minHeapObj *minHeap) -{ - if (isEmpty(minHeap)) return nullptr; - // store root node minHeapNodeObj *root = minHeap->nodes[0]; - + // replace root node with last node minHeapNodeObj *lastNode = minHeap->nodes[minHeap->size - 1]; minHeap->nodes[0] = lastNode; - + // update position of last node minHeap->pos[root->idx] = minHeap->size - 1; minHeap->pos[lastNode->idx] = 0; - + // Reduce heap size and heapify root --minHeap->size; minHeapify(minHeap, 0); - + return root; } -static void decreaseKey(minHeapObj *minHeap, int idx, int dist) -{ +static void decreaseKey(minHeapObj *minHeap, int idx, int dist) { // get the index of idx in min heap nodes int i = minHeap->pos[idx]; - + // get the node and update its dist value minHeap->nodes[i]->dist = dist; - + // travel up while the complete tree is not hepified (this is a O(Logn) loop) while (i && minHeap->nodes[i]->dist < minHeap->nodes[(i - 1) / 2]->dist) { // swap this node with its parent - minHeap->pos[minHeap->nodes[i]->idx] = (i-1)/2; - minHeap->pos[minHeap->nodes[(i-1)/2]->idx] = i; + minHeap->pos[minHeap->nodes[i]->idx] = (i - 1) / 2; + minHeap->pos[minHeap->nodes[(i - 1) / 2]->idx] = i; std::swap(minHeap->nodes[i], minHeap->nodes[(i - 1) / 2]); - + // move to parent index i = (i - 1) / 2; } } -static bool isInMinHeap(const minHeapObj *minHeap, int idx) -{ +static bool isInMinHeap(const minHeapObj *minHeap, int idx) { return minHeap->pos[idx] < minHeap->size; } @@ -258,18 +259,19 @@ typedef struct { int *prev; } dijkstraOutputObj; -static dijkstraOutputObj *dijkstra(graphObj *graph, int src) -{ +static dijkstraOutputObj *dijkstra(graphObj *graph, int src) { int n = graph->numnodes; - minHeapObj *minHeap = createMinHeap(n); // priority queue implemented as a min heap structure - if(!minHeap) return nullptr; + minHeapObj *minHeap = + createMinHeap(n); // priority queue implemented as a min heap structure + if (!minHeap) + return nullptr; dijkstraOutputObj *output = nullptr; - output = (dijkstraOutputObj *) malloc(sizeof(dijkstraOutputObj)); - output->dist = (double *) malloc(n * sizeof(double)); - output->prev = (int *) malloc(n * sizeof(int)); - if(!output->dist || !output->prev) { + output = (dijkstraOutputObj *)malloc(sizeof(dijkstraOutputObj)); + output->dist = (double *)malloc(n * sizeof(double)); + output->prev = (int *)malloc(n * sizeof(int)); + if (!output->dist || !output->prev) { msFree(output->dist); msFree(output->prev); free(output); @@ -278,21 +280,22 @@ static dijkstraOutputObj *dijkstra(graphObj *graph, int src) } // initialize - for (int i=0; idist[i] = HUGE_VAL; output->prev[i] = -1; - minHeap->nodes[i] = newMinHeapNode(i, output->dist[i]); // allocate a min heap node for each graph node + minHeap->nodes[i] = newMinHeapNode( + i, output->dist[i]); // allocate a min heap node for each graph node minHeap->pos[i] = i; } - + // make dist value of src vertex as 0 so that it is extracted first minHeap->pos[src] = src; output->dist[src] = 0; decreaseKey(minHeap, src, output->dist[src]); - + // initially size of min heap is equal to graph->numnodes (n) minHeap->size = n; - + // In the following loop, minHeap contains all nodes // whose shortest distance is not yet finalized. while (!isEmpty(minHeap)) { @@ -306,10 +309,11 @@ static dijkstraOutputObj *dijkstra(graphObj *graph, int src) graphNodeObj *node = graph->head[u]; while (node != nullptr) { int v = node->dest; - + // if shortest distance to v is not finalized yet, and distance to v // through u is less than its previously calculated distance - if (isInMinHeap(minHeap, v) && output->dist[u] != HUGE_VAL && node->weight + output->dist[u] < output->dist[v]) { + if (isInMinHeap(minHeap, v) && output->dist[u] != HUGE_VAL && + node->weight + output->dist[u] < output->dist[v]) { output->dist[v] = output->dist[u] + node->weight; output->prev[v] = u; decreaseKey(minHeap, v, output->dist[v]); @@ -317,21 +321,25 @@ static dijkstraOutputObj *dijkstra(graphObj *graph, int src) node = node->next; } } - + freeMinHeap(minHeap); return output; } -int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, double *path_dist) -{ - if(!graph || src < 0 || src > graph->numnodes) return nullptr; +int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, + double *path_dist) { + if (!graph || src < 0 || src > graph->numnodes) + return nullptr; - int* path = (int *) malloc((graph->numnodes)*sizeof(int)); // worst case is path traverses all nodes - if(!path) return nullptr; + int *path = + (int *)malloc((graph->numnodes) * + sizeof(int)); // worst case is path traverses all nodes + if (!path) + return nullptr; dijkstraOutputObj *output = dijkstra(graph, src); - if(!output) { + if (!output) { free(path); return nullptr; // algorithm failed for some reason } @@ -339,14 +347,14 @@ int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, dou // get longest shortest distance from src to another node (our dest) *path_dist = -1; int dest = -1; - for(int i=0; inumnodes; i++) { - if(output->dist[i] != HUGE_VAL && *path_dist < output->dist[i]) { + for (int i = 0; i < graph->numnodes; i++) { + if (output->dist[i] != HUGE_VAL && *path_dist < output->dist[i]) { *path_dist = output->dist[i]; dest = i; } } - if(dest == -1) { // unable to determine destination node + if (dest == -1) { // unable to determine destination node free(path); free(output->dist); free(output->prev); @@ -356,7 +364,8 @@ int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, dou // construct the path from src to dest int j = 0; - for(int i=dest; i!=-1; i=output->prev[i],j++) path[j] = i; + for (int i = dest; i != -1; i = output->prev[i], j++) + path[j] = i; std::reverse(path, path + j); *path_size = j; diff --git a/mapgraph.h b/mapgraph.h index e05401d3c4..d6730867ed 100644 --- a/mapgraph.h +++ b/mapgraph.h @@ -30,7 +30,7 @@ #ifndef MAPGRAPH_H #define MAPGRAPH_H -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -50,9 +50,10 @@ void msFreeGraph(graphObj *graph); int msGraphAddEdge(graphObj *graph, int src, int dest, double weight); void msPrintGraph(graphObj *graph); -int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, double *path_dist); +int *msGraphGetLongestShortestPath(graphObj *graph, int src, int *path_size, + double *path_dist); -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/mapgraticule.c b/mapgraticule.c index d5586f1998..80b8c562e1 100644 --- a/mapgraticule.c +++ b/mapgraticule.c @@ -30,17 +30,10 @@ #include #include "mapproject.h" - - /********************************************************************************************************************** * */ -typedef enum { - posBottom = 1, - posTop, - posLeft, - posRight -} msGraticulePosition; +typedef enum { posBottom = 1, posTop, posLeft, posRight } msGraticulePosition; typedef enum { lpDefault = 0, @@ -49,27 +42,28 @@ typedef enum { lpDD } msLabelProcessingType; -void DefineAxis( int iTickCountTarget, double *Min, double *Max, double *Inc ); -static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticulePosition ePosition ); -static void _FormatLabel( layerObj *pLayer, shapeObj *pShape, double dDataToFormat ); +void DefineAxis(int iTickCountTarget, double *Min, double *Max, double *Inc); +static int _AdjustLabelPosition(layerObj *pLayer, shapeObj *pShape, + msGraticulePosition ePosition); +static void _FormatLabel(layerObj *pLayer, shapeObj *pShape, + double dDataToFormat); int msGraticuleLayerInitItemInfo(layerObj *layer); -#define MAPGRATICULE_ARC_SUBDIVISION_DEFAULT (256) -#define MAPGRATICULE_ARC_MINIMUM (16) -#define MAPGRATICULE_FORMAT_STRING_DEFAULT "%5.2g" -#define MAPGRATICULE_FORMAT_STRING_DDMMSS "%3d %02d %02d" -#define MAPGRATICULE_FORMAT_STRING_DDMM "%3d %02d" -#define MAPGRATICULE_FORMAT_STRING_DD "%3d" +#define MAPGRATICULE_ARC_SUBDIVISION_DEFAULT (256) +#define MAPGRATICULE_ARC_MINIMUM (16) +#define MAPGRATICULE_FORMAT_STRING_DEFAULT "%5.2g" +#define MAPGRATICULE_FORMAT_STRING_DDMMSS "%3d %02d %02d" +#define MAPGRATICULE_FORMAT_STRING_DDMM "%3d %02d" +#define MAPGRATICULE_FORMAT_STRING_DD "%3d" /********************************************************************************************************************** * */ -int msGraticuleLayerOpen(layerObj *layer) -{ +int msGraticuleLayerOpen(layerObj *layer) { graticuleObj *pInfo = layer->grid; - if( pInfo == NULL ) + if (pInfo == NULL) return MS_FAILURE; pInfo->dincrementlatitude = 15.0; @@ -78,33 +72,37 @@ int msGraticuleLayerOpen(layerObj *layer) pInfo->dwhichlongitude = -180.0; pInfo->bvertical = 1; - if( layer->numclasses == 0 ) - msDebug( "GRID layer has no classes, nothing will be rendered.\n" ); + if (layer->numclasses == 0) + msDebug("GRID layer has no classes, nothing will be rendered.\n"); - if( layer->numclasses > 0 && layer->class[0]->numlabels > 0 ) + if (layer->numclasses > 0 && layer->class[0] -> numlabels > 0) pInfo->blabelaxes = 1; else pInfo->blabelaxes = 0; - if( pInfo->labelformat == NULL ) { - pInfo->labelformat = (char *) msSmallMalloc( strlen( MAPGRATICULE_FORMAT_STRING_DEFAULT ) + 1 ); - pInfo->ilabeltype = (int) lpDefault; - strcpy( pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DEFAULT ); - } else if( strcmp( pInfo->labelformat, "DDMMSS" ) == 0 ) { + if (pInfo->labelformat == NULL) { + pInfo->labelformat = + (char *)msSmallMalloc(strlen(MAPGRATICULE_FORMAT_STRING_DEFAULT) + 1); + pInfo->ilabeltype = (int)lpDefault; + strcpy(pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DEFAULT); + } else if (strcmp(pInfo->labelformat, "DDMMSS") == 0) { msFree(pInfo->labelformat); - pInfo->labelformat = (char *) msSmallMalloc( strlen( MAPGRATICULE_FORMAT_STRING_DDMMSS ) + 1 ); - pInfo->ilabeltype = (int) lpDDMMSS; - strcpy( pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DDMMSS ); - } else if( strcmp( pInfo->labelformat, "DDMM" ) == 0 ) { + pInfo->labelformat = + (char *)msSmallMalloc(strlen(MAPGRATICULE_FORMAT_STRING_DDMMSS) + 1); + pInfo->ilabeltype = (int)lpDDMMSS; + strcpy(pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DDMMSS); + } else if (strcmp(pInfo->labelformat, "DDMM") == 0) { msFree(pInfo->labelformat); - pInfo->labelformat = (char *) msSmallMalloc( strlen( MAPGRATICULE_FORMAT_STRING_DDMM ) + 1 ); - pInfo->ilabeltype = (int) lpDDMM; - strcpy( pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DDMM ); - } else if( strcmp( pInfo->labelformat, "DD" ) == 0 ) { + pInfo->labelformat = + (char *)msSmallMalloc(strlen(MAPGRATICULE_FORMAT_STRING_DDMM) + 1); + pInfo->ilabeltype = (int)lpDDMM; + strcpy(pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DDMM); + } else if (strcmp(pInfo->labelformat, "DD") == 0) { msFree(pInfo->labelformat); - pInfo->labelformat = (char *) msSmallMalloc( strlen( MAPGRATICULE_FORMAT_STRING_DD ) + 1 ); - pInfo->ilabeltype = (int) lpDD; - strcpy( pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DD ); + pInfo->labelformat = + (char *)msSmallMalloc(strlen(MAPGRATICULE_FORMAT_STRING_DD) + 1); + pInfo->ilabeltype = (int)lpDD; + strcpy(pInfo->labelformat, MAPGRATICULE_FORMAT_STRING_DD); } return MS_SUCCESS; @@ -113,20 +111,17 @@ int msGraticuleLayerOpen(layerObj *layer) /********************************************************************************************************************** * Return MS_TRUE if layer is open, MS_FALSE otherwise. */ -int msGraticuleLayerIsOpen(layerObj *layer) -{ - if(layer->grid) +int msGraticuleLayerIsOpen(layerObj *layer) { + if (layer->grid) return MS_TRUE; return MS_FALSE; } - /********************************************************************************************************************** * */ -int msGraticuleLayerClose(layerObj *layer) -{ +int msGraticuleLayerClose(layerObj *layer) { (void)layer; return MS_SUCCESS; } @@ -134,14 +129,13 @@ int msGraticuleLayerClose(layerObj *layer) /********************************************************************************************************************** * */ -int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)isQuery; graticuleObj *pInfo = layer->grid; int iAxisTickCount = 0; rectObj rectMapCoordinates; - if(msCheckParentPointer(layer->map,"map") == MS_FAILURE) + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; pInfo->dstartlatitude = rect.miny; @@ -149,12 +143,12 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) pInfo->dendlatitude = rect.maxy; pInfo->dendlongitude = rect.maxx; pInfo->bvertical = 1; - pInfo->extent = rect; + pInfo->extent = rect; - if( pInfo->minincrement > 0.0 ) { + if (pInfo->minincrement > 0.0) { pInfo->dincrementlongitude = pInfo->minincrement; pInfo->dincrementlatitude = pInfo->minincrement; - } else if( pInfo->maxincrement > 0.0 ) { + } else if (pInfo->maxincrement > 0.0) { pInfo->dincrementlongitude = pInfo->maxincrement; pInfo->dincrementlatitude = pInfo->maxincrement; } else { @@ -162,64 +156,68 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) pInfo->dincrementlatitude = 0; } - if( pInfo->maxarcs > 0 ) - iAxisTickCount = (int) pInfo->maxarcs; - else if( pInfo->minarcs > 0 ) - iAxisTickCount = (int) pInfo->minarcs; + if (pInfo->maxarcs > 0) + iAxisTickCount = (int)pInfo->maxarcs; + else if (pInfo->minarcs > 0) + iAxisTickCount = (int)pInfo->minarcs; - DefineAxis( iAxisTickCount, &pInfo->dstartlongitude, &pInfo->dendlongitude, &pInfo->dincrementlongitude); - DefineAxis( iAxisTickCount, &pInfo->dstartlatitude, &pInfo->dendlatitude, &pInfo->dincrementlatitude); + DefineAxis(iAxisTickCount, &pInfo->dstartlongitude, &pInfo->dendlongitude, + &pInfo->dincrementlongitude); + DefineAxis(iAxisTickCount, &pInfo->dstartlatitude, &pInfo->dendlatitude, + &pInfo->dincrementlatitude); - pInfo->dwhichlatitude = pInfo->dstartlatitude; + pInfo->dwhichlatitude = pInfo->dstartlatitude; pInfo->dwhichlongitude = pInfo->dstartlongitude; - if( pInfo->minincrement > 0.0 && pInfo->maxincrement > 0.0 && pInfo->minincrement == pInfo->maxincrement ) { + if (pInfo->minincrement > 0.0 && pInfo->maxincrement > 0.0 && + pInfo->minincrement == pInfo->maxincrement) { pInfo->dincrementlongitude = pInfo->minincrement; pInfo->dincrementlatitude = pInfo->minincrement; - } else if( pInfo->minincrement > 0.0 ) { + } else if (pInfo->minincrement > 0.0) { pInfo->dincrementlongitude = pInfo->minincrement; pInfo->dincrementlatitude = pInfo->minincrement; - } else if( pInfo->maxincrement > 0.0 ) { + } else if (pInfo->maxincrement > 0.0) { pInfo->dincrementlongitude = pInfo->maxincrement; pInfo->dincrementlatitude = pInfo->maxincrement; } /* - * If using PROJ, project rect back into map system, and generate rect corner points in native system. - * These lines will be used when generating labels to get correct placement at arc/rect edge intersections. + * If using PROJ, project rect back into map system, and generate rect corner + * points in native system. These lines will be used when generating labels to + * get correct placement at arc/rect edge intersections. */ rectMapCoordinates = layer->map->extent; - layer->project = msProjectionsDiffer(&(layer->projection), &(layer->map->projection)); - if( layer->project && - strstr(layer->map->projection.args[0], "epsg:3857") && - msProjIsGeographicCRS(&(layer->projection)) ) - { - if( rectMapCoordinates.minx < -20037508) - rectMapCoordinates.minx = -20037508; - if( rectMapCoordinates.maxx > 20037508 ) - rectMapCoordinates.maxx = 20037508; + layer->project = + msProjectionsDiffer(&(layer->projection), &(layer->map->projection)); + if (layer->project && strstr(layer->map->projection.args[0], "epsg:3857") && + msProjIsGeographicCRS(&(layer->projection))) { + if (rectMapCoordinates.minx < -20037508) + rectMapCoordinates.minx = -20037508; + if (rectMapCoordinates.maxx > 20037508) + rectMapCoordinates.maxx = 20037508; } msFree(pInfo->pboundinglines); - pInfo->pboundinglines = (lineObj *) msSmallMalloc( sizeof( lineObj ) * 4 ); + pInfo->pboundinglines = (lineObj *)msSmallMalloc(sizeof(lineObj) * 4); msFree(pInfo->pboundingpoints); - pInfo->pboundingpoints = (pointObj *) msSmallMalloc( sizeof( pointObj ) * 8 ); + pInfo->pboundingpoints = (pointObj *)msSmallMalloc(sizeof(pointObj) * 8); { /* * top */ - pInfo->pboundinglines[0].numpoints = 2; + pInfo->pboundinglines[0].numpoints = 2; pInfo->pboundinglines[0].point = &pInfo->pboundingpoints[0]; pInfo->pboundinglines[0].point[0].x = rectMapCoordinates.minx; pInfo->pboundinglines[0].point[0].y = rectMapCoordinates.maxy; pInfo->pboundinglines[0].point[1].x = rectMapCoordinates.maxx; pInfo->pboundinglines[0].point[1].y = rectMapCoordinates.maxy; - if(layer->project) - msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[0]); + if (layer->project) + msProjectLine(&layer->map->projection, &layer->projection, + &pInfo->pboundinglines[0]); /* * bottom @@ -227,38 +225,41 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) pInfo->pboundinglines[1].numpoints = 2; pInfo->pboundinglines[1].point = &pInfo->pboundingpoints[2]; pInfo->pboundinglines[1].point[0].x = rectMapCoordinates.minx; - pInfo->pboundinglines[1].point[0].y = rectMapCoordinates.miny; - pInfo->pboundinglines[1].point[1].x = rectMapCoordinates.maxx; + pInfo->pboundinglines[1].point[0].y = rectMapCoordinates.miny; + pInfo->pboundinglines[1].point[1].x = rectMapCoordinates.maxx; pInfo->pboundinglines[1].point[1].y = rectMapCoordinates.miny; - if(layer->project) - msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[1]); + if (layer->project) + msProjectLine(&layer->map->projection, &layer->projection, + &pInfo->pboundinglines[1]); /* * left */ pInfo->pboundinglines[2].numpoints = 2; pInfo->pboundinglines[2].point = &pInfo->pboundingpoints[4]; - pInfo->pboundinglines[2].point[0].x = rectMapCoordinates.minx; - pInfo->pboundinglines[2].point[0].y = rectMapCoordinates.miny; - pInfo->pboundinglines[2].point[1].x = rectMapCoordinates.minx; - pInfo->pboundinglines[2].point[1].y = rectMapCoordinates.maxy; + pInfo->pboundinglines[2].point[0].x = rectMapCoordinates.minx; + pInfo->pboundinglines[2].point[0].y = rectMapCoordinates.miny; + pInfo->pboundinglines[2].point[1].x = rectMapCoordinates.minx; + pInfo->pboundinglines[2].point[1].y = rectMapCoordinates.maxy; - if(layer->project) - msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[2]); + if (layer->project) + msProjectLine(&layer->map->projection, &layer->projection, + &pInfo->pboundinglines[2]); /* * right */ pInfo->pboundinglines[3].numpoints = 2; pInfo->pboundinglines[3].point = &pInfo->pboundingpoints[6]; - pInfo->pboundinglines[3].point[0].x = rectMapCoordinates.maxx; - pInfo->pboundinglines[3].point[0].y = rectMapCoordinates.miny; + pInfo->pboundinglines[3].point[0].x = rectMapCoordinates.maxx; + pInfo->pboundinglines[3].point[0].y = rectMapCoordinates.miny; pInfo->pboundinglines[3].point[1].x = rectMapCoordinates.maxx; pInfo->pboundinglines[3].point[1].y = rectMapCoordinates.maxy; - if(layer->project) - msProjectLine(&layer->map->projection, &layer->projection, &pInfo->pboundinglines[3]); + if (layer->project) + msProjectLine(&layer->map->projection, &layer->projection, + &pInfo->pboundinglines[3]); } return MS_SUCCESS; @@ -267,219 +268,242 @@ int msGraticuleLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) /********************************************************************************************************************** * */ -int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape) -{ +int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape) { graticuleObj *pInfo = layer->grid; - if( pInfo->minsubdivides <= 0.0 || pInfo->maxsubdivides <= 0.0 ) - pInfo->minsubdivides = pInfo->maxsubdivides = MAPGRATICULE_ARC_SUBDIVISION_DEFAULT; + if (pInfo->minsubdivides <= 0.0 || pInfo->maxsubdivides <= 0.0) + pInfo->minsubdivides = pInfo->maxsubdivides = + MAPGRATICULE_ARC_SUBDIVISION_DEFAULT; shape->numlines = 1; shape->type = MS_SHAPE_LINE; - shape->line = (lineObj *) msSmallMalloc(sizeof( lineObj )); - shape->line->numpoints = (int) pInfo->maxsubdivides; + shape->line = (lineObj *)msSmallMalloc(sizeof(lineObj)); + shape->line->numpoints = (int)pInfo->maxsubdivides; shape->line->point = NULL; /* * Subdivide and draw current arc, rendering the arc labels first */ - if( pInfo->bvertical ) { + if (pInfo->bvertical) { int iPointIndex; - double dArcDelta = (pInfo->dendlatitude - pInfo->dstartlatitude) / (double) shape->line->numpoints; - double dArcPosition = pInfo->dstartlatitude + dArcDelta; + double dArcDelta = (pInfo->dendlatitude - pInfo->dstartlatitude) / + (double)shape->line->numpoints; + double dArcPosition = pInfo->dstartlatitude + dArcDelta; double dStartY, dDeltaX; - switch( pInfo->ilabelstate ) { - case 0: - if(!pInfo->blabelaxes) { /* Bottom */ - pInfo->ilabelstate++; - msFreeShape(shape); - return MS_SUCCESS; - } - - dDeltaX = (pInfo->dwhichlongitude - pInfo->pboundinglines[1].point[0].x) / (pInfo->pboundinglines[1].point[1].x - pInfo->pboundinglines[1].point[0].x); - if (dDeltaX < 0) - dDeltaX=dDeltaX*-1; - - dStartY = (pInfo->pboundinglines[1].point[1].y - pInfo->pboundinglines[1].point[0].y) * dDeltaX + pInfo->pboundinglines[1].point[0].y; - shape->line->numpoints = (int) 2; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * 2 ); - - shape->line->point[0].x = pInfo->dwhichlongitude; - shape->line->point[0].y = dStartY; - shape->line->point[1].x = pInfo->dwhichlongitude; - shape->line->point[1].y = dStartY + dArcDelta; - - _FormatLabel( layer, shape, shape->line->point[0].x ); - if(_AdjustLabelPosition( layer, shape, posBottom ) != MS_SUCCESS) - { - msFreeShape(shape); - pInfo->ilabelstate++; - return MS_SUCCESS; - } + switch (pInfo->ilabelstate) { + case 0: + if (!pInfo->blabelaxes) { /* Bottom */ + pInfo->ilabelstate++; + msFreeShape(shape); + return MS_SUCCESS; + } + dDeltaX = (pInfo->dwhichlongitude - pInfo->pboundinglines[1].point[0].x) / + (pInfo->pboundinglines[1].point[1].x - + pInfo->pboundinglines[1].point[0].x); + if (dDeltaX < 0) + dDeltaX = dDeltaX * -1; + + dStartY = (pInfo->pboundinglines[1].point[1].y - + pInfo->pboundinglines[1].point[0].y) * + dDeltaX + + pInfo->pboundinglines[1].point[0].y; + shape->line->numpoints = (int)2; + shape->line->point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 2); + + shape->line->point[0].x = pInfo->dwhichlongitude; + shape->line->point[0].y = dStartY; + shape->line->point[1].x = pInfo->dwhichlongitude; + shape->line->point[1].y = dStartY + dArcDelta; + + _FormatLabel(layer, shape, shape->line->point[0].x); + if (_AdjustLabelPosition(layer, shape, posBottom) != MS_SUCCESS) { + msFreeShape(shape); pInfo->ilabelstate++; return MS_SUCCESS; + } - case 1: - if(!pInfo->blabelaxes) { /* Top */ - pInfo->ilabelstate++; - msFreeShape(shape); - return MS_SUCCESS; - } + pInfo->ilabelstate++; + return MS_SUCCESS; - dDeltaX = (pInfo->dwhichlongitude - pInfo->pboundinglines[0].point[0].x) / (pInfo->pboundinglines[0].point[1].x - pInfo->pboundinglines[0].point[0].x ); - if (dDeltaX < 0) - dDeltaX=dDeltaX*-1; - - dStartY = (pInfo->pboundinglines[0].point[1].y - pInfo->pboundinglines[0].point[0].y) * dDeltaX + pInfo->pboundinglines[0].point[1].y; - shape->line->numpoints = (int) 2; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * 2 ); - - shape->line->point[0].x = pInfo->dwhichlongitude; - shape->line->point[0].y = dStartY - dArcDelta; - shape->line->point[1].x = pInfo->dwhichlongitude; - shape->line->point[1].y = dStartY; - - _FormatLabel( layer, shape, shape->line->point[0].x ); - if(_AdjustLabelPosition( layer, shape, posTop ) != MS_SUCCESS) - { - msFreeShape(shape); - pInfo->ilabelstate++; - return MS_SUCCESS; - } + case 1: + if (!pInfo->blabelaxes) { /* Top */ + pInfo->ilabelstate++; + msFreeShape(shape); + return MS_SUCCESS; + } + dDeltaX = (pInfo->dwhichlongitude - pInfo->pboundinglines[0].point[0].x) / + (pInfo->pboundinglines[0].point[1].x - + pInfo->pboundinglines[0].point[0].x); + if (dDeltaX < 0) + dDeltaX = dDeltaX * -1; + + dStartY = (pInfo->pboundinglines[0].point[1].y - + pInfo->pboundinglines[0].point[0].y) * + dDeltaX + + pInfo->pboundinglines[0].point[1].y; + shape->line->numpoints = (int)2; + shape->line->point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 2); + + shape->line->point[0].x = pInfo->dwhichlongitude; + shape->line->point[0].y = dStartY - dArcDelta; + shape->line->point[1].x = pInfo->dwhichlongitude; + shape->line->point[1].y = dStartY; + + _FormatLabel(layer, shape, shape->line->point[0].x); + if (_AdjustLabelPosition(layer, shape, posTop) != MS_SUCCESS) { + msFreeShape(shape); pInfo->ilabelstate++; return MS_SUCCESS; + } - case 2: - shape->line->numpoints = (int) shape->line->numpoints + 1; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * shape->line->numpoints ); + pInfo->ilabelstate++; + return MS_SUCCESS; - shape->line->point[0].x = pInfo->dwhichlongitude; - shape->line->point[0].y = pInfo->dstartlatitude; + case 2: + shape->line->numpoints = (int)shape->line->numpoints + 1; + shape->line->point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * shape->line->numpoints); - for( iPointIndex = 1; iPointIndex < shape->line->numpoints; iPointIndex++ ) { - shape->line->point[iPointIndex].x = pInfo->dwhichlongitude; - shape->line->point[iPointIndex].y = dArcPosition; + shape->line->point[0].x = pInfo->dwhichlongitude; + shape->line->point[0].y = pInfo->dstartlatitude; - dArcPosition += dArcDelta; - } + for (iPointIndex = 1; iPointIndex < shape->line->numpoints; + iPointIndex++) { + shape->line->point[iPointIndex].x = pInfo->dwhichlongitude; + shape->line->point[iPointIndex].y = dArcPosition; - pInfo->ilabelstate = 0; + dArcPosition += dArcDelta; + } - pInfo->dwhichlongitude += pInfo->dincrementlongitude; - break; + pInfo->ilabelstate = 0; - default: - pInfo->ilabelstate = 0; - break; + pInfo->dwhichlongitude += pInfo->dincrementlongitude; + break; + + default: + pInfo->ilabelstate = 0; + break; } } else { /*horizontal*/ int iPointIndex; - double dArcDelta = (pInfo->dendlongitude - pInfo->dstartlongitude) / (double) shape->line->numpoints; - double dArcPosition = pInfo->dstartlongitude + dArcDelta; + double dArcDelta = (pInfo->dendlongitude - pInfo->dstartlongitude) / + (double)shape->line->numpoints; + double dArcPosition = pInfo->dstartlongitude + dArcDelta; double dStartX, dDeltaY; - switch( pInfo->ilabelstate ) { - case 0: - if(!pInfo->blabelaxes) { /* Left side */ - pInfo->ilabelstate++; - msFreeShape(shape); - return MS_SUCCESS; - } - - dDeltaY = (pInfo->dwhichlatitude - pInfo->pboundinglines[2].point[0].y) / (pInfo->pboundinglines[2].point[1].y - pInfo->pboundinglines[2].point[0].y ); - if (dDeltaY < 0) - dDeltaY= dDeltaY*-1; - - dStartX = (pInfo->pboundinglines[2].point[1].x - pInfo->pboundinglines[2].point[0].x) * dDeltaY + pInfo->pboundinglines[2].point[0].x; - shape->line->numpoints = (int) 2; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * 2 ); - - shape->line->point[0].x = dStartX; - shape->line->point[0].y = pInfo->dwhichlatitude; - shape->line->point[1].x = dStartX + dArcDelta; - shape->line->point[1].y = pInfo->dwhichlatitude; - - _FormatLabel( layer, shape, shape->line->point[0].y ); - if(_AdjustLabelPosition( layer, shape, posLeft ) != MS_SUCCESS) - { - msFreeShape(shape); - pInfo->ilabelstate++; - return MS_SUCCESS; - } + switch (pInfo->ilabelstate) { + case 0: + if (!pInfo->blabelaxes) { /* Left side */ + pInfo->ilabelstate++; + msFreeShape(shape); + return MS_SUCCESS; + } + dDeltaY = (pInfo->dwhichlatitude - pInfo->pboundinglines[2].point[0].y) / + (pInfo->pboundinglines[2].point[1].y - + pInfo->pboundinglines[2].point[0].y); + if (dDeltaY < 0) + dDeltaY = dDeltaY * -1; + + dStartX = (pInfo->pboundinglines[2].point[1].x - + pInfo->pboundinglines[2].point[0].x) * + dDeltaY + + pInfo->pboundinglines[2].point[0].x; + shape->line->numpoints = (int)2; + shape->line->point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 2); + + shape->line->point[0].x = dStartX; + shape->line->point[0].y = pInfo->dwhichlatitude; + shape->line->point[1].x = dStartX + dArcDelta; + shape->line->point[1].y = pInfo->dwhichlatitude; + + _FormatLabel(layer, shape, shape->line->point[0].y); + if (_AdjustLabelPosition(layer, shape, posLeft) != MS_SUCCESS) { + msFreeShape(shape); pInfo->ilabelstate++; return MS_SUCCESS; + } - case 1: - if(!pInfo->blabelaxes) { /* Right side */ - pInfo->ilabelstate++; - msFreeShape(shape); - return MS_SUCCESS; - } + pInfo->ilabelstate++; + return MS_SUCCESS; - dDeltaY = (pInfo->dwhichlatitude - pInfo->pboundinglines[3].point[0].y) / (pInfo->pboundinglines[3].point[1].y - pInfo->pboundinglines[3].point[0].y ); - if (dDeltaY < 0) - dDeltaY= dDeltaY*-1; - - dStartX = (pInfo->pboundinglines[3].point[1].x - pInfo->pboundinglines[3].point[0].x) * dDeltaY + pInfo->pboundinglines[3].point[0].x; - shape->line->numpoints = (int) 2; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * 2 ); - - shape->line->point[0].x = dStartX - dArcDelta; - shape->line->point[0].y = pInfo->dwhichlatitude; - shape->line->point[1].x = dStartX; - shape->line->point[1].y = pInfo->dwhichlatitude; - - _FormatLabel( layer, shape, shape->line->point[0].y ); - if(_AdjustLabelPosition( layer, shape, posRight ) != MS_SUCCESS) - { - msFreeShape(shape); - pInfo->ilabelstate++; - return MS_SUCCESS; - } + case 1: + if (!pInfo->blabelaxes) { /* Right side */ + pInfo->ilabelstate++; + msFreeShape(shape); + return MS_SUCCESS; + } + dDeltaY = (pInfo->dwhichlatitude - pInfo->pboundinglines[3].point[0].y) / + (pInfo->pboundinglines[3].point[1].y - + pInfo->pboundinglines[3].point[0].y); + if (dDeltaY < 0) + dDeltaY = dDeltaY * -1; + + dStartX = (pInfo->pboundinglines[3].point[1].x - + pInfo->pboundinglines[3].point[0].x) * + dDeltaY + + pInfo->pboundinglines[3].point[0].x; + shape->line->numpoints = (int)2; + shape->line->point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 2); + + shape->line->point[0].x = dStartX - dArcDelta; + shape->line->point[0].y = pInfo->dwhichlatitude; + shape->line->point[1].x = dStartX; + shape->line->point[1].y = pInfo->dwhichlatitude; + + _FormatLabel(layer, shape, shape->line->point[0].y); + if (_AdjustLabelPosition(layer, shape, posRight) != MS_SUCCESS) { + msFreeShape(shape); pInfo->ilabelstate++; return MS_SUCCESS; + } - case 2: - shape->line->numpoints = (int) shape->line->numpoints + 1; - shape->line->point = (pointObj *) msSmallMalloc( sizeof( pointObj ) * shape->line->numpoints ); + pInfo->ilabelstate++; + return MS_SUCCESS; - shape->line->point[0].x = pInfo->dstartlongitude; - shape->line->point[0].y = pInfo->dwhichlatitude; + case 2: + shape->line->numpoints = (int)shape->line->numpoints + 1; + shape->line->point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * shape->line->numpoints); - for(iPointIndex = 1; iPointIndex < shape->line->numpoints; iPointIndex++) { - shape->line->point[iPointIndex].x = dArcPosition; - shape->line->point[iPointIndex].y = pInfo->dwhichlatitude; + shape->line->point[0].x = pInfo->dstartlongitude; + shape->line->point[0].y = pInfo->dwhichlatitude; - dArcPosition += dArcDelta; - } + for (iPointIndex = 1; iPointIndex < shape->line->numpoints; + iPointIndex++) { + shape->line->point[iPointIndex].x = dArcPosition; + shape->line->point[iPointIndex].y = pInfo->dwhichlatitude; - pInfo->ilabelstate = 0; - pInfo->dwhichlatitude += pInfo->dincrementlatitude; - break; + dArcPosition += dArcDelta; + } + + pInfo->ilabelstate = 0; + pInfo->dwhichlatitude += pInfo->dincrementlatitude; + break; - default: - pInfo->ilabelstate = 0; - break; + default: + pInfo->ilabelstate = 0; + break; } } /* - * Increment and move to next arc - */ + * Increment and move to next arc + */ - if( pInfo->bvertical && pInfo->dwhichlongitude > pInfo->dendlongitude ) { - pInfo->dwhichlatitude = pInfo->dstartlatitude; - pInfo->bvertical = 0; + if (pInfo->bvertical && pInfo->dwhichlongitude > pInfo->dendlongitude) { + pInfo->dwhichlatitude = pInfo->dstartlatitude; + pInfo->bvertical = 0; } - if (pInfo->dwhichlatitude > pInfo->dendlatitude) { - /* free the lineObj and pointObj that have been erroneously allocated beforehand */ + if (pInfo->dwhichlatitude > pInfo->dendlatitude) { + /* free the lineObj and pointObj that have been erroneously allocated + * beforehand */ msFreeShape(shape); return MS_DONE; } @@ -490,15 +514,14 @@ int msGraticuleLayerNextShape(layerObj *layer, shapeObj *shape) /********************************************************************************************************************** * */ -int msGraticuleLayerGetItems(layerObj *layer) -{ - char **ppItemName = (char **) msSmallMalloc( sizeof( char * ) ); +int msGraticuleLayerGetItems(layerObj *layer) { + char **ppItemName = (char **)msSmallMalloc(sizeof(char *)); - *ppItemName = (char *) msSmallMalloc( 64 ); /* why is this necessary? */ - strcpy( *ppItemName, "Graticule" ); + *ppItemName = (char *)msSmallMalloc(64); /* why is this necessary? */ + strcpy(*ppItemName, "Graticule"); - layer->numitems = 1; - layer->items = ppItemName; + layer->numitems = 1; + layer->items = ppItemName; return MS_SUCCESS; } @@ -506,8 +529,7 @@ int msGraticuleLayerGetItems(layerObj *layer) /********************************************************************************************************************** * */ -int msGraticuleLayerInitItemInfo(layerObj *layer) -{ +int msGraticuleLayerInitItemInfo(layerObj *layer) { (void)layer; return MS_SUCCESS; } @@ -515,16 +537,13 @@ int msGraticuleLayerInitItemInfo(layerObj *layer) /********************************************************************************************************************** * */ -void msGraticuleLayerFreeItemInfo(layerObj *layer) -{ - (void)layer; -} +void msGraticuleLayerFreeItemInfo(layerObj *layer) { (void)layer; } /********************************************************************************************************************** * */ -int msGraticuleLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ +int msGraticuleLayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { (void)layer; (void)shape; (void)record; @@ -534,11 +553,10 @@ int msGraticuleLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record /********************************************************************************************************************** * */ -int msGraticuleLayerGetExtent(layerObj *layer, rectObj *extent) -{ +int msGraticuleLayerGetExtent(layerObj *layer, rectObj *extent) { graticuleObj *pInfo = layer->grid; - if(pInfo) { + if (pInfo) { *extent = pInfo->extent; return MS_SUCCESS; } @@ -549,8 +567,8 @@ int msGraticuleLayerGetExtent(layerObj *layer, rectObj *extent) /********************************************************************************************************************** * */ -int msGraticuleLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* shape) -{ +int msGraticuleLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, + shapeObj *shape) { (void)map; (void)layer; (void)c; @@ -558,32 +576,29 @@ int msGraticuleLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shap return MS_SUCCESS; } - /************************************************************************/ /* msGraticuleLayerFreeIntersectionPoints */ /* */ /* Free intersection object. */ /************************************************************************/ -void msGraticuleLayerFreeIntersectionPoints( graticuleIntersectionObj *psValue) -{ +void msGraticuleLayerFreeIntersectionPoints(graticuleIntersectionObj *psValue) { if (psValue) { - for (int i=0; inTop; i++) + for (int i = 0; i < psValue->nTop; i++) msFree(psValue->papszTopLabels[i]); msFree(psValue->papszTopLabels); msFree(psValue->pasTop); - for (int i=0; inBottom; i++) + for (int i = 0; i < psValue->nBottom; i++) msFree(psValue->papszBottomLabels[i]); msFree(psValue->papszBottomLabels); msFree(psValue->pasBottom); - - for (int i=0; inLeft; i++) + for (int i = 0; i < psValue->nLeft; i++) msFree(psValue->papszLeftLabels[i]); msFree(psValue->papszLeftLabels); msFree(psValue->pasLeft); - for (int i=0; inRight; i++) + for (int i = 0; i < psValue->nRight; i++) msFree(psValue->papszRightLabels[i]); msFree(psValue->papszRightLabels); msFree(psValue->pasRight); @@ -592,14 +607,13 @@ void msGraticuleLayerFreeIntersectionPoints( graticuleIntersectionObj *psValue) } } - /************************************************************************/ /* msGraticuleLayerInitIntersectionPoints */ /* */ /* init intersection object. */ /************************************************************************/ -static void msGraticuleLayerInitIntersectionPoints( graticuleIntersectionObj *psValue) -{ +static void +msGraticuleLayerInitIntersectionPoints(graticuleIntersectionObj *psValue) { if (psValue) { psValue->nTop = 0; psValue->pasTop = NULL; @@ -616,81 +630,82 @@ static void msGraticuleLayerInitIntersectionPoints( graticuleIntersectionObj *ps } } - /************************************************************************/ /* msGraticuleLayerGetIntersectionPoints */ /* */ /* Utility function thar returns all intersection positions and */ /* labels (4 sides of the map) for a grid layer. */ /************************************************************************/ -graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, - layerObj *layer) -{ +graticuleIntersectionObj * +msGraticuleLayerGetIntersectionPoints(mapObj *map, layerObj *layer) { - shapeObj shapegrid, tmpshape; - rectObj searchrect; - int status; + shapeObj shapegrid, tmpshape; + rectObj searchrect; + int status; pointObj oFirstPoint; pointObj oLastPoint; lineObj oLineObj; rectObj cliprect; - graticuleObj *pInfo = NULL; + graticuleObj *pInfo = NULL; double dfTmp; graticuleIntersectionObj *psValues = NULL; - int i=0; + int i = 0; if (layer->connectiontype != MS_GRATICULE) return NULL; - pInfo = layer->grid; + pInfo = layer->grid; /*set cellsize if bnot already set*/ if (map->cellsize == 0) - map->cellsize = msAdjustExtent(&(map->extent),map->width,map->height); + map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - psValues = (graticuleIntersectionObj *)msSmallMalloc(sizeof(graticuleIntersectionObj)); + psValues = (graticuleIntersectionObj *)msSmallMalloc( + sizeof(graticuleIntersectionObj)); msGraticuleLayerInitIntersectionPoints(psValues); - if(layer->transform == MS_TRUE) + if (layer->transform == MS_TRUE) searchrect = map->extent; else { searchrect.minx = searchrect.miny = 0; - searchrect.maxx = map->width-1; - searchrect.maxy = map->height-1; + searchrect.maxx = map->width - 1; + searchrect.maxy = map->height - 1; } - if((map->projection.numargs > 0) && (layer->projection.numargs > 0)) - msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */ + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0)) + msProjectRect(&map->projection, &layer->projection, + &searchrect); /* project the searchrect to source coords */ - status = msLayerOpen(layer); - if(status != MS_SUCCESS) - return NULL; + status = msLayerOpen(layer); + if (status != MS_SUCCESS) + return NULL; status = msLayerWhichShapes(layer, searchrect, MS_FALSE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(layer); return NULL; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(layer); return NULL; } /* step through the target shapes */ msInitShape(&shapegrid); - cliprect.minx = map->extent.minx- map->cellsize; - cliprect.miny = map->extent.miny- map->cellsize; + cliprect.minx = map->extent.minx - map->cellsize; + cliprect.miny = map->extent.miny - map->cellsize; cliprect.maxx = map->extent.maxx + map->cellsize; cliprect.maxy = map->extent.maxy + map->cellsize; /* clip using the layer projection */ /* msProjectRect(&map->projection , &layer->projection, &cliprect); */ - while((status = msLayerNextShape(layer, &shapegrid)) == MS_SUCCESS) { + while ((status = msLayerNextShape(layer, &shapegrid)) == MS_SUCCESS) { /*don't really need a class here*/ /* - shapegrid.classindex = msShapeGetClass(layer, &shapegrid, map->scaledenom, NULL, 0); - if((shapegrid.classindex == -1) || (layer->class[shapegrid.classindex]->status == MS_OFF)) { + shapegrid.classindex = msShapeGetClass(layer, &shapegrid, map->scaledenom, + NULL, 0); if((shapegrid.classindex == -1) || + (layer->class[shapegrid.classindex]->status == MS_OFF)) { msFreeShape(&shapegrid); continue; } @@ -700,31 +715,27 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, msCopyShape(&shapegrid, &tmpshape); /* status = msDrawShape(map, layer, &tmpshape, image, -1); */ - if(layer->project) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); + if (layer->project) { + if (layer->reprojectorLayerToMap == NULL) { + layer->reprojectorLayerToMap = + msProjectCreateReprojector(&layer->projection, &map->projection); } - if( layer->reprojectorLayerToMap ) + if (layer->reprojectorLayerToMap) msProjectShapeEx(layer->reprojectorLayerToMap, &shapegrid); } msClipPolylineRect(&shapegrid, cliprect); - msTransformShapeToPixelRound(&shapegrid, map->extent, map->cellsize); - - - if(shapegrid.numlines <= 0 || shapegrid.line[0].numpoints < 2) { /* once clipped the shape didn't need to be drawn */ + if (shapegrid.numlines <= 0 || + shapegrid.line[0].numpoints < + 2) { /* once clipped the shape didn't need to be drawn */ msFreeShape(&shapegrid); msFreeShape(&tmpshape); continue; } - - { int iTmpLine = 0; int nNumPoints = 0; @@ -733,7 +744,7 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, points, which should be the most likley to be correct*/ if (shapegrid.numlines > 1) { - for (i=0; i nNumPoints) { nNumPoints = shapegrid.line[i].numpoints; iTmpLine = i; @@ -744,14 +755,14 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, oFirstPoint.x = shapegrid.line[iTmpLine].point[0].x; oFirstPoint.y = shapegrid.line[iTmpLine].point[0].y; oLineObj = shapegrid.line[iTmpLine]; - oLastPoint.x = oLineObj.point[oLineObj.numpoints-1].x; - oLastPoint.y = oLineObj.point[oLineObj.numpoints-1].y; + oLastPoint.x = oLineObj.point[oLineObj.numpoints - 1].x; + oLastPoint.y = oLineObj.point[oLineObj.numpoints - 1].y; - if ( pInfo->bvertical) { /*vertical*/ + if (pInfo->bvertical) { /*vertical*/ /*SHAPES ARE DRAWN FROM BOTTOM TO TOP.*/ - /*Normally lines are drawn FROM BOTTOM TO TOP but not always for some reason, so - make sure that firstpoint < lastpoint in y, We are in pixel coordinates so y increases as we - we go down*/ + /*Normally lines are drawn FROM BOTTOM TO TOP but not always for some + reason, so make sure that firstpoint < lastpoint in y, We are in pixel + coordinates so y increases as we we go down*/ if (oFirstPoint.y < oLastPoint.y) { dfTmp = oFirstPoint.x; oFirstPoint.x = oLastPoint.x; @@ -759,13 +770,12 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, dfTmp = oFirstPoint.y; oFirstPoint.y = oLastPoint.y; oLastPoint.y = dfTmp; - } /*first point should cross the BOTTOM base where y== map->height*/ - if (abs ((int)oFirstPoint.y - map->height) <=1) { - char *pszLabel=NULL; + if (abs((int)oFirstPoint.y - map->height) <= 1) { + char *pszLabel = NULL; oFirstPoint.y = map->height; /*validate point is in map width/height*/ @@ -777,46 +787,51 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, continue; if (shapegrid.text) - pszLabel = msStrdup(shapegrid.text); + pszLabel = msStrdup(shapegrid.text); else { - _FormatLabel(layer, &tmpshape, tmpshape.line[0].point[tmpshape.line[0].numpoints-1].x ); + _FormatLabel( + layer, &tmpshape, + tmpshape.line[0].point[tmpshape.line[0].numpoints - 1].x); if (tmpshape.text) pszLabel = msStrdup(tmpshape.text); else pszLabel = msStrdup("unknown"); } /*validate that the value is not already in the array*/ - if ( psValues->nBottom > 0) { + if (psValues->nBottom > 0) { /* if (psValues->pasBottom[psValues->nBottom-1].x == oFirstPoint.x) continue; */ - for (i=0; inBottom; i++) { + for (i = 0; i < psValues->nBottom; i++) { if (psValues->pasBottom[i].x == oFirstPoint.x) break; } - if (i < psValues->nBottom) { + if (i < psValues->nBottom) { msFree(pszLabel); continue; } } if (psValues->pasBottom == NULL) { psValues->pasBottom = (pointObj *)msSmallMalloc(sizeof(pointObj)); - psValues->papszBottomLabels = (char **)msSmallMalloc(sizeof(char *)); + psValues->papszBottomLabels = + (char **)msSmallMalloc(sizeof(char *)); psValues->nBottom = 1; } else { psValues->nBottom++; - psValues->pasBottom = (pointObj *)msSmallRealloc(psValues->pasBottom, sizeof(pointObj)*psValues->nBottom); - psValues->papszBottomLabels = (char **)msSmallRealloc(psValues->papszBottomLabels, sizeof(char *)*psValues->nBottom); + psValues->pasBottom = (pointObj *)msSmallRealloc( + psValues->pasBottom, sizeof(pointObj) * psValues->nBottom); + psValues->papszBottomLabels = + (char **)msSmallRealloc(psValues->papszBottomLabels, + sizeof(char *) * psValues->nBottom); } - psValues->pasBottom[psValues->nBottom-1].x = oFirstPoint.x; - psValues->pasBottom[psValues->nBottom-1].y = oFirstPoint.y; - psValues->papszBottomLabels[psValues->nBottom-1] = pszLabel; - + psValues->pasBottom[psValues->nBottom - 1].x = oFirstPoint.x; + psValues->pasBottom[psValues->nBottom - 1].y = oFirstPoint.y; + psValues->papszBottomLabels[psValues->nBottom - 1] = pszLabel; } /*first point should cross the TOP base where y==0*/ - if (abs((int)oLastPoint.y) <=1) { - char *pszLabel=NULL; + if (abs((int)oLastPoint.y) <= 1) { + char *pszLabel = NULL; oLastPoint.y = 0; /*validate point is in map width/height*/ @@ -824,20 +839,22 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, continue; if (shapegrid.text) - pszLabel = msStrdup(shapegrid.text); + pszLabel = msStrdup(shapegrid.text); else { - _FormatLabel(layer, &tmpshape, tmpshape.line[0].point[tmpshape.line[0].numpoints-1].x ); + _FormatLabel( + layer, &tmpshape, + tmpshape.line[0].point[tmpshape.line[0].numpoints - 1].x); if (tmpshape.text) pszLabel = msStrdup(tmpshape.text); else pszLabel = msStrdup("unknown"); } /*validate if same value is not already there*/ - if ( psValues->nTop > 0) { + if (psValues->nTop > 0) { /* if (psValues->pasTop[psValues->nTop-1].x == oLastPoint.x) continue; */ - for (i=0; inTop; i++) { + for (i = 0; i < psValues->nTop; i++) { if (psValues->pasTop[i].x == oLastPoint.x || strcasecmp(pszLabel, psValues->papszTopLabels[i]) == 0) break; @@ -848,24 +865,25 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, } } - if (psValues->pasTop == NULL) { psValues->pasTop = (pointObj *)msSmallMalloc(sizeof(pointObj)); psValues->papszTopLabels = (char **)msSmallMalloc(sizeof(char *)); psValues->nTop = 1; } else { psValues->nTop++; - psValues->pasTop = (pointObj *)msSmallRealloc(psValues->pasTop, sizeof(pointObj)*psValues->nTop); - psValues->papszTopLabels = (char **)msSmallRealloc(psValues->papszTopLabels, sizeof(char *)*psValues->nTop); + psValues->pasTop = (pointObj *)msSmallRealloc( + psValues->pasTop, sizeof(pointObj) * psValues->nTop); + psValues->papszTopLabels = (char **)msSmallRealloc( + psValues->papszTopLabels, sizeof(char *) * psValues->nTop); } - psValues->pasTop[psValues->nTop-1].x = oLastPoint.x; - psValues->pasTop[psValues->nTop-1].y = oLastPoint.y; - psValues->papszTopLabels[psValues->nTop-1] = pszLabel; + psValues->pasTop[psValues->nTop - 1].x = oLastPoint.x; + psValues->pasTop[psValues->nTop - 1].y = oLastPoint.y; + psValues->papszTopLabels[psValues->nTop - 1] = pszLabel; } } else { /*horzontal*/ - /*Normally lines are drawn from left to right but not always for some reason, so - make sure that firstpoint < lastpoint in x*/ + /*Normally lines are drawn from left to right but not always for some + reason, so make sure that firstpoint < lastpoint in x*/ if (oFirstPoint.x > oLastPoint.x) { dfTmp = oFirstPoint.x; @@ -874,11 +892,10 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, dfTmp = oFirstPoint.y; oFirstPoint.y = oLastPoint.y; oLastPoint.y = dfTmp; - } /*first point should cross the LEFT base where x=0 axis*/ - if (abs((int)oFirstPoint.x) <=1) { - char *pszLabel=NULL; + if (abs((int)oFirstPoint.x) <= 1) { + char *pszLabel = NULL; oFirstPoint.x = 0; /*validate point is in map width/height*/ @@ -886,9 +903,11 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, continue; if (shapegrid.text) - pszLabel = msStrdup(shapegrid.text); + pszLabel = msStrdup(shapegrid.text); else { - _FormatLabel(layer, &tmpshape, tmpshape.line[0].point[tmpshape.line[0].numpoints-1].y ); + _FormatLabel( + layer, &tmpshape, + tmpshape.line[0].point[tmpshape.line[0].numpoints - 1].y); if (tmpshape.text) pszLabel = msStrdup(tmpshape.text); else @@ -896,11 +915,11 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, } /*validate that the previous value is not the same*/ - if ( psValues->nLeft > 0) { + if (psValues->nLeft > 0) { /* if (psValues->pasLeft[psValues->nLeft-1].y == oFirstPoint.y) continue; */ - for (i=0; inLeft; i++) { + for (i = 0; i < psValues->nLeft; i++) { if (psValues->pasLeft[i].y == oFirstPoint.y) break; } @@ -915,27 +934,32 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, psValues->nLeft = 1; } else { psValues->nLeft++; - psValues->pasLeft = (pointObj *)msSmallRealloc(psValues->pasLeft, sizeof(pointObj)*psValues->nLeft); - psValues->papszLeftLabels = (char **)msSmallRealloc(psValues->papszLeftLabels, sizeof(char *)*psValues->nLeft); + psValues->pasLeft = (pointObj *)msSmallRealloc( + psValues->pasLeft, sizeof(pointObj) * psValues->nLeft); + psValues->papszLeftLabels = (char **)msSmallRealloc( + psValues->papszLeftLabels, sizeof(char *) * psValues->nLeft); } - psValues->pasLeft[psValues->nLeft-1].x = oFirstPoint.x; - psValues->pasLeft[psValues->nLeft-1].y = oFirstPoint.y; - psValues->papszLeftLabels[psValues->nLeft-1] = pszLabel; /* takes ownership of allocated pszLabel */ + psValues->pasLeft[psValues->nLeft - 1].x = oFirstPoint.x; + psValues->pasLeft[psValues->nLeft - 1].y = oFirstPoint.y; + psValues->papszLeftLabels[psValues->nLeft - 1] = + pszLabel; /* takes ownership of allocated pszLabel */ } /*first point should cross the RIGHT base where x=map=>width axis*/ - if (abs((int)oLastPoint.x - map->width) <=1) { - char *pszLabel=NULL; - oLastPoint.x = map->width; + if (abs((int)oLastPoint.x - map->width) <= 1) { + char *pszLabel = NULL; + oLastPoint.x = map->width; /*validate point is in map width/height*/ if (oLastPoint.y < 0 || oLastPoint.y > map->height) continue; if (shapegrid.text) - pszLabel = msStrdup(shapegrid.text); + pszLabel = msStrdup(shapegrid.text); else { - _FormatLabel(layer, &tmpshape, tmpshape.line[0].point[tmpshape.line[0].numpoints-1].y ); + _FormatLabel( + layer, &tmpshape, + tmpshape.line[0].point[tmpshape.line[0].numpoints - 1].y); if (tmpshape.text) pszLabel = msStrdup(tmpshape.text); else @@ -943,10 +967,10 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, } /*validate that the previous value is not the same*/ - if ( psValues->nRight > 0) { + if (psValues->nRight > 0) { /* if (psValues->pasRight[psValues->nRight-1].y == oLastPoint.y) continue; */ - for (i=0; inRight; i++) { + for (i = 0; i < psValues->nRight; i++) { if (psValues->pasRight[i].y == oLastPoint.y) break; } @@ -961,38 +985,36 @@ graticuleIntersectionObj *msGraticuleLayerGetIntersectionPoints(mapObj *map, psValues->nRight = 1; } else { psValues->nRight++; - psValues->pasRight = (pointObj *)msSmallRealloc(psValues->pasRight, sizeof(pointObj)*psValues->nRight); - psValues->papszRightLabels = (char **)msSmallRealloc(psValues->papszRightLabels, sizeof(char *)*psValues->nRight); + psValues->pasRight = (pointObj *)msSmallRealloc( + psValues->pasRight, sizeof(pointObj) * psValues->nRight); + psValues->papszRightLabels = (char **)msSmallRealloc( + psValues->papszRightLabels, sizeof(char *) * psValues->nRight); } - psValues->pasRight[psValues->nRight-1].x = oLastPoint.x; - psValues->pasRight[psValues->nRight-1].y = oLastPoint.y; - psValues->papszRightLabels[psValues->nRight-1] = pszLabel; + psValues->pasRight[psValues->nRight - 1].x = oLastPoint.x; + psValues->pasRight[psValues->nRight - 1].y = oLastPoint.y; + psValues->papszRightLabels[psValues->nRight - 1] = pszLabel; } } msFreeShape(&shapegrid); msFreeShape(&tmpshape); } msInitShape(&shapegrid); - - - } msLayerClose(layer); return psValues; - } - /********************************************************************************************************************** * */ -int msGraticuleLayerInitializeVirtualTable(layerObj *layer) -{ +int msGraticuleLayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); - layer->vtable->LayerInitItemInfo = msGraticuleLayerInitItemInfo; /* should use defaults for item info functions */ + layer->vtable->LayerInitItemInfo = + msGraticuleLayerInitItemInfo; /* should use defaults for item info + functions */ layer->vtable->LayerFreeItemInfo = msGraticuleLayerFreeItemInfo; layer->vtable->LayerOpen = msGraticuleLayerOpen; layer->vtable->LayerIsOpen = msGraticuleLayerIsOpen; @@ -1017,208 +1039,208 @@ int msGraticuleLayerInitializeVirtualTable(layerObj *layer) /********************************************************************************************************************** * */ -static void _FormatLabel( layerObj *pLayer, shapeObj *pShape, double dDataToFormat ) -{ +static void _FormatLabel(layerObj *pLayer, shapeObj *pShape, + double dDataToFormat) { graticuleObj *pInfo = pLayer->grid; char cBuffer[32]; int iDegrees, iMinutes; - switch( pInfo->ilabeltype ) { - case lpDDMMSS: - iDegrees = (int) dDataToFormat; - dDataToFormat = fabs( dDataToFormat - (double) iDegrees ); - iMinutes = (int) (dDataToFormat * 60.0); - dDataToFormat = dDataToFormat - (((double) iMinutes) / 60.0); - sprintf( cBuffer, pInfo->labelformat, iDegrees, iMinutes, (int) (dDataToFormat * 3600.0) ); - break; - case lpDDMM: - iDegrees = (int) dDataToFormat; - dDataToFormat = fabs( dDataToFormat - (double) iDegrees ); - sprintf( cBuffer, pInfo->labelformat, iDegrees, (int) (dDataToFormat * 60.0) ); - break; - case lpDD: - iDegrees = (int) dDataToFormat; - sprintf( cBuffer, pInfo->labelformat, iDegrees); - break; - case lpDefault: - default: - sprintf( cBuffer, pInfo->labelformat, dDataToFormat ); + switch (pInfo->ilabeltype) { + case lpDDMMSS: + iDegrees = (int)dDataToFormat; + dDataToFormat = fabs(dDataToFormat - (double)iDegrees); + iMinutes = (int)(dDataToFormat * 60.0); + dDataToFormat = dDataToFormat - (((double)iMinutes) / 60.0); + sprintf(cBuffer, pInfo->labelformat, iDegrees, iMinutes, + (int)(dDataToFormat * 3600.0)); + break; + case lpDDMM: + iDegrees = (int)dDataToFormat; + dDataToFormat = fabs(dDataToFormat - (double)iDegrees); + sprintf(cBuffer, pInfo->labelformat, iDegrees, (int)(dDataToFormat * 60.0)); + break; + case lpDD: + iDegrees = (int)dDataToFormat; + sprintf(cBuffer, pInfo->labelformat, iDegrees); + break; + case lpDefault: + default: + sprintf(cBuffer, pInfo->labelformat, dDataToFormat); } - pShape->text = msStrdup( cBuffer ); + pShape->text = msStrdup(cBuffer); } /********************************************************************************************************************** * * Move label position into display area by adjusting underlying shape line. */ -static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticulePosition ePosition ) -{ +static int _AdjustLabelPosition(layerObj *pLayer, shapeObj *pShape, + msGraticulePosition ePosition) { graticuleObj *pInfo = pLayer->grid; rectObj rectLabel; pointObj ptPoint; double size = -1; char *labeltxt; - if( pInfo == NULL || pShape == NULL ) { - msSetError(MS_MISCERR, "Assertion failed: Null shape or non-configured grid!, ", "_AdjustLabelPosition()"); + if (pInfo == NULL || pShape == NULL) { + msSetError(MS_MISCERR, + "Assertion failed: Null shape or non-configured grid!, ", + "_AdjustLabelPosition()"); return MS_FAILURE; } - assert(pLayer->class[0]->numlabels >= 1); + assert(pLayer->class[0] -> numlabels >= 1); - if(msCheckParentPointer(pLayer->map,"map")==MS_FAILURE) + if (msCheckParentPointer(pLayer->map, "map") == MS_FAILURE) return MS_FAILURE; ptPoint = pShape->line->point[0]; - if(pLayer->project) - { - if( pLayer->reprojectorLayerToMap == NULL ) - { - pLayer->reprojectorLayerToMap = msProjectCreateReprojector( - &pLayer->projection, &pLayer->map->projection); + if (pLayer->project) { + if (pLayer->reprojectorLayerToMap == NULL) { + pLayer->reprojectorLayerToMap = msProjectCreateReprojector( + &pLayer->projection, &pLayer->map->projection); } - if( pLayer->reprojectorLayerToMap ) - msProjectShapeEx(pLayer->reprojectorLayerToMap, pShape ); + if (pLayer->reprojectorLayerToMap) + msProjectShapeEx(pLayer->reprojectorLayerToMap, pShape); /* Poor man detection of reprojection failure */ - if( msProjIsGeographicCRS(&(pLayer->projection)) != - msProjIsGeographicCRS(&(pLayer->map->projection)) ) - { - if( ptPoint.x == pShape->line->point[0].x && - ptPoint.y == pShape->line->point[0].y ) - { - return MS_FAILURE; - } + if (msProjIsGeographicCRS(&(pLayer->projection)) != + msProjIsGeographicCRS(&(pLayer->map->projection))) { + if (ptPoint.x == pShape->line->point[0].x && + ptPoint.y == pShape->line->point[0].y) { + return MS_FAILURE; + } } } - if(pLayer->transform) { - msTransformShapeToPixelRound(pShape, pLayer->map->extent, pLayer->map->cellsize); + if (pLayer->transform) { + msTransformShapeToPixelRound(pShape, pLayer->map->extent, + pLayer->map->cellsize); } - - size = pLayer->class[0]->labels[0]->size; /* TODO someday: adjust minsize/maxsize/resolution*/ - /* We only use the first label as there's no use (yet) in defining multiple lables for GRID layers, - as the only label to represent is the longitude or latitude */ - labeltxt = msShapeGetLabelAnnotation(pLayer, pShape, pLayer->class[0]->labels[0]); + + size = pLayer->class[0] + ->labels[0] + ->size; /* TODO someday: adjust minsize/maxsize/resolution*/ + /* We only use the first label as there's no use (yet) in defining multiple + lables for GRID layers, as the only label to represent is the longitude or + latitude */ + labeltxt = + msShapeGetLabelAnnotation(pLayer, pShape, pLayer->class[0] -> labels[0]); assert(labeltxt); - if(msGetStringSize(pLayer->map, pLayer->class[0]->labels[0], size, labeltxt, &rectLabel) != MS_SUCCESS) { + if (msGetStringSize(pLayer->map, pLayer->class[0] -> labels[0], size, + labeltxt, &rectLabel) != MS_SUCCESS) { free(labeltxt); - return MS_FAILURE; /* msSetError already called */ + return MS_FAILURE; /* msSetError already called */ } free(labeltxt); - switch( ePosition ) { - case posBottom: - pShape->line->point[1].y = pLayer->map->height; - pShape->line->point[0].y = pLayer->map->height - (fabs(rectLabel.maxy - rectLabel.miny) * 2 + 5); - break; - case posTop: - pShape->line->point[1].y = 0; - pShape->line->point[0].y = fabs(rectLabel.maxy - rectLabel.miny) * 2 + 5; - break; - case posLeft: - pShape->line->point[0].x = 0; - pShape->line->point[1].x = fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5; - break; - case posRight: - pShape->line->point[1].x = pLayer->map->width; - pShape->line->point[0].x = pLayer->map->width - (fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5); - break; + switch (ePosition) { + case posBottom: + pShape->line->point[1].y = pLayer->map->height; + pShape->line->point[0].y = + pLayer->map->height - (fabs(rectLabel.maxy - rectLabel.miny) * 2 + 5); + break; + case posTop: + pShape->line->point[1].y = 0; + pShape->line->point[0].y = fabs(rectLabel.maxy - rectLabel.miny) * 2 + 5; + break; + case posLeft: + pShape->line->point[0].x = 0; + pShape->line->point[1].x = fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5; + break; + case posRight: + pShape->line->point[1].x = pLayer->map->width; + pShape->line->point[0].x = + pLayer->map->width - (fabs(rectLabel.maxx - rectLabel.minx) * 2 + 5); + break; } - if(pLayer->transform) - msTransformPixelToShape( pShape, pLayer->map->extent, pLayer->map->cellsize ); + if (pLayer->transform) + msTransformPixelToShape(pShape, pLayer->map->extent, pLayer->map->cellsize); - if(pLayer->project) - { + if (pLayer->project) { /* Clamp coordinates into the validity area of the projection, in the */ /* particular case of EPSG:3857 (WebMercator) to longlat reprojection */ - if( strstr(pLayer->map->projection.args[0], "epsg:3857") && - msProjIsGeographicCRS(&(pLayer->projection)) ) - { - if( !pLayer->map->projection.gt.need_geotransform && - ePosition == posLeft && pShape->line->point[0].x < -20037508) - { - pShape->line->point[1].x = -20037508 + (pShape->line->point[1].x - - pShape->line->point[0].x); - pShape->line->point[0].x = -20037508; - } - else if( pLayer->map->projection.gt.need_geotransform && + if (strstr(pLayer->map->projection.args[0], "epsg:3857") && + msProjIsGeographicCRS(&(pLayer->projection))) { + if (!pLayer->map->projection.gt.need_geotransform && + ePosition == posLeft && pShape->line->point[0].x < -20037508) { + pShape->line->point[1].x = + -20037508 + (pShape->line->point[1].x - pShape->line->point[0].x); + pShape->line->point[0].x = -20037508; + } else if (pLayer->map->projection.gt.need_geotransform && ePosition == posLeft && pLayer->map->projection.gt.geotransform[0] + - pShape->line->point[0].x * - pLayer->map->projection.gt.geotransform[1] + - pShape->line->point[0].y * - pLayer->map->projection.gt.geotransform[2] < -20037508) - { - double y_tmp; - double width = pShape->line->point[1].x - pShape->line->point[0].x; - - y_tmp = pLayer->map->projection.gt.geotransform[3] + - pShape->line->point[0].x * + pShape->line->point[0].x * + pLayer->map->projection.gt.geotransform[1] + + pShape->line->point[0].y * + pLayer->map->projection.gt.geotransform[2] < + -20037508) { + double y_tmp; + double width = pShape->line->point[1].x - pShape->line->point[0].x; + + y_tmp = pLayer->map->projection.gt.geotransform[3] + + pShape->line->point[0].x * pLayer->map->projection.gt.geotransform[4] + - pShape->line->point[0].y * + pShape->line->point[0].y * pLayer->map->projection.gt.geotransform[5]; - pShape->line->point[0].x = + pShape->line->point[0].x = pLayer->map->projection.gt.invgeotransform[0] + - -20037508 * pLayer->map->projection.gt.invgeotransform[1] + - y_tmp * pLayer->map->projection.gt.invgeotransform[2]; - pShape->line->point[1].x = pShape->line->point[0].x + width; - } + -20037508 * pLayer->map->projection.gt.invgeotransform[1] + + y_tmp * pLayer->map->projection.gt.invgeotransform[2]; + pShape->line->point[1].x = pShape->line->point[0].x + width; + } - if( !pLayer->map->projection.gt.need_geotransform && - ePosition == posRight && pShape->line->point[1].x > 20037508) - { - pShape->line->point[0].x = 20037508 - (pShape->line->point[1].x - - pShape->line->point[0].x); - pShape->line->point[1].x = 20037508; - } - else if( pLayer->map->projection.gt.need_geotransform && + if (!pLayer->map->projection.gt.need_geotransform && + ePosition == posRight && pShape->line->point[1].x > 20037508) { + pShape->line->point[0].x = + 20037508 - (pShape->line->point[1].x - pShape->line->point[0].x); + pShape->line->point[1].x = 20037508; + } else if (pLayer->map->projection.gt.need_geotransform && ePosition == posRight && pLayer->map->projection.gt.geotransform[0] + - pShape->line->point[1].x * - pLayer->map->projection.gt.geotransform[1] + - pShape->line->point[1].y * - pLayer->map->projection.gt.geotransform[2] > 20037508) - { - double y_tmp; - double width = pShape->line->point[1].x - pShape->line->point[0].x; - - y_tmp = pLayer->map->projection.gt.geotransform[3] + - pShape->line->point[1].x * + pShape->line->point[1].x * + pLayer->map->projection.gt.geotransform[1] + + pShape->line->point[1].y * + pLayer->map->projection.gt.geotransform[2] > + 20037508) { + double y_tmp; + double width = pShape->line->point[1].x - pShape->line->point[0].x; + + y_tmp = pLayer->map->projection.gt.geotransform[3] + + pShape->line->point[1].x * pLayer->map->projection.gt.geotransform[4] + - pShape->line->point[1].y * + pShape->line->point[1].y * pLayer->map->projection.gt.geotransform[5]; - pShape->line->point[1].x = + pShape->line->point[1].x = pLayer->map->projection.gt.invgeotransform[0] + - 20037508 * pLayer->map->projection.gt.invgeotransform[1] + - y_tmp * pLayer->map->projection.gt.invgeotransform[2]; - pShape->line->point[0].x = pShape->line->point[1].x - width; - } + 20037508 * pLayer->map->projection.gt.invgeotransform[1] + + y_tmp * pLayer->map->projection.gt.invgeotransform[2]; + pShape->line->point[0].x = pShape->line->point[1].x - width; + } } - if( pLayer->reprojectorMapToLayer == NULL ) - { - pLayer->reprojectorMapToLayer = msProjectCreateReprojector( - &pLayer->map->projection, &pLayer->projection); + if (pLayer->reprojectorMapToLayer == NULL) { + pLayer->reprojectorMapToLayer = msProjectCreateReprojector( + &pLayer->map->projection, &pLayer->projection); } - if( pLayer->reprojectorMapToLayer ) - msProjectShapeEx(pLayer->reprojectorMapToLayer, pShape ); + if (pLayer->reprojectorMapToLayer) + msProjectShapeEx(pLayer->reprojectorMapToLayer, pShape); } - switch( ePosition ) { - case posBottom: - case posTop: - pShape->line->point[1].x = ptPoint.x; - pShape->line->point[0].x = ptPoint.x; - break; - case posLeft: - case posRight: - pShape->line->point[1].y = ptPoint.y; - pShape->line->point[0].y = ptPoint.y; - break; + switch (ePosition) { + case posBottom: + case posTop: + pShape->line->point[1].x = ptPoint.x; + pShape->line->point[0].x = ptPoint.x; + break; + case posLeft: + case posRight: + pShape->line->point[1].y = ptPoint.y; + pShape->line->point[0].y = ptPoint.y; + break; } return MS_SUCCESS; @@ -1233,51 +1255,50 @@ static int _AdjustLabelPosition( layerObj *pLayer, shapeObj *pShape, msGraticule * * Minor tweaks to incrment calculations - jnovak */ -void DefineAxis( int iTickCountTarget, double *Min, double *Max, double *Inc ) -{ +void DefineAxis(int iTickCountTarget, double *Min, double *Max, double *Inc) { /* define local variables... */ - double Test_inc, /* candidate increment value */ - Test_min, /* minimum scale value */ - Test_max, /* maximum scale value */ - Range = *Max - *Min ; /* range of data */ + double Test_inc, /* candidate increment value */ + Test_min, /* minimum scale value */ + Test_max, /* maximum scale value */ + Range = *Max - *Min; /* range of data */ - int i = 0 ; /* counter */ + int i = 0; /* counter */ /* don't create problems -- solve them */ - if( Range < 0 ) { - *Inc = 0 ; - return ; + if (Range < 0) { + *Inc = 0; + return; } /* handle special case of repeated values */ - else if( Range == 0) { - *Min = ceil(*Max) - 1 ; - *Max = *Min + 1 ; - *Inc = 1 ; - return ; + else if (Range == 0) { + *Min = ceil(*Max) - 1; + *Max = *Min + 1; + *Inc = 1; + return; } /* compute candidate for increment */ - Test_inc = pow( 10.0, ceil( log10( Range/10 ) ) ) ; - if(*Inc > 0 && ( Test_inc < *Inc || Test_inc > *Inc )) + Test_inc = pow(10.0, ceil(log10(Range / 10))); + if (*Inc > 0 && (Test_inc < *Inc || Test_inc > *Inc)) Test_inc = *Inc; /* establish maximum scale value... */ - Test_max = ( (long)(*Max / Test_inc)) * Test_inc ; + Test_max = ((long)(*Max / Test_inc)) * Test_inc; - if( Test_max < *Max ) - Test_max += Test_inc ; + if (Test_max < *Max) + Test_max += Test_inc; /* establish minimum scale value... */ - Test_min = Test_max ; + Test_min = Test_max; do { - ++i ; - Test_min -= Test_inc ; - } while( Test_min > *Min ) ; + ++i; + Test_min -= Test_inc; + } while (Test_min > *Min); /* subtracting small values can screw up the scale limits, */ /* eg: if DefineAxis is called with (min,max)=(0.01, 0.1), */ @@ -1289,20 +1310,20 @@ void DefineAxis( int iTickCountTarget, double *Min, double *Max, double *Inc ) /* adjust for too few tick marks */ - if(iTickCountTarget <= 0) - iTickCountTarget = MAPGRATICULE_ARC_MINIMUM; + if (iTickCountTarget <= 0) + iTickCountTarget = MAPGRATICULE_ARC_MINIMUM; - while(i < iTickCountTarget) { - Test_inc /= 2 ; - i *= 2 ; + while (i < iTickCountTarget) { + Test_inc /= 2; + i *= 2; } - if(i < 6 && 0) { - Test_inc /= 2 ; - if((Test_min + Test_inc) <= *Min) - Test_min += Test_inc ; - if((Test_max - Test_inc) >= *Max) - Test_max -= Test_inc ; + if (i < 6 && 0) { + Test_inc /= 2; + if ((Test_min + Test_inc) <= *Min) + Test_min += Test_inc; + if ((Test_max - Test_inc) >= *Max) + Test_max -= Test_inc; } /* pass back axis definition to caller */ diff --git a/maphash.c b/maphash.c index 5eaa9e9428..c11f47dd6a 100644 --- a/maphash.c +++ b/maphash.c @@ -32,74 +32,69 @@ #include "mapserver.h" #include "maphash.h" - - -static unsigned hash(const char *key) -{ +static unsigned hash(const char *key) { unsigned hashval; - for(hashval=0; *key!='\0'; key++) + for (hashval = 0; *key != '\0'; key++) hashval = tolower(*key) + 31 * hashval; - return(hashval % MS_HASHSIZE); + return (hashval % MS_HASHSIZE); } -hashTableObj *msCreateHashTable() -{ +hashTableObj *msCreateHashTable() { int i; hashTableObj *table; - table = (hashTableObj *) msSmallMalloc(sizeof(hashTableObj)); - table->items = (struct hashObj **) msSmallMalloc(sizeof(struct hashObj *)*MS_HASHSIZE); + table = (hashTableObj *)msSmallMalloc(sizeof(hashTableObj)); + table->items = + (struct hashObj **)msSmallMalloc(sizeof(struct hashObj *) * MS_HASHSIZE); - for (i=0; iitems[i] = NULL; table->numitems = 0; return table; } -int initHashTable( hashTableObj *table ) -{ +int initHashTable(hashTableObj *table) { int i; - table->items = (struct hashObj **) malloc(sizeof(struct hashObj *)*MS_HASHSIZE); - MS_CHECK_ALLOC(table->items, sizeof(struct hashObj *)*MS_HASHSIZE, MS_FAILURE); + table->items = + (struct hashObj **)malloc(sizeof(struct hashObj *) * MS_HASHSIZE); + MS_CHECK_ALLOC(table->items, sizeof(struct hashObj *) * MS_HASHSIZE, + MS_FAILURE); - for (i=0; iitems[i] = NULL; table->numitems = 0; return MS_SUCCESS; } -void msFreeHashTable( hashTableObj *table ) -{ - if( table != NULL ) { +void msFreeHashTable(hashTableObj *table) { + if (table != NULL) { msFreeHashItems(table); free(table); } } -int msHashIsEmpty( const hashTableObj *table ) -{ - if (table->numitems == 0 ) +int msHashIsEmpty(const hashTableObj *table) { + if (table->numitems == 0) return MS_TRUE; else return MS_FALSE; } - -void msFreeHashItems( hashTableObj *table ) -{ +void msFreeHashItems(hashTableObj *table) { int i; - struct hashObj *tp=NULL; - struct hashObj *prev_tp=NULL; + struct hashObj *tp = NULL; + struct hashObj *prev_tp = NULL; if (table) { - if(table->items) { - for (i=0; iitems) { + for (i = 0; i < MS_HASHSIZE; i++) { if (table->items[i] != NULL) { - for (tp=table->items[i]; tp!=NULL; prev_tp=tp,tp=tp->next,free(prev_tp)) { + for (tp = table->items[i]; tp != NULL; + prev_tp = tp, tp = tp->next, free(prev_tp)) { msFree(tp->key); msFree(tp->data); } @@ -115,23 +110,22 @@ void msFreeHashItems( hashTableObj *table ) } } -struct hashObj *msInsertHashTable(hashTableObj *table, - const char *key, const char *value) { +struct hashObj *msInsertHashTable(hashTableObj *table, const char *key, + const char *value) { struct hashObj *tp; unsigned hashval; if (!table || !key || !value) { - msSetError(MS_HASHERR, "Invalid hash table or key", - "msInsertHashTable"); + msSetError(MS_HASHERR, "Invalid hash table or key", "msInsertHashTable"); return NULL; } - for (tp=table->items[hash(key)]; tp!=NULL; tp=tp->next) - if(strcasecmp(key, tp->key) == 0) + for (tp = table->items[hash(key)]; tp != NULL; tp = tp->next) + if (strcasecmp(key, tp->key) == 0) break; if (tp == NULL) { /* not found */ - tp = (struct hashObj *) malloc(sizeof(*tp)); + tp = (struct hashObj *)malloc(sizeof(*tp)); MS_CHECK_ALLOC(tp, sizeof(*tp), NULL); tp->key = msStrdup(key); hashval = hash(key); @@ -148,25 +142,23 @@ struct hashObj *msInsertHashTable(hashTableObj *table, return tp; } -const char *msLookupHashTable(const hashTableObj *table, const char *key) -{ +const char *msLookupHashTable(const hashTableObj *table, const char *key) { struct hashObj *tp; if (!table || !key) { - return(NULL); + return (NULL); } - for (tp=table->items[hash(key)]; tp!=NULL; tp=tp->next) + for (tp = table->items[hash(key)]; tp != NULL; tp = tp->next) if (strcasecmp(key, tp->key) == 0) - return(tp->data); + return (tp->data); return NULL; } -int msRemoveHashTable(hashTableObj *table, const char *key) -{ +int msRemoveHashTable(hashTableObj *table, const char *key) { struct hashObj *tp; - struct hashObj *prev_tp=NULL; + struct hashObj *prev_tp = NULL; int status = MS_FAILURE; if (!table || !key) { @@ -174,7 +166,7 @@ int msRemoveHashTable(hashTableObj *table, const char *key) return MS_FAILURE; } - tp=table->items[hash(key)]; + tp = table->items[hash(key)]; if (!tp) { msSetError(MS_HASHERR, "No such hash entry", "msRemoveHashTable"); return MS_FAILURE; @@ -208,8 +200,7 @@ int msRemoveHashTable(hashTableObj *table, const char *key) return status; } -const char *msFirstKeyFromHashTable( const hashTableObj *table ) -{ +const char *msFirstKeyFromHashTable(const hashTableObj *table) { int hash_index; if (!table) { @@ -217,16 +208,16 @@ const char *msFirstKeyFromHashTable( const hashTableObj *table ) return NULL; } - for (hash_index = 0; hash_index < MS_HASHSIZE; hash_index++ ) { - if (table->items[hash_index] != NULL ) + for (hash_index = 0; hash_index < MS_HASHSIZE; hash_index++) { + if (table->items[hash_index] != NULL) return table->items[hash_index]->key; } return NULL; } -const char *msNextKeyFromHashTable( const hashTableObj *table, const char *lastKey ) -{ +const char *msNextKeyFromHashTable(const hashTableObj *table, + const char *lastKey) { int hash_index; struct hashObj *link; @@ -235,22 +226,21 @@ const char *msNextKeyFromHashTable( const hashTableObj *table, const char *lastK return NULL; } - if ( lastKey == NULL ) - return msFirstKeyFromHashTable( table ); + if (lastKey == NULL) + return msFirstKeyFromHashTable(table); hash_index = hash(lastKey); - for ( link = table->items[hash_index]; - link != NULL && strcasecmp(lastKey,link->key) != 0; - link = link->next ) {} + for (link = table->items[hash_index]; + link != NULL && strcasecmp(lastKey, link->key) != 0; link = link->next) { + } - if ( link != NULL && link->next != NULL ) + if (link != NULL && link->next != NULL) return link->next->key; - while ( ++hash_index < MS_HASHSIZE ) { - if ( table->items[hash_index] != NULL ) + while (++hash_index < MS_HASHSIZE) { + if (table->items[hash_index] != NULL) return table->items[hash_index]->key; } return NULL; } - diff --git a/maphash.h b/maphash.h index c349a16515..06dc46df66 100644 --- a/maphash.h +++ b/maphash.h @@ -35,128 +35,127 @@ extern "C" { #endif #if defined(_WIN32) && !defined(__CYGWIN__) -# define MS_DLL_EXPORT __declspec(dllexport) +#define MS_DLL_EXPORT __declspec(dllexport) #else -#define MS_DLL_EXPORT +#define MS_DLL_EXPORT #endif #define MS_HASHSIZE 41 - /* ========================================================================= - * Structs - * ========================================================================= */ +/* ========================================================================= + * Structs + * ========================================================================= */ #ifndef SWIG - struct hashObj { - struct hashObj *next; /* pointer to next item */ - char *key; /* string key that is hashed */ - char *data; /* string stored in this item */ - }; +struct hashObj { + struct hashObj *next; /* pointer to next item */ + char *key; /* string key that is hashed */ + char *data; /* string stored in this item */ +}; #endif /*SWIG*/ - /** * An object to store key-value pairs * */ - typedef struct { +typedef struct { #ifndef SWIG - struct hashObj **items; /* the hash table */ + struct hashObj **items; /* the hash table */ #endif #ifdef SWIG %immutable; -#endif /*SWIG*/ - int numitems; ///< \**immutable** number of items +#endif /*SWIG*/ + int numitems; ///< \**immutable** number of items #ifdef SWIG %mutable; #endif /*SWIG*/ - } hashTableObj; +} hashTableObj; - /* ========================================================================= - * Functions - * ========================================================================= */ +/* ========================================================================= + * Functions + * ========================================================================= */ #ifndef SWIG - /* msCreateHashTable - create a hash table - * ARGS: - * None - * RETURNS: - * New hash table - */ - MS_DLL_EXPORT hashTableObj *msCreateHashTable( void ); - - /* For use in mapfile.c with hashTableObj structure members */ - MS_DLL_EXPORT int initHashTable( hashTableObj *table ); - - /* msFreeHashTable - free allocated memory - * ARGS: - * table - target hash table - * RETURNS: - * None - */ - MS_DLL_EXPORT void msFreeHashTable( hashTableObj *table ); - - /* Free only the items for hashTableObj structure members (metadata, &c) */ - MS_DLL_EXPORT void msFreeHashItems( hashTableObj *table ); - - /* msInsertHashTable - insert new item - * ARGS: - * table - the target hash table - * key - key string for new item - * value - data string for new item - * RETURNS: - * pointer to the new item or NULL - * EXCEPTIONS: - * raise MS_HASHERR on failure - */ - MS_DLL_EXPORT struct hashObj *msInsertHashTable( hashTableObj *table, - const char *key, - const char *value ); - - /* msLookupHashTable - get the value of an item by its key - * ARGS: - * table - the target hash table - * key - key string of item - * RETURNS: - * string value of item - */ - MS_DLL_EXPORT const char *msLookupHashTable( const hashTableObj *table, const char *key); - - /* msRemoveHashTable - remove item from table at key - * ARGS: - * table - target hash table - * key - key string - * RETURNS: - * MS_SUCCESS or MS_FAILURE - */ - MS_DLL_EXPORT int msRemoveHashTable( hashTableObj *table, const char *key); - - /* msFirstKeyFromHashTable - get key of first item - * ARGS: - * table - target hash table - * RETURNS: - * first key as a string - */ - MS_DLL_EXPORT const char *msFirstKeyFromHashTable( const hashTableObj *table ); - - /* msNextKeyFromHashTable - get next key - * ARGS: - * table - target hash table - * prevkey - the previous key - * RETURNS: - * the key of the item of following prevkey as a string - */ - MS_DLL_EXPORT const char *msNextKeyFromHashTable( const hashTableObj *table, - const char *prevkey ); - - /* msHashIsEmpty - get next key - * ARGS: - * table - target hash table - * RETURNS: - * MS_TRUE if the table is empty and MS_FALSE if the table has items - */ - - MS_DLL_EXPORT int msHashIsEmpty( const hashTableObj* table ); +/* msCreateHashTable - create a hash table + * ARGS: + * None + * RETURNS: + * New hash table + */ +MS_DLL_EXPORT hashTableObj *msCreateHashTable(void); + +/* For use in mapfile.c with hashTableObj structure members */ +MS_DLL_EXPORT int initHashTable(hashTableObj *table); + +/* msFreeHashTable - free allocated memory + * ARGS: + * table - target hash table + * RETURNS: + * None + */ +MS_DLL_EXPORT void msFreeHashTable(hashTableObj *table); + +/* Free only the items for hashTableObj structure members (metadata, &c) */ +MS_DLL_EXPORT void msFreeHashItems(hashTableObj *table); + +/* msInsertHashTable - insert new item + * ARGS: + * table - the target hash table + * key - key string for new item + * value - data string for new item + * RETURNS: + * pointer to the new item or NULL + * EXCEPTIONS: + * raise MS_HASHERR on failure + */ +MS_DLL_EXPORT struct hashObj * +msInsertHashTable(hashTableObj *table, const char *key, const char *value); + +/* msLookupHashTable - get the value of an item by its key + * ARGS: + * table - the target hash table + * key - key string of item + * RETURNS: + * string value of item + */ +MS_DLL_EXPORT const char *msLookupHashTable(const hashTableObj *table, + const char *key); + +/* msRemoveHashTable - remove item from table at key + * ARGS: + * table - target hash table + * key - key string + * RETURNS: + * MS_SUCCESS or MS_FAILURE + */ +MS_DLL_EXPORT int msRemoveHashTable(hashTableObj *table, const char *key); + +/* msFirstKeyFromHashTable - get key of first item + * ARGS: + * table - target hash table + * RETURNS: + * first key as a string + */ +MS_DLL_EXPORT const char *msFirstKeyFromHashTable(const hashTableObj *table); + +/* msNextKeyFromHashTable - get next key + * ARGS: + * table - target hash table + * prevkey - the previous key + * RETURNS: + * the key of the item of following prevkey as a string + */ +MS_DLL_EXPORT const char *msNextKeyFromHashTable(const hashTableObj *table, + const char *prevkey); + +/* msHashIsEmpty - get next key + * ARGS: + * table - target hash table + * RETURNS: + * MS_TRUE if the table is empty and MS_FALSE if the table has items + */ + +MS_DLL_EXPORT int msHashIsEmpty(const hashTableObj *table); #endif /*SWIG*/ diff --git a/maphttp.c b/maphttp.c index 50a9bd5314..1c9743614d 100644 --- a/maphttp.c +++ b/maphttp.c @@ -57,8 +57,8 @@ */ #include - -#define unchecked_curl_easy_setopt(handle,opt,param) IGNORE_RET_VAL(curl_easy_setopt(handle,opt,param)) +#define unchecked_curl_easy_setopt(handle, opt, param) \ + IGNORE_RET_VAL(curl_easy_setopt(handle, opt, param)) /********************************************************************** * msHTTPInit() @@ -74,19 +74,16 @@ **********************************************************************/ static int gbCurlInitialized = MS_FALSE; -int msHTTPInit() -{ +int msHTTPInit() { /* curl_global_init() should only be called once (no matter how * many threads or libcurl sessions that'll be used) by every * application that uses libcurl. */ msAcquireLock(TLOCK_OWS); - if (!gbCurlInitialized && - curl_global_init(CURL_GLOBAL_ALL) != 0) { + if (!gbCurlInitialized && curl_global_init(CURL_GLOBAL_ALL) != 0) { msReleaseLock(TLOCK_OWS); - msSetError(MS_HTTPERR, "Libcurl initialization failed.", - "msHTTPInit()"); + msSetError(MS_HTTPERR, "Libcurl initialization failed.", "msHTTPInit()"); return MS_FAILURE; } @@ -96,13 +93,11 @@ int msHTTPInit() return MS_SUCCESS; } - /********************************************************************** * msHTTPCleanup() * **********************************************************************/ -void msHTTPCleanup() -{ +void msHTTPCleanup() { msAcquireLock(TLOCK_OWS); if (gbCurlInitialized) curl_global_cleanup(); @@ -111,7 +106,6 @@ void msHTTPCleanup() msReleaseLock(TLOCK_OWS); } - /********************************************************************** * msHTTPInitRequestObj() * @@ -119,11 +113,10 @@ void msHTTPCleanup() * for use with msHTTPExecuteRequest(), etc. * **********************************************************************/ -void msHTTPInitRequestObj(httpRequestObj *pasReqInfo, int numRequests) -{ +void msHTTPInitRequestObj(httpRequestObj *pasReqInfo, int numRequests) { int i; - for(i=0; idebug) { - msDebug("msHTTPWriteFct(id=%d, %d bytes)\n", - psReq->nLayerId, (int)(size*nmemb)); + msDebug("msHTTPWriteFct(id=%d, %d bytes)\n", psReq->nLayerId, + (int)(size * nmemb)); } - if(psReq->nMaxBytes > 0 && (psReq->result_size + size*nmemb) > (size_t)psReq->nMaxBytes) { - msSetError(MS_HTTPERR, "Requested transfer larger than configured maximum %d.", - "msHTTPWriteFct()", - psReq->nMaxBytes ); - return -1; + if (psReq->nMaxBytes > 0 && + (psReq->result_size + size * nmemb) > (size_t)psReq->nMaxBytes) { + msSetError(MS_HTTPERR, + "Requested transfer larger than configured maximum %d.", + "msHTTPWriteFct()", psReq->nMaxBytes); + return -1; } /* Case where we are writing to a disk file. */ - if( psReq->fp != NULL ) { - psReq->result_size += size*nmemb; + if (psReq->fp != NULL) { + psReq->result_size += size * nmemb; return fwrite(buffer, size, nmemb, psReq->fp); } /* Case where we build up the result in memory */ else { - if( psReq->result_data == NULL ) { - psReq->result_buf_size = size*nmemb + 10000; - psReq->result_data = (char *) msSmallMalloc( psReq->result_buf_size ); - } else if( psReq->result_size + nmemb * size > (size_t)psReq->result_buf_size ) { - psReq->result_buf_size = psReq->result_size + nmemb*size + 10000; - psReq->result_data = (char *) msSmallRealloc( psReq->result_data, - psReq->result_buf_size ); + if (psReq->result_data == NULL) { + psReq->result_buf_size = size * nmemb + 10000; + psReq->result_data = (char *)msSmallMalloc(psReq->result_buf_size); + } else if (psReq->result_size + nmemb * size > + (size_t)psReq->result_buf_size) { + psReq->result_buf_size = psReq->result_size + nmemb * size + 10000; + psReq->result_data = + (char *)msSmallRealloc(psReq->result_data, psReq->result_buf_size); } - if( psReq->result_data == NULL ) { - msSetError(MS_HTTPERR, - "Unable to grow HTTP result buffer to size %d.", - "msHTTPWriteFct()", - psReq->result_buf_size ); + if (psReq->result_data == NULL) { + msSetError(MS_HTTPERR, "Unable to grow HTTP result buffer to size %d.", + "msHTTPWriteFct()", psReq->result_buf_size); psReq->result_buf_size = 0; psReq->result_size = 0; return -1; } - memcpy( psReq->result_data + psReq->result_size, - buffer, size*nmemb ); - psReq->result_size += size*nmemb; + memcpy(psReq->result_data + psReq->result_size, buffer, size * nmemb); + psReq->result_size += size * nmemb; - return size*nmemb; + return size * nmemb; } } @@ -272,25 +260,23 @@ static size_t msHTTPWriteFct(void *buffer, size_t size, size_t nmemb, * Returns the equivalent CURL CURLAUTH_ constant given a * MS_HTTP_AUTH_TYPE, or CURLAUTH_BASIC if no match is found. **********************************************************************/ -long msGetCURLAuthType(enum MS_HTTP_AUTH_TYPE authType) -{ +long msGetCURLAuthType(enum MS_HTTP_AUTH_TYPE authType) { switch (authType) { - case MS_BASIC: - return CURLAUTH_BASIC; - case MS_DIGEST: - return CURLAUTH_DIGEST; - case MS_NTLM: - return CURLAUTH_NTLM; - case MS_ANY: - return CURLAUTH_ANY; - case MS_ANYSAFE: - return CURLAUTH_ANYSAFE; - default: - return CURLAUTH_BASIC; + case MS_BASIC: + return CURLAUTH_BASIC; + case MS_DIGEST: + return CURLAUTH_DIGEST; + case MS_NTLM: + return CURLAUTH_NTLM; + case MS_ANY: + return CURLAUTH_ANY; + case MS_ANYSAFE: + return CURLAUTH_ANYSAFE; + default: + return CURLAUTH_BASIC; } } - /********************************************************************** * msHTTPAuthProxySetup() * @@ -303,35 +289,33 @@ long msGetCURLAuthType(enum MS_HTTP_AUTH_TYPE authType) **********************************************************************/ int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, httpRequestObj *pasReqInfo, int numRequests, - mapObj *map, const char* namespaces) -{ + mapObj *map, const char *namespaces) { const char *pszTmp; - char *pszProxyHost=NULL; - long nProxyPort=0; - char *pszProxyUsername=NULL, *pszProxyPassword=NULL; - char *pszHttpAuthUsername=NULL, *pszHttpAuthPassword=NULL; + char *pszProxyHost = NULL; + long nProxyPort = 0; + char *pszProxyUsername = NULL, *pszProxyPassword = NULL; + char *pszHttpAuthUsername = NULL, *pszHttpAuthPassword = NULL; enum MS_HTTP_AUTH_TYPE eHttpAuthType = MS_BASIC; enum MS_HTTP_AUTH_TYPE eProxyAuthType = MS_BASIC; enum MS_HTTP_PROXY_TYPE eProxyType = MS_HTTP; - /* ------------------------------------------------------------------ - * Check for authentication and proxying metadata. If the metadata is not found - * in the layer metadata, check the map-level metadata. + * Check for authentication and proxying metadata. If the metadata is not + * found in the layer metadata, check the map-level metadata. * ------------------------------------------------------------------ */ - if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, - "proxy_host")) != NULL) { + if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, "proxy_host")) != + NULL) { pszProxyHost = msStrdup(pszTmp); } - if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, - "proxy_port")) != NULL) { + if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, "proxy_port")) != + NULL) { nProxyPort = atol(pszTmp); } - if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, - "proxy_type")) != NULL) { + if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, "proxy_type")) != + NULL) { if (strcasecmp(pszTmp, "HTTP") == 0) eProxyType = MS_HTTP; @@ -363,7 +347,6 @@ int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, } } - if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, "proxy_username")) != NULL) { pszProxyUsername = msStrdup(pszTmp); @@ -375,12 +358,12 @@ int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, if (pszProxyPassword == NULL) { msFree(pszProxyHost); msFree(pszProxyUsername); - return(MS_FAILURE); /* An error should already have been produced */ + return (MS_FAILURE); /* An error should already have been produced */ } } - if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, - "auth_type")) != NULL) { + if ((pszTmp = msOWSLookupMetadata2(lyrmd, mapmd, namespaces, "auth_type")) != + NULL) { if (strcasecmp(pszTmp, "BASIC") == 0) eHttpAuthType = MS_BASIC; else if (strcasecmp(pszTmp, "DIGEST") == 0) @@ -411,19 +394,19 @@ int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, msFree(pszProxyHost); msFree(pszProxyUsername); msFree(pszProxyPassword); - return(MS_FAILURE); /* An error should already have been produced */ + return (MS_FAILURE); /* An error should already have been produced */ } } - pasReqInfo[numRequests].pszProxyAddress = pszProxyHost; - pasReqInfo[numRequests].nProxyPort = nProxyPort; - pasReqInfo[numRequests].eProxyType = eProxyType; - pasReqInfo[numRequests].eProxyAuthType = eProxyAuthType; + pasReqInfo[numRequests].pszProxyAddress = pszProxyHost; + pasReqInfo[numRequests].nProxyPort = nProxyPort; + pasReqInfo[numRequests].eProxyType = eProxyType; + pasReqInfo[numRequests].eProxyAuthType = eProxyAuthType; pasReqInfo[numRequests].pszProxyUsername = pszProxyUsername; pasReqInfo[numRequests].pszProxyPassword = pszProxyPassword; - pasReqInfo[numRequests].eHttpAuthType = eHttpAuthType; - pasReqInfo[numRequests].pszHttpUsername = pszHttpAuthUsername; - pasReqInfo[numRequests].pszHttpPassword = pszHttpAuthPassword; + pasReqInfo[numRequests].eHttpAuthType = eHttpAuthType; + pasReqInfo[numRequests].pszHttpUsername = pszHttpAuthUsername; + pasReqInfo[numRequests].pszHttpPassword = pszHttpAuthPassword; return MS_SUCCESS; } @@ -442,16 +425,15 @@ int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, * MS_DONE if some requests failed with 40x status for instance (not fatal) **********************************************************************/ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, - int bCheckLocalCache) -{ - int i, nStatus = MS_SUCCESS, nTimeout, still_running=0, num_msgs=0; - CURLM *multi_handle; + int bCheckLocalCache) { + int i, nStatus = MS_SUCCESS, nTimeout, still_running = 0, num_msgs = 0; + CURLM *multi_handle; CURLMsg *curl_msg; - char debug = MS_FALSE; + char debug = MS_FALSE; const char *pszCurlCABundle = NULL; if (numRequests == 0) - return MS_SUCCESS; /* Nothing to do */ + return MS_SUCCESS; /* Nothing to do */ if (!gbCurlInitialized) msHTTPInit(); @@ -461,12 +443,12 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, * We use the longest timeout value in the array of requests */ nTimeout = pasReqInfo[0].nTimeout; - for (i=0; i nTimeout) nTimeout = pasReqInfo[i].nTimeout; if (pasReqInfo[i].debug) - debug = MS_TRUE; /* For the download loop */ + debug = MS_TRUE; /* For the download loop */ } if (nTimeout <= 0) @@ -484,7 +466,7 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, msDebug("Using CURL_CA_BUNDLE=%s\n", pszCurlCABundle); } - const char* pszHttpVersion = CPLGetConfigOption("CURL_HTTP_VERSION", NULL); + const char *pszHttpVersion = CPLGetConfigOption("CURL_HTTP_VERSION", NULL); /* Alloc a curl-multi handle, and add a curl-easy handle to it for each * file to download. @@ -493,22 +475,22 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, if (multi_handle == NULL) { msSetError(MS_HTTPERR, "curl_multi_init() failed.", "msHTTPExecuteRequests()"); - return(MS_FAILURE); + return (MS_FAILURE); } - for (i=0; iversion_num/0x10000 & 0xff, - psCurlVInfo->version_num/0x100 & 0xff, - psCurlVInfo->version_num & 0xff ); + sprintf(pasReqInfo[i].pszUserAgent, "MapServer/%s libcurl/%d.%d.%d", + MS_VERSION, psCurlVInfo->version_num / 0x10000 & 0xff, + psCurlVInfo->version_num / 0x100 & 0xff, + psCurlVInfo->version_num & 0xff); } } if (pasReqInfo[i].pszUserAgent) { - unchecked_curl_easy_setopt(http_handle, - CURLOPT_USERAGENT, pasReqInfo[i].pszUserAgent ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_USERAGENT, + pasReqInfo[i].pszUserAgent); } /* Enable following redirections. Requires libcurl 7.10.1 at least */ - unchecked_curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1 ); - unchecked_curl_easy_setopt(http_handle, CURLOPT_MAXREDIRS, 10 ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1); + unchecked_curl_easy_setopt(http_handle, CURLOPT_MAXREDIRS, 10); /* Set timeout.*/ - unchecked_curl_easy_setopt(http_handle, CURLOPT_TIMEOUT, nTimeout ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_TIMEOUT, nTimeout); /* Pass CURL_CA_BUNDLE if set */ if (pszCurlCABundle) - unchecked_curl_easy_setopt(http_handle, CURLOPT_CAINFO, pszCurlCABundle ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_CAINFO, pszCurlCABundle); /* Set proxying settings */ - if (pasReqInfo[i].pszProxyAddress != NULL - && strlen(pasReqInfo[i].pszProxyAddress) > 0) { - long nProxyType = CURLPROXY_HTTP; + if (pasReqInfo[i].pszProxyAddress != NULL && + strlen(pasReqInfo[i].pszProxyAddress) > 0) { + long nProxyType = CURLPROXY_HTTP; unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXY, - pasReqInfo[i].pszProxyAddress); + pasReqInfo[i].pszProxyAddress); - if (pasReqInfo[i].nProxyPort > 0 - && pasReqInfo[i].nProxyPort < 65535) { + if (pasReqInfo[i].nProxyPort > 0 && pasReqInfo[i].nProxyPort < 65535) { unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXYPORT, - pasReqInfo[i].nProxyPort); + pasReqInfo[i].nProxyPort); } switch (pasReqInfo[i].eProxyType) { - case MS_HTTP: - nProxyType = CURLPROXY_HTTP; - break; - case MS_SOCKS5: - nProxyType = CURLPROXY_SOCKS5; - break; + case MS_HTTP: + nProxyType = CURLPROXY_HTTP; + break; + case MS_SOCKS5: + nProxyType = CURLPROXY_SOCKS5; + break; } unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXYTYPE, nProxyType); /* If there is proxy authentication information, set it */ - if (pasReqInfo[i].pszProxyUsername != NULL - && pasReqInfo[i].pszProxyPassword != NULL - && strlen(pasReqInfo[i].pszProxyUsername) > 0 - && strlen(pasReqInfo[i].pszProxyPassword) > 0) { - char szUsernamePasswd[128]; + if (pasReqInfo[i].pszProxyUsername != NULL && + pasReqInfo[i].pszProxyPassword != NULL && + strlen(pasReqInfo[i].pszProxyUsername) > 0 && + strlen(pasReqInfo[i].pszProxyPassword) > 0) { + char szUsernamePasswd[128]; #if LIBCURL_VERSION_NUM >= 0x070a07 - long nProxyAuthType = CURLAUTH_BASIC; + long nProxyAuthType = CURLAUTH_BASIC; /* CURLOPT_PROXYAUTH available only in Curl 7.10.7 and up */ nProxyAuthType = msGetCURLAuthType(pasReqInfo[i].eProxyAuthType); - unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXYAUTH, nProxyAuthType); + unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXYAUTH, + nProxyAuthType); #else /* We log an error but don't abort processing */ - msSetError(MS_HTTPERR, "CURLOPT_PROXYAUTH not supported. Requires Curl 7.10.7 and up. *_proxy_auth_type setting ignored.", + msSetError(MS_HTTPERR, + "CURLOPT_PROXYAUTH not supported. Requires Curl 7.10.7 and " + "up. *_proxy_auth_type setting ignored.", "msHTTPExecuteRequests()"); #endif /* LIBCURL_VERSION_NUM */ - snprintf(szUsernamePasswd, 127, "%s:%s", - pasReqInfo[i].pszProxyUsername, + snprintf(szUsernamePasswd, 127, "%s:%s", pasReqInfo[i].pszProxyUsername, pasReqInfo[i].pszProxyPassword); unchecked_curl_easy_setopt(http_handle, CURLOPT_PROXYUSERPWD, - szUsernamePasswd); + szUsernamePasswd); } } /* Set HTTP Authentication settings */ - if (pasReqInfo[i].pszHttpUsername != NULL - && pasReqInfo[i].pszHttpPassword != NULL - && strlen(pasReqInfo[i].pszHttpUsername) > 0 - && strlen(pasReqInfo[i].pszHttpPassword) > 0) { - char szUsernamePasswd[128]; - long nHttpAuthType = CURLAUTH_BASIC; - - snprintf(szUsernamePasswd, 127, "%s:%s", - pasReqInfo[i].pszHttpUsername, + if (pasReqInfo[i].pszHttpUsername != NULL && + pasReqInfo[i].pszHttpPassword != NULL && + strlen(pasReqInfo[i].pszHttpUsername) > 0 && + strlen(pasReqInfo[i].pszHttpPassword) > 0) { + char szUsernamePasswd[128]; + long nHttpAuthType = CURLAUTH_BASIC; + + snprintf(szUsernamePasswd, 127, "%s:%s", pasReqInfo[i].pszHttpUsername, pasReqInfo[i].pszHttpPassword); unchecked_curl_easy_setopt(http_handle, CURLOPT_USERPWD, - szUsernamePasswd); + szUsernamePasswd); nHttpAuthType = msGetCURLAuthType(pasReqInfo[i].eHttpAuthType); unchecked_curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, nHttpAuthType); @@ -659,73 +641,75 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, * (this force avoiding the use of sgnal handlers) */ #ifdef CURLOPT_NOSIGNAL - unchecked_curl_easy_setopt(http_handle, CURLOPT_NOSIGNAL, 1 ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_NOSIGNAL, 1); #endif /* If we are writing file to disk, open the file now. */ - if( pasReqInfo[i].pszOutputFile != NULL ) { - if ( (fp = fopen(pasReqInfo[i].pszOutputFile, "wb")) == NULL) { + if (pasReqInfo[i].pszOutputFile != NULL) { + if ((fp = fopen(pasReqInfo[i].pszOutputFile, "wb")) == NULL) { msSetError(MS_HTTPERR, "Can't open output file %s.", "msHTTPExecuteRequests()", pasReqInfo[i].pszOutputFile); - return(MS_FAILURE); + return (MS_FAILURE); } pasReqInfo[i].fp = fp; } /* coverity[bad_sizeof] */ - unchecked_curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, &(pasReqInfo[i])); - unchecked_curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, msHTTPWriteFct); + unchecked_curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, + &(pasReqInfo[i])); + unchecked_curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, + msHTTPWriteFct); /* Provide a buffer where libcurl can write human readable error msgs */ if (pasReqInfo[i].pszErrBuf == NULL) - pasReqInfo[i].pszErrBuf = (char *)msSmallMalloc((CURL_ERROR_SIZE+1)* - sizeof(char)); + pasReqInfo[i].pszErrBuf = + (char *)msSmallMalloc((CURL_ERROR_SIZE + 1) * sizeof(char)); pasReqInfo[i].pszErrBuf[0] = '\0'; unchecked_curl_easy_setopt(http_handle, CURLOPT_ERRORBUFFER, - pasReqInfo[i].pszErrBuf); + pasReqInfo[i].pszErrBuf); - if(pasReqInfo[i].pszPostRequest != NULL ) { + if (pasReqInfo[i].pszPostRequest != NULL) { char szBuf[100]; - struct curl_slist *headers=NULL; - snprintf(szBuf, 100, - "Content-Type: %s", pasReqInfo[i].pszPostContentType); + struct curl_slist *headers = NULL; + snprintf(szBuf, 100, "Content-Type: %s", + pasReqInfo[i].pszPostContentType); headers = curl_slist_append(headers, szBuf); - unchecked_curl_easy_setopt(http_handle, CURLOPT_POST, 1 ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_POST, 1); unchecked_curl_easy_setopt(http_handle, CURLOPT_POSTFIELDS, - pasReqInfo[i].pszPostRequest); - if( debug ) - { - msDebug("HTTP: POST = %s", pasReqInfo[i].pszPostRequest); + pasReqInfo[i].pszPostRequest); + if (debug) { + msDebug("HTTP: POST = %s", pasReqInfo[i].pszPostRequest); } unchecked_curl_easy_setopt(http_handle, CURLOPT_HTTPHEADER, headers); /* curl_slist_free_all(headers); */ /* free the header list */ } /* Added by RFC-42 HTTP Cookie Forwarding */ - if(pasReqInfo[i].pszHTTPCookieData != NULL) { + if (pasReqInfo[i].pszHTTPCookieData != NULL) { /* Check if there's no end of line in the Cookie string */ /* This could break the HTTP Header */ - for(size_t nPos=0; nPosmsg == CURLMSG_DONE && - curl_msg->data.result != CURLE_OK) { + if (curl_msg->msg == CURLMSG_DONE && curl_msg->data.result != CURLE_OK) { /* Something went wrong with this transfer... report error */ - for (i=0; ieasy_handle) { psReq = &(pasReqInfo[i]); break; @@ -810,38 +794,37 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, if (debug) { /* Print a msDebug header for timings reported in the loop below */ - msDebug("msHTTPExecuteRequests() timing summary per layer (connect_time + time_to_first_packet + download_time = total_time in seconds)\n"); + msDebug("msHTTPExecuteRequests() timing summary per layer (connect_time + " + "time_to_first_packet + download_time = total_time in seconds)\n"); } /* Check status of all requests, close files, report errors and cleanup * handles */ - for (i=0; inStatus == 242) - continue; /* Nothing to do here, this file was in cache already */ + continue; /* Nothing to do here, this file was in cache already */ if (psReq->fp) fclose(psReq->fp); psReq->fp = NULL; - http_handle = (CURL*)(psReq->curl_handle); + http_handle = (CURL *)(psReq->curl_handle); if (psReq->nStatus == 0 && - curl_easy_getinfo(http_handle, - CURLINFO_HTTP_CODE, &lVal) == CURLE_OK) { + curl_easy_getinfo(http_handle, CURLINFO_HTTP_CODE, &lVal) == CURLE_OK) { char *pszContentType = NULL; psReq->nStatus = lVal; /* Fetch content type of response */ - if (curl_easy_getinfo(http_handle, - CURLINFO_CONTENT_TYPE, + if (curl_easy_getinfo(http_handle, CURLINFO_CONTENT_TYPE, &pszContentType) == CURLE_OK && pszContentType != NULL) { psReq->pszContentType = msStrdup(pszContentType); @@ -856,33 +839,29 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, if (psReq->nStatus == -(CURLE_OPERATION_TIMEOUTED)) { /* Timeout isn't a fatal error */ if (psReq->debug) - msDebug("HTTP: TIMEOUT of %d seconds exceeded for %s\n", - nTimeout, psReq->pszGetUrl ); + msDebug("HTTP: TIMEOUT of %d seconds exceeded for %s\n", nTimeout, + psReq->pszGetUrl); - msSetError(MS_HTTPERR, - "HTTP: TIMEOUT of %d seconds exceeded for %s\n", - "msHTTPExecuteRequests()", - nTimeout, psReq->pszGetUrl); + msSetError(MS_HTTPERR, "HTTP: TIMEOUT of %d seconds exceeded for %s\n", + "msHTTPExecuteRequests()", nTimeout, psReq->pszGetUrl); /* Rewrite error message, the curl timeout message isn't * of much use to our users. */ - sprintf(psReq->pszErrBuf, - "TIMEOUT of %d seconds exceeded.", nTimeout); + sprintf(psReq->pszErrBuf, "TIMEOUT of %d seconds exceeded.", nTimeout); } else if (psReq->nStatus > 0) { /* Got an HTTP Error, e.g. 404, etc. */ if (psReq->debug) msDebug("HTTP: HTTP GET request failed with status %d (%s)" " for %s\n", - psReq->nStatus, psReq->pszErrBuf, - psReq->pszGetUrl); + psReq->nStatus, psReq->pszErrBuf, psReq->pszGetUrl); msSetError(MS_HTTPERR, "HTTP GET request failed with status %d (%s) " "for %s", - "msHTTPExecuteRequests()", psReq->nStatus, - psReq->pszErrBuf, psReq->pszGetUrl); + "msHTTPExecuteRequests()", psReq->nStatus, psReq->pszErrBuf, + psReq->pszGetUrl); } else { /* Got a curl error */ @@ -890,45 +869,42 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, if (psReq->debug) msDebug("HTTP: request failed with curl error " "code %d (%s) for %s", - -psReq->nStatus, psReq->pszErrBuf, - psReq->pszGetUrl); + -psReq->nStatus, psReq->pszErrBuf, psReq->pszGetUrl); - if(!error || error->code == MS_NOERR) /* only set error if one hasn't already been set */ + if (!error || + error->code == + MS_NOERR) /* only set error if one hasn't already been set */ msSetError(MS_HTTPERR, - "HTTP: request failed with curl error " - "code %d (%s) for %s", - "msHTTPExecuteRequests()", - -psReq->nStatus, psReq->pszErrBuf, - psReq->pszGetUrl); + "HTTP: request failed with curl error " + "code %d (%s) for %s", + "msHTTPExecuteRequests()", -psReq->nStatus, + psReq->pszErrBuf, psReq->pszGetUrl); } } /* Report download times foreach handle, in debug mode */ if (psReq->debug) { - double dConnectTime=0.0, dTotalTime=0.0, dStartTfrTime=0.0; - - curl_easy_getinfo(http_handle, - CURLINFO_CONNECT_TIME, &dConnectTime); - curl_easy_getinfo(http_handle, - CURLINFO_STARTTRANSFER_TIME, &dStartTfrTime); - curl_easy_getinfo(http_handle, - CURLINFO_TOTAL_TIME, &dTotalTime); + double dConnectTime = 0.0, dTotalTime = 0.0, dStartTfrTime = 0.0; + + curl_easy_getinfo(http_handle, CURLINFO_CONNECT_TIME, &dConnectTime); + curl_easy_getinfo(http_handle, CURLINFO_STARTTRANSFER_TIME, + &dStartTfrTime); + curl_easy_getinfo(http_handle, CURLINFO_TOTAL_TIME, &dTotalTime); /* STARTTRANSFER_TIME includes CONNECT_TIME, but TOTAL_TIME * doesn't, so we need to add it. */ dTotalTime += dConnectTime; msDebug("Layer %d: %.3f + %.3f + %.3f = %.3fs\n", psReq->nLayerId, - dConnectTime, dStartTfrTime-dConnectTime, - dTotalTime-dStartTfrTime, dTotalTime); + dConnectTime, dStartTfrTime - dConnectTime, + dTotalTime - dStartTfrTime, dTotalTime); } /* Cleanup this handle */ - unchecked_curl_easy_setopt(http_handle, CURLOPT_URL, "" ); + unchecked_curl_easy_setopt(http_handle, CURLOPT_URL, ""); curl_multi_remove_handle(multi_handle, http_handle); curl_easy_cleanup(http_handle); psReq->curl_handle = NULL; - } /* Cleanup multi handle, each handle had to be cleaned up individually */ @@ -944,17 +920,16 @@ int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, **********************************************************************/ int msHTTPGetFile(const char *pszGetUrl, const char *pszOutputFile, int *pnHTTPStatus, int nTimeout, int bCheckLocalCache, - int bDebug, int nMaxBytes) -{ + int bDebug, int nMaxBytes) { httpRequestObj *pasReqInfo; /* Alloc httpRequestInfo structs through which status of each request * will be returned. * We need to alloc 2 instance of requestobj so that the last * object in the array can be set to NULL. - */ - pasReqInfo = (httpRequestObj*)calloc(2, sizeof(httpRequestObj)); - MS_CHECK_ALLOC(pasReqInfo, 2*sizeof(httpRequestObj), MS_FAILURE); + */ + pasReqInfo = (httpRequestObj *)calloc(2, sizeof(httpRequestObj)); + MS_CHECK_ALLOC(pasReqInfo, 2 * sizeof(httpRequestObj), MS_FAILURE); msHTTPInitRequestObj(pasReqInfo, 2); @@ -981,5 +956,4 @@ int msHTTPGetFile(const char *pszGetUrl, const char *pszOutputFile, return MS_SUCCESS; } - #endif /* defined(USE_WMS_LYR) || defined(USE_WMS_SVR) */ diff --git a/maphttp.h b/maphttp.h index 5164cdd483..cde5376d6c 100644 --- a/maphttp.h +++ b/maphttp.h @@ -30,8 +30,6 @@ #ifndef MAPHTTP_H #define MAPHTTP_H - - #include "mapprimitive.h" #include @@ -39,86 +37,73 @@ extern "C" { #endif -#define MS_HTTP_SUCCESS(status) (status == 200 || status == 242) - - enum MS_HTTP_PROXY_TYPE - { - MS_HTTP, - MS_SOCKS5 - }; - - enum MS_HTTP_AUTH_TYPE { - MS_BASIC, - MS_DIGEST, - MS_NTLM, - MS_ANY, - MS_ANYSAFE - }; - - typedef struct http_request_info { - int nLayerId; - char *pszGetUrl; - char *pszOutputFile; - int nTimeout; - int nMaxBytes; - rectObj bbox; - int width; - int height; - int nStatus; /* 200=success, value < 0 if request failed */ - char *pszContentType; /* Content-Type of the response */ - char *pszErrBuf; /* Buffer where curl can write errors */ - char *pszPostRequest; /* post request content (NULL for GET) */ - char *pszPostContentType;/* post request MIME type */ - char *pszUserAgent; /* User-Agent, auto-generated if not set */ - char *pszHTTPCookieData; /* HTTP Cookie data */ - - char *pszProxyAddress; /* The address (IP or hostname) of proxy svr */ - long nProxyPort; /* The proxy's port */ - enum MS_HTTP_PROXY_TYPE eProxyType; /* The type of proxy */ - enum MS_HTTP_AUTH_TYPE eProxyAuthType; /* Auth method against proxy */ - char *pszProxyUsername; /* Proxy authentication username */ - char *pszProxyPassword; /* Proxy authentication password */ - - enum MS_HTTP_AUTH_TYPE eHttpAuthType; /* HTTP Authentication type */ - char *pszHttpUsername; /* HTTP Authentication username */ - char *pszHttpPassword; /* HTTP Authentication password */ - - /* For debugging/profiling */ - int debug; /* Debug mode? MS_TRUE/MS_FALSE */ - - /* Private members */ - void * curl_handle; /* CURLM * handle */ - FILE * fp; /* FILE * used during download */ - - char * result_data; /* output if pszOutputFile is NULL */ - int result_size; - int result_buf_size; - - } httpRequestObj; +#define MS_HTTP_SUCCESS(status) (status == 200 || status == 242) + +enum MS_HTTP_PROXY_TYPE { MS_HTTP, MS_SOCKS5 }; + +enum MS_HTTP_AUTH_TYPE { MS_BASIC, MS_DIGEST, MS_NTLM, MS_ANY, MS_ANYSAFE }; + +typedef struct http_request_info { + int nLayerId; + char *pszGetUrl; + char *pszOutputFile; + int nTimeout; + int nMaxBytes; + rectObj bbox; + int width; + int height; + int nStatus; /* 200=success, value < 0 if request failed */ + char *pszContentType; /* Content-Type of the response */ + char *pszErrBuf; /* Buffer where curl can write errors */ + char *pszPostRequest; /* post request content (NULL for GET) */ + char *pszPostContentType; /* post request MIME type */ + char *pszUserAgent; /* User-Agent, auto-generated if not set */ + char *pszHTTPCookieData; /* HTTP Cookie data */ + + char *pszProxyAddress; /* The address (IP or hostname) of proxy svr */ + long nProxyPort; /* The proxy's port */ + enum MS_HTTP_PROXY_TYPE eProxyType; /* The type of proxy */ + enum MS_HTTP_AUTH_TYPE eProxyAuthType; /* Auth method against proxy */ + char *pszProxyUsername; /* Proxy authentication username */ + char *pszProxyPassword; /* Proxy authentication password */ + + enum MS_HTTP_AUTH_TYPE eHttpAuthType; /* HTTP Authentication type */ + char *pszHttpUsername; /* HTTP Authentication username */ + char *pszHttpPassword; /* HTTP Authentication password */ + + /* For debugging/profiling */ + int debug; /* Debug mode? MS_TRUE/MS_FALSE */ + + /* Private members */ + void *curl_handle; /* CURLM * handle */ + FILE *fp; /* FILE * used during download */ + + char *result_data; /* output if pszOutputFile is NULL */ + int result_size; + int result_buf_size; + +} httpRequestObj; #ifdef USE_CURL - int msHTTPInit(void); - void msHTTPCleanup(void); +int msHTTPInit(void); +void msHTTPCleanup(void); - void msHTTPInitRequestObj(httpRequestObj *pasReqInfo, int numRequests); - void msHTTPFreeRequestObj(httpRequestObj *pasReqInfo, int numRequests); - int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, - int bCheckLocalCache); - int msHTTPGetFile(const char *pszGetUrl, const char *pszOutputFile, - int *pnHTTPStatus, int nTimeout, int bCheckLocalCache, - int bDebug, int nMaxBytes); +void msHTTPInitRequestObj(httpRequestObj *pasReqInfo, int numRequests); +void msHTTPFreeRequestObj(httpRequestObj *pasReqInfo, int numRequests); +int msHTTPExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, + int bCheckLocalCache); +int msHTTPGetFile(const char *pszGetUrl, const char *pszOutputFile, + int *pnHTTPStatus, int nTimeout, int bCheckLocalCache, + int bDebug, int nMaxBytes); - int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, - httpRequestObj *pasReqInfo, int numRequests, - mapObj *map, const char* namespaces); +int msHTTPAuthProxySetup(hashTableObj *mapmd, hashTableObj *lyrmd, + httpRequestObj *pasReqInfo, int numRequests, + mapObj *map, const char *namespaces); #endif /*USE_CURL*/ #ifdef __cplusplus } #endif - - - #endif /* MAPHTTP_H */ diff --git a/mapiconv.c b/mapiconv.c index b0d9de7430..96512e4c2c 100644 --- a/mapiconv.c +++ b/mapiconv.c @@ -28,9 +28,7 @@ #include "mapiconv.h" -size_t msIconv(iconv_t cd, - char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft) -{ - return iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); +size_t msIconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, + size_t *outbytesleft) { + return iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); } diff --git a/mapiconv.h b/mapiconv.h index cbc25b5dff..4eb752c74e 100644 --- a/mapiconv.h +++ b/mapiconv.h @@ -36,9 +36,8 @@ extern "C" { #include /* Wrapper of iconv() to be used from C++ */ -size_t msIconv(iconv_t cd, - char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); +size_t msIconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, + size_t *outbytesleft); #ifdef __cplusplus } diff --git a/mapimageio.c b/mapimageio.c index 215a0f9146..f962dd28e1 100644 --- a/mapimageio.c +++ b/mapimageio.c @@ -38,30 +38,24 @@ #include #endif - - typedef struct _streamInfo { FILE *fp; bufferObj *buffer; } streamInfo; -static -void png_write_data_to_stream(png_structp png_ptr, png_bytep data, png_size_t length) -{ - FILE *fp = ((streamInfo*)png_get_io_ptr(png_ptr))->fp; - msIO_fwrite(data,length,1,fp); +static void png_write_data_to_stream(png_structp png_ptr, png_bytep data, + png_size_t length) { + FILE *fp = ((streamInfo *)png_get_io_ptr(png_ptr))->fp; + msIO_fwrite(data, length, 1, fp); } -static -void png_write_data_to_buffer(png_structp png_ptr, png_bytep data, png_size_t length) -{ - bufferObj *buffer = ((streamInfo*)png_get_io_ptr(png_ptr))->buffer; - msBufferAppend(buffer,data,length); +static void png_write_data_to_buffer(png_structp png_ptr, png_bytep data, + png_size_t length) { + bufferObj *buffer = ((streamInfo *)png_get_io_ptr(png_ptr))->buffer; + msBufferAppend(buffer, data, length); } -static -void png_flush_data(png_structp png_ptr) -{ +static void png_flush_data(png_structp png_ptr) { (void)png_ptr; /* do nothing */ } @@ -83,123 +77,116 @@ typedef struct { #define OUTPUT_BUF_SIZE 4096 -static void -jpeg_init_destination (j_compress_ptr cinfo) -{ - ms_destination_mgr *dest = (ms_destination_mgr*) cinfo->dest; +static void jpeg_init_destination(j_compress_ptr cinfo) { + ms_destination_mgr *dest = (ms_destination_mgr *)cinfo->dest; /* Allocate the output buffer --- it will be released when done with image */ - dest->data = (unsigned char *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - OUTPUT_BUF_SIZE * sizeof (unsigned char)); + dest->data = (unsigned char *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * sizeof(unsigned char)); dest->pub.next_output_byte = dest->data; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } -static -void jpeg_stream_term_destination (j_compress_ptr cinfo) -{ - ms_stream_destination_mgr *dest = (ms_stream_destination_mgr*) cinfo->dest; - msIO_fwrite(dest->mgr.data, OUTPUT_BUF_SIZE-dest->mgr.pub.free_in_buffer, 1, dest->stream); +static void jpeg_stream_term_destination(j_compress_ptr cinfo) { + ms_stream_destination_mgr *dest = (ms_stream_destination_mgr *)cinfo->dest; + msIO_fwrite(dest->mgr.data, OUTPUT_BUF_SIZE - dest->mgr.pub.free_in_buffer, 1, + dest->stream); dest->mgr.pub.next_output_byte = dest->mgr.data; dest->mgr.pub.free_in_buffer = OUTPUT_BUF_SIZE; } -static -void jpeg_buffer_term_destination (j_compress_ptr cinfo) -{ - ms_buffer_destination_mgr *dest = (ms_buffer_destination_mgr*) cinfo->dest; - msBufferAppend(dest->buffer, dest->mgr.data, OUTPUT_BUF_SIZE-dest->mgr.pub.free_in_buffer); +static void jpeg_buffer_term_destination(j_compress_ptr cinfo) { + ms_buffer_destination_mgr *dest = (ms_buffer_destination_mgr *)cinfo->dest; + msBufferAppend(dest->buffer, dest->mgr.data, + OUTPUT_BUF_SIZE - dest->mgr.pub.free_in_buffer); dest->mgr.pub.next_output_byte = dest->mgr.data; dest->mgr.pub.free_in_buffer = OUTPUT_BUF_SIZE; } -static -boolean jpeg_stream_empty_output_buffer (j_compress_ptr cinfo) -{ - ms_stream_destination_mgr *dest = (ms_stream_destination_mgr*) cinfo->dest; +static boolean jpeg_stream_empty_output_buffer(j_compress_ptr cinfo) { + ms_stream_destination_mgr *dest = (ms_stream_destination_mgr *)cinfo->dest; msIO_fwrite(dest->mgr.data, OUTPUT_BUF_SIZE, 1, dest->stream); dest->mgr.pub.next_output_byte = dest->mgr.data; dest->mgr.pub.free_in_buffer = OUTPUT_BUF_SIZE; return TRUE; } -static -boolean jpeg_buffer_empty_output_buffer (j_compress_ptr cinfo) -{ - ms_buffer_destination_mgr *dest = (ms_buffer_destination_mgr*) cinfo->dest; +static boolean jpeg_buffer_empty_output_buffer(j_compress_ptr cinfo) { + ms_buffer_destination_mgr *dest = (ms_buffer_destination_mgr *)cinfo->dest; msBufferAppend(dest->buffer, dest->mgr.data, OUTPUT_BUF_SIZE); dest->mgr.pub.next_output_byte = dest->mgr.data; dest->mgr.pub.free_in_buffer = OUTPUT_BUF_SIZE; return TRUE; } -static void msJPEGErrorExit(j_common_ptr cinfo) -{ - jmp_buf* pJmpBuffer = (jmp_buf* ) cinfo->client_data; - char buffer[JMSG_LENGTH_MAX]; +static void msJPEGErrorExit(j_common_ptr cinfo) { + jmp_buf *pJmpBuffer = (jmp_buf *)cinfo->client_data; + char buffer[JMSG_LENGTH_MAX]; - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); + /* Create the message */ + (*cinfo->err->format_message)(cinfo, buffer); - msSetError(MS_MISCERR,"libjpeg: %s","jpeg_ErrorExit()", buffer); + msSetError(MS_MISCERR, "libjpeg: %s", "jpeg_ErrorExit()", buffer); - /* Return control to the setjmp point */ - longjmp(*pJmpBuffer, 1); + /* Return control to the setjmp point */ + longjmp(*pJmpBuffer, 1); } int saveAsJPEG(mapObj *map, rasterBufferObj *rb, streamInfo *info, - outputFormatObj *format) -{ + outputFormatObj *format) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; int quality; - const char* pszOptimized; + const char *pszOptimized; int optimized; int arithmetic; ms_destination_mgr *dest; JSAMPLE *rowdata = NULL; unsigned int row; jmp_buf setjmp_buffer; - - quality = atoi(msGetOutputFormatOption( format, "QUALITY", "75")); - pszOptimized = msGetOutputFormatOption( format, "OPTIMIZED", "YES"); + + quality = atoi(msGetOutputFormatOption(format, "QUALITY", "75")); + pszOptimized = msGetOutputFormatOption(format, "OPTIMIZED", "YES"); optimized = EQUAL(pszOptimized, "YES") || EQUAL(pszOptimized, "ON") || EQUAL(pszOptimized, "TRUE"); arithmetic = EQUAL(pszOptimized, "ARITHMETIC"); - if (setjmp(setjmp_buffer)) - { - jpeg_destroy_compress(&cinfo); - free(rowdata); - return MS_FAILURE; + if (setjmp(setjmp_buffer)) { + jpeg_destroy_compress(&cinfo); + free(rowdata); + return MS_FAILURE; } cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = msJPEGErrorExit; - cinfo.client_data = (void *) &(setjmp_buffer); + cinfo.client_data = (void *)&(setjmp_buffer); jpeg_create_compress(&cinfo); if (cinfo.dest == NULL) { - if(info->fp) { - cinfo.dest = (struct jpeg_destination_mgr *) - (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, - sizeof (ms_stream_destination_mgr)); - ((ms_stream_destination_mgr*)cinfo.dest)->mgr.pub.empty_output_buffer = jpeg_stream_empty_output_buffer; - ((ms_stream_destination_mgr*)cinfo.dest)->mgr.pub.term_destination = jpeg_stream_term_destination; - ((ms_stream_destination_mgr*)cinfo.dest)->stream = info->fp; + if (info->fp) { + cinfo.dest = (struct jpeg_destination_mgr *)(*cinfo.mem->alloc_small)( + (j_common_ptr)&cinfo, JPOOL_PERMANENT, + sizeof(ms_stream_destination_mgr)); + ((ms_stream_destination_mgr *)cinfo.dest)->mgr.pub.empty_output_buffer = + jpeg_stream_empty_output_buffer; + ((ms_stream_destination_mgr *)cinfo.dest)->mgr.pub.term_destination = + jpeg_stream_term_destination; + ((ms_stream_destination_mgr *)cinfo.dest)->stream = info->fp; } else { - cinfo.dest = (struct jpeg_destination_mgr *) - (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, - sizeof (ms_buffer_destination_mgr)); - ((ms_buffer_destination_mgr*)cinfo.dest)->mgr.pub.empty_output_buffer = jpeg_buffer_empty_output_buffer; - ((ms_buffer_destination_mgr*)cinfo.dest)->mgr.pub.term_destination = jpeg_buffer_term_destination; - ((ms_buffer_destination_mgr*)cinfo.dest)->buffer = info->buffer; + cinfo.dest = (struct jpeg_destination_mgr *)(*cinfo.mem->alloc_small)( + (j_common_ptr)&cinfo, JPOOL_PERMANENT, + sizeof(ms_buffer_destination_mgr)); + ((ms_buffer_destination_mgr *)cinfo.dest)->mgr.pub.empty_output_buffer = + jpeg_buffer_empty_output_buffer; + ((ms_buffer_destination_mgr *)cinfo.dest)->mgr.pub.term_destination = + jpeg_buffer_term_destination; + ((ms_buffer_destination_mgr *)cinfo.dest)->buffer = info->buffer; } } - dest = (ms_destination_mgr*) cinfo.dest; + dest = (ms_destination_mgr *)cinfo.dest; dest->pub.init_destination = jpeg_init_destination; cinfo.image_width = rb->width; @@ -208,43 +195,47 @@ int saveAsJPEG(mapObj *map, rasterBufferObj *rb, streamInfo *info, cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); - if( arithmetic ) + if (arithmetic) cinfo.arith_code = TRUE; - else if( optimized ) + else if (optimized) cinfo.optimize_coding = TRUE; - if( arithmetic || optimized ) { + if (arithmetic || optimized) { /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ /* store implementation, so better not set max_memory_to_use ourselves. */ /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ - if( cinfo.mem->max_memory_to_use > 0 ) { + if (cinfo.mem->max_memory_to_use > 0) { if (map == NULL || msGetConfigOption(map, "JPEGMEM") == NULL) { - /* If the user doesn't provide a value for JPEGMEM, we want to be sure */ - /* that at least the image size will be used before creating the temporary file */ + /* If the user doesn't provide a value for JPEGMEM, we want to be sure + */ + /* that at least the image size will be used before creating the + * temporary file */ cinfo.mem->max_memory_to_use = - MS_MAX(cinfo.mem->max_memory_to_use, cinfo.input_components * rb->width * rb->height); + MS_MAX(cinfo.mem->max_memory_to_use, + cinfo.input_components * rb->width * rb->height); } } } jpeg_start_compress(&cinfo, TRUE); - rowdata = (JSAMPLE*)malloc(rb->width*cinfo.input_components*sizeof(JSAMPLE)); + rowdata = + (JSAMPLE *)malloc(rb->width * cinfo.input_components * sizeof(JSAMPLE)); - for(row=0; rowheight; row++) { + for (row = 0; row < rb->height; row++) { JSAMPLE *pixptr = rowdata; - unsigned char *r,*g,*b; - r=rb->data.rgba.r+row*rb->data.rgba.row_step; - g=rb->data.rgba.g+row*rb->data.rgba.row_step; - b=rb->data.rgba.b+row*rb->data.rgba.row_step; - for(unsigned col=0; colwidth; col++) { + unsigned char *r, *g, *b; + r = rb->data.rgba.r + row * rb->data.rgba.row_step; + g = rb->data.rgba.g + row * rb->data.rgba.row_step; + b = rb->data.rgba.b + row * rb->data.rgba.row_step; + for (unsigned col = 0; col < rb->width; col++) { *(pixptr++) = *r; *(pixptr++) = *g; *(pixptr++) = *b; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; } - (void) jpeg_write_scanlines(&cinfo, &rowdata, 1); + (void)jpeg_write_scanlines(&cinfo, &rowdata, 1); } /* Step 6: Finish compression */ @@ -256,10 +247,11 @@ int saveAsJPEG(mapObj *map, rasterBufferObj *rb, streamInfo *info, } /* - * sort a given list of rgba entries so that all the opaque pixels are at the end + * sort a given list of rgba entries so that all the opaque pixels are at the + * end */ -int remapPaletteForPNG(rasterBufferObj *rb, rgbPixel *rgb, unsigned char *a, int *num_a) -{ +int remapPaletteForPNG(rasterBufferObj *rb, rgbPixel *rgb, unsigned char *a, + int *num_a) { int bot_idx, top_idx; unsigned x; int remap[256]; @@ -275,7 +267,8 @@ int remapPaletteForPNG(rasterBufferObj *rb, rgbPixel *rgb, unsigned char *a, int ** --not that this should matter to anyone. */ - for (top_idx = (int)rb->data.palette.num_entries-1, bot_idx = x = 0; x < rb->data.palette.num_entries; ++x) { + for (top_idx = (int)rb->data.palette.num_entries - 1, bot_idx = x = 0; + x < rb->data.palette.num_entries; ++x) { if (rb->data.palette.palette[x].a == maxval) remap[x] = top_idx--; else @@ -283,50 +276,53 @@ int remapPaletteForPNG(rasterBufferObj *rb, rgbPixel *rgb, unsigned char *a, int } /* sanity check: top and bottom indices should have just crossed paths */ if (bot_idx != top_idx + 1) { - msSetError(MS_MISCERR,"quantization sanity check failed","createPNGPalette()"); + msSetError(MS_MISCERR, "quantization sanity check failed", + "createPNGPalette()"); return MS_FAILURE; } *num_a = bot_idx; - for(x=0; xwidth*rb->height; x++) + for (x = 0; x < rb->width * rb->height; x++) rb->data.palette.pixels[x] = remap[rb->data.palette.pixels[x]]; - for (x = 0; x < rb->data.palette.num_entries; ++x) { - if(maxval == 255) { + if (maxval == 255) { a[remap[x]] = rb->data.palette.palette[x].a; rgb[remap[x]].r = rb->data.palette.palette[x].r; rgb[remap[x]].g = rb->data.palette.palette[x].g; rgb[remap[x]].b = rb->data.palette.palette[x].b; } else { /* rescale palette */ - rgb[remap[x]].r = (rb->data.palette.palette[x].r * 255 + (maxval >> 1)) / maxval; - rgb[remap[x]].g = (rb->data.palette.palette[x].g * 255 + (maxval >> 1)) / maxval; - rgb[remap[x]].b = (rb->data.palette.palette[x].b * 255 + (maxval >> 1)) / maxval; - a[remap[x]] = (rb->data.palette.palette[x].a * 255 + (maxval >> 1)) / maxval; + rgb[remap[x]].r = + (rb->data.palette.palette[x].r * 255 + (maxval >> 1)) / maxval; + rgb[remap[x]].g = + (rb->data.palette.palette[x].g * 255 + (maxval >> 1)) / maxval; + rgb[remap[x]].b = + (rb->data.palette.palette[x].b * 255 + (maxval >> 1)) / maxval; + a[remap[x]] = + (rb->data.palette.palette[x].a * 255 + (maxval >> 1)) / maxval; } - if(a[remap[x]] != 255) { + if (a[remap[x]] != 255) { /* un-premultiply pixels */ - double da = 255.0/a[remap[x]]; - rgb[remap[x]].r *= da; - rgb[remap[x]].g *= da; - rgb[remap[x]].b *= da; + double da = 255.0 / a[remap[x]]; + rgb[remap[x]].r *= da; + rgb[remap[x]].g *= da; + rgb[remap[x]].b *= da; } } return MS_SUCCESS; } -int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) -{ +int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) { png_infop info_ptr; rgbPixel rgb[256]; unsigned char a[256]; int num_a; int sample_depth; - png_structp png_ptr = png_create_write_struct( - PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); + png_structp png_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); assert(rb->type == MS_BUFFER_BYTE_PALETTE); @@ -334,12 +330,11 @@ int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) return (MS_FAILURE); png_set_compression_level(png_ptr, compression); - png_set_filter (png_ptr,0, PNG_FILTER_NONE); + png_set_filter(png_ptr, 0, PNG_FILTER_NONE); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, - (png_infopp)NULL); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return (MS_FAILURE); } @@ -347,11 +342,10 @@ int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) png_destroy_write_struct(&png_ptr, &info_ptr); return (MS_FAILURE); } - if(info->fp) - png_set_write_fn(png_ptr,info, png_write_data_to_stream, png_flush_data); + if (info->fp) + png_set_write_fn(png_ptr, info, png_write_data_to_stream, png_flush_data); else - png_set_write_fn(png_ptr,info, png_write_data_to_buffer, png_flush_data); - + png_set_write_fn(png_ptr, info, png_write_data_to_buffer, png_flush_data); if (rb->data.palette.num_entries <= 2) sample_depth = 1; @@ -362,22 +356,22 @@ int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) else sample_depth = 8; - png_set_IHDR(png_ptr, info_ptr, rb->width, rb->height, - sample_depth, PNG_COLOR_TYPE_PALETTE, - 0, PNG_COMPRESSION_TYPE_DEFAULT, + png_set_IHDR(png_ptr, info_ptr, rb->width, rb->height, sample_depth, + PNG_COLOR_TYPE_PALETTE, 0, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - remapPaletteForPNG(rb,rgb,a,&num_a); + remapPaletteForPNG(rb, rgb, a, &num_a); - png_set_PLTE(png_ptr, info_ptr, (png_colorp)(rgb),rb->data.palette.num_entries); - if(num_a) - png_set_tRNS(png_ptr, info_ptr, a,num_a, NULL); + png_set_PLTE(png_ptr, info_ptr, (png_colorp)(rgb), + rb->data.palette.num_entries); + if (num_a) + png_set_tRNS(png_ptr, info_ptr, a, num_a, NULL); png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); - for(unsigned row=0; rowheight; row++) { - unsigned char *rowptr = &(rb->data.palette.pixels[row*rb->width]); + for (unsigned row = 0; row < rb->height; row++) { + unsigned char *rowptr = &(rb->data.palette.pixels[row * rb->width]); png_write_row(png_ptr, rowptr); } png_write_end(png_ptr, info_ptr); @@ -385,38 +379,45 @@ int savePalettePNG(rasterBufferObj *rb, streamInfo *info, int compression) return MS_SUCCESS; } -int readPalette(const char *palette, rgbaPixel *entries, unsigned int *nEntries, int useAlpha) -{ +int readPalette(const char *palette, rgbaPixel *entries, unsigned int *nEntries, + int useAlpha) { FILE *stream = NULL; char buffer[MS_BUFFER_LENGTH]; *nEntries = 0; stream = fopen(palette, "r"); - if(!stream) { - msSetError(MS_IOERR, "Error opening palette file %s.", "readPalette()", palette); + if (!stream) { + msSetError(MS_IOERR, "Error opening palette file %s.", "readPalette()", + palette); return MS_FAILURE; } - while(fgets(buffer, MS_BUFFER_LENGTH, stream) && *nEntries<256) { - int r,g,b,a = 0; + while (fgets(buffer, MS_BUFFER_LENGTH, stream) && *nEntries < 256) { + int r, g, b, a = 0; /* while there are colors to load */ - if(buffer[0] == '#' || buffer[0] == '\n' || buffer[0] == '\r') + if (buffer[0] == '#' || buffer[0] == '\n' || buffer[0] == '\r') continue; /* skip comments and blank lines */ - if(!useAlpha) { - if(3 != sscanf(buffer,"%d,%d,%d\n",&r,&g,&b)) { + if (!useAlpha) { + if (3 != sscanf(buffer, "%d,%d,%d\n", &r, &g, &b)) { fclose(stream); - msSetError(MS_MISCERR,"failed to parse color %d r,g,b triplet in line \"%s\" from file %s","readPalette()",*nEntries+1,buffer,palette); + msSetError(MS_MISCERR, + "failed to parse color %d r,g,b triplet in line \"%s\" from " + "file %s", + "readPalette()", *nEntries + 1, buffer, palette); return MS_FAILURE; } } else { - if(4 != sscanf(buffer,"%d,%d,%d,%d\n",&r,&g,&b,&a)) { + if (4 != sscanf(buffer, "%d,%d,%d,%d\n", &r, &g, &b, &a)) { fclose(stream); - msSetError(MS_MISCERR,"failed to parse color %d r,g,b,a quadruplet in line \"%s\" from file %s","readPalette()",*nEntries+1,buffer,palette); + msSetError(MS_MISCERR, + "failed to parse color %d r,g,b,a quadruplet in line \"%s\" " + "from file %s", + "readPalette()", *nEntries + 1, buffer, palette); return MS_FAILURE; } } - if(useAlpha && a != 255) { - double da = a/255.0; + if (useAlpha && a != 255) { + double da = a / 255.0; entries[*nEntries].r = r * da; entries[*nEntries].g = g * da; entries[*nEntries].b = b * da; @@ -433,100 +434,113 @@ int readPalette(const char *palette, rgbaPixel *entries, unsigned int *nEntries, return MS_SUCCESS; } -int saveAsPNG(mapObj *map,rasterBufferObj *rb, streamInfo *info, outputFormatObj *format) -{ +int saveAsPNG(mapObj *map, rasterBufferObj *rb, streamInfo *info, + outputFormatObj *format) { int force_pc256 = MS_FALSE; int force_palette = MS_FALSE; - const char *force_string,*zlib_compression; + const char *force_string, *zlib_compression; int compression = -1; - zlib_compression = msGetOutputFormatOption( format, "COMPRESSION", NULL); - if(zlib_compression && *zlib_compression) { + zlib_compression = msGetOutputFormatOption(format, "COMPRESSION", NULL); + if (zlib_compression && *zlib_compression) { char *endptr; - compression = strtol(zlib_compression,&endptr,10); - if(*endptr || compression<-1 || compression>9) { - msSetError(MS_MISCERR,"failed to parse FORMATOPTION \"COMPRESSION=%s\", expecting integer from 0 to 9.","saveAsPNG()",zlib_compression); + compression = strtol(zlib_compression, &endptr, 10); + if (*endptr || compression < -1 || compression > 9) { + msSetError(MS_MISCERR, + "failed to parse FORMATOPTION \"COMPRESSION=%s\", expecting " + "integer from 0 to 9.", + "saveAsPNG()", zlib_compression); return MS_FAILURE; } } - - force_string = msGetOutputFormatOption( format, "QUANTIZE_FORCE", NULL ); - if( force_string && (strcasecmp(force_string,"on") == 0 || strcasecmp(force_string,"yes") == 0 || strcasecmp(force_string,"true") == 0) ) + force_string = msGetOutputFormatOption(format, "QUANTIZE_FORCE", NULL); + if (force_string && (strcasecmp(force_string, "on") == 0 || + strcasecmp(force_string, "yes") == 0 || + strcasecmp(force_string, "true") == 0)) force_pc256 = MS_TRUE; - force_string = msGetOutputFormatOption( format, "PALETTE_FORCE", NULL ); - if( force_string && (strcasecmp(force_string,"on") == 0 || strcasecmp(force_string,"yes") == 0 || strcasecmp(force_string,"true") == 0) ) + force_string = msGetOutputFormatOption(format, "PALETTE_FORCE", NULL); + if (force_string && (strcasecmp(force_string, "on") == 0 || + strcasecmp(force_string, "yes") == 0 || + strcasecmp(force_string, "true") == 0)) force_palette = MS_TRUE; - if(force_pc256 || force_palette) { + if (force_pc256 || force_palette) { rasterBufferObj qrb; rgbaPixel palette[256], paletteGiven[256]; unsigned int numPaletteGivenEntries; - memset(&qrb,0,sizeof(rasterBufferObj)); + memset(&qrb, 0, sizeof(rasterBufferObj)); qrb.type = MS_BUFFER_BYTE_PALETTE; qrb.width = rb->width; qrb.height = rb->height; - qrb.data.palette.pixels = (unsigned char*)malloc(qrb.width*qrb.height*sizeof(unsigned char)); + qrb.data.palette.pixels = + (unsigned char *)malloc(qrb.width * qrb.height * sizeof(unsigned char)); qrb.data.palette.scaling_maxval = 255; int ret; - if(force_pc256) { + if (force_pc256) { qrb.data.palette.palette = palette; - qrb.data.palette.num_entries = atoi(msGetOutputFormatOption( format, "QUANTIZE_COLORS", "256")); - ret = msQuantizeRasterBuffer(rb,&(qrb.data.palette.num_entries),qrb.data.palette.palette, - NULL, 0, + qrb.data.palette.num_entries = + atoi(msGetOutputFormatOption(format, "QUANTIZE_COLORS", "256")); + ret = msQuantizeRasterBuffer(rb, &(qrb.data.palette.num_entries), + qrb.data.palette.palette, NULL, 0, &qrb.data.palette.scaling_maxval); } else { - unsigned colorsWanted = (unsigned)atoi(msGetOutputFormatOption( format, "QUANTIZE_COLORS", "0")); - const char *palettePath = msGetOutputFormatOption( format, "PALETTE", "palette.txt"); + unsigned colorsWanted = (unsigned)atoi( + msGetOutputFormatOption(format, "QUANTIZE_COLORS", "0")); + const char *palettePath = + msGetOutputFormatOption(format, "PALETTE", "palette.txt"); char szPath[MS_MAXPATHLEN]; - if(map) { + if (map) { msBuildPath(szPath, map->mappath, palettePath); palettePath = szPath; } - if(readPalette(palettePath,paletteGiven,&numPaletteGivenEntries,format->transparent) != MS_SUCCESS) { + if (readPalette(palettePath, paletteGiven, &numPaletteGivenEntries, + format->transparent) != MS_SUCCESS) { return MS_FAILURE; } - if(numPaletteGivenEntries == 256 || colorsWanted == 0) { + if (numPaletteGivenEntries == 256 || colorsWanted == 0) { qrb.data.palette.palette = paletteGiven; qrb.data.palette.num_entries = numPaletteGivenEntries; ret = MS_SUCCESS; - /* we have a full palette and don't want an additional quantization step */ + /* we have a full palette and don't want an additional quantization step + */ } else { /* quantize the image, and mix our colours in the resulting palette */ qrb.data.palette.palette = palette; - qrb.data.palette.num_entries = MS_MAX(colorsWanted,numPaletteGivenEntries); - ret = msQuantizeRasterBuffer(rb,&(qrb.data.palette.num_entries),qrb.data.palette.palette, - paletteGiven,numPaletteGivenEntries, + qrb.data.palette.num_entries = + MS_MAX(colorsWanted, numPaletteGivenEntries); + ret = msQuantizeRasterBuffer(rb, &(qrb.data.palette.num_entries), + qrb.data.palette.palette, paletteGiven, + numPaletteGivenEntries, &qrb.data.palette.scaling_maxval); } } - if(ret != MS_FAILURE) { - msClassifyRasterBuffer(rb,&qrb); - ret = savePalettePNG(&qrb,info,compression); + if (ret != MS_FAILURE) { + msClassifyRasterBuffer(rb, &qrb); + ret = savePalettePNG(&qrb, info, compression); } msFree(qrb.data.palette.pixels); return ret; - } else if(rb->type == MS_BUFFER_BYTE_RGBA) { + } else if (rb->type == MS_BUFFER_BYTE_RGBA) { png_infop info_ptr; int color_type; unsigned int *rowdata; - png_structp png_ptr = png_create_write_struct( - PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); + png_structp png_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return (MS_FAILURE); png_set_compression_level(png_ptr, compression); - png_set_filter (png_ptr,0, PNG_FILTER_NONE); + png_set_filter(png_ptr, 0, PNG_FILTER_NONE); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, - (png_infopp)NULL); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return (MS_FAILURE); } @@ -534,73 +548,72 @@ int saveAsPNG(mapObj *map,rasterBufferObj *rb, streamInfo *info, outputFormatObj png_destroy_write_struct(&png_ptr, &info_ptr); return (MS_FAILURE); } - if(info->fp) - png_set_write_fn(png_ptr,info, png_write_data_to_stream, png_flush_data); + if (info->fp) + png_set_write_fn(png_ptr, info, png_write_data_to_stream, png_flush_data); else - png_set_write_fn(png_ptr,info, png_write_data_to_buffer, png_flush_data); + png_set_write_fn(png_ptr, info, png_write_data_to_buffer, png_flush_data); - if(rb->data.rgba.a) + if (rb->data.rgba.a) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; - png_set_IHDR(png_ptr, info_ptr, rb->width, rb->height, - 8, color_type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(png_ptr, info_ptr, rb->width, rb->height, 8, color_type, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); - if(!rb->data.rgba.a && rb->data.rgba.pixel_step==4) + if (!rb->data.rgba.a && rb->data.rgba.pixel_step == 4) png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - rowdata = (unsigned int*)malloc(rb->width*sizeof(unsigned int)); - for(unsigned row=0; rowheight; row++) { + rowdata = (unsigned int *)malloc(rb->width * sizeof(unsigned int)); + for (unsigned row = 0; row < rb->height; row++) { unsigned int *pixptr = rowdata; - unsigned char *a,*r,*g,*b; - r=rb->data.rgba.r+row*rb->data.rgba.row_step; - g=rb->data.rgba.g+row*rb->data.rgba.row_step; - b=rb->data.rgba.b+row*rb->data.rgba.row_step; - if(rb->data.rgba.a) { - a=rb->data.rgba.a+row*rb->data.rgba.row_step; - for(unsigned col=0; colwidth; col++) { - if(*a) { - double da = *a/255.0; - unsigned char *pix = (unsigned char*)pixptr; - pix[0] = *r/da; - pix[1] = *g/da; - pix[2] = *b/da; + unsigned char *a, *r, *g, *b; + r = rb->data.rgba.r + row * rb->data.rgba.row_step; + g = rb->data.rgba.g + row * rb->data.rgba.row_step; + b = rb->data.rgba.b + row * rb->data.rgba.row_step; + if (rb->data.rgba.a) { + a = rb->data.rgba.a + row * rb->data.rgba.row_step; + for (unsigned col = 0; col < rb->width; col++) { + if (*a) { + double da = *a / 255.0; + unsigned char *pix = (unsigned char *)pixptr; + pix[0] = *r / da; + pix[1] = *g / da; + pix[2] = *b / da; pix[3] = *a; } else { - *pixptr=0; + *pixptr = 0; } pixptr++; - a+=rb->data.rgba.pixel_step; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; + a += rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; } } else { - for(unsigned col=0; colwidth; col++) { - unsigned char *pix = (unsigned char*)pixptr; + for (unsigned col = 0; col < rb->width; col++) { + unsigned char *pix = (unsigned char *)pixptr; pix[0] = *r; pix[1] = *g; pix[2] = *b; pixptr++; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; } } - png_write_row(png_ptr,(png_bytep)rowdata); - + png_write_row(png_ptr, (png_bytep)rowdata); } png_write_end(png_ptr, info_ptr); free(rowdata); png_destroy_write_struct(&png_ptr, &info_ptr); return MS_SUCCESS; } else { - msSetError(MS_MISCERR,"Unknown buffer type","saveAsPNG()"); + msSetError(MS_MISCERR, "Unknown buffer type", "saveAsPNG()"); return MS_FAILURE; } } @@ -612,60 +625,58 @@ int saveAsPNG(mapObj *map,rasterBufferObj *rb, streamInfo *info, outputFormatObj #define SEEK_SET 0 #endif /* SEEK_SET */ - -int readPNG(char *path, rasterBufferObj *rb) -{ - png_uint_32 width,height; - unsigned char *a,*r,*g,*b; - int bit_depth,color_type; +int readPNG(char *path, rasterBufferObj *rb) { + png_uint_32 width, height; + unsigned char *a, *r, *g, *b; + int bit_depth, color_type; unsigned char **row_pointers; png_structp png_ptr = NULL; png_infop info_ptr = NULL; - FILE *stream = fopen(path,"rb"); - if(!stream) + FILE *stream = fopen(path, "rb"); + if (!stream) return MS_FAILURE; /* could pass pointers to user-defined error handlers instead of NULLs: */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(stream); - return MS_FAILURE; /* out of memory */ + return MS_FAILURE; /* out of memory */ } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(stream); - return MS_FAILURE; /* out of memory */ + return MS_FAILURE; /* out of memory */ } - if(setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr,&info_ptr,NULL); + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(stream); return MS_FAILURE; } - png_init_io(png_ptr,stream); - png_read_info(png_ptr,info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, - &bit_depth, &color_type, - NULL,NULL,NULL); + png_init_io(png_ptr, stream); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + NULL, NULL, NULL); rb->width = width; rb->height = height; rb->type = MS_BUFFER_BYTE_RGBA; - rb->data.rgba.pixels = (unsigned char*)malloc(width*height*4*sizeof(unsigned char)); - row_pointers = (unsigned char**)malloc(height*sizeof(unsigned char*)); - rb->data.rgba.pixel_step=4; - rb->data.rgba.row_step = width*4; + rb->data.rgba.pixels = + (unsigned char *)malloc(width * height * 4 * sizeof(unsigned char)); + row_pointers = (unsigned char **)malloc(height * sizeof(unsigned char *)); + rb->data.rgba.pixel_step = 4; + rb->data.rgba.row_step = width * 4; b = rb->data.rgba.b = &rb->data.rgba.pixels[0]; g = rb->data.rgba.g = &rb->data.rgba.pixels[1]; r = rb->data.rgba.r = &rb->data.rgba.pixels[2]; a = rb->data.rgba.a = &rb->data.rgba.pixels[3]; - for(unsigned i=0; idata.rgba.pixels[i*rb->data.rgba.row_step]); + for (unsigned i = 0; i < height; i++) { + row_pointers[i] = &(rb->data.rgba.pixels[i * rb->data.rgba.row_step]); } if (color_type == PNG_COLOR_TYPE_PALETTE) @@ -695,68 +706,67 @@ int readPNG(char *path, rasterBufferObj *rb) png_read_image(png_ptr, row_pointers); free(row_pointers); - row_pointers=NULL; - png_read_end(png_ptr,NULL); + row_pointers = NULL; + png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); /*premultiply data*/ - for(unsigned i=0; i> 8; *g = (*g * *a + 255) >> 8; *b = (*b * *a + 255) >> 8; } } - a+=4; - b+=4; - g+=4; - r+=4; + a += 4; + b += 4; + g += 4; + r += 4; } fclose(stream); return MS_SUCCESS; - } int msSaveRasterBuffer(mapObj *map, rasterBufferObj *rb, FILE *stream, - outputFormatObj *format) -{ - if(strcasestr(format->driver,"/png")) { + outputFormatObj *format) { + if (strcasestr(format->driver, "/png")) { streamInfo info; info.fp = stream; info.buffer = NULL; - return saveAsPNG(map, rb,&info,format); - } else if(strcasestr(format->driver,"/jpeg")) { + return saveAsPNG(map, rb, &info, format); + } else if (strcasestr(format->driver, "/jpeg")) { streamInfo info; info.fp = stream; - info.buffer=NULL; - - return saveAsJPEG(map, rb,&info,format); + info.buffer = NULL; + + return saveAsJPEG(map, rb, &info, format); } else { - msSetError(MS_MISCERR,"unsupported image format\n", "msSaveRasterBuffer()"); + msSetError(MS_MISCERR, "unsupported image format\n", + "msSaveRasterBuffer()"); return MS_FAILURE; } } int msSaveRasterBufferToBuffer(rasterBufferObj *data, bufferObj *buffer, - outputFormatObj *format) -{ - if(strcasestr(format->driver,"/png")) { + outputFormatObj *format) { + if (strcasestr(format->driver, "/png")) { streamInfo info; info.fp = NULL; info.buffer = buffer; - return saveAsPNG(NULL, data,&info,format); - } else if(strcasestr(format->driver,"/jpeg")) { + return saveAsPNG(NULL, data, &info, format); + } else if (strcasestr(format->driver, "/jpeg")) { streamInfo info; info.fp = NULL; - info.buffer=buffer; - return saveAsJPEG(NULL, data,&info,format); + info.buffer = buffer; + return saveAsJPEG(NULL, data, &info, format); } else { - msSetError(MS_MISCERR,"unsupported image format\n", "msSaveRasterBuffer()"); + msSetError(MS_MISCERR, "unsupported image format\n", + "msSaveRasterBuffer()"); return MS_FAILURE; } } @@ -774,112 +784,111 @@ static char const *gif_error_msg() int code = GifLastError(); #endif switch (code) { - case E_GIF_ERR_OPEN_FAILED: /* should not see this */ - return "Failed to open given file"; + case E_GIF_ERR_OPEN_FAILED: /* should not see this */ + return "Failed to open given file"; - case E_GIF_ERR_WRITE_FAILED: - return "Write failed"; + case E_GIF_ERR_WRITE_FAILED: + return "Write failed"; - case E_GIF_ERR_HAS_SCRN_DSCR: /* should not see this */ - return "Screen descriptor already passed to giflib"; + case E_GIF_ERR_HAS_SCRN_DSCR: /* should not see this */ + return "Screen descriptor already passed to giflib"; - case E_GIF_ERR_HAS_IMAG_DSCR: /* should not see this */ - return "Image descriptor already passed to giflib"; + case E_GIF_ERR_HAS_IMAG_DSCR: /* should not see this */ + return "Image descriptor already passed to giflib"; - case E_GIF_ERR_NO_COLOR_MAP: /* should not see this */ - return "Neither global nor local color map set"; + case E_GIF_ERR_NO_COLOR_MAP: /* should not see this */ + return "Neither global nor local color map set"; - case E_GIF_ERR_DATA_TOO_BIG: /* should not see this */ - return "Too much pixel data passed to giflib"; + case E_GIF_ERR_DATA_TOO_BIG: /* should not see this */ + return "Too much pixel data passed to giflib"; - case E_GIF_ERR_NOT_ENOUGH_MEM: - return "Out of memory"; + case E_GIF_ERR_NOT_ENOUGH_MEM: + return "Out of memory"; - case E_GIF_ERR_DISK_IS_FULL: - return "Disk is full"; + case E_GIF_ERR_DISK_IS_FULL: + return "Disk is full"; - case E_GIF_ERR_CLOSE_FAILED: /* should not see this */ - return "File close failed"; + case E_GIF_ERR_CLOSE_FAILED: /* should not see this */ + return "File close failed"; - case E_GIF_ERR_NOT_WRITEABLE: /* should not see this */ - return "File not writable"; + case E_GIF_ERR_NOT_WRITEABLE: /* should not see this */ + return "File not writable"; - case D_GIF_ERR_OPEN_FAILED: - return "Failed to open file"; + case D_GIF_ERR_OPEN_FAILED: + return "Failed to open file"; - case D_GIF_ERR_READ_FAILED: - return "Failed to read from file"; + case D_GIF_ERR_READ_FAILED: + return "Failed to read from file"; - case D_GIF_ERR_NOT_GIF_FILE: - return "File is not a GIF file"; + case D_GIF_ERR_NOT_GIF_FILE: + return "File is not a GIF file"; - case D_GIF_ERR_NO_SCRN_DSCR: - return "No screen descriptor detected - invalid file"; + case D_GIF_ERR_NO_SCRN_DSCR: + return "No screen descriptor detected - invalid file"; - case D_GIF_ERR_NO_IMAG_DSCR: - return "No image descriptor detected - invalid file"; + case D_GIF_ERR_NO_IMAG_DSCR: + return "No image descriptor detected - invalid file"; - case D_GIF_ERR_NO_COLOR_MAP: - return "No global or local color map found"; + case D_GIF_ERR_NO_COLOR_MAP: + return "No global or local color map found"; - case D_GIF_ERR_WRONG_RECORD: - return "Wrong record type detected - invalid file?"; + case D_GIF_ERR_WRONG_RECORD: + return "Wrong record type detected - invalid file?"; - case D_GIF_ERR_DATA_TOO_BIG: - return "Data in file too big for image"; + case D_GIF_ERR_DATA_TOO_BIG: + return "Data in file too big for image"; - case D_GIF_ERR_NOT_ENOUGH_MEM: - return "Out of memory"; + case D_GIF_ERR_NOT_ENOUGH_MEM: + return "Out of memory"; - case D_GIF_ERR_CLOSE_FAILED: - return "Close failed"; + case D_GIF_ERR_CLOSE_FAILED: + return "Close failed"; - case D_GIF_ERR_NOT_READABLE: - return "File not opened for read"; + case D_GIF_ERR_NOT_READABLE: + return "File not opened for read"; - case D_GIF_ERR_IMAGE_DEFECT: - return "Defective image"; + case D_GIF_ERR_IMAGE_DEFECT: + return "Defective image"; - case D_GIF_ERR_EOF_TOO_SOON: - return "Unexpected EOF - invalid file"; + case D_GIF_ERR_EOF_TOO_SOON: + return "Unexpected EOF - invalid file"; - default: - sprintf(msg, "Unknown giflib error code %d", code); - return msg; + default: + sprintf(msg, "Unknown giflib error code %d", code); + return msg; } } - /* not fully implemented and tested */ /* missing: set the first pointer to a,r,g,b */ -int readGIF(char *path, rasterBufferObj *rb) -{ +int readGIF(char *path, rasterBufferObj *rb) { int codeSize, extCode, firstImageRead = MS_FALSE; - unsigned char *r,*g,*b,*a; + unsigned char *r, *g, *b, *a; int transIdx = -1; GifFileType *image; GifPixelType *line; GifRecordType recordType; GifByteType *codeBlock, *extension; ColorMapObject *cmap; - int interlacedOffsets[] = {0,4,2,1}; - int interlacedJumps[] = {8,8,4,2}; + int interlacedOffsets[] = {0, 4, 2, 1}; + int interlacedJumps[] = {8, 8, 4, 2}; #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 int errcode; #endif - rb->type = MS_BUFFER_BYTE_RGBA; #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - image = DGifOpenFileName(path, &errcode); + image = DGifOpenFileName(path, &errcode); if (image == NULL) { - msSetError(MS_MISCERR,"failed to load gif image: %s","readGIF()", gif_error_msg(errcode)); + msSetError(MS_MISCERR, "failed to load gif image: %s", "readGIF()", + gif_error_msg(errcode)); return MS_FAILURE; } #else - image = DGifOpenFileName(path); + image = DGifOpenFileName(path); if (image == NULL) { - msSetError(MS_MISCERR,"failed to load gif image: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "failed to load gif image: %s", "readGIF()", + gif_error_msg()); return MS_FAILURE; } #endif @@ -887,114 +896,93 @@ int readGIF(char *path, rasterBufferObj *rb) rb->height = image->SHeight; rb->data.rgba.row_step = rb->width * 4; rb->data.rgba.pixel_step = 4; - rb->data.rgba.pixels = (unsigned char*)malloc(rb->width*rb->height*4*sizeof(unsigned char)); + rb->data.rgba.pixels = (unsigned char *)malloc(rb->width * rb->height * 4 * + sizeof(unsigned char)); b = rb->data.rgba.b = &rb->data.rgba.pixels[0]; g = rb->data.rgba.g = &rb->data.rgba.pixels[1]; r = rb->data.rgba.r = &rb->data.rgba.pixels[2]; a = rb->data.rgba.a = &rb->data.rgba.pixels[3]; - cmap = (image->Image.ColorMap)?image->Image.ColorMap:image->SColorMap; - for(unsigned i=0; iwidth*rb->height; i++) { + cmap = (image->Image.ColorMap) ? image->Image.ColorMap : image->SColorMap; + for (unsigned i = 0; i < rb->width * rb->height; i++) { *a = 255; *r = cmap->Colors[image->SBackGroundColor].Red; *g = cmap->Colors[image->SBackGroundColor].Green; *b = cmap->Colors[image->SBackGroundColor].Blue; - a+=rb->data.rgba.pixel_step; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; + a += rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; } do { if (DGifGetRecordType(image, &recordType) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } switch (recordType) { - case SCREEN_DESC_RECORD_TYPE: - DGifGetScreenDesc(image); - break; - case IMAGE_DESC_RECORD_TYPE: - if (DGifGetImageDesc(image) == GIF_ERROR) { + case SCREEN_DESC_RECORD_TYPE: + DGifGetScreenDesc(image); + break; + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(image) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif + return MS_FAILURE; + } + if (!firstImageRead) { + + unsigned row = image->Image.Top; + unsigned col = image->Image.Left; + unsigned width = image->Image.Width; + unsigned height = image->Image.Height; + + /* sanity check: */ + if (col + width > rb->width || row + height > rb->height) { + msSetError(MS_MISCERR, + "corrupted gif image, img size exceeds screen size", + "readGIF()"); return MS_FAILURE; } - if (!firstImageRead) { - unsigned row = image->Image.Top; - unsigned col = image->Image.Left; - unsigned width = image->Image.Width; - unsigned height = image->Image.Height; - - /* sanity check: */ - if(col+width>rb->width || row+height>rb->height) { - msSetError(MS_MISCERR,"corrupted gif image, img size exceeds screen size","readGIF()"); - return MS_FAILURE; - } - - line = (GifPixelType *) malloc(width * sizeof(GifPixelType)); - if(image->Image.Interlace) { - int count; - for(count=0; count<4; count++) { - for(unsigned i=row+interlacedOffsets[count]; idata.rgba.row_step + col * rb->data.rgba.pixel_step; - a = rb->data.rgba.a + offset; - r = rb->data.rgba.r + offset; - g = rb->data.rgba.g + offset; - b = rb->data.rgba.b + offset; - if (DGifGetLine(image, line, width) == GIF_ERROR) { -#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()",gif_error_msg(image->Error)); -#else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()",gif_error_msg()); -#endif - return MS_FAILURE; - } - - for(unsigned j=0; jColors[pix].Red; - *g = cmap->Colors[pix].Green; - *b = cmap->Colors[pix].Blue; - } else { - *a = *r = *g = *b = 0; - } - a+=rb->data.rgba.pixel_step; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; - } - } - } - } else { - for (unsigned i = 0; i < height; i++) { - int offset = i * rb->data.rgba.row_step + col * rb->data.rgba.pixel_step; + line = (GifPixelType *)malloc(width * sizeof(GifPixelType)); + if (image->Image.Interlace) { + int count; + for (count = 0; count < 4; count++) { + for (unsigned i = row + interlacedOffsets[count]; i < row + height; + i += interlacedJumps[count]) { + int offset = + i * rb->data.rgba.row_step + col * rb->data.rgba.pixel_step; a = rb->data.rgba.a + offset; r = rb->data.rgba.r + offset; g = rb->data.rgba.g + offset; b = rb->data.rgba.b + offset; if (DGifGetLine(image, line, width) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()",gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()",gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } - for(unsigned j=0; jColors[pix].Red; *g = cmap->Colors[pix].Green; @@ -1002,86 +990,132 @@ int readGIF(char *path, rasterBufferObj *rb) } else { *a = *r = *g = *b = 0; } - a+=rb->data.rgba.pixel_step; - r+=rb->data.rgba.pixel_step; - g+=rb->data.rgba.pixel_step; - b+=rb->data.rgba.pixel_step; + a += rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; } } } - free((char *) line); - firstImageRead = MS_TRUE; } else { - /* Skip all next images */ - if (DGifGetCode(image, &codeSize, &codeBlock) == GIF_ERROR) { -#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); -#else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); -#endif - return MS_FAILURE; - } - while (codeBlock != NULL) { - if (DGifGetCodeNext(image, &codeBlock) == GIF_ERROR) { + for (unsigned i = 0; i < height; i++) { + int offset = + i * rb->data.rgba.row_step + col * rb->data.rgba.pixel_step; + a = rb->data.rgba.a + offset; + r = rb->data.rgba.r + offset; + g = rb->data.rgba.g + offset; + b = rb->data.rgba.b + offset; + if (DGifGetLine(image, line, width) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } + for (unsigned j = 0; j < width; j++) { + GifPixelType pix = line[j]; + if (transIdx == -1 || pix != transIdx) { + *a = 255; + *r = cmap->Colors[pix].Red; + *g = cmap->Colors[pix].Green; + *b = cmap->Colors[pix].Blue; + } else { + *a = *r = *g = *b = 0; + } + a += rb->data.rgba.pixel_step; + r += rb->data.rgba.pixel_step; + g += rb->data.rgba.pixel_step; + b += rb->data.rgba.pixel_step; + } } } - break; - case EXTENSION_RECORD_TYPE: - /* skip all extension blocks */ - if (DGifGetExtension(image, &extCode, &extension) == GIF_ERROR) { + free((char *)line); + firstImageRead = MS_TRUE; + } else { + /* Skip all next images */ + if (DGifGetCode(image, &codeSize, &codeBlock) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } - if(extCode == 249 && (extension[1] & 1)) - transIdx = extension[4]; - for (;;) { - if (DGifGetExtensionNext(image, &extension) == GIF_ERROR) { + while (codeBlock != NULL) { + if (DGifGetCodeNext(image, &codeBlock) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"corrupted gif image?: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } - if (extension == NULL) - break; - if(extension[1] & 1) - transIdx = extension[4]; } - break; - case UNDEFINED_RECORD_TYPE: - break; - case TERMINATE_RECORD_TYPE: - break; - default: - break; + } + break; + case EXTENSION_RECORD_TYPE: + /* skip all extension blocks */ + if (DGifGetExtension(image, &extCode, &extension) == GIF_ERROR) { +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); +#else + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); +#endif + return MS_FAILURE; + } + if (extCode == 249 && (extension[1] & 1)) + transIdx = extension[4]; + for (;;) { + if (DGifGetExtensionNext(image, &extension) == GIF_ERROR) { +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg(image->Error)); +#else + msSetError(MS_MISCERR, "corrupted gif image?: %s", "readGIF()", + gif_error_msg()); +#endif + return MS_FAILURE; + } + if (extension == NULL) + break; + if (extension[1] & 1) + transIdx = extension[4]; + } + break; + case UNDEFINED_RECORD_TYPE: + break; + case TERMINATE_RECORD_TYPE: + break; + default: + break; } } while (recordType != TERMINATE_RECORD_TYPE); - -#if defined GIFLIB_MAJOR && GIFLIB_MINOR && ((GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || (GIFLIB_MAJOR > 5)) +#if defined GIFLIB_MAJOR && GIFLIB_MINOR && \ + ((GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || (GIFLIB_MAJOR > 5)) if (DGifCloseFile(image, &errcode) == GIF_ERROR) { - msSetError(MS_MISCERR,"failed to close gif after loading: %s","readGIF()", gif_error_msg(errcode)); + msSetError(MS_MISCERR, "failed to close gif after loading: %s", "readGIF()", + gif_error_msg(errcode)); return MS_FAILURE; } #else if (DGifCloseFile(image) == GIF_ERROR) { #if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 - msSetError(MS_MISCERR,"failed to close gif after loading: %s","readGIF()", gif_error_msg(image->Error)); + msSetError(MS_MISCERR, "failed to close gif after loading: %s", "readGIF()", + gif_error_msg(image->Error)); #else - msSetError(MS_MISCERR,"failed to close gif after loading: %s","readGIF()", gif_error_msg()); + msSetError(MS_MISCERR, "failed to close gif after loading: %s", "readGIF()", + gif_error_msg()); #endif return MS_FAILURE; } @@ -1091,33 +1125,37 @@ int readGIF(char *path, rasterBufferObj *rb) } #endif -int msLoadMSRasterBufferFromFile(char *path, rasterBufferObj *rb) -{ +int msLoadMSRasterBufferFromFile(char *path, rasterBufferObj *rb) { FILE *stream; unsigned char signature[8]; int ret = MS_FAILURE; - stream = fopen(path,"rb"); - if(!stream) { - msSetError(MS_MISCERR, "unable to open file %s for reading", "msLoadMSRasterBufferFromFile()", path); + stream = fopen(path, "rb"); + if (!stream) { + msSetError(MS_MISCERR, "unable to open file %s for reading", + "msLoadMSRasterBufferFromFile()", path); return MS_FAILURE; } - if(1 != fread(signature,8,1,stream)) { + if (1 != fread(signature, 8, 1, stream)) { fclose(stream); - msSetError(MS_MISCERR, "Unable to read header from image file %s", "msLoadMSRasterBufferFromFile()",path); + msSetError(MS_MISCERR, "Unable to read header from image file %s", + "msLoadMSRasterBufferFromFile()", path); return MS_FAILURE; } fclose(stream); - if(png_sig_cmp(signature,0,8) == 0) { - ret = readPNG(path,rb); - } else if (!strncmp((char*)signature,"GIF",3)) { + if (png_sig_cmp(signature, 0, 8) == 0) { + ret = readPNG(path, rb); + } else if (!strncmp((char *)signature, "GIF", 3)) { #ifdef USE_GIF - ret = readGIF(path,rb); + ret = readGIF(path, rb); #else - msSetError(MS_MISCERR,"pixmap %s seems to be GIF formatted, but this server is compiled without GIF support","readImage()",path); + msSetError(MS_MISCERR, + "pixmap %s seems to be GIF formatted, but this server is " + "compiled without GIF support", + "readImage()", path); return MS_FAILURE; #endif } else { - msSetError(MS_MISCERR,"unsupported pixmap format","readImage()"); + msSetError(MS_MISCERR, "unsupported pixmap format", "readImage()"); return MS_FAILURE; } return ret; diff --git a/mapimagemap.c b/mapimagemap.c index 0d378d6f64..f37bb2d138 100644 --- a/mapimagemap.c +++ b/mapimagemap.c @@ -38,8 +38,6 @@ #include #endif - - #define MYDEBUG 0 #define DEBUG_IF if (MYDEBUG > 2) @@ -107,46 +105,45 @@ typedef struct pString { * imagemap/dxf file; parts of this live in another data structure and * are only referenced indirectly here. The other contains layer-specific * information for the dxf output. */ -static char *layerlist=NULL; -static int layersize=0; -static pString imgStr, layerStr= { &layerlist, &layersize, 0 }; +static char *layerlist = NULL; +static int layersize = 0; +static pString imgStr, layerStr = {&layerlist, &layersize, 0}; /* Format strings for the various bits of a client-side imagemap. */ static const char *polyHrefFmt, *polyMOverFmt, *polyMOutFmt; static const char *symbolHrefFmt, *symbolMOverFmt, *symbolMOutFmt; static const char *mapName; /* Should we suppress AREA declarations in imagemaps with no title? */ -static int suppressEmpty=0; +static int suppressEmpty = 0; /* Prevent buffer-overrun and format-string attacks by "sanitizing" any * provided format string to fit the number of expected string arguments * (MAX) exactly. */ -static const char *makeFmtSafe(const char *fmt, int MAX) -{ +static const char *makeFmtSafe(const char *fmt, int MAX) { /* format string should have exactly 'MAX' %s */ - char *result = msSmallMalloc(strlen(fmt)+1+3*MAX), *cp; - int numstr=0, saw_percent=0; + char *result = msSmallMalloc(strlen(fmt) + 1 + 3 * MAX), *cp; + int numstr = 0, saw_percent = 0; strcpy(result, fmt); - for (cp=result; *cp; cp++) { + for (cp = result; *cp; cp++) { if (saw_percent) { - if (*cp=='%') { + if (*cp == '%') { /* safe */ - } else if (*cp=='s' && numstralloc_size) - ps->string_len; va_start(ap, fmt); #if defined(HAVE_VSNPRINTF) - n = vsnprintf((*(ps->string)) + ps->string_len, - remaining, fmt, ap); + n = vsnprintf((*(ps->string)) + ps->string_len, remaining, fmt, ap); #else /* If vsnprintf() is not available then require a minimum * of 512 bytes of free space to prevent a buffer overflow @@ -177,35 +172,33 @@ static void im_iprintf(pString *ps, const char *fmt, ...) #endif va_end(ap); /* if that worked, we're done! */ - if (-1string_len += n; return; - } else { /* double allocated string size */ - *(ps->alloc_size) *= 2;/* these keeps realloc linear.*/ + } else { /* double allocated string size */ + *(ps->alloc_size) *= 2; /* these keeps realloc linear.*/ if (*(ps->alloc_size) < 1024) /* careful: initial size can be 0 */ - *(ps->alloc_size)=1024; - if (n>-1 && *(ps->alloc_size) <= (n + ps->string_len)) + *(ps->alloc_size) = 1024; + if (n > -1 && *(ps->alloc_size) <= (n + ps->string_len)) /* ensure at least as much as what is needed */ - *(ps->alloc_size) = n+ps->string_len+1; - *(ps->string) = (char *) msSmallRealloc - (*(ps->string), *(ps->alloc_size)); + *(ps->alloc_size) = n + ps->string_len + 1; + *(ps->string) = (char *)msSmallRealloc(*(ps->string), *(ps->alloc_size)); /* if realloc doesn't work, we're screwed! */ } } while (1); /* go back and try again. */ } - - -static int lastcolor=-1; -static int matchdxfcolor(colorObj col) -{ - int best=7; - int delta=128*255; +static int lastcolor = -1; +static int matchdxfcolor(colorObj col) { + int best = 7; + int delta = 128 * 255; int tcolor = 0; if (lastcolor != -1) return lastcolor; - while (tcolor < 256 && (ctable[tcolor].r != col.red || ctable[tcolor].g != col.green || ctable[tcolor].b != col.blue)) { + while (tcolor < 256 && + (ctable[tcolor].r != col.red || ctable[tcolor].g != col.green || + ctable[tcolor].b != col.blue)) { const int dr = ctable[tcolor].r - col.red; const int dg = ctable[tcolor].g - col.green; const int db = ctable[tcolor].b - col.blue; @@ -216,17 +209,19 @@ static int matchdxfcolor(colorObj col) } tcolor++; } - if (tcolor >= 256) tcolor = best; - /* DEBUG_IF printf("%d/%d/%d (%d/%d - %d), %d : %d/%d/%d
\n", ctable[tcolor].r, ctable[tcolor].g, ctable[tcolor].b, tcolor, best, delta, lastcolor, col.red, col.green, col.blue); */ + if (tcolor >= 256) + tcolor = best; + /* DEBUG_IF printf("%d/%d/%d (%d/%d - %d), %d : %d/%d/%d
\n", + * ctable[tcolor].r, ctable[tcolor].g, ctable[tcolor].b, tcolor, best, delta, + * lastcolor, col.red, col.green, col.blue); */ lastcolor = tcolor; return tcolor; } -static char* lname; +static char *lname; static int dxf; -void msImageStartLayerIM(mapObj *map, layerObj *layer, imageObj *image) -{ +void msImageStartLayerIM(mapObj *map, layerObj *layer, imageObj *image) { (void)map; (void)image; DEBUG_IF printf("ImageStartLayerIM\n
"); @@ -240,7 +235,8 @@ void msImageStartLayerIM(mapObj *map, layerObj *layer, imageObj *image) } else if (dxf) { im_iprintf(&layerStr, " 0\nLAYER\n 2\n%s\n" - " 70\n 64\n 6\nCONTINUOUS\n", lname); + " 70\n 64\n 6\nCONTINUOUS\n", + lname); } lastcolor = -1; } @@ -250,15 +246,15 @@ void msImageStartLayerIM(mapObj *map, layerObj *layer, imageObj *image) * a pointer to an imageObj structure. */ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, - char *imagepath, char *imageurl, double resolution, double defresolution) -{ - imageObj *image=NULL; - if (setvbuf(stdout, NULL, _IONBF , 0)) { + char *imagepath, char *imageurl, double resolution, + double defresolution) { + imageObj *image = NULL; + if (setvbuf(stdout, NULL, _IONBF, 0)) { printf("Whoops..."); }; DEBUG_IF printf("msImageCreateIM
\n"); if (width > 0 && height > 0) { - image = (imageObj *)msSmallCalloc(1,sizeof(imageObj)); + image = (imageObj *)msSmallCalloc(1, sizeof(imageObj)); imgStr.string = &(image->img.imagemap); imgStr.alloc_size = &(image->size); @@ -270,48 +266,51 @@ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, image->imagepath = NULL; image->imageurl = NULL; image->resolution = resolution; - image->resolutionfactor = resolution/defresolution; + image->resolutionfactor = resolution / defresolution; - if( strcasecmp("ON",msGetOutputFormatOption( format, "DXF", "OFF" )) == 0) { + if (strcasecmp("ON", msGetOutputFormatOption(format, "DXF", "OFF")) == 0) { dxf = 1; im_iprintf(&layerStr, " 2\nLAYER\n 70\n 10\n"); } else dxf = 0; - if( strcasecmp("ON",msGetOutputFormatOption( format, "SCRIPT", "OFF" )) == 0) { + if (strcasecmp("ON", msGetOutputFormatOption(format, "SCRIPT", "OFF")) == + 0) { dxf = 2; im_iprintf(&layerStr, ""); } /* get href formation string options */ - polyHrefFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "POLYHREF", "javascript:Clicked('%s');"), 1); - polyMOverFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "POLYMOUSEOVER", ""), 1); - polyMOutFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "POLYMOUSEOUT", ""), 1); - symbolHrefFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "SYMBOLHREF", "javascript:SymbolClicked();"), 1); - symbolMOverFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "SYMBOLMOUSEOVER", ""), 1); - symbolMOutFmt = makeFmtSafe(msGetOutputFormatOption - ( format, "SYMBOLMOUSEOUT", ""), 1); + polyHrefFmt = + makeFmtSafe(msGetOutputFormatOption(format, "POLYHREF", + "javascript:Clicked('%s');"), + 1); + polyMOverFmt = + makeFmtSafe(msGetOutputFormatOption(format, "POLYMOUSEOVER", ""), 1); + polyMOutFmt = + makeFmtSafe(msGetOutputFormatOption(format, "POLYMOUSEOUT", ""), 1); + symbolHrefFmt = + makeFmtSafe(msGetOutputFormatOption(format, "SYMBOLHREF", + "javascript:SymbolClicked();"), + 1); + symbolMOverFmt = + makeFmtSafe(msGetOutputFormatOption(format, "SYMBOLMOUSEOVER", ""), 1); + symbolMOutFmt = + makeFmtSafe(msGetOutputFormatOption(format, "SYMBOLMOUSEOUT", ""), 1); /* get name of client-side image map */ - mapName = msGetOutputFormatOption - ( format, "MAPNAME", "map1" ); + mapName = msGetOutputFormatOption(format, "MAPNAME", "map1"); /* should we suppress area declarations with no title? */ - if( strcasecmp("YES",msGetOutputFormatOption( format, "SUPPRESS", "NO" )) == 0) { - suppressEmpty=1; + if (strcasecmp("YES", msGetOutputFormatOption(format, "SUPPRESS", "NO")) == + 0) { + suppressEmpty = 1; } lname = msStrdup("NONE"); *(imgStr.string) = msStrdup(""); if (*(imgStr.string)) { - *(imgStr.alloc_size) = - imgStr.string_len = strlen(*(imgStr.string)); + *(imgStr.alloc_size) = imgStr.string_len = strlen(*(imgStr.string)); } else { - *(imgStr.alloc_size) = - imgStr.string_len = 0; + *(imgStr.alloc_size) = imgStr.string_len = 0; } if (imagepath) { image->imagepath = msStrdup(imagepath); @@ -322,9 +321,8 @@ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, return image; } else { - msSetError(MS_IMGERR, - "Cannot create IM image of size %d x %d.", - "msImageCreateIM()", width, height ); + msSetError(MS_IMGERR, "Cannot create IM image of size %d x %d.", + "msImageCreateIM()", width, height); } return image; } @@ -332,8 +330,8 @@ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, /* ------------------------------------------------------------------------- */ /* Draw a single marker symbol of the specified size and color */ /* ------------------------------------------------------------------------- */ -void msDrawMarkerSymbolIM(mapObj *map, imageObj* img, pointObj *p, styleObj *style, double scalefactor) -{ +void msDrawMarkerSymbolIM(mapObj *map, imageObj *img, pointObj *p, + styleObj *style, double scalefactor) { symbolObj *symbol; int ox, oy; double size; @@ -342,56 +340,57 @@ void msDrawMarkerSymbolIM(mapObj *map, imageObj* img, pointObj *p, styleObj *sty /* skip this, we don't do text */ + if (!p) + return; - - if(!p) return; - - - if(style->symbol > map->symbolset.numsymbols || style->symbol < 0) return; /* no such symbol, 0 is OK */ + if (style->symbol > map->symbolset.numsymbols || style->symbol < 0) + return; /* no such symbol, 0 is OK */ symbol = map->symbolset.symbol[style->symbol]; - ox = style->offsetx*scalefactor; - oy = style->offsety*scalefactor; - if(style->size == -1) { - size = msSymbolGetDefaultSize( symbol ); - size = MS_NINT(size*scalefactor); + ox = style->offsetx * scalefactor; + oy = style->offsety * scalefactor; + if (style->size == -1) { + size = msSymbolGetDefaultSize(symbol); + size = MS_NINT(size * scalefactor); } else - size = MS_NINT(style->size*scalefactor); - size = MS_MAX(size, style->minsize*img->resolutionfactor); - size = MS_MIN(size, style->maxsize*img->resolutionfactor); + size = MS_NINT(style->size * scalefactor); + size = MS_MAX(size, style->minsize * img->resolutionfactor); + size = MS_MIN(size, style->maxsize * img->resolutionfactor); - if(size < 1) return; /* size too small */ + if (size < 1) + return; /* size too small */ /* DEBUG_IF printf(".%d.%d.%d.", symbol->type, style->symbol, fc); */ - if(style->symbol == 0) { /* simply draw a single pixel of the specified color */ + if (style->symbol == + 0) { /* simply draw a single pixel of the specified color */ if (dxf) { - if (dxf==2) - im_iprintf (&imgStr, "POINT\n%.0f %.0f\n%d\n", - p->x + ox, p->y + oy, matchdxfcolor(style->color)); + if (dxf == 2) + im_iprintf(&imgStr, "POINT\n%.0f %.0f\n%d\n", p->x + ox, p->y + oy, + matchdxfcolor(style->color)); else - im_iprintf (&imgStr, - " 0\nPOINT\n 10\n%f\n 20\n%f\n 30\n0.0\n" - " 62\n%6d\n 8\n%s\n", - p->x + ox, p->y + oy, matchdxfcolor(style->color), lname); + im_iprintf(&imgStr, + " 0\nPOINT\n 10\n%f\n 20\n%f\n 30\n0.0\n" + " 62\n%6d\n 8\n%s\n", + p->x + ox, p->y + oy, matchdxfcolor(style->color), lname); } else { - im_iprintf (&imgStr, "\n", - p->x + ox, p->y + oy); + im_iprintf(&imgStr, "shape=\"circle\" coords=\"%.0f,%.0f, 3\" />\n", + p->x + ox, p->y + oy); } /* point2 = &( p->line[j].point[i] ); */ @@ -399,61 +398,61 @@ void msDrawMarkerSymbolIM(mapObj *map, imageObj* img, pointObj *p, styleObj *sty return; } DEBUG_IF printf("A"); - switch(symbol->type) { - case(MS_SYMBOL_TRUETYPE): - DEBUG_IF printf("T"); - break; - case(MS_SYMBOL_PIXMAP): - DEBUG_IF printf("P"); - break; - case(MS_SYMBOL_VECTOR): - DEBUG_IF printf("V"); - { - double d, offset_x, offset_y; - - d = size/symbol->sizey; - offset_x = MS_NINT(p->x - d*.5*symbol->sizex + ox); - offset_y = MS_NINT(p->y - d*.5*symbol->sizey + oy); - - /* For now I only render filled vector symbols in imagemap, and no */ - /* dxf support available yet. */ - if(symbol->filled && !dxf /* && fc >= 0 */ ) { - /* char *title=(p->numvalues) ? p->values[0] : ""; */ - char *title = ""; - int j; - - im_iprintf (&imgStr, "numpoints; j++) { - im_iprintf (&imgStr, "%s %d,%d", j == 0 ? "": ",", - (int)MS_NINT(d*symbol->points[j].x + offset_x), - (int)MS_NINT(d*symbol->points[j].y + offset_y) ); - } - im_iprintf (&imgStr, "\" />\n"); - } /* end of imagemap, filled case. */ - } - break; + switch (symbol->type) { + case (MS_SYMBOL_TRUETYPE): + DEBUG_IF printf("T"); + break; + case (MS_SYMBOL_PIXMAP): + DEBUG_IF printf("P"); + break; + case (MS_SYMBOL_VECTOR): + DEBUG_IF printf("V"); + { + double d, offset_x, offset_y; + + d = size / symbol->sizey; + offset_x = MS_NINT(p->x - d * .5 * symbol->sizex + ox); + offset_y = MS_NINT(p->y - d * .5 * symbol->sizey + oy); + + /* For now I only render filled vector symbols in imagemap, and no */ + /* dxf support available yet. */ + if (symbol->filled && !dxf /* && fc >= 0 */) { + /* char *title=(p->numvalues) ? p->values[0] : ""; */ + char *title = ""; + int j; + + im_iprintf(&imgStr, "numpoints; j++) { + im_iprintf(&imgStr, "%s %d,%d", j == 0 ? "" : ",", + (int)MS_NINT(d * symbol->points[j].x + offset_x), + (int)MS_NINT(d * symbol->points[j].y + offset_y)); + } + im_iprintf(&imgStr, "\" />\n"); + } /* end of imagemap, filled case. */ + } + break; - default: - DEBUG_IF printf("DEF"); - break; + default: + DEBUG_IF printf("DEF"); + break; } /* end switch statement */ return; @@ -462,174 +461,197 @@ void msDrawMarkerSymbolIM(mapObj *map, imageObj* img, pointObj *p, styleObj *sty /* ------------------------------------------------------------------------- */ /* Draw a line symbol of the specified size and color */ /* ------------------------------------------------------------------------- */ -void msDrawLineSymbolIM(mapObj *map, imageObj* img, shapeObj *p, styleObj *style, double scalefactor_ignored) -{ +void msDrawLineSymbolIM(mapObj *map, imageObj *img, shapeObj *p, + styleObj *style, double scalefactor_ignored) { (void)img; (void)scalefactor_ignored; symbolObj *symbol; - int i,j,l; + int i, j, l; char first = 1; DEBUG_IF printf("msDrawLineSymbolIM
\n"); + if (!p) + return; + if (p->numlines <= 0) + return; - if(!p) return; - if(p->numlines <= 0) return; - - if(style->symbol > map->symbolset.numsymbols || style->symbol < 0) return; /* no such symbol, 0 is OK */ + if (style->symbol > map->symbolset.numsymbols || style->symbol < 0) + return; /* no such symbol, 0 is OK */ symbol = map->symbolset.symbol[style->symbol]; - if (suppressEmpty && p->numvalues==0) return;/* suppress area with empty title */ - if(style->symbol == 0) { /* just draw a single width line */ - for(l=0,j=0; jnumlines; j++) { + if (suppressEmpty && p->numvalues == 0) + return; /* suppress area with empty title */ + if (style->symbol == 0) { /* just draw a single width line */ + for (l = 0, j = 0; j < p->numlines; j++) { if (dxf == 2) { - im_iprintf (&imgStr, "LINE\n%d\n", matchdxfcolor(style->color)); + im_iprintf(&imgStr, "LINE\n%d\n", matchdxfcolor(style->color)); } else if (dxf) { - im_iprintf (&imgStr, " 0\nPOLYLINE\n 70\n 0\n 62\n%6d\n 8\n%s\n", matchdxfcolor(style->color), lname); + im_iprintf(&imgStr, " 0\nPOLYLINE\n 70\n 0\n 62\n%6d\n 8\n%s\n", + matchdxfcolor(style->color), lname); } else { char *title; first = 1; - title=(p->numvalues) ? p->values[0] : ""; - im_iprintf (&imgStr, "numvalues) ? p->values[0] : ""; + im_iprintf(&imgStr, "line[j].point[p->line[j].numpoints-1] ); */ - for(i=0; i < p->line[j].numpoints; i++,l++) { + for (i = 0; i < p->line[j].numpoints; i++, l++) { if (dxf == 2) { - im_iprintf (&imgStr, "%.0f %.0f\n", p->line[j].point[i].x, p->line[j].point[i].y); + im_iprintf(&imgStr, "%.0f %.0f\n", p->line[j].point[i].x, + p->line[j].point[i].y); } else if (dxf) { - im_iprintf (&imgStr, " 0\nVERTEX\n 10\n%f\n 20\n%f\n 30\n%f\n", p->line[j].point[i].x, p->line[j].point[i].y, 0.0); + im_iprintf(&imgStr, " 0\nVERTEX\n 10\n%f\n 20\n%f\n 30\n%f\n", + p->line[j].point[i].x, p->line[j].point[i].y, 0.0); } else { - im_iprintf (&imgStr, "%s %.0f,%.0f", first ? "": ",", p->line[j].point[i].x, p->line[j].point[i].y); + im_iprintf(&imgStr, "%s %.0f,%.0f", first ? "" : ",", + p->line[j].point[i].x, p->line[j].point[i].y); } first = 0; /* point2 = &( p->line[j].point[i] ); */ /* if(point1->y == point2->y) {} */ } - im_iprintf (&imgStr, dxf ? (dxf == 2 ? "": " 0\nSEQEND\n") : "\" />\n"); + im_iprintf(&imgStr, dxf ? (dxf == 2 ? "" : " 0\nSEQEND\n") : "\" />\n"); } /* DEBUG_IF printf ("%d, ",strlen(img->img.imagemap) ); */ return; } - DEBUG_IF printf("-%d-",symbol->type); + DEBUG_IF printf("-%d-", symbol->type); return; } - /* ------------------------------------------------------------------------- */ /* Draw a shade symbol of the specified size and color */ /* ------------------------------------------------------------------------- */ -void msDrawShadeSymbolIM(mapObj *map, imageObj* img, shapeObj *p, styleObj *style, double scalefactor_ignored) -{ +void msDrawShadeSymbolIM(mapObj *map, imageObj *img, shapeObj *p, + styleObj *style, double scalefactor_ignored) { (void)img; (void)scalefactor_ignored; symbolObj *symbol; - int i,j,l; + int i, j, l; char first = 1; DEBUG_IF printf("msDrawShadeSymbolIM\n
"); - if(!p) return; - if(p->numlines <= 0) return; + if (!p) + return; + if (p->numlines <= 0) + return; symbol = map->symbolset.symbol[style->symbol]; - if (suppressEmpty && p->numvalues==0) return;/* suppress area with empty title */ - if(style->symbol == 0) { /* simply draw a single pixel of the specified color // */ - for(l=0,j=0; jnumlines; j++) { + if (suppressEmpty && p->numvalues == 0) + return; /* suppress area with empty title */ + if (style->symbol == + 0) { /* simply draw a single pixel of the specified color // */ + for (l = 0, j = 0; j < p->numlines; j++) { if (dxf == 2) { - im_iprintf (&imgStr, "POLY\n%d\n", matchdxfcolor(style->color)); + im_iprintf(&imgStr, "POLY\n%d\n", matchdxfcolor(style->color)); } else if (dxf) { - im_iprintf (&imgStr, " 0\nPOLYLINE\n 73\n 1\n 62\n%6d\n 8\n%s\n", matchdxfcolor(style->color), lname); + im_iprintf(&imgStr, " 0\nPOLYLINE\n 73\n 1\n 62\n%6d\n 8\n%s\n", + matchdxfcolor(style->color), lname); } else { - char *title=(p->numvalues) ? p->values[0] : ""; + char *title = (p->numvalues) ? p->values[0] : ""; first = 1; - im_iprintf (&imgStr, "line[j].point[p->line[j].numpoints-1] ); */ - for(i=0; i < p->line[j].numpoints; i++,l++) { + for (i = 0; i < p->line[j].numpoints; i++, l++) { if (dxf == 2) { - im_iprintf (&imgStr, "%.0f %.0f\n", p->line[j].point[i].x, p->line[j].point[i].y); + im_iprintf(&imgStr, "%.0f %.0f\n", p->line[j].point[i].x, + p->line[j].point[i].y); } else if (dxf) { - im_iprintf (&imgStr, " 0\nVERTEX\n 10\n%f\n 20\n%f\n 30\n%f\n", p->line[j].point[i].x, p->line[j].point[i].y, 0.0); + im_iprintf(&imgStr, " 0\nVERTEX\n 10\n%f\n 20\n%f\n 30\n%f\n", + p->line[j].point[i].x, p->line[j].point[i].y, 0.0); } else { - im_iprintf (&imgStr, "%s %.0f,%.0f", first ? "": ",", p->line[j].point[i].x, p->line[j].point[i].y); + im_iprintf(&imgStr, "%s %.0f,%.0f", first ? "" : ",", + p->line[j].point[i].x, p->line[j].point[i].y); } first = 0; /* point2 = &( p->line[j].point[i] ); */ /* if(point1->y == point2->y) {} */ } - im_iprintf (&imgStr, dxf ? (dxf == 2 ? "": " 0\nSEQEND\n") : "\" />\n"); + im_iprintf(&imgStr, dxf ? (dxf == 2 ? "" : " 0\nSEQEND\n") : "\" />\n"); } return; } /* DEBUG_IF printf ("d"); */ - DEBUG_IF printf("-%d-",symbol->type); + DEBUG_IF printf("-%d-", symbol->type); return; } /* * Simply draws a label based on the label point and the supplied label object. */ -int msDrawTextIM(mapObj *map, imageObj* img, pointObj labelPnt, char *string, labelObj *label, double scalefactor) -{ +int msDrawTextIM(mapObj *map, imageObj *img, pointObj labelPnt, char *string, + labelObj *label, double scalefactor) { (void)map; (void)img; DEBUG_IF printf("msDrawText
\n"); - if(!string) return(0); /* not errors, just don't want to do anything */ - if(strlen(string) == 0) return(0); - if(!dxf) return (0); + if (!string) + return (0); /* not errors, just don't want to do anything */ + if (strlen(string) == 0) + return (0); + if (!dxf) + return (0); if (dxf == 2) { - im_iprintf (&imgStr, "TEXT\n%d\n%s\n%.0f\n%.0f\n%.0f\n" , matchdxfcolor(label->color), string, labelPnt.x, labelPnt.y, -label->angle); + im_iprintf(&imgStr, "TEXT\n%d\n%s\n%.0f\n%.0f\n%.0f\n", + matchdxfcolor(label->color), string, labelPnt.x, labelPnt.y, + -label->angle); } else { - im_iprintf (&imgStr, " 0\nTEXT\n 1\n%s\n 10\n%f\n 20\n%f\n 30\n0.0\n 40\n%f\n 50\n%f\n 62\n%6d\n 8\n%s\n 73\n 2\n 72\n 1\n" , string, labelPnt.x, labelPnt.y, label->size * scalefactor *100, -label->angle, matchdxfcolor(label->color), lname); + im_iprintf(&imgStr, + " 0\nTEXT\n 1\n%s\n 10\n%f\n 20\n%f\n 30\n0.0\n 40\n%f\n " + "50\n%f\n 62\n%6d\n 8\n%s\n 73\n 2\n 72\n 1\n", + string, labelPnt.x, labelPnt.y, label->size * scalefactor * 100, + -label->angle, matchdxfcolor(label->color), lname); } - return(0); + return (0); } /* * Save an image to a file named filename, if filename is NULL it goes to stdout */ -int msSaveImageIM(imageObj* img, const char *filename, outputFormatObj *format ) +int msSaveImageIM(imageObj *img, const char *filename, outputFormatObj *format) { FILE *stream_to_free = NULL; @@ -638,11 +660,11 @@ int msSaveImageIM(imageObj* img, const char *filename, outputFormatObj *format ) DEBUG_IF printf("msSaveImageIM\n
"); - if(filename != NULL && strlen(filename) > 0) { + if (filename != NULL && strlen(filename) > 0) { stream_to_free = fopen(filename, "wb"); - if(!stream_to_free) { + if (!stream_to_free) { msSetError(MS_IOERR, "(%s)", "msSaveImage()", filename); - return(MS_FAILURE); + return (MS_FAILURE); } stream = stream_to_free; } else { /* use stdout */ @@ -651,24 +673,31 @@ int msSaveImageIM(imageObj* img, const char *filename, outputFormatObj *format ) /* * Change stdout mode to binary on win32 platforms */ - if(_setmode( _fileno(stdout), _O_BINARY) == -1) { - msSetError(MS_IOERR, "Unable to change stdout to binary mode.", "msSaveImage()"); - return(MS_FAILURE); + if (_setmode(_fileno(stdout), _O_BINARY) == -1) { + msSetError(MS_IOERR, "Unable to change stdout to binary mode.", + "msSaveImage()"); + return (MS_FAILURE); } #endif stream = stdout; } - if( strcasecmp(format->driver,"imagemap") == 0 ) { + if (strcasecmp(format->driver, "imagemap") == 0) { DEBUG_IF printf("ALLOCD %d
\n", img->size); /* DEBUG_IF printf("F %s
\n", img->img.imagemap); */ DEBUG_IF printf("FLEN %d
\n", (int)strlen(img->img.imagemap)); if (dxf == 2) { msIO_fprintf(stream, "%s", layerlist); } else if (dxf) { - msIO_fprintf(stream, " 0\nSECTION\n 2\nHEADER\n 9\n$ACADVER\n 1\nAC1009\n0\nENDSEC\n 0\nSECTION\n 2\nTABLES\n 0\nTABLE\n%s0\nENDTAB\n0\nENDSEC\n 0\nSECTION\n 2\nBLOCKS\n0\nENDSEC\n 0\nSECTION\n 2\nENTITIES\n", layerlist); + msIO_fprintf( + stream, + " 0\nSECTION\n 2\nHEADER\n 9\n$ACADVER\n 1\nAC1009\n0\nENDSEC\n " + "0\nSECTION\n 2\nTABLES\n 0\nTABLE\n%s0\nENDTAB\n0\nENDSEC\n " + "0\nSECTION\n 2\nBLOCKS\n0\nENDSEC\n 0\nSECTION\n 2\nENTITIES\n", + layerlist); } else { - msIO_fprintf(stream, "\n", mapName, img->width, img->height); + msIO_fprintf(stream, "\n", + mapName, img->width, img->height); } const int nSize = sizeof(workbuffer); @@ -676,18 +705,20 @@ int msSaveImageIM(imageObj* img, const char *filename, outputFormatObj *format ) if (size > nSize) { int iIndice = 0; while ((iIndice + nSize) <= size) { - snprintf(workbuffer, sizeof(workbuffer), "%s", img->img.imagemap+iIndice ); - workbuffer[nSize-1] = '\0'; + snprintf(workbuffer, sizeof(workbuffer), "%s", + img->img.imagemap + iIndice); + workbuffer[nSize - 1] = '\0'; msIO_fwrite(workbuffer, strlen(workbuffer), 1, stream); - iIndice +=nSize-1; + iIndice += nSize - 1; } if (iIndice < size) { - sprintf(workbuffer, "%s", img->img.imagemap+iIndice ); + sprintf(workbuffer, "%s", img->img.imagemap + iIndice); msIO_fprintf(stream, "%s", workbuffer); } } else msIO_fwrite(img->img.imagemap, size, 1, stream); - if( strcasecmp("OFF",msGetOutputFormatOption( format, "SKIPENDTAG", "OFF" )) == 0) { + if (strcasecmp("OFF", + msGetOutputFormatOption(format, "SKIPENDTAG", "OFF")) == 0) { if (dxf == 2) msIO_fprintf(stream, "END"); else if (dxf) @@ -697,21 +728,18 @@ int msSaveImageIM(imageObj* img, const char *filename, outputFormatObj *format ) } } else { msSetError(MS_MISCERR, "Unknown output image type driver: %s.", - "msSaveImage()", format->driver ); - if(stream_to_free != NULL) fclose(stream_to_free); - return(MS_FAILURE); + "msSaveImage()", format->driver); + if (stream_to_free != NULL) + fclose(stream_to_free); + return (MS_FAILURE); } - if(stream_to_free != NULL) fclose(stream_to_free); - return(MS_SUCCESS); + if (stream_to_free != NULL) + fclose(stream_to_free); + return (MS_SUCCESS); } - /* * Free gdImagePtr */ -void msFreeImageIM(imageObj* img) -{ - free(img->img.imagemap); -} - +void msFreeImageIM(imageObj *img) { free(img->img.imagemap); } diff --git a/mapio.c b/mapio.c index 85912f015c..8d31c04b7a 100644 --- a/mapio.c +++ b/mapio.c @@ -38,13 +38,10 @@ #endif #ifdef MOD_WMS_ENABLED -# include "httpd.h" -# include "apr_strings.h" +#include "httpd.h" +#include "apr_strings.h" #endif - - - static int is_msIO_initialized = MS_FALSE; static int is_msIO_header_enabled = MS_TRUE; @@ -53,20 +50,20 @@ typedef struct msIOContextGroup_t { msIOContext stdout_context; msIOContext stderr_context; - void* thread_id; + void *thread_id; struct msIOContextGroup_t *next; } msIOContextGroup; static msIOContextGroup default_contexts; static msIOContextGroup *io_context_list = NULL; -static void msIO_Initialize( void ); +static void msIO_Initialize(void); #ifdef msIO_printf -# undef msIO_printf -# undef msIO_fprintf -# undef msIO_fwrite -# undef msIO_fread -# undef msIO_vfprintf +#undef msIO_printf +#undef msIO_fprintf +#undef msIO_fwrite +#undef msIO_fread +#undef msIO_vfprintf #endif /************************************************************************/ @@ -76,14 +73,14 @@ static void msIO_Initialize( void ); void msIO_Cleanup() { - if( is_msIO_initialized ) + if (is_msIO_initialized) { is_msIO_initialized = MS_FALSE; - while( io_context_list != NULL ) { + while (io_context_list != NULL) { msIOContextGroup *last = io_context_list; io_context_list = io_context_list->next; - free( last ); + free(last); } } } @@ -95,20 +92,20 @@ void msIO_Cleanup() static msIOContextGroup *msIO_GetContextGroup() { - void* nThreadId = msGetThreadId(); + void *nThreadId = msGetThreadId(); msIOContextGroup *prev = NULL, *group = io_context_list; - if( group != NULL && group->thread_id == nThreadId ) + if (group != NULL && group->thread_id == nThreadId) return group; /* -------------------------------------------------------------------- */ /* Search for group for this thread */ /* -------------------------------------------------------------------- */ - msAcquireLock( TLOCK_IOCONTEXT ); + msAcquireLock(TLOCK_IOCONTEXT); msIO_Initialize(); group = io_context_list; - while( group != NULL && group->thread_id != nThreadId ) { + while (group != NULL && group->thread_id != nThreadId) { prev = group; group = group->next; } @@ -117,21 +114,21 @@ static msIOContextGroup *msIO_GetContextGroup() /* If we found it, make sure it is pushed to the front of the */ /* link for faster finding next time, and return it. */ /* -------------------------------------------------------------------- */ - if( group != NULL ) { - if( prev != NULL ) { + if (group != NULL) { + if (prev != NULL) { prev->next = group->next; group->next = io_context_list; io_context_list = group; } - msReleaseLock( TLOCK_IOCONTEXT ); + msReleaseLock(TLOCK_IOCONTEXT); return group; } /* -------------------------------------------------------------------- */ /* Create a new context group for this thread. */ /* -------------------------------------------------------------------- */ - group = (msIOContextGroup *) calloc(sizeof(msIOContextGroup),1); + group = (msIOContextGroup *)calloc(sizeof(msIOContextGroup), 1); group->stdin_context = default_contexts.stdin_context; group->stdout_context = default_contexts.stdout_context; @@ -141,7 +138,7 @@ static msIOContextGroup *msIO_GetContextGroup() group->next = io_context_list; io_context_list = group; - msReleaseLock( TLOCK_IOCONTEXT ); + msReleaseLock(TLOCK_IOCONTEXT); return group; } @@ -149,16 +146,16 @@ static msIOContextGroup *msIO_GetContextGroup() /* returns MS_TRUE if the msIO standard output hasn't been redirected */ int msIO_isStdContext() { msIOContextGroup *group = io_context_list; - void* nThreadId = msGetThreadId(); - if(!group || group->thread_id != nThreadId) { + void *nThreadId = msGetThreadId(); + if (!group || group->thread_id != nThreadId) { group = msIO_GetContextGroup(); - if(!group) { + if (!group) { return MS_FALSE; /* probably a bug */ } } - if(group->stderr_context.cbData == (void*)stderr && - group->stdin_context.cbData == (void*)stdin && - group->stdout_context.cbData == (void*)stdout) + if (group->stderr_context.cbData == (void *)stderr && + group->stdin_context.cbData == (void *)stdin && + group->stdout_context.cbData == (void *)stdout) return MS_TRUE; return MS_FALSE; } @@ -167,25 +164,25 @@ int msIO_isStdContext() { /* msIO_getHandler() */ /************************************************************************/ -msIOContext *msIO_getHandler( FILE * fp ) +msIOContext *msIO_getHandler(FILE *fp) { - void* nThreadId = msGetThreadId(); + void *nThreadId = msGetThreadId(); msIOContextGroup *group = io_context_list; msIO_Initialize(); - if( group == NULL || group->thread_id != nThreadId ) { + if (group == NULL || group->thread_id != nThreadId) { group = msIO_GetContextGroup(); - if( group == NULL ) + if (group == NULL) return NULL; } - if( fp == stdin || fp == NULL || strcmp((const char *)fp,"stdin") == 0 ) + if (fp == stdin || fp == NULL || strcmp((const char *)fp, "stdin") == 0) return &(group->stdin_context); - else if( fp == stdout || strcmp((const char *)fp,"stdout") == 0 ) + else if (fp == stdout || strcmp((const char *)fp, "stdout") == 0) return &(group->stdout_context); - else if( fp == stderr || strcmp((const char *)fp,"stderr") == 0 ) + else if (fp == stderr || strcmp((const char *)fp, "stderr") == 0) return &(group->stderr_context); else return NULL; @@ -195,68 +192,60 @@ msIOContext *msIO_getHandler( FILE * fp ) /* msIO_setHeaderEnabled() */ /************************************************************************/ -void msIO_setHeaderEnabled(int bFlag) -{ - is_msIO_header_enabled = bFlag; -} +void msIO_setHeaderEnabled(int bFlag) { is_msIO_header_enabled = bFlag; } /************************************************************************/ /* msIO_setHeader() */ /************************************************************************/ -void msIO_setHeader (const char *header, const char* value, ...) -{ +void msIO_setHeader(const char *header, const char *value, ...) { va_list args; - va_start( args, value ); + va_start(args, value); #ifdef MOD_WMS_ENABLED - msIOContext *ioctx = msIO_getHandler (stdout); - if(ioctx && !strcmp(ioctx->label,"apache")) { + msIOContext *ioctx = msIO_getHandler(stdout); + if (ioctx && !strcmp(ioctx->label, "apache")) { - request_rec *r = (request_rec*) (ioctx->cbData); - char *fullvalue = apr_pvsprintf(r->pool, value,args); - if (strcasecmp (header, "Content-Type") == 0) { + request_rec *r = (request_rec *)(ioctx->cbData); + char *fullvalue = apr_pvsprintf(r->pool, value, args); + if (strcasecmp(header, "Content-Type") == 0) { r->content_type = fullvalue; - } else if (strcasecmp (header, "Status") == 0) { - r->status = atoi (fullvalue); + } else if (strcasecmp(header, "Status") == 0) { + r->status = atoi(fullvalue); } else { - apr_table_setn (r->headers_out, - apr_pstrdup (r->pool, header), - fullvalue - ); + apr_table_setn(r->headers_out, apr_pstrdup(r->pool, header), fullvalue); } } else { #endif // MOD_WMS_ENABLED - if( is_msIO_header_enabled ) { - msIO_fprintf(stdout,"%s: ",header); - msIO_vfprintf(stdout,value,args); - msIO_fprintf(stdout,"\r\n"); - } + if (is_msIO_header_enabled) { + msIO_fprintf(stdout, "%s: ", header); + msIO_vfprintf(stdout, value, args); + msIO_fprintf(stdout, "\r\n"); + } #ifdef MOD_WMS_ENABLED } #endif - va_end( args ); + va_end(args); } -void msIO_sendHeaders () -{ +void msIO_sendHeaders() { #ifdef MOD_WMS_ENABLED - msIOContext *ioctx = msIO_getHandler (stdout); - if(ioctx && !strcmp(ioctx->label,"apache")) return; + msIOContext *ioctx = msIO_getHandler(stdout); + if (ioctx && !strcmp(ioctx->label, "apache")) + return; #endif // !MOD_WMS_ENABLED - if( is_msIO_header_enabled ) { - msIO_printf ("\r\n"); - fflush (stdout); + if (is_msIO_header_enabled) { + msIO_printf("\r\n"); + fflush(stdout); } } - /************************************************************************/ /* msIO_installHandlers() */ /************************************************************************/ -int msIO_installHandlers( msIOContext *stdin_context, - msIOContext *stdout_context, - msIOContext *stderr_context ) +int msIO_installHandlers(msIOContext *stdin_context, + msIOContext *stdout_context, + msIOContext *stderr_context) { msIOContextGroup *group; @@ -265,19 +254,19 @@ int msIO_installHandlers( msIOContext *stdin_context, group = msIO_GetContextGroup(); - if( stdin_context == NULL ) + if (stdin_context == NULL) group->stdin_context = default_contexts.stdin_context; - else if( stdin_context != &group->stdin_context ) + else if (stdin_context != &group->stdin_context) group->stdin_context = *stdin_context; - if( stdout_context == NULL ) + if (stdout_context == NULL) group->stdout_context = default_contexts.stdout_context; - else if( stdout_context != &group->stdout_context ) + else if (stdout_context != &group->stdout_context) group->stdout_context = *stdout_context; - if( stderr_context == NULL ) + if (stderr_context == NULL) group->stderr_context = default_contexts.stderr_context; - else if( stderr_context != &group->stderr_context ) + else if (stderr_context != &group->stderr_context) group->stderr_context = *stderr_context; return MS_TRUE; @@ -287,27 +276,26 @@ int msIO_installHandlers( msIOContext *stdin_context, /* msIO_contextRead() */ /************************************************************************/ -int msIO_contextRead( msIOContext *context, void *data, int byteCount ) +int msIO_contextRead(msIOContext *context, void *data, int byteCount) { - if( context->write_channel == MS_TRUE ) + if (context->write_channel == MS_TRUE) return 0; else - return context->readWriteFunc( context->cbData, data, byteCount ); + return context->readWriteFunc(context->cbData, data, byteCount); } /************************************************************************/ /* msIO_contextWrite() */ /************************************************************************/ -int msIO_contextWrite( msIOContext *context, const void *data, int byteCount ) +int msIO_contextWrite(msIOContext *context, const void *data, int byteCount) { - if( context->write_channel == MS_FALSE ) + if (context->write_channel == MS_FALSE) return 0; else - return context->readWriteFunc( context->cbData, (void *) data, - byteCount ); + return context->readWriteFunc(context->cbData, (void *)data, byteCount); } /* ==================================================================== */ @@ -320,15 +308,15 @@ int msIO_contextWrite( msIOContext *context, const void *data, int byteCount ) /* _ms_vsprintf() */ /************************************************************************/ -static int _ms_vsprintf(char **workBufPtr, const char *format, va_list ap ) +static int _ms_vsprintf(char **workBufPtr, const char *format, va_list ap) { - int ret_val; - int workBufSize = 16000; + int ret_val; + int workBufSize = 16000; - *workBufPtr = (char*)malloc(workBufSize * sizeof(char)); + *workBufPtr = (char *)malloc(workBufSize * sizeof(char)); if (*workBufPtr == NULL) { - msSetError( MS_MEMERR, NULL, "_ms_vsprintf()"); + msSetError(MS_MEMERR, NULL, "_ms_vsprintf()"); return -1; } @@ -338,35 +326,35 @@ static int _ms_vsprintf(char **workBufPtr, const char *format, va_list ap ) va_list wrk_args; #ifdef va_copy - va_copy( wrk_args, ap ); + va_copy(wrk_args, ap); #else wrk_args = ap; #endif - while( (ret_val = vsnprintf( *workBufPtr, workBufSize, - format, wrk_args)) >= workBufSize-1 - || ret_val == -1 ) { + while ((ret_val = vsnprintf(*workBufPtr, workBufSize, format, wrk_args)) >= + workBufSize - 1 || + ret_val == -1) { workBufSize *= 4; - *workBufPtr = (char *) realloc(*workBufPtr, workBufSize ); + *workBufPtr = (char *)realloc(*workBufPtr, workBufSize); if (*workBufPtr == NULL) { - msSetError( MS_MEMERR, NULL, "_ms_vsprintf()"); - va_end( wrk_args ); + msSetError(MS_MEMERR, NULL, "_ms_vsprintf()"); + va_end(wrk_args); return -1; } #ifdef va_copy - va_end( wrk_args ); - va_copy( wrk_args, ap ); + va_end(wrk_args); + va_copy(wrk_args, ap); #else wrk_args = ap; #endif } - va_end( wrk_args ); + va_end(wrk_args); } #else /* We do not have vsnprintf()... there is a risk of buffer overrun */ - ret_val = vsprintf( *workBufPtr, format, ap ); + ret_val = vsprintf(*workBufPtr, format, ap); - if( ret_val < 0 || ret_val >= workBufSize ) { + if (ret_val < 0 || ret_val >= workBufSize) { msSetError(MS_MISCERR, "Possible buffer overrun.", "_ms_vsprintf()"); msFree(*workBufPtr); *workBufPtr = NULL; @@ -377,18 +365,17 @@ static int _ms_vsprintf(char **workBufPtr, const char *format, va_list ap ) return ret_val; } - /************************************************************************/ /* msIO_printf() */ /************************************************************************/ -int msIO_printf( const char *format, ... ) +int msIO_printf(const char *format, ...) { va_list args; int ret; - va_start( args, format ); - ret = msIO_vfprintf(stdout,format,args); + va_start(args, format); + ret = msIO_vfprintf(stdout, format, args); va_end(args); return ret; } @@ -397,13 +384,13 @@ int msIO_printf( const char *format, ... ) /* msIO_fprintf() */ /************************************************************************/ -int msIO_fprintf( FILE *fp, const char *format, ... ) +int msIO_fprintf(FILE *fp, const char *format, ...) { va_list args; int ret; - va_start( args, format ); - ret = msIO_vfprintf(fp,format,args); + va_start(args, format); + ret = msIO_vfprintf(fp, format, args); va_end(args); return ret; } @@ -412,53 +399,51 @@ int msIO_fprintf( FILE *fp, const char *format, ... ) /* msIO_vfprintf() */ /************************************************************************/ -int msIO_vfprintf( FILE *fp, const char *format, va_list ap ) +int msIO_vfprintf(FILE *fp, const char *format, va_list ap) { - int return_val; + int return_val; msIOContext *context; char workBuf[8000]; #if !defined(HAVE_VSNPRINTF) - return_val = vsprintf( workBuf, format, ap); + return_val = vsprintf(workBuf, format, ap); - if( return_val < 0 || return_val >= sizeof(workBuf) ) { + if (return_val < 0 || return_val >= sizeof(workBuf)) { msSetError(MS_MISCERR, "Possible buffer overrun.", "msIO_vfprintf()"); return -1; } - char* outbuf = workBuf; + char *outbuf = workBuf; #else va_list args_copy; #ifdef va_copy - va_copy( args_copy, ap ); + va_copy(args_copy, ap); #else args_copy = ap; #endif /* va_copy */ - char* largerBuf = NULL; - return_val = vsnprintf( workBuf, sizeof(workBuf), format, ap ); - if (return_val == -1 || return_val >= (int)sizeof(workBuf)-1) { - return_val = _ms_vsprintf(&largerBuf, format, args_copy ); + char *largerBuf = NULL; + return_val = vsnprintf(workBuf, sizeof(workBuf), format, ap); + if (return_val == -1 || return_val >= (int)sizeof(workBuf) - 1) { + return_val = _ms_vsprintf(&largerBuf, format, args_copy); } va_end(args_copy); if (return_val < 0) return -1; - char* outbuf = largerBuf?largerBuf:workBuf; + char *outbuf = largerBuf ? largerBuf : workBuf; #endif /* HAVE_VSNPRINTF */ - context = msIO_getHandler( fp ); - if( context == NULL ) - return_val = fwrite(outbuf , 1, return_val, fp ); + context = msIO_getHandler(fp); + if (context == NULL) + return_val = fwrite(outbuf, 1, return_val, fp); else - return_val = msIO_contextWrite( context, - outbuf, - return_val ); + return_val = msIO_contextWrite(context, outbuf, return_val); #if defined(HAVE_VSNPRINTF) msFree(largerBuf); @@ -471,38 +456,38 @@ int msIO_vfprintf( FILE *fp, const char *format, va_list ap ) /* msIO_fwrite() */ /************************************************************************/ -int msIO_fwrite( const void *data, size_t size, size_t nmemb, FILE *fp ) +int msIO_fwrite(const void *data, size_t size, size_t nmemb, FILE *fp) { msIOContext *context; - if( size == 0 || nmemb == 0 ) + if (size == 0 || nmemb == 0) return 0; - context = msIO_getHandler( fp ); - if( context == NULL ) - return fwrite( data, size, nmemb, fp ); + context = msIO_getHandler(fp); + if (context == NULL) + return fwrite(data, size, nmemb, fp); else - return msIO_contextWrite( context, data, size * nmemb ) / size; + return msIO_contextWrite(context, data, size * nmemb) / size; } /************************************************************************/ /* msIO_fread() */ /************************************************************************/ -int msIO_fread( void *data, size_t size, size_t nmemb, FILE *fp ) +int msIO_fread(void *data, size_t size, size_t nmemb, FILE *fp) { msIOContext *context; - if( size == 0 || nmemb == 0 ) + if (size == 0 || nmemb == 0) return 0; - context = msIO_getHandler( fp ); - if( context == NULL ) - return fread( data, size, nmemb, fp ); + context = msIO_getHandler(fp); + if (context == NULL) + return fread(data, size, nmemb, fp); else - return msIO_contextRead( context, data, size * nmemb ) / size; + return msIO_contextRead(context, data, size * nmemb) / size; } /* ==================================================================== */ @@ -518,10 +503,10 @@ int msIO_fread( void *data, size_t size, size_t nmemb, FILE *fp ) /* This is the default implementation via stdio. */ /************************************************************************/ -static int msIO_stdioRead( void *cbData, void *data, int byteCount ) +static int msIO_stdioRead(void *cbData, void *data, int byteCount) { - return fread( data, 1, byteCount, (FILE *) cbData ); + return fread(data, 1, byteCount, (FILE *)cbData); } /************************************************************************/ @@ -530,36 +515,36 @@ static int msIO_stdioRead( void *cbData, void *data, int byteCount ) /* This is the default implementation via stdio. */ /************************************************************************/ -static int msIO_stdioWrite( void *cbData, void *data, int byteCount ) +static int msIO_stdioWrite(void *cbData, void *data, int byteCount) { - return fwrite( data, 1, byteCount, (FILE *) cbData ); + return fwrite(data, 1, byteCount, (FILE *)cbData); } /************************************************************************/ /* msIO_Initialize() */ /************************************************************************/ -static void msIO_Initialize( void ) +static void msIO_Initialize(void) { - if( is_msIO_initialized == MS_TRUE ) + if (is_msIO_initialized == MS_TRUE) return; default_contexts.stdin_context.label = "stdio"; default_contexts.stdin_context.write_channel = MS_FALSE; default_contexts.stdin_context.readWriteFunc = msIO_stdioRead; - default_contexts.stdin_context.cbData = (void *) stdin; + default_contexts.stdin_context.cbData = (void *)stdin; default_contexts.stdout_context.label = "stdio"; default_contexts.stdout_context.write_channel = MS_TRUE; default_contexts.stdout_context.readWriteFunc = msIO_stdioWrite; - default_contexts.stdout_context.cbData = (void *) stdout; + default_contexts.stdout_context.cbData = (void *)stdout; default_contexts.stderr_context.label = "stdio"; default_contexts.stderr_context.write_channel = MS_TRUE; default_contexts.stderr_context.readWriteFunc = msIO_stdioWrite; - default_contexts.stderr_context.cbData = (void *) stderr; + default_contexts.stderr_context.cbData = (void *)stderr; default_contexts.next = NULL; default_contexts.thread_id = 0; @@ -567,15 +552,12 @@ static void msIO_Initialize( void ) is_msIO_initialized = MS_TRUE; } - /* ==================================================================== */ /* ==================================================================== */ /* FastCGI output redirection functions. */ /* ==================================================================== */ /* ==================================================================== */ - - /************************************************************************/ /* msIO_needBinaryStdout() */ /* */ @@ -592,11 +574,10 @@ int msIO_needBinaryStdout() { #if defined(_WIN32) && !defined(USE_FASTCGI) - if(_setmode( _fileno(stdout), _O_BINARY) == -1) { - msSetError(MS_IOERR, - "Unable to change stdout to binary mode.", - "msIO_needBinaryStdout()" ); - return(MS_FAILURE); + if (_setmode(_fileno(stdout), _O_BINARY) == -1) { + msSetError(MS_IOERR, "Unable to change stdout to binary mode.", + "msIO_needBinaryStdout()"); + return (MS_FAILURE); } #endif @@ -619,11 +600,10 @@ int msIO_needBinaryStdin() { #if defined(_WIN32) && !defined(USE_FASTCGI) - if(_setmode( _fileno(stdin), _O_BINARY) == -1) { - msSetError(MS_IOERR, - "Unable to change stdin to binary mode.", - "msIO_needBinaryStdin()" ); - return(MS_FAILURE); + if (_setmode(_fileno(stdin), _O_BINARY) == -1) { + msSetError(MS_IOERR, "Unable to change stdin to binary mode.", + "msIO_needBinaryStdin()"); + return (MS_FAILURE); } #endif @@ -643,34 +623,34 @@ void msIO_resetHandlers() { msIOContextGroup *group = msIO_GetContextGroup(); - if( group == NULL ) + if (group == NULL) return; - if( strcmp(group->stdin_context.label,"buffer") == 0 ) { - msIOBuffer *buf = (msIOBuffer *) group->stdin_context.cbData; + if (strcmp(group->stdin_context.label, "buffer") == 0) { + msIOBuffer *buf = (msIOBuffer *)group->stdin_context.cbData; - if( buf->data != NULL ) - free( buf->data ); - free( buf ); + if (buf->data != NULL) + free(buf->data); + free(buf); } - if( strcmp(group->stdout_context.label,"buffer") == 0 ) { - msIOBuffer *buf = (msIOBuffer *) group->stdout_context.cbData; + if (strcmp(group->stdout_context.label, "buffer") == 0) { + msIOBuffer *buf = (msIOBuffer *)group->stdout_context.cbData; - if( buf->data != NULL ) - free( buf->data ); - free( buf ); + if (buf->data != NULL) + free(buf->data); + free(buf); } - if( strcmp(group->stderr_context.label,"buffer") == 0 ) { - msIOBuffer *buf = (msIOBuffer *) group->stderr_context.cbData; + if (strcmp(group->stderr_context.label, "buffer") == 0) { + msIOBuffer *buf = (msIOBuffer *)group->stderr_context.cbData; - if( buf->data != NULL ) - free( buf->data ); - free( buf ); + if (buf->data != NULL) + free(buf->data); + free(buf); } - msIO_installHandlers( NULL, NULL, NULL ); + msIO_installHandlers(NULL, NULL, NULL); } /************************************************************************/ @@ -681,19 +661,16 @@ void msIO_installStdoutToBuffer() { msIOContextGroup *group = msIO_GetContextGroup(); - msIOContext context; + msIOContext context; context.label = "buffer"; context.write_channel = MS_TRUE; context.readWriteFunc = msIO_bufferWrite; - context.cbData = calloc(sizeof(msIOBuffer),1); + context.cbData = calloc(sizeof(msIOBuffer), 1); - msIO_installHandlers( &group->stdin_context, - &context, - &group->stderr_context ); + msIO_installHandlers(&group->stdin_context, &context, &group->stderr_context); } - /************************************************************************/ /* msIO_pushStdoutToBufferAndGetOldContext() */ /* */ @@ -704,14 +681,14 @@ void msIO_installStdoutToBuffer() /* libxml objects XML generated by msIO_fprintf() */ /************************************************************************/ -msIOContext* msIO_pushStdoutToBufferAndGetOldContext() +msIOContext *msIO_pushStdoutToBufferAndGetOldContext() { msIOContextGroup *group = msIO_GetContextGroup(); msIOContext *old_context; /* Backup current context */ - old_context = (msIOContext*) msSmallMalloc(sizeof(msIOContext)); + old_context = (msIOContext *)msSmallMalloc(sizeof(msIOContext)); memcpy(old_context, &group->stdout_context, sizeof(msIOContext)); msIO_installStdoutToBuffer(); @@ -723,23 +700,21 @@ msIOContext* msIO_pushStdoutToBufferAndGetOldContext() /* msIO_restoreOldStdoutContext() */ /************************************************************************/ -void msIO_restoreOldStdoutContext(msIOContext *context_to_restore) -{ +void msIO_restoreOldStdoutContext(msIOContext *context_to_restore) { msIOContextGroup *group = msIO_GetContextGroup(); msIOContext *prev_context = &group->stdout_context; - msIOBuffer* buffer; - + msIOBuffer *buffer; + /* Free memory associated to our temporary context */ - assert( strcmp(prev_context->label, "buffer") == 0 ); + assert(strcmp(prev_context->label, "buffer") == 0); - buffer = (msIOBuffer* )prev_context->cbData; + buffer = (msIOBuffer *)prev_context->cbData; msFree(buffer->data); msFree(buffer); /* Restore old context */ - msIO_installHandlers( &group->stdin_context, - context_to_restore, - &group->stderr_context ); + msIO_installHandlers(&group->stdin_context, context_to_restore, + &group->stderr_context); msFree(context_to_restore); } @@ -752,16 +727,15 @@ void msIO_installStdinFromBuffer() { msIOContextGroup *group = msIO_GetContextGroup(); - msIOContext context; + msIOContext context; context.label = "buffer"; context.write_channel = MS_FALSE; context.readWriteFunc = msIO_bufferRead; - context.cbData = calloc(sizeof(msIOBuffer),1); + context.cbData = calloc(sizeof(msIOBuffer), 1); - msIO_installHandlers( &context, - &group->stdout_context, - &group->stderr_context ); + msIO_installHandlers(&context, &group->stdout_context, + &group->stderr_context); } /************************************************************************/ @@ -769,24 +743,23 @@ void msIO_installStdinFromBuffer() /* */ /************************************************************************/ -hashTableObj* msIO_getAndStripStdoutBufferMimeHeaders() -{ +hashTableObj *msIO_getAndStripStdoutBufferMimeHeaders() { /* -------------------------------------------------------------------- */ /* Find stdout buffer. */ /* -------------------------------------------------------------------- */ - msIOContext *ctx = msIO_getHandler( (FILE *) "stdout" ); - msIOBuffer *buf; + msIOContext *ctx = msIO_getHandler((FILE *)"stdout"); + msIOBuffer *buf; int start_of_mime_header, current_pos; - hashTableObj* hashTable; + hashTableObj *hashTable; - if( ctx == NULL || ctx->write_channel == MS_FALSE - || strcmp(ctx->label,"buffer") != 0 ) { - msSetError( MS_MISCERR, "Can't identify msIO buffer.", - "msIO_getAndStripStdoutBufferMimeHeaders" ); + if (ctx == NULL || ctx->write_channel == MS_FALSE || + strcmp(ctx->label, "buffer") != 0) { + msSetError(MS_MISCERR, "Can't identify msIO buffer.", + "msIO_getAndStripStdoutBufferMimeHeaders"); return NULL; } - buf = (msIOBuffer *) ctx->cbData; + buf = (msIOBuffer *)ctx->cbData; hashTable = msCreateHashTable(); @@ -794,90 +767,82 @@ hashTableObj* msIO_getAndStripStdoutBufferMimeHeaders() /* Loop over all headers. */ /* -------------------------------------------------------------------- */ current_pos = 0; - while( MS_TRUE ) { + while (MS_TRUE) { int pos_of_column = -1; - char* key, *value; + char *key, *value; start_of_mime_header = current_pos; - while( current_pos < buf->data_offset ) - { - if( buf->data[current_pos] == '\r' ) - { - if( current_pos + 1 == buf->data_offset || - buf->data[current_pos + 1] != '\n' ) - { - pos_of_column = -1; - break; - } - break; + while (current_pos < buf->data_offset) { + if (buf->data[current_pos] == '\r') { + if (current_pos + 1 == buf->data_offset || + buf->data[current_pos + 1] != '\n') { + pos_of_column = -1; + break; } - if( buf->data[current_pos] == ':' ) - { - pos_of_column = current_pos; - if( current_pos + 1 == buf->data_offset || - buf->data[current_pos + 1] != ' ' ) - { - pos_of_column = -1; - break; - } + break; + } + if (buf->data[current_pos] == ':') { + pos_of_column = current_pos; + if (current_pos + 1 == buf->data_offset || + buf->data[current_pos + 1] != ' ') { + pos_of_column = -1; + break; } - current_pos++; + } + current_pos++; } - if( pos_of_column < 0 || current_pos == buf->data_offset ) { - msSetError( MS_MISCERR, "Corrupt mime headers.", - "msIO_getAndStripStdoutBufferMimeHeaders" ); + if (pos_of_column < 0 || current_pos == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt mime headers.", + "msIO_getAndStripStdoutBufferMimeHeaders"); msFreeHashTable(hashTable); return NULL; } - key = (char*) malloc( pos_of_column - start_of_mime_header + 1 ); - memcpy( key, buf->data+start_of_mime_header, pos_of_column - start_of_mime_header); + key = (char *)malloc(pos_of_column - start_of_mime_header + 1); + memcpy(key, buf->data + start_of_mime_header, + pos_of_column - start_of_mime_header); key[pos_of_column - start_of_mime_header] = '\0'; - value = (char*) malloc( current_pos - (pos_of_column+2) + 1 ); - memcpy( value, buf->data+pos_of_column+2, current_pos - (pos_of_column+2)); - value[current_pos - (pos_of_column+2)] = '\0'; + value = (char *)malloc(current_pos - (pos_of_column + 2) + 1); + memcpy(value, buf->data + pos_of_column + 2, + current_pos - (pos_of_column + 2)); + value[current_pos - (pos_of_column + 2)] = '\0'; - msInsertHashTable( hashTable, key, value ); + msInsertHashTable(hashTable, key, value); - msFree( key ); - msFree( value ); + msFree(key); + msFree(value); /* -------------------------------------------------------------------- */ /* Go to next line. */ /* -------------------------------------------------------------------- */ current_pos += 2; - if( current_pos == buf->data_offset ) - { - msSetError( MS_MISCERR, "Corrupt mime headers.", - "msIO_getAndStripStdoutBufferMimeHeaders" ); + if (current_pos == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt mime headers.", + "msIO_getAndStripStdoutBufferMimeHeaders"); msFreeHashTable(hashTable); return NULL; } /* If next line is a '\r', this is the end of mime headers. */ - if( buf->data[current_pos] == '\r' ) - { - current_pos ++; - if( current_pos == buf->data_offset || - buf->data[current_pos] != '\n' ) - { - msSetError( MS_MISCERR, "Corrupt mime headers.", - "msIO_getAndStripStdoutBufferMimeHeaders" ); - msFreeHashTable(hashTable); - return NULL; - } - current_pos ++; - break; + if (buf->data[current_pos] == '\r') { + current_pos++; + if (current_pos == buf->data_offset || buf->data[current_pos] != '\n') { + msSetError(MS_MISCERR, "Corrupt mime headers.", + "msIO_getAndStripStdoutBufferMimeHeaders"); + msFreeHashTable(hashTable); + return NULL; + } + current_pos++; + break; } } /* -------------------------------------------------------------------- */ /* Move data to front of buffer, and reset length. */ /* -------------------------------------------------------------------- */ - memmove( buf->data, buf->data+current_pos, - buf->data_offset - current_pos ); + memmove(buf->data, buf->data + current_pos, buf->data_offset - current_pos); buf->data[buf->data_offset - current_pos] = '\0'; buf->data_offset -= current_pos; @@ -899,38 +864,37 @@ char *msIO_stripStdoutBufferContentType() /* -------------------------------------------------------------------- */ /* Find stdout buffer. */ /* -------------------------------------------------------------------- */ - msIOContext *ctx = msIO_getHandler( (FILE *) "stdout" ); - msIOBuffer *buf; + msIOContext *ctx = msIO_getHandler((FILE *)"stdout"); + msIOBuffer *buf; char *content_type = NULL; int end_of_ct, start_of_data; - if( ctx == NULL || ctx->write_channel == MS_FALSE - || strcmp(ctx->label,"buffer") != 0 ) { - msSetError( MS_MISCERR, "Can't identify msIO buffer.", - "msIO_stripStdoutBufferContentType" ); + if (ctx == NULL || ctx->write_channel == MS_FALSE || + strcmp(ctx->label, "buffer") != 0) { + msSetError(MS_MISCERR, "Can't identify msIO buffer.", + "msIO_stripStdoutBufferContentType"); return NULL; } - buf = (msIOBuffer *) ctx->cbData; + buf = (msIOBuffer *)ctx->cbData; /* -------------------------------------------------------------------- */ /* Return NULL if we don't have a Content-Type header. */ /* -------------------------------------------------------------------- */ - if( buf->data_offset < 14 - || strncasecmp((const char*) buf->data,"Content-Type: ",14) != 0 ) + if (buf->data_offset < 14 || + strncasecmp((const char *)buf->data, "Content-Type: ", 14) != 0) return NULL; /* -------------------------------------------------------------------- */ /* Find newline marker at end of content type argument. */ /* -------------------------------------------------------------------- */ end_of_ct = 13; - while( end_of_ct+1 < buf->data_offset - && buf->data[end_of_ct+1] != '\r' ) + while (end_of_ct + 1 < buf->data_offset && buf->data[end_of_ct + 1] != '\r') end_of_ct++; - if( end_of_ct+1 == buf->data_offset ) { - msSetError( MS_MISCERR, "Corrupt Content-Type header.", - "msIO_stripStdoutBufferContentType" ); + if (end_of_ct + 1 == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt Content-Type header.", + "msIO_stripStdoutBufferContentType"); return NULL; } @@ -938,14 +902,13 @@ char *msIO_stripStdoutBufferContentType() /* Continue on to the start of data ... */ /* Go to next line and skip if empty. */ /* -------------------------------------------------------------------- */ - start_of_data = end_of_ct+3; - if( start_of_data < buf->data_offset - && buf->data[start_of_data] == '\r' ) - start_of_data +=2; - - if( start_of_data == buf->data_offset ) { - msSetError( MS_MISCERR, "Corrupt Content-Type header.", - "msIO_stripStdoutBufferContentType" ); + start_of_data = end_of_ct + 3; + if (start_of_data < buf->data_offset && buf->data[start_of_data] == '\r') + start_of_data += 2; + + if (start_of_data == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt Content-Type header.", + "msIO_stripStdoutBufferContentType"); return NULL; } @@ -955,15 +918,15 @@ char *msIO_stripStdoutBufferContentType() /* buffer may not be NULL terminated - strlcpy() requires NULL */ /* terminated sources (see issue #4672). */ /* -------------------------------------------------------------------- */ - content_type = (char *) malloc(end_of_ct-14+2); - strncpy( content_type, (const char *) buf->data + 14, end_of_ct - 14 + 2); - content_type[end_of_ct-14+1] = '\0'; + content_type = (char *)malloc(end_of_ct - 14 + 2); + strncpy(content_type, (const char *)buf->data + 14, end_of_ct - 14 + 2); + content_type[end_of_ct - 14 + 1] = '\0'; /* -------------------------------------------------------------------- */ /* Move data to front of buffer, and reset length. */ /* -------------------------------------------------------------------- */ - memmove( buf->data, buf->data+start_of_data, - buf->data_offset - start_of_data ); + memmove(buf->data, buf->data + start_of_data, + buf->data_offset - start_of_data); buf->data[buf->data_offset - start_of_data] = '\0'; buf->data_offset -= start_of_data; @@ -976,75 +939,74 @@ char *msIO_stripStdoutBufferContentType() /* Strip off Content-* headers from buffer. */ /************************************************************************/ -void msIO_stripStdoutBufferContentHeaders() -{ +void msIO_stripStdoutBufferContentHeaders() { /* -------------------------------------------------------------------- */ /* Find stdout buffer. */ /* -------------------------------------------------------------------- */ - msIOContext *ctx = msIO_getHandler( (FILE *) "stdout" ); - msIOBuffer *buf; + msIOContext *ctx = msIO_getHandler((FILE *)"stdout"); + msIOBuffer *buf; int start_of_data; - if( ctx == NULL || ctx->write_channel == MS_FALSE - || strcmp(ctx->label,"buffer") != 0 ) { - msSetError( MS_MISCERR, "Can't identify msIO buffer.", - "msIO_stripStdoutBufferContentHeaders" ); + if (ctx == NULL || ctx->write_channel == MS_FALSE || + strcmp(ctx->label, "buffer") != 0) { + msSetError(MS_MISCERR, "Can't identify msIO buffer.", + "msIO_stripStdoutBufferContentHeaders"); return; } - buf = (msIOBuffer *) ctx->cbData; + buf = (msIOBuffer *)ctx->cbData; /* -------------------------------------------------------------------- */ /* Exit if we don't have any content-* header. */ /* -------------------------------------------------------------------- */ - if( buf->data_offset < 8 - || strncasecmp((const char*) buf->data,"Content-",8) != 0 ) + if (buf->data_offset < 8 || + strncasecmp((const char *)buf->data, "Content-", 8) != 0) return; /* -------------------------------------------------------------------- */ /* Loop over all content-* headers. */ /* -------------------------------------------------------------------- */ start_of_data = 0; - while( buf->data_offset > start_of_data - && strncasecmp((const char*) buf->data+start_of_data,"Content-",8) == 0 ) { + while (buf->data_offset > start_of_data && + strncasecmp((const char *)buf->data + start_of_data, "Content-", 8) == + 0) { /* -------------------------------------------------------------------- */ /* Find newline marker at end of content-* header argument. */ /* -------------------------------------------------------------------- */ - start_of_data +=7; - while( start_of_data+1 < buf->data_offset - && buf->data[start_of_data+1] != '\r' ) + start_of_data += 7; + while (start_of_data + 1 < buf->data_offset && + buf->data[start_of_data + 1] != '\r') start_of_data++; - if( start_of_data+1 == buf->data_offset ) { - msSetError( MS_MISCERR, "Corrupt Content-* header.", - "msIO_stripStdoutBufferContentHeaders" ); + if (start_of_data + 1 == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt Content-* header.", + "msIO_stripStdoutBufferContentHeaders"); return; } /* -------------------------------------------------------------------- */ /* Go to next line. */ /* -------------------------------------------------------------------- */ - start_of_data +=3; + start_of_data += 3; } /* -------------------------------------------------------------------- */ /* Continue on to the start of data ... */ /* Skip next line if empty. */ /* -------------------------------------------------------------------- */ - if( start_of_data < buf->data_offset - && buf->data[start_of_data] == '\r' ) - start_of_data +=2; + if (start_of_data < buf->data_offset && buf->data[start_of_data] == '\r') + start_of_data += 2; - if( start_of_data == buf->data_offset ) { - msSetError( MS_MISCERR, "Corrupt Content-* header.", - "msIO_stripStdoutBufferContentHeaders" ); + if (start_of_data == buf->data_offset) { + msSetError(MS_MISCERR, "Corrupt Content-* header.", + "msIO_stripStdoutBufferContentHeaders"); return; } /* -------------------------------------------------------------------- */ /* Move data to front of buffer, and reset length. */ /* -------------------------------------------------------------------- */ - memmove( buf->data, buf->data+start_of_data, - buf->data_offset - start_of_data ); + memmove(buf->data, buf->data + start_of_data, + buf->data_offset - start_of_data); buf->data[buf->data_offset - start_of_data] = '\0'; buf->data_offset -= start_of_data; @@ -1055,25 +1017,24 @@ void msIO_stripStdoutBufferContentHeaders() /* msIO_bufferWrite() */ /************************************************************************/ -int msIO_bufferWrite( void *cbData, void *data, int byteCount ) +int msIO_bufferWrite(void *cbData, void *data, int byteCount) { - msIOBuffer *buf = (msIOBuffer *) cbData; + msIOBuffer *buf = (msIOBuffer *)cbData; /* ** Grow buffer if needed (reserve one extra byte to put nul character) */ - if( buf->data_offset + byteCount >= buf->data_len ) { + if (buf->data_offset + byteCount >= buf->data_len) { buf->data_len = buf->data_len * 2 + byteCount + 100; - if( buf->data == NULL ) - buf->data = (unsigned char *) malloc(buf->data_len); + if (buf->data == NULL) + buf->data = (unsigned char *)malloc(buf->data_len); else - buf->data = (unsigned char *) realloc(buf->data, buf->data_len); + buf->data = (unsigned char *)realloc(buf->data, buf->data_len); - if( buf->data == NULL ) { - msSetError( MS_MEMERR, - "Failed to allocate %d bytes for capture buffer.", - "msIO_bufferWrite()", buf->data_len ); + if (buf->data == NULL) { + msSetError(MS_MEMERR, "Failed to allocate %d bytes for capture buffer.", + "msIO_bufferWrite()", buf->data_len); buf->data_len = 0; return 0; } @@ -1083,7 +1044,7 @@ int msIO_bufferWrite( void *cbData, void *data, int byteCount ) ** Copy result into buffer. */ - memcpy( buf->data + buf->data_offset, data, byteCount ); + memcpy(buf->data + buf->data_offset, data, byteCount); buf->data_offset += byteCount; buf->data[buf->data_offset] = '\0'; @@ -1094,7 +1055,7 @@ int msIO_bufferWrite( void *cbData, void *data, int byteCount ) /* msIO_bufferRead() */ /************************************************************************/ -int msIO_bufferRead( void *cbData, void *data, int byteCount ) +int msIO_bufferRead(void *cbData, void *data, int byteCount) { (void)cbData; diff --git a/mapio.h b/mapio.h index e0499150a2..2e45d376d4 100644 --- a/mapio.h +++ b/mapio.h @@ -45,79 +45,85 @@ extern "C" { #ifndef MS_PRINT_FUNC_FORMAT #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP) -#define MS_PRINT_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#define MS_PRINT_FUNC_FORMAT(format_idx, arg_idx) \ + __attribute__((__format__(__printf__, format_idx, arg_idx))) #else -#define MS_PRINT_FUNC_FORMAT( format_idx, arg_idx ) +#define MS_PRINT_FUNC_FORMAT(format_idx, arg_idx) #endif #endif - /* stdio analogs */ - int MS_DLL_EXPORT msIO_printf( const char *format, ... ) MS_PRINT_FUNC_FORMAT(1,2); - int MS_DLL_EXPORT msIO_fprintf( FILE *stream, const char *format, ... ) MS_PRINT_FUNC_FORMAT(2,3); - int MS_DLL_EXPORT msIO_fwrite( const void *ptr, size_t size, size_t nmemb, FILE *stream ); - int MS_DLL_EXPORT msIO_fread( void *ptr, size_t size, size_t nmemb, FILE *stream ); - int MS_DLL_EXPORT msIO_vfprintf( FILE *fp, const char *format, va_list ap ) MS_PRINT_FUNC_FORMAT(2,0); - - /* - ** Definitions for the callback function and the details of the IO - ** channel contexts. - */ - - typedef int (*msIO_llReadWriteFunc)( void *cbData, void *data, int byteCount ); - - typedef struct msIOContext_t { - const char *label; - int write_channel; /* 1 for stdout/stderr, 0 for stdin */ - msIO_llReadWriteFunc readWriteFunc; - void *cbData; - } msIOContext; - - int MS_DLL_EXPORT msIO_installHandlers( msIOContext *stdin_context, - msIOContext *stdout_context, - msIOContext *stderr_context ); - msIOContext MS_DLL_EXPORT *msIO_getHandler( FILE * ); - void MS_DLL_EXPORT msIO_setHeaderEnabled(int bFlag); - void msIO_setHeader (const char *header, const char* value, ...) MS_PRINT_FUNC_FORMAT(2,3); - void msIO_sendHeaders(void); - - /* - ** These can be used instead of the stdio style functions if you have - ** msIOContext's for the channel in question. - */ - int msIO_contextRead( msIOContext *context, void *data, int byteCount ); - int msIO_contextWrite( msIOContext *context, const void *data, int byteCount ); - - /* - ** For redirecting IO to a memory buffer. - */ - - typedef struct { - unsigned char *data; - int data_len; /* really buffer length */ - int data_offset; /* really buffer used */ - } msIOBuffer; - - int MS_DLL_EXPORT msIO_bufferRead( void *, void *, int ); - int MS_DLL_EXPORT msIO_bufferWrite( void *, void *, int ); - - void MS_DLL_EXPORT msIO_resetHandlers(void); - void MS_DLL_EXPORT msIO_installStdoutToBuffer(void); - void MS_DLL_EXPORT msIO_installStdinFromBuffer(void); - void MS_DLL_EXPORT msIO_Cleanup(void); - char MS_DLL_EXPORT *msIO_stripStdoutBufferContentType(void); - void MS_DLL_EXPORT msIO_stripStdoutBufferContentHeaders(void); - hashTableObj MS_DLL_EXPORT *msIO_getAndStripStdoutBufferMimeHeaders(void); - - msIOContext *msIO_pushStdoutToBufferAndGetOldContext(void); - void msIO_restoreOldStdoutContext(msIOContext *context_to_restore); - - int MS_DLL_EXPORT msIO_isStdContext(void); - - - /* this is just for setting normal stdout's to binary mode on windows */ - - int msIO_needBinaryStdout( void ); - int msIO_needBinaryStdin( void ); +/* stdio analogs */ +int MS_DLL_EXPORT msIO_printf(const char *format, ...) + MS_PRINT_FUNC_FORMAT(1, 2); +int MS_DLL_EXPORT msIO_fprintf(FILE *stream, const char *format, ...) + MS_PRINT_FUNC_FORMAT(2, 3); +int MS_DLL_EXPORT msIO_fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *stream); +int MS_DLL_EXPORT msIO_fread(void *ptr, size_t size, size_t nmemb, + FILE *stream); +int MS_DLL_EXPORT msIO_vfprintf(FILE *fp, const char *format, va_list ap) + MS_PRINT_FUNC_FORMAT(2, 0); + +/* +** Definitions for the callback function and the details of the IO +** channel contexts. +*/ + +typedef int (*msIO_llReadWriteFunc)(void *cbData, void *data, int byteCount); + +typedef struct msIOContext_t { + const char *label; + int write_channel; /* 1 for stdout/stderr, 0 for stdin */ + msIO_llReadWriteFunc readWriteFunc; + void *cbData; +} msIOContext; + +int MS_DLL_EXPORT msIO_installHandlers(msIOContext *stdin_context, + msIOContext *stdout_context, + msIOContext *stderr_context); +msIOContext MS_DLL_EXPORT *msIO_getHandler(FILE *); +void MS_DLL_EXPORT msIO_setHeaderEnabled(int bFlag); +void msIO_setHeader(const char *header, const char *value, ...) + MS_PRINT_FUNC_FORMAT(2, 3); +void msIO_sendHeaders(void); + +/* +** These can be used instead of the stdio style functions if you have +** msIOContext's for the channel in question. +*/ +int msIO_contextRead(msIOContext *context, void *data, int byteCount); +int msIO_contextWrite(msIOContext *context, const void *data, int byteCount); + +/* +** For redirecting IO to a memory buffer. +*/ + +typedef struct { + unsigned char *data; + int data_len; /* really buffer length */ + int data_offset; /* really buffer used */ +} msIOBuffer; + +int MS_DLL_EXPORT msIO_bufferRead(void *, void *, int); +int MS_DLL_EXPORT msIO_bufferWrite(void *, void *, int); + +void MS_DLL_EXPORT msIO_resetHandlers(void); +void MS_DLL_EXPORT msIO_installStdoutToBuffer(void); +void MS_DLL_EXPORT msIO_installStdinFromBuffer(void); +void MS_DLL_EXPORT msIO_Cleanup(void); +char MS_DLL_EXPORT *msIO_stripStdoutBufferContentType(void); +void MS_DLL_EXPORT msIO_stripStdoutBufferContentHeaders(void); +hashTableObj MS_DLL_EXPORT *msIO_getAndStripStdoutBufferMimeHeaders(void); + +msIOContext *msIO_pushStdoutToBufferAndGetOldContext(void); +void msIO_restoreOldStdoutContext(msIOContext *context_to_restore); + +int MS_DLL_EXPORT msIO_isStdContext(void); + +/* this is just for setting normal stdout's to binary mode on windows */ + +int msIO_needBinaryStdout(void); +int msIO_needBinaryStdin(void); #ifdef __cplusplus } diff --git a/mapjoin.c b/mapjoin.c index 8d1a09af95..eceb7a96a5 100644 --- a/mapjoin.c +++ b/mapjoin.c @@ -29,11 +29,8 @@ #include "mapserver.h" - - #define ROW_ALLOCATION_SIZE 10 - /* DBF/XBase function prototypes */ int msDBFJoinConnect(layerObj *layer, joinObj *join); int msDBFJoinPrepare(joinObj *join, shapeObj *shape); @@ -62,92 +59,90 @@ int msPOSTGRESQLJoinNext(joinObj *join); int msPOSTGRESQLJoinClose(joinObj *join); /* wrapper function for DB specific join functions */ -int msJoinConnect(layerObj *layer, joinObj *join) -{ - switch(join->connectiontype) { - case(MS_DB_XBASE): - return msDBFJoinConnect(layer, join); - break; - case(MS_DB_CSV): - return msCSVJoinConnect(layer, join); - break; - case(MS_DB_MYSQL): - return msMySQLJoinConnect(layer, join); - break; - case(MS_DB_POSTGRES): - return msPOSTGRESQLJoinConnect(layer, join); - break; - default: - break; - } - - msSetError(MS_JOINERR, "Unsupported join connection type.", "msJoinConnect()"); +int msJoinConnect(layerObj *layer, joinObj *join) { + switch (join->connectiontype) { + case (MS_DB_XBASE): + return msDBFJoinConnect(layer, join); + break; + case (MS_DB_CSV): + return msCSVJoinConnect(layer, join); + break; + case (MS_DB_MYSQL): + return msMySQLJoinConnect(layer, join); + break; + case (MS_DB_POSTGRES): + return msPOSTGRESQLJoinConnect(layer, join); + break; + default: + break; + } + + msSetError(MS_JOINERR, "Unsupported join connection type.", + "msJoinConnect()"); return MS_FAILURE; } -int msJoinPrepare(joinObj *join, shapeObj *shape) -{ - switch(join->connectiontype) { - case(MS_DB_XBASE): - return msDBFJoinPrepare(join, shape); - break; - case(MS_DB_CSV): - return msCSVJoinPrepare(join, shape); - break; - case(MS_DB_MYSQL): - return msMySQLJoinPrepare(join, shape); - break; - case(MS_DB_POSTGRES): - return msPOSTGRESQLJoinPrepare(join, shape); - break; - default: - break; - } - - msSetError(MS_JOINERR, "Unsupported join connection type.", "msJoinPrepare()"); +int msJoinPrepare(joinObj *join, shapeObj *shape) { + switch (join->connectiontype) { + case (MS_DB_XBASE): + return msDBFJoinPrepare(join, shape); + break; + case (MS_DB_CSV): + return msCSVJoinPrepare(join, shape); + break; + case (MS_DB_MYSQL): + return msMySQLJoinPrepare(join, shape); + break; + case (MS_DB_POSTGRES): + return msPOSTGRESQLJoinPrepare(join, shape); + break; + default: + break; + } + + msSetError(MS_JOINERR, "Unsupported join connection type.", + "msJoinPrepare()"); return MS_FAILURE; } -int msJoinNext(joinObj *join) -{ - switch(join->connectiontype) { - case(MS_DB_XBASE): - return msDBFJoinNext(join); - break; - case(MS_DB_CSV): - return msCSVJoinNext(join); - break; - case(MS_DB_MYSQL): - return msMySQLJoinNext(join); - break; - case(MS_DB_POSTGRES): - return msPOSTGRESQLJoinNext(join); - break; - default: - break; +int msJoinNext(joinObj *join) { + switch (join->connectiontype) { + case (MS_DB_XBASE): + return msDBFJoinNext(join); + break; + case (MS_DB_CSV): + return msCSVJoinNext(join); + break; + case (MS_DB_MYSQL): + return msMySQLJoinNext(join); + break; + case (MS_DB_POSTGRES): + return msPOSTGRESQLJoinNext(join); + break; + default: + break; } msSetError(MS_JOINERR, "Unsupported join connection type.", "msJoinNext()"); return MS_FAILURE; } -int msJoinClose(joinObj *join) -{ - switch(join->connectiontype) { - case(MS_DB_XBASE): - return msDBFJoinClose(join); - break; - case(MS_DB_CSV): - return msCSVJoinClose(join); - break; - case(MS_DB_MYSQL): - return msMySQLJoinClose(join); - break; - case(MS_DB_POSTGRES): - return msPOSTGRESQLJoinClose(join); - break; - default: - break; +int msJoinClose(joinObj *join) { + switch (join->connectiontype) { + case (MS_DB_XBASE): + return msDBFJoinClose(join); + break; + case (MS_DB_CSV): + return msCSVJoinClose(join); + break; + case (MS_DB_MYSQL): + return msMySQLJoinClose(join); + break; + case (MS_DB_POSTGRES): + return msPOSTGRESQLJoinClose(join); + break; + default: + break; } msSetError(MS_JOINERR, "Unsupported join connection type.", "msJoinClose()"); @@ -164,23 +159,23 @@ typedef struct { int nextrecord; } msDBFJoinInfo; -int msDBFJoinConnect(layerObj *layer, joinObj *join) -{ +int msDBFJoinConnect(layerObj *layer, joinObj *join) { int i; char szPath[MS_MAXPATHLEN]; msDBFJoinInfo *joininfo; - if(join->joininfo) return(MS_SUCCESS); /* already open */ + if (join->joininfo) + return (MS_SUCCESS); /* already open */ - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; - /* allocate a msDBFJoinInfo struct */ - joininfo = (msDBFJoinInfo *) malloc(sizeof(msDBFJoinInfo)); - if(!joininfo) { - msSetError(MS_MEMERR, "Error allocating XBase table info structure.", "msDBFJoinConnect()"); - return(MS_FAILURE); + joininfo = (msDBFJoinInfo *)malloc(sizeof(msDBFJoinInfo)); + if (!joininfo) { + msSetError(MS_MEMERR, "Error allocating XBase table info structure.", + "msDBFJoinConnect()"); + return (MS_FAILURE); } /* initialize any members that won't get set later on in this function */ @@ -190,126 +185,145 @@ int msDBFJoinConnect(layerObj *layer, joinObj *join) join->joininfo = joininfo; /* open the XBase file */ - if((joininfo->hDBF = msDBFOpen( msBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, join->table), "rb" )) == NULL) { - if((joininfo->hDBF = msDBFOpen( msBuildPath(szPath, layer->map->mappath, join->table), "rb" )) == NULL) { + if ((joininfo->hDBF = + msDBFOpen(msBuildPath3(szPath, layer->map->mappath, + layer->map->shapepath, join->table), + "rb")) == NULL) { + if ((joininfo->hDBF = + msDBFOpen(msBuildPath(szPath, layer->map->mappath, join->table), + "rb")) == NULL) { msSetError(MS_IOERR, "(%s)", "msDBFJoinConnect()", join->table); - return(MS_FAILURE); + return (MS_FAILURE); } } /* get "to" item index */ - if((joininfo->toindex = msDBFGetItemIndex(joininfo->hDBF, join->to)) == -1) { - msSetError(MS_DBFERR, "Item %s not found in table %s.", "msDBFJoinConnect()", join->to, join->table); - return(MS_FAILURE); + if ((joininfo->toindex = msDBFGetItemIndex(joininfo->hDBF, join->to)) == -1) { + msSetError(MS_DBFERR, "Item %s not found in table %s.", + "msDBFJoinConnect()", join->to, join->table); + return (MS_FAILURE); } /* get "from" item index */ - for(i=0; inumitems; i++) { - if(strcasecmp(layer->items[i],join->from) == 0) { /* found it */ + for (i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], join->from) == 0) { /* found it */ joininfo->fromindex = i; break; } } - if(i == layer->numitems) { - msSetError(MS_JOINERR, "Item %s not found in layer %s.", "msDBFJoinConnect()", join->from, layer->name); - return(MS_FAILURE); + if (i == layer->numitems) { + msSetError(MS_JOINERR, "Item %s not found in layer %s.", + "msDBFJoinConnect()", join->from, layer->name); + return (MS_FAILURE); } /* finally store away the item names in the XBase table */ - join->numitems = msDBFGetFieldCount(joininfo->hDBF); + join->numitems = msDBFGetFieldCount(joininfo->hDBF); join->items = msDBFGetItems(joininfo->hDBF); - if(!join->items) return(MS_FAILURE); + if (!join->items) + return (MS_FAILURE); - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msDBFJoinPrepare(joinObj *join, shapeObj *shape) -{ +int msDBFJoinPrepare(joinObj *join, shapeObj *shape) { msDBFJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msDBFJoinPrepare()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msDBFJoinPrepare()"); + return (MS_FAILURE); } - if(!shape) { - msSetError(MS_JOINERR, "Shape to be joined is empty.", "msDBFJoinPrepare()"); - return(MS_FAILURE); + if (!shape) { + msSetError(MS_JOINERR, "Shape to be joined is empty.", + "msDBFJoinPrepare()"); + return (MS_FAILURE); } - if(!shape->values) { - msSetError(MS_JOINERR, "Shape to be joined has no attributes.", "msDBFJoinPrepare()"); - return(MS_FAILURE); + if (!shape->values) { + msSetError(MS_JOINERR, "Shape to be joined has no attributes.", + "msDBFJoinPrepare()"); + return (MS_FAILURE); } joininfo->nextrecord = 0; /* starting with the first record */ - if(joininfo->target) free(joininfo->target); /* clear last target */ + if (joininfo->target) + free(joininfo->target); /* clear last target */ joininfo->target = msStrdup(shape->values[joininfo->fromindex]); - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msDBFJoinNext(joinObj *join) -{ +int msDBFJoinNext(joinObj *join) { int i, n; msDBFJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msDBFJoinNext()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msDBFJoinNext()"); + return (MS_FAILURE); } - if(!joininfo->target) { - msSetError(MS_JOINERR, "No target specified, run msDBFJoinPrepare() first.", "msDBFJoinNext()"); - return(MS_FAILURE); + if (!joininfo->target) { + msSetError(MS_JOINERR, "No target specified, run msDBFJoinPrepare() first.", + "msDBFJoinNext()"); + return (MS_FAILURE); } /* clear any old data */ - if(join->values) { + if (join->values) { msFreeCharArray(join->values, join->numitems); join->values = NULL; } n = msDBFGetRecordCount(joininfo->hDBF); - for(i=joininfo->nextrecord; itarget, msDBFReadStringAttribute(joininfo->hDBF, i, joininfo->toindex)) == 0) break; + for (i = joininfo->nextrecord; i < n; i++) { /* find a match */ + if (strcmp(joininfo->target, msDBFReadStringAttribute(joininfo->hDBF, i, + joininfo->toindex)) == + 0) + break; } - if(i == n) { /* unable to do the join */ - if((join->values = (char **)malloc(sizeof(char *)*join->numitems)) == NULL) { + if (i == n) { /* unable to do the join */ + if ((join->values = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msDBFJoinNext()"); - return(MS_FAILURE); + return (MS_FAILURE); } - for(i=0; inumitems; i++) + for (i = 0; i < join->numitems; i++) join->values[i] = msStrdup("\0"); /* intialize to zero length strings */ joininfo->nextrecord = n; - return(MS_DONE); + return (MS_DONE); } - if((join->values = msDBFGetValues(joininfo->hDBF,i)) == NULL) - return(MS_FAILURE); + if ((join->values = msDBFGetValues(joininfo->hDBF, i)) == NULL) + return (MS_FAILURE); - joininfo->nextrecord = i+1; /* so we know where to start looking next time through */ + joininfo->nextrecord = + i + 1; /* so we know where to start looking next time through */ - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msDBFJoinClose(joinObj *join) -{ +int msDBFJoinClose(joinObj *join) { msDBFJoinInfo *joininfo = join->joininfo; - if(!joininfo) return(MS_SUCCESS); /* already closed */ + if (!joininfo) + return (MS_SUCCESS); /* already closed */ - if(joininfo->hDBF) msDBFClose(joininfo->hDBF); - if(joininfo->target) free(joininfo->target); + if (joininfo->hDBF) + msDBFClose(joininfo->hDBF); + if (joininfo->target) + free(joininfo->target); free(joininfo); joininfo = NULL; - return(MS_SUCCESS); + return (MS_SUCCESS); } /* */ @@ -323,23 +337,23 @@ typedef struct { int nextrow; } msCSVJoinInfo; -int msCSVJoinConnect(layerObj *layer, joinObj *join) -{ +int msCSVJoinConnect(layerObj *layer, joinObj *join) { int i; FILE *stream; char szPath[MS_MAXPATHLEN]; msCSVJoinInfo *joininfo; char buffer[MS_BUFFER_LENGTH]; - if(join->joininfo) return(MS_SUCCESS); /* already open */ - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) + if (join->joininfo) + return (MS_SUCCESS); /* already open */ + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; - /* allocate a msCSVJoinInfo struct */ - if((joininfo = (msCSVJoinInfo *) malloc(sizeof(msCSVJoinInfo))) == NULL) { - msSetError(MS_MEMERR, "Error allocating CSV table info structure.", "msCSVJoinConnect()"); - return(MS_FAILURE); + if ((joininfo = (msCSVJoinInfo *)malloc(sizeof(msCSVJoinInfo))) == NULL) { + msSetError(MS_MEMERR, "Error allocating CSV table info structure.", + "msCSVJoinConnect()"); + return (MS_FAILURE); } /* initialize any members that won't get set later on in this function */ @@ -349,175 +363,190 @@ int msCSVJoinConnect(layerObj *layer, joinObj *join) join->joininfo = joininfo; /* open the CSV file */ - if((stream = fopen( msBuildPath3(szPath, layer->map->mappath, layer->map->shapepath, join->table), "r" )) == NULL) { - if((stream = fopen( msBuildPath(szPath, layer->map->mappath, join->table), "r" )) == NULL) { + if ((stream = fopen(msBuildPath3(szPath, layer->map->mappath, + layer->map->shapepath, join->table), + "r")) == NULL) { + if ((stream = fopen(msBuildPath(szPath, layer->map->mappath, join->table), + "r")) == NULL) { msSetError(MS_IOERR, "(%s)", "msCSVJoinConnect()", join->table); - return(MS_FAILURE); + return (MS_FAILURE); } } /* once through to get the number of rows */ joininfo->numrows = 0; - while(fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) joininfo->numrows++; + while (fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) + joininfo->numrows++; rewind(stream); - if((joininfo->rows = (char ***) malloc(joininfo->numrows*sizeof(char **))) == NULL) { + if ((joininfo->rows = + (char ***)malloc(joininfo->numrows * sizeof(char **))) == NULL) { fclose(stream); msSetError(MS_MEMERR, "Error allocating rows.", "msCSVJoinConnect()"); - return(MS_FAILURE); + return (MS_FAILURE); } /* load the rows */ i = 0; - while(fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { + while (fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { msStringTrimEOL(buffer); - joininfo->rows[i] = msStringSplitComplex(buffer, ",", &(join->numitems), MS_ALLOWEMPTYTOKENS); + joininfo->rows[i] = msStringSplitComplex(buffer, ",", &(join->numitems), + MS_ALLOWEMPTYTOKENS); i++; } fclose(stream); /* get "from" item index */ - for(i=0; inumitems; i++) { - if(strcasecmp(layer->items[i],join->from) == 0) { /* found it */ + for (i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], join->from) == 0) { /* found it */ joininfo->fromindex = i; break; } } - if(i == layer->numitems) { - msSetError(MS_JOINERR, "Item %s not found in layer %s.", "msCSVJoinConnect()", join->from, layer->name); - return(MS_FAILURE); + if (i == layer->numitems) { + msSetError(MS_JOINERR, "Item %s not found in layer %s.", + "msCSVJoinConnect()", join->from, layer->name); + return (MS_FAILURE); } /* get "to" index (for now the user tells us which column, 1..n) */ joininfo->toindex = atoi(join->to) - 1; - if(joininfo->toindex < 0 || joininfo->toindex > join->numitems) { - msSetError(MS_JOINERR, "Invalid column index %s.", "msCSVJoinConnect()", join->to); - return(MS_FAILURE); + if (joininfo->toindex < 0 || joininfo->toindex > join->numitems) { + msSetError(MS_JOINERR, "Invalid column index %s.", "msCSVJoinConnect()", + join->to); + return (MS_FAILURE); } /* store away the column names (1..n) */ - if((join->items = (char **) malloc(sizeof(char *)*join->numitems)) == NULL) { - msSetError(MS_MEMERR, "Error allocating space for join item names.", "msCSVJoinConnect()"); - return(MS_FAILURE); + if ((join->items = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { + msSetError(MS_MEMERR, "Error allocating space for join item names.", + "msCSVJoinConnect()"); + return (MS_FAILURE); } - for(i=0; inumitems; i++) { - join->items[i] = (char *) malloc(12); /* plenty of space */ - sprintf(join->items[i], "%d", i+1); + for (i = 0; i < join->numitems; i++) { + join->items[i] = (char *)malloc(12); /* plenty of space */ + sprintf(join->items[i], "%d", i + 1); } - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msCSVJoinPrepare(joinObj *join, shapeObj *shape) -{ +int msCSVJoinPrepare(joinObj *join, shapeObj *shape) { msCSVJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msCSVJoinPrepare()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msCSVJoinPrepare()"); + return (MS_FAILURE); } - if(!shape) { - msSetError(MS_JOINERR, "Shape to be joined is empty.", "msCSVJoinPrepare()"); - return(MS_FAILURE); + if (!shape) { + msSetError(MS_JOINERR, "Shape to be joined is empty.", + "msCSVJoinPrepare()"); + return (MS_FAILURE); } - if(!shape->values) { - msSetError(MS_JOINERR, "Shape to be joined has no attributes.", "msCSVJoinPrepare()"); - return(MS_FAILURE); + if (!shape->values) { + msSetError(MS_JOINERR, "Shape to be joined has no attributes.", + "msCSVJoinPrepare()"); + return (MS_FAILURE); } joininfo->nextrow = 0; /* starting with the first record */ - if(joininfo->target) free(joininfo->target); /* clear last target */ + if (joininfo->target) + free(joininfo->target); /* clear last target */ joininfo->target = msStrdup(shape->values[joininfo->fromindex]); - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msCSVJoinNext(joinObj *join) -{ - int i,j; +int msCSVJoinNext(joinObj *join) { + int i, j; msCSVJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msCSVJoinNext()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msCSVJoinNext()"); + return (MS_FAILURE); } /* clear any old data */ - if(join->values) { + if (join->values) { msFreeCharArray(join->values, join->numitems); join->values = NULL; } - for(i=joininfo->nextrow; inumrows; i++) { /* find a match */ - if(strcmp(joininfo->target, joininfo->rows[i][joininfo->toindex]) == 0) break; + for (i = joininfo->nextrow; i < joininfo->numrows; i++) { /* find a match */ + if (strcmp(joininfo->target, joininfo->rows[i][joininfo->toindex]) == 0) + break; } - if((join->values = (char ** )malloc(sizeof(char *)*join->numitems)) == NULL) { + if ((join->values = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msCSVJoinNext()"); - return(MS_FAILURE); + return (MS_FAILURE); } - if(i == joininfo->numrows) { /* unable to do the join */ - for(j=0; jnumitems; j++) + if (i == joininfo->numrows) { /* unable to do the join */ + for (j = 0; j < join->numitems; j++) join->values[j] = msStrdup("\0"); /* intialize to zero length strings */ joininfo->nextrow = joininfo->numrows; - return(MS_DONE); + return (MS_DONE); } - for(j=0; jnumitems; j++) + for (j = 0; j < join->numitems; j++) join->values[j] = msStrdup(joininfo->rows[i][j]); - joininfo->nextrow = i+1; /* so we know where to start looking next time through */ + joininfo->nextrow = + i + 1; /* so we know where to start looking next time through */ - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msCSVJoinClose(joinObj *join) -{ +int msCSVJoinClose(joinObj *join) { int i; msCSVJoinInfo *joininfo = join->joininfo; - if(!joininfo) return(MS_SUCCESS); /* already closed */ + if (!joininfo) + return (MS_SUCCESS); /* already closed */ - for(i=0; inumrows; i++) + for (i = 0; i < joininfo->numrows; i++) msFreeCharArray(joininfo->rows[i], join->numitems); free(joininfo->rows); - if(joininfo->target) free(joininfo->target); + if (joininfo->target) + free(joininfo->target); free(joininfo); joininfo = NULL; - return(MS_SUCCESS); + return (MS_SUCCESS); } - #ifdef USE_MYSQL #ifndef _mysql_h #include #endif -char* DB_HOST = NULL; -char* DB_USER = NULL; -char* DB_PASSWD = NULL; -char* DB_DATABASE = NULL; -char* delim; +char *DB_HOST = NULL; +char *DB_USER = NULL; +char *DB_PASSWD = NULL; +char *DB_DATABASE = NULL; +char *delim; #define MYDEBUG if (0) -MYSQL_RES *msMySQLQuery(char *q, MYSQL *conn) -{ - MYSQL_RES *qresult=NULL; - if (mysql_query(conn,q) < 0) { +MYSQL_RES *msMySQLQuery(char *q, MYSQL *conn) { + MYSQL_RES *qresult = NULL; + if (mysql_query(conn, q) < 0) { mysql_close(conn); msSetError(MS_QUERYERR, "Bad mysql query (%s)", "msMySQLQuery()", q); return qresult; } - if (!(qresult=mysql_store_result(conn))) { + if (!(qresult = mysql_store_result(conn))) { mysql_close(conn); msSetError(MS_QUERYERR, "mysql query failed (%s)", "msMySQLQuery()", q); return qresult; @@ -540,30 +569,30 @@ typedef struct { } msMySQLJoinInfo; #endif - -int msMySQLJoinConnect(layerObj *layer, joinObj *join) -{ +int msMySQLJoinConnect(layerObj *layer, joinObj *join) { (void)layer; (void)join; #ifndef USE_MYSQL - msSetError(MS_QUERYERR, "MySQL support not available (compile with --with-mysql)", "msMySQLJoinConnect()"); - return(MS_FAILURE); + msSetError(MS_QUERYERR, + "MySQL support not available (compile with --with-mysql)", + "msMySQLJoinConnect()"); + return (MS_FAILURE); #else int i; char qbuf[4000]; char *conn_decrypted; msMySQLJoinInfo *joininfo; - MYDEBUG if (setvbuf(stdout, NULL, _IONBF , 0)) { - printf("Whoops..."); - }; - if(join->joininfo) return(MS_SUCCESS); /* already open */ + MYDEBUG if (setvbuf(stdout, NULL, _IONBF, 0)) { printf("Whoops..."); }; + if (join->joininfo) + return (MS_SUCCESS); /* already open */ /* allocate a msMySQLJoinInfo struct */ - joininfo = (msMySQLJoinInfo *) malloc(sizeof(msMySQLJoinInfo)); - if(!joininfo) { - msSetError(MS_MEMERR, "Error allocating mysql table info structure.", "msMySQLJoinConnect()"); - return(MS_FAILURE); + joininfo = (msMySQLJoinInfo *)malloc(sizeof(msMySQLJoinInfo)); + if (!joininfo) { + msSetError(MS_MEMERR, "Error allocating mysql table info structure.", + "msMySQLJoinConnect()"); + return (MS_FAILURE); } /* initialize any members that won't get set later on in this function */ @@ -575,18 +604,22 @@ int msMySQLJoinConnect(layerObj *layer, joinObj *join) /* open the mysql connection */ - if( join->connection == NULL ) { - msSetError(MS_QUERYERR, "Error parsing MYSQL JOIN: nothing specified in CONNECTION statement.", - "msMySQLJoinConnect()"); + if (join->connection == NULL) { + msSetError( + MS_QUERYERR, + "Error parsing MYSQL JOIN: nothing specified in CONNECTION statement.", + "msMySQLJoinConnect()"); - return(MS_FAILURE); + return (MS_FAILURE); } conn_decrypted = msDecryptStringTokens(layer->map, join->connection); if (conn_decrypted == NULL) { - msSetError(MS_QUERYERR, "Error parsing MYSQL JOIN: unable to decrypt CONNECTION statement.", - "msMySQLJoinConnect()"); - return(MS_FAILURE); + msSetError( + MS_QUERYERR, + "Error parsing MYSQL JOIN: unable to decrypt CONNECTION statement.", + "msMySQLJoinConnect()"); + return (MS_FAILURE); } delim = msStrdup(":"); @@ -596,29 +629,38 @@ int msMySQLJoinConnect(layerObj *layer, joinObj *join) DB_DATABASE = msStrdup(strtok(NULL, delim)); free(conn_decrypted); - if (DB_HOST == NULL || DB_USER == NULL || DB_PASSWD == NULL || DB_DATABASE == NULL) { - msSetError(MS_QUERYERR, "DB param error: at least one of HOST, USER, PASSWD or DATABASE is null!", "msMySQLJoinConnect()"); + if (DB_HOST == NULL || DB_USER == NULL || DB_PASSWD == NULL || + DB_DATABASE == NULL) { + msSetError(MS_QUERYERR, + "DB param error: at least one of HOST, USER, PASSWD or DATABASE " + "is null!", + "msMySQLJoinConnect()"); return MS_FAILURE; } - if (strcmp(DB_PASSWD, "none") == 0) strcpy(DB_PASSWD, ""); + if (strcmp(DB_PASSWD, "none") == 0) + strcpy(DB_PASSWD, ""); #if MYSQL_VERSION_ID >= 40000 mysql_init(&(joininfo->mysql)); - if (!(joininfo->conn = mysql_real_connect(&(joininfo->mysql),DB_HOST,DB_USER,DB_PASSWD,NULL, 0, NULL, 0))) + if (!(joininfo->conn = mysql_real_connect( + &(joininfo->mysql), DB_HOST, DB_USER, DB_PASSWD, NULL, 0, NULL, 0))) #else - if (!(joininfo->conn = mysql_connect(&(joininfo->mysql),DB_HOST,DB_USER,DB_PASSWD))) + if (!(joininfo->conn = + mysql_connect(&(joininfo->mysql), DB_HOST, DB_USER, DB_PASSWD))) #endif { char tmp[4000]; - snprintf( tmp, sizeof(tmp), "Failed to connect to SQL server: Error: %s\nHost: %s\nUsername:%s\nPassword:%s\n", mysql_error(joininfo->conn), DB_HOST, DB_USER, DB_PASSWD); - msSetError(MS_QUERYERR, "%s", - "msMYSQLLayerOpen()", tmp); + snprintf(tmp, sizeof(tmp), + "Failed to connect to SQL server: Error: %s\nHost: " + "%s\nUsername:%s\nPassword:%s\n", + mysql_error(joininfo->conn), DB_HOST, DB_USER, DB_PASSWD); + msSetError(MS_QUERYERR, "%s", "msMYSQLLayerOpen()", tmp); free(joininfo); return MS_FAILURE; } MYDEBUG printf("msMYSQLLayerOpen2 called
\n"); - if (mysql_select_db(joininfo->conn,DB_DATABASE) < 0) { + if (mysql_select_db(joininfo->conn, DB_DATABASE) < 0) { mysql_close(joininfo->conn); } MYDEBUG printf("msMYSQLLayerOpen3 called
\n"); @@ -627,118 +669,135 @@ int msMySQLJoinConnect(layerObj *layer, joinObj *join) mysql_free_result(joininfo->qresult); } MYDEBUG printf("msMYSQLLayerOpen5 called
\n"); - snprintf(qbuf, sizeof(qbuf), "SELECT count(%s) FROM %s", join->to, join->table); + snprintf(qbuf, sizeof(qbuf), "SELECT count(%s) FROM %s", join->to, + join->table); MYDEBUG printf("%s
\n", qbuf); - if ((joininfo->qresult = msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, write 'em out for debug */ + if ((joininfo->qresult = + msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, + write 'em out for debug */ int numrows = mysql_affected_rows(joininfo->conn); MYDEBUG printf("%d rows
\n", numrows); - for(i=0; iqresult); - MYDEBUG printf("(%s)
\n",row[0]); + MYDEBUG printf("(%s)
\n", row[0]); joininfo->rows = atoi(row[0]); } } else { - msSetError(MS_DBFERR, "Item %s not found in table %s.", "msMySQLJoinConnect()", join->to, join->table); - return(MS_FAILURE); + msSetError(MS_DBFERR, "Item %s not found in table %s.", + "msMySQLJoinConnect()", join->to, join->table); + return (MS_FAILURE); } snprintf(qbuf, sizeof(qbuf), "EXPLAIN %s", join->table); - if ((joininfo->qresult = msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, write 'em out for debug */ + if ((joininfo->qresult = + msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, + write 'em out for debug */ join->numitems = mysql_affected_rows(joininfo->conn); - if((join->items = (char **)malloc(sizeof(char *)*join->numitems)) == NULL) { + if ((join->items = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msMySQLJoinConnect()"); - return(MS_FAILURE); + return (MS_FAILURE); } MYDEBUG printf("%d rows
\n", join->numitems); - for(i=0; inumitems; i++) { + for (i = 0; i < join->numitems; i++) { MYSQL_ROW row = mysql_fetch_row(joininfo->qresult); - MYDEBUG printf("(%s)
\n",row[0]); + MYDEBUG printf("(%s)
\n", row[0]); join->items[i] = msStrdup(row[0]); } } else { - msSetError(MS_DBFERR, "Item %s not found in table %s.", "msMySQLJoinConnect()", join->to, join->table); - return(MS_FAILURE); + msSetError(MS_DBFERR, "Item %s not found in table %s.", + "msMySQLJoinConnect()", join->to, join->table); + return (MS_FAILURE); } joininfo->tocolumn = msStrdup(join->to); - - /* get "from" item index */ - for(i=0; inumitems; i++) { - if(strcasecmp(layer->items[i],join->from) == 0) { /* found it */ + for (i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], join->from) == 0) { /* found it */ joininfo->fromindex = i; break; } } - if(i == layer->numitems) { - msSetError(MS_JOINERR, "Item %s not found in layer %s.", "msMySQLJoinConnect()", join->from, layer->name); - return(MS_FAILURE); + if (i == layer->numitems) { + msSetError(MS_JOINERR, "Item %s not found in layer %s.", + "msMySQLJoinConnect()", join->from, layer->name); + return (MS_FAILURE); } /* finally store away the item names in the XBase table */ - if(!join->items) return(MS_FAILURE); + if (!join->items) + return (MS_FAILURE); - return(MS_SUCCESS); + return (MS_SUCCESS); #endif } -int msMySQLJoinPrepare(joinObj *join, shapeObj *shape) -{ +int msMySQLJoinPrepare(joinObj *join, shapeObj *shape) { (void)join; (void)shape; #ifndef USE_MYSQL - msSetError(MS_QUERYERR, "MySQL support not available (compile with --with-mysql)", "msMySQLJoinPrepare()"); - return(MS_FAILURE); + msSetError(MS_QUERYERR, + "MySQL support not available (compile with --with-mysql)", + "msMySQLJoinPrepare()"); + return (MS_FAILURE); #else msMySQLJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msMySQLJoinPrepare()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msMySQLJoinPrepare()"); + return (MS_FAILURE); } - if(!shape) { - msSetError(MS_JOINERR, "Shape to be joined is empty.", "msMySQLJoinPrepare()"); - return(MS_FAILURE); + if (!shape) { + msSetError(MS_JOINERR, "Shape to be joined is empty.", + "msMySQLJoinPrepare()"); + return (MS_FAILURE); } - if(!shape->values) { - msSetError(MS_JOINERR, "Shape to be joined has no attributes.", "msMySQLJoinPrepare()"); - return(MS_FAILURE); + if (!shape->values) { + msSetError(MS_JOINERR, "Shape to be joined has no attributes.", + "msMySQLJoinPrepare()"); + return (MS_FAILURE); } joininfo->nextrecord = 0; /* starting with the first record */ - if(joininfo->target) free(joininfo->target); /* clear last target */ + if (joininfo->target) + free(joininfo->target); /* clear last target */ joininfo->target = msStrdup(shape->values[joininfo->fromindex]); - return(MS_SUCCESS); + return (MS_SUCCESS); #endif } -int msMySQLJoinNext(joinObj *join) -{ +int msMySQLJoinNext(joinObj *join) { (void)join; #ifndef USE_MYSQL - msSetError(MS_QUERYERR, "MySQL support not available (compile with --with-mysql)", "msMySQLJoinNext()"); - return(MS_FAILURE); + msSetError(MS_QUERYERR, + "MySQL support not available (compile with --with-mysql)", + "msMySQLJoinNext()"); + return (MS_FAILURE); #else int i; char qbuf[4000]; msMySQLJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join connection has not be created.", "msMySQLJoinNext()"); - return(MS_FAILURE); + if (!joininfo) { + msSetError(MS_JOINERR, "Join connection has not be created.", + "msMySQLJoinNext()"); + return (MS_FAILURE); } - if(!joininfo->target) { - msSetError(MS_JOINERR, "No target specified, run msMySQLJoinPrepare() first.", "msMySQLJoinNext()"); - return(MS_FAILURE); + if (!joininfo->target) { + msSetError(MS_JOINERR, + "No target specified, run msMySQLJoinPrepare() first.", + "msMySQLJoinNext()"); + return (MS_FAILURE); } /* clear any old data */ - if(join->values) { + if (join->values) { msFreeCharArray(join->values, join->numitems); join->values = NULL; } @@ -746,84 +805,97 @@ int msMySQLJoinNext(joinObj *join) /* int n = joininfo->rows; */ /* for(i=joininfo->nextrecord; itarget, msMySQLReadStringAttribute(joininfo->conn, i, joininfo->toindex)) == 0) break; */ + /* if(strcmp(joininfo->target, msMySQLReadStringAttribute(joininfo->conn, i, + * joininfo->toindex)) == 0) break; */ /* } */ - snprintf(qbuf, sizeof(qbuf), "SELECT * FROM %s WHERE %s = %s", join->table, joininfo->tocolumn, joininfo->target); + snprintf(qbuf, sizeof(qbuf), "SELECT * FROM %s WHERE %s = %s", join->table, + joininfo->tocolumn, joininfo->target); MYDEBUG printf("%s
\n", qbuf); - if ((joininfo->qresult = msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, write 'em out for debug */ + if ((joininfo->qresult = + msMySQLQuery(qbuf, joininfo->conn))) { /* There were some rows found, + write 'em out for debug */ int numrows = mysql_affected_rows(joininfo->conn); int numfields = mysql_field_count(joininfo->conn); MYDEBUG printf("%d rows
\n", numrows); if (numrows > 0) { MYSQL_ROW row = mysql_fetch_row(joininfo->qresult); - for(i=0; i\n"); free(join->values); - if((join->values = (char **)malloc(sizeof(char *)*join->numitems)) == NULL) { + if ((join->values = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msMySQLJoinNext()"); - return(MS_FAILURE); + return (MS_FAILURE); } - for(i=0; inumitems; i++) { - /* join->values[i] = msStrdup("\0"); */ /* intialize to zero length strings */ - join->values[i] = msStrdup(row[i]); /* intialize to zero length strings */ + for (i = 0; i < join->numitems; i++) { + /* join->values[i] = msStrdup("\0"); */ /* intialize to zero length + strings */ + join->values[i] = + msStrdup(row[i]); /* intialize to zero length strings */ /* rows = atoi(row[0]); */ } } else { - if((join->values = (char **)malloc(sizeof(char *)*join->numitems)) == NULL) { + if ((join->values = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msMySQLJoinNext()"); - return(MS_FAILURE); + return (MS_FAILURE); } - for(i=0; inumitems; i++) - join->values[i] = msStrdup("\0"); /* intialize to zero length strings */ + for (i = 0; i < join->numitems; i++) + join->values[i] = msStrdup("\0"); /* intialize to zero length strings */ - return(MS_DONE); + return (MS_DONE); } } else { msSetError(MS_QUERYERR, "Query error (%s)", "msMySQLJoinNext()", qbuf); - return(MS_FAILURE); + return (MS_FAILURE); } #ifdef __NOTDEF__ - if(i == n) { /* unable to do the join */ - if((join->values = (char **)malloc(sizeof(char *)*join->numitems)) == NULL) { + if (i == n) { /* unable to do the join */ + if ((join->values = (char **)malloc(sizeof(char *) * join->numitems)) == + NULL) { msSetError(MS_MEMERR, NULL, "msMySQLJoinNext()"); - return(MS_FAILURE); + return (MS_FAILURE); } - for(i=0; inumitems; i++) + for (i = 0; i < join->numitems; i++) join->values[i] = msStrdup("\0"); /* intialize to zero length strings */ joininfo->nextrecord = n; - return(MS_DONE); + return (MS_DONE); } - if((join->values = msMySQLGetValues(joininfo->conn,i)) == NULL) - return(MS_FAILURE); + if ((join->values = msMySQLGetValues(joininfo->conn, i)) == NULL) + return (MS_FAILURE); - joininfo->nextrecord = i+1; /* so we know where to start looking next time through */ + joininfo->nextrecord = + i + 1; /* so we know where to start looking next time through */ #endif /* __NOTDEF__ */ - return(MS_SUCCESS); + return (MS_SUCCESS); #endif } -int msMySQLJoinClose(joinObj *join) -{ +int msMySQLJoinClose(joinObj *join) { (void)join; #ifndef USE_MYSQL - msSetError(MS_QUERYERR, "MySQL support not available (compile with --with-mysql)", "msMySQLJoinClose()"); - return(MS_FAILURE); + msSetError(MS_QUERYERR, + "MySQL support not available (compile with --with-mysql)", + "msMySQLJoinClose()"); + return (MS_FAILURE); #else msMySQLJoinInfo *joininfo = join->joininfo; - if(!joininfo) return(MS_SUCCESS); /* already closed */ + if (!joininfo) + return (MS_SUCCESS); /* already closed */ mysql_close(joininfo->conn); - if(joininfo->target) free(joininfo->target); + if (joininfo->target) + free(joininfo->target); free(joininfo); joininfo = NULL; - return(MS_SUCCESS); + return (MS_SUCCESS); #endif } diff --git a/mapkml.cpp b/mapkml.cpp index 388bc9f6e9..f7c264f1a7 100644 --- a/mapkml.cpp +++ b/mapkml.cpp @@ -36,183 +36,166 @@ extern "C" { #endif - KmlRenderer* getKmlRenderer(imageObj* img) - { - return (KmlRenderer*) img->img.plugin; - } - - imageObj* msCreateImageKml(int width, int height, outputFormatObj *format, colorObj* bg) - { - imageObj *image = NULL; - - image = (imageObj*)malloc(sizeof(imageObj)); - MS_CHECK_ALLOC(image, sizeof(imageObj), NULL); - memset(image, 0, sizeof(imageObj)); +KmlRenderer *getKmlRenderer(imageObj *img) { + return (KmlRenderer *)img->img.plugin; +} - KmlRenderer *ren = new KmlRenderer(width, height, format, bg); - image->img.plugin = (void *) ren; +imageObj *msCreateImageKml(int width, int height, outputFormatObj *format, + colorObj *bg) { + imageObj *image = NULL; - return image; - } + image = (imageObj *)malloc(sizeof(imageObj)); + MS_CHECK_ALLOC(image, sizeof(imageObj), NULL); + memset(image, 0, sizeof(imageObj)); - int msSaveImageKml(imageObj *img, mapObj* /*map*/, FILE *fp, outputFormatObj *format) - { - KmlRenderer* renderer = getKmlRenderer(img); - return renderer->saveImage(img, fp, format); - } + KmlRenderer *ren = new KmlRenderer(width, height, format, bg); + image->img.plugin = (void *)ren; - int msRenderLineKml(imageObj *img, shapeObj *p, strokeStyleObj *style) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->renderLine(img, p, style); - return MS_SUCCESS; - } + return image; +} - int msRenderPolygonKml(imageObj *img, shapeObj *p, colorObj *color) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->renderPolygon(img, p, color); - return MS_SUCCESS; - } +int msSaveImageKml(imageObj *img, mapObj * /*map*/, FILE *fp, + outputFormatObj *format) { + KmlRenderer *renderer = getKmlRenderer(img); + return renderer->saveImage(img, fp, format); +} - int msRenderPolygonTiledKml(imageObj * /*img*/, shapeObj * /*p*/, imageObj * /*tile*/) - { - /*KmlRenderer* renderer = getKmlRenderer(img);*/ - return MS_SUCCESS; - } +int msRenderLineKml(imageObj *img, shapeObj *p, strokeStyleObj *style) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->renderLine(img, p, style); + return MS_SUCCESS; +} - int msRenderLineTiledKml(imageObj * /*img*/, shapeObj * /*p*/, imageObj * /*tile*/) - { - return MS_SUCCESS; - } +int msRenderPolygonKml(imageObj *img, shapeObj *p, colorObj *color) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->renderPolygon(img, p, color); + return MS_SUCCESS; +} - int msRenderGlyphsKml(imageObj *img, const textSymbolObj *ts, colorObj *c, colorObj *oc, int ow, int /*isMarker*/) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->renderGlyphs(img, ts, c, oc, ow); - return MS_SUCCESS; - } +int msRenderPolygonTiledKml(imageObj * /*img*/, shapeObj * /*p*/, + imageObj * /*tile*/) { + /*KmlRenderer* renderer = getKmlRenderer(img);*/ + return MS_SUCCESS; +} - int msRenderVectorSymbolKml(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj *style) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->renderVectorSymbol(img, x, y, symbol, style); - return MS_SUCCESS; - } +int msRenderLineTiledKml(imageObj * /*img*/, shapeObj * /*p*/, + imageObj * /*tile*/) { + return MS_SUCCESS; +} - int msRenderPixmapSymbolKml(imageObj *img, double x, double y, - symbolObj *symbol, symbolStyleObj *style) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->renderPixmapSymbol(img, x, y, symbol, style); - return MS_SUCCESS; - } +int msRenderGlyphsKml(imageObj *img, const textSymbolObj *ts, colorObj *c, + colorObj *oc, int ow, int /*isMarker*/) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->renderGlyphs(img, ts, c, oc, ow); + return MS_SUCCESS; +} - int msRenderEllipseSymbolKml(imageObj *image, double x, double y, - symbolObj *symbol, symbolStyleObj *style) - { - KmlRenderer* renderer = getKmlRenderer(image); - renderer->renderEllipseSymbol(image, x, y, symbol, style); - return MS_SUCCESS; - } +int msRenderVectorSymbolKml(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->renderVectorSymbol(img, x, y, symbol, style); + return MS_SUCCESS; +} - int msRenderTruetypeSymbolKml(imageObj *image, double x, double y, - symbolObj *symbol, symbolStyleObj *style) - { - KmlRenderer* renderer = getKmlRenderer(image); - renderer->renderTruetypeSymbol(image, x, y, symbol, style); - return MS_SUCCESS; - } +int msRenderPixmapSymbolKml(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->renderPixmapSymbol(img, x, y, symbol, style); + return MS_SUCCESS; +} +int msRenderEllipseSymbolKml(imageObj *image, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { + KmlRenderer *renderer = getKmlRenderer(image); + renderer->renderEllipseSymbol(image, x, y, symbol, style); + return MS_SUCCESS; +} - int msRenderTileKml(imageObj * /*img*/, imageObj * /*tile*/, double /*x*/, double /*y*/) - { - return MS_SUCCESS; - } +int msRenderTruetypeSymbolKml(imageObj *image, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { + KmlRenderer *renderer = getKmlRenderer(image); + renderer->renderTruetypeSymbol(image, x, y, symbol, style); + return MS_SUCCESS; +} - int msGetRasterBufferKml(imageObj * /*img*/,rasterBufferObj * /*rb*/) - { - return MS_FAILURE; //not supported for kml - } +int msRenderTileKml(imageObj * /*img*/, imageObj * /*tile*/, double /*x*/, + double /*y*/) { + return MS_SUCCESS; +} +int msGetRasterBufferKml(imageObj * /*img*/, rasterBufferObj * /*rb*/) { + return MS_FAILURE; // not supported for kml +} - int msGetTruetypeTextBBoxKml(rendererVTableObj * /*r*/,char** /*fonts*/, int /*numfonts*/, double size, char *string, - rectObj *rect, double **advances, int /*bAdjustBaseline*/) - { - rect->minx=0.0; - rect->maxx=0.0; - rect->miny=0.0; - rect->maxy=0.0; - if (advances) { - int numglyphs = msGetNumGlyphs(string); - *advances = (double*) msSmallMalloc(numglyphs * sizeof (double)); - for(int i=0; iminx = 0.0; + rect->maxx = 0.0; + rect->miny = 0.0; + rect->maxy = 0.0; + if (advances) { + int numglyphs = msGetNumGlyphs(string); + *advances = (double *)msSmallMalloc(numglyphs * sizeof(double)); + for (int i = 0; i < numglyphs; i++) { + (*advances)[i] = size; } - return MS_SUCCESS; } + return MS_SUCCESS; +} - int msStartNewLayerKml(imageObj *img, mapObj * /*map*/, layerObj *layer) - { - KmlRenderer* renderer = getKmlRenderer(img); - return renderer->startNewLayer(img, layer); - } +int msStartNewLayerKml(imageObj *img, mapObj * /*map*/, layerObj *layer) { + KmlRenderer *renderer = getKmlRenderer(img); + return renderer->startNewLayer(img, layer); +} - int msCloseNewLayerKml(imageObj *img, mapObj * /*map*/, layerObj *layer) - { - KmlRenderer* renderer = getKmlRenderer(img); - return renderer->closeNewLayer(img, layer); - } +int msCloseNewLayerKml(imageObj *img, mapObj * /*map*/, layerObj *layer) { + KmlRenderer *renderer = getKmlRenderer(img); + return renderer->closeNewLayer(img, layer); +} - int msFreeImageKml(imageObj *image) - { - KmlRenderer* renderer = getKmlRenderer(image); - if (renderer) { - delete renderer; - } - image->img.plugin=NULL; - return MS_SUCCESS; +int msFreeImageKml(imageObj *image) { + KmlRenderer *renderer = getKmlRenderer(image); + if (renderer) { + delete renderer; } + image->img.plugin = NULL; + return MS_SUCCESS; +} - int msFreeSymbolKml(symbolObj * /*symbol*/) - { - return MS_SUCCESS; - } +int msFreeSymbolKml(symbolObj * /*symbol*/) { return MS_SUCCESS; } - int msStartShapeKml(imageObj *img, shapeObj *shape) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->startShape(img, shape); - return MS_SUCCESS; - } +int msStartShapeKml(imageObj *img, shapeObj *shape) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->startShape(img, shape); + return MS_SUCCESS; +} - int msEndShapeKml(imageObj *img, shapeObj *shape) - { - KmlRenderer* renderer = getKmlRenderer(img); - renderer->endShape(img, shape); - return MS_SUCCESS; - } +int msEndShapeKml(imageObj *img, shapeObj *shape) { + KmlRenderer *renderer = getKmlRenderer(img); + renderer->endShape(img, shape); + return MS_SUCCESS; +} - int msMergeRasterBufferKml(imageObj *dest, rasterBufferObj *overlay, double /*opacity*/, int /*srcX*/, - int /*srcY*/, int /*dstX*/, int /*dstY*/, int /*width*/, int /*height*/) - { - KmlRenderer* renderer = getKmlRenderer(dest); - return renderer->mergeRasterBuffer(dest,overlay); - } +int msMergeRasterBufferKml(imageObj *dest, rasterBufferObj *overlay, + double /*opacity*/, int /*srcX*/, int /*srcY*/, + int /*dstX*/, int /*dstY*/, int /*width*/, + int /*height*/) { + KmlRenderer *renderer = getKmlRenderer(dest); + return renderer->mergeRasterBuffer(dest, overlay); +} #ifdef __cplusplus } #endif - #endif /*USE_KML*/ -int aggInitializeRasterBuffer(rasterBufferObj *rb, int width, int height, int mode); +int aggInitializeRasterBuffer(rasterBufferObj *rb, int width, int height, + int mode); -int msPopulateRendererVTableKML( rendererVTableObj *renderer ) -{ +int msPopulateRendererVTableKML(rendererVTableObj *renderer) { #ifdef USE_KML renderer->supports_pixel_buffer = 0; renderer->supports_clipping = 0; @@ -221,11 +204,11 @@ int msPopulateRendererVTableKML( rendererVTableObj *renderer ) renderer->startLayer = msStartNewLayerKml; renderer->endLayer = msCloseNewLayerKml; - renderer->renderLine=&msRenderLineKml; - renderer->createImage=&msCreateImageKml; - renderer->saveImage=&msSaveImageKml; - renderer->renderPolygon=&msRenderPolygonKml; - renderer->renderGlyphs=&msRenderGlyphsKml; + renderer->renderLine = &msRenderLineKml; + renderer->createImage = &msCreateImageKml; + renderer->saveImage = &msSaveImageKml; + renderer->renderPolygon = &msRenderPolygonKml; + renderer->renderGlyphs = &msRenderGlyphsKml; renderer->renderEllipseSymbol = &msRenderEllipseSymbolKml; renderer->renderVectorSymbol = &msRenderVectorSymbolKml; renderer->renderPixmapSymbol = &msRenderPixmapSymbolKml; @@ -236,12 +219,12 @@ int msPopulateRendererVTableKML( rendererVTableObj *renderer ) renderer->renderPolygonTiled = &msRenderPolygonTiledKml; renderer->renderLineTiled = NULL; renderer->freeSymbol = &msFreeSymbolKml; - renderer->freeImage=&msFreeImageKml; + renderer->freeImage = &msFreeImageKml; renderer->mergeRasterBuffer = msMergeRasterBufferKml; renderer->compositeRasterBuffer = NULL; - renderer->startShape=&msStartShapeKml; - renderer->endShape=&msEndShapeKml; + renderer->startShape = &msStartShapeKml; + renderer->endShape = &msEndShapeKml; return MS_SUCCESS; #else @@ -250,4 +233,3 @@ int msPopulateRendererVTableKML( rendererVTableObj *renderer ) return MS_FAILURE; #endif } - diff --git a/mapkmlrenderer.cpp b/mapkmlrenderer.cpp index 360a51f6f5..feaaf62e67 100644 --- a/mapkmlrenderer.cpp +++ b/mapkmlrenderer.cpp @@ -39,22 +39,25 @@ #include "cpl_conv.h" #include "cpl_vsi.h" -#define KML_MAXFEATURES_TODRAW 1000 +#define KML_MAXFEATURES_TODRAW 1000 -KmlRenderer::KmlRenderer(int width, int height, outputFormatObj * /*format*/, colorObj* /*color*/) - : Width(width), Height(height), MapCellsize(1.0), XmlDoc(NULL), LayerNode(NULL), GroundOverlayNode(NULL), - PlacemarkNode(NULL), GeomNode(NULL), - Items(NULL), NumItems(0), FirstLayer(MS_TRUE), map(NULL), currentLayer(NULL), - mElevationFromAttribute( false ), mElevationAttributeIndex( -1 ), mCurrentElevationValue(0.0) +KmlRenderer::KmlRenderer(int width, int height, outputFormatObj * /*format*/, + colorObj * /*color*/) + : Width(width), Height(height), MapCellsize(1.0), XmlDoc(NULL), + LayerNode(NULL), GroundOverlayNode(NULL), PlacemarkNode(NULL), + GeomNode(NULL), Items(NULL), NumItems(0), FirstLayer(MS_TRUE), map(NULL), + currentLayer(NULL), mElevationFromAttribute(false), + mElevationAttributeIndex(-1), mCurrentElevationValue(0.0) { /*private variables*/ pszLayerDescMetadata = NULL; papszLayerIncludeItems = NULL; - nIncludeItems=0; + nIncludeItems = 0; papszLayerExcludeItems = NULL; - nExcludeItems=0; - pszLayerNameAttributeMetadata = NULL; /*metadata to use for a name for each feature*/ + nExcludeItems = 0; + pszLayerNameAttributeMetadata = + NULL; /*metadata to use for a name for each feature*/ LineStyle = NULL; numLineStyle = 0; @@ -67,7 +70,8 @@ KmlRenderer::KmlRenderer(int width, int height, outputFormatObj * /*format*/, co xmlNodePtr rootNode = xmlNewNode(NULL, BAD_CAST "kml"); /* Name spaces*/ - xmlSetNs(rootNode, xmlNewNs(rootNode, BAD_CAST "http://www.opengis.net/kml/2.2", NULL)); + xmlSetNs(rootNode, + xmlNewNs(rootNode, BAD_CAST "http://www.opengis.net/kml/2.2", NULL)); xmlDocSetRootElement(XmlDoc, rootNode); @@ -79,46 +83,45 @@ KmlRenderer::KmlRenderer(int width, int height, outputFormatObj * /*format*/, co xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", BAD_CAST "check"); styleNode = xmlNewChild(DocNode, NULL, BAD_CAST "Style", NULL); - xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST "LayerFolder_checkHideChildren"); + xmlNewProp(styleNode, BAD_CAST "id", + BAD_CAST "LayerFolder_checkHideChildren"); listStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "ListStyle", NULL); - xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", BAD_CAST "checkHideChildren"); + xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", + BAD_CAST "checkHideChildren"); styleNode = xmlNewChild(DocNode, NULL, BAD_CAST "Style", NULL); xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST "LayerFolder_checkOffOnly"); listStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "ListStyle", NULL); - xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", BAD_CAST "checkOffOnly"); + xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", + BAD_CAST "checkOffOnly"); styleNode = xmlNewChild(DocNode, NULL, BAD_CAST "Style", NULL); xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST "LayerFolder_radioFolder"); listStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "ListStyle", NULL); - xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", BAD_CAST "radioFolder"); - + xmlNewChild(listStyleNode, NULL, BAD_CAST "listItemType", + BAD_CAST "radioFolder"); StyleHashTable = msCreateHashTable(); - } -KmlRenderer::~KmlRenderer() -{ +KmlRenderer::~KmlRenderer() { if (XmlDoc) xmlFreeDoc(XmlDoc); if (StyleHashTable) msFreeHashTable(StyleHashTable); - if(LineStyle) + if (LineStyle) msFree(LineStyle); xmlCleanupParser(); } -imageObj* KmlRenderer::createImage(int, int, outputFormatObj*, colorObj*) -{ +imageObj *KmlRenderer::createImage(int, int, outputFormatObj *, colorObj *) { return NULL; } -int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format) -{ +int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format) { /* -------------------------------------------------------------------- */ /* Write out the document. */ /* -------------------------------------------------------------------- */ @@ -129,7 +132,7 @@ int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format) int chunkSize = 4096; int bZip = MS_FALSE; - if( msIO_needBinaryStdout() == MS_FAILURE ) + if (msIO_needBinaryStdout() == MS_FAILURE) return MS_FAILURE; xmlDocDumpFormatMemoryEnc(XmlDoc, &buf, &bufSize, "UTF-8", 1); @@ -142,63 +145,60 @@ int KmlRenderer::saveImage(imageObj *, FILE *fp, outputFormatObj *format) VSILFILE *fpZip; int bytes_read; char buffer[1024]; - char *zip_filename =NULL; - void *hZip=NULL; + char *zip_filename = NULL; + void *hZip = NULL; - zip_filename = msTmpFile(NULL, NULL, "/vsimem/kmlzip/", "kmz" ); - hZip = CPLCreateZip( zip_filename, NULL ); - CPLCreateFileInZip( hZip, "mapserver.kml", NULL ); - for (int i=0; i bufSize) size = bufSize - i; - CPLWriteFileInZip( hZip, buf+i, size); + CPLWriteFileInZip(hZip, buf + i, size); } - CPLCloseFileInZip( hZip ); - CPLCloseZip( hZip ); + CPLCloseFileInZip(hZip); + CPLCloseZip(hZip); context = msIO_getHandler(fp); - fpZip = VSIFOpenL( zip_filename, "r" ); + fpZip = VSIFOpenL(zip_filename, "r"); - while( (bytes_read = VSIFReadL( buffer, 1, sizeof(buffer), fpZip )) > 0 ) { + while ((bytes_read = VSIFReadL(buffer, 1, sizeof(buffer), fpZip)) > 0) { if (context) msIO_contextWrite(context, buffer, bytes_read); else - msIO_fwrite( buffer, 1, bytes_read, fp ); + msIO_fwrite(buffer, 1, bytes_read, fp); } - VSIFCloseL( fpZip ); - msFree( zip_filename); + VSIFCloseL(fpZip); + msFree(zip_filename); xmlFree(buf); - return(MS_SUCCESS); + return (MS_SUCCESS); } context = msIO_getHandler(fp); - - for (int i=0; i bufSize) size = bufSize - i; if (context) - msIO_contextWrite(context, buf+i, size); + msIO_contextWrite(context, buf + i, size); else - msIO_fwrite(buf+i, 1, size, fp); + msIO_fwrite(buf + i, 1, size, fp); } xmlFree(buf); - return(MS_SUCCESS); + return (MS_SUCCESS); } - /************************************************************************/ /* processLayer */ /* */ /* Set parameters that make sense to a kml output. */ /************************************************************************/ -void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) -{ +void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) { int i; const char *asRaster = NULL; int nMaxFeatures = -1; @@ -213,29 +213,30 @@ void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) /*if there are labels we want the coordinates to be the center of the element.*/ - for(i=0; inumclasses; i++) - if(layer->_class[i]->numlabels > 0) layer->_class[i]->labels[0]->position = MS_XY; + for (i = 0; i < layer->numclasses; i++) + if (layer->_class[i]->numlabels > 0) + layer->_class[i]->labels[0]->position = MS_XY; /*we do not want to draw multiple styles. the new rendering architecture does not allow to know if we are dealing with a multi-style. So here we remove all styles beside the first one*/ - for(i=0; inumclasses; i++) { + for (i = 0; i < layer->numclasses; i++) { while (layer->_class[i]->numstyles > 1) - msDeleteStyle(layer->_class[i], layer->_class[i]->numstyles-1); + msDeleteStyle(layer->_class[i], layer->_class[i]->numstyles - 1); } - /*if layer has a metadata KML_OUTPUTASRASTER set to true, add a processing directive - to use an agg driver*/ + /*if layer has a metadata KML_OUTPUTASRASTER set to true, add a processing + directive to use an agg driver*/ asRaster = msLookupHashTable(&layer->metadata, "kml_outputasraster"); if (!asRaster) - asRaster = msLookupHashTable(&(layer->map->web.metadata), "kml_outputasraster"); - if (asRaster && (strcasecmp(asRaster, "true") == 0 || - strcasecmp(asRaster, "yes") == 0)) + asRaster = + msLookupHashTable(&(layer->map->web.metadata), "kml_outputasraster"); + if (asRaster && + (strcasecmp(asRaster, "true") == 0 || strcasecmp(asRaster, "yes") == 0)) msLayerAddProcessing(layer, "RENDERER=png24"); - /*set a maxfeaturestodraw, if not already set*/ pszTmp = msLookupHashTable(&layer->metadata, "maxfeaturestodraw"); @@ -247,13 +248,13 @@ void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) nMaxFeatures = atoi(pszTmp); } if (nMaxFeatures < 0 && format) - nMaxFeatures = atoi(msGetOutputFormatOption( format, "maxfeaturestodraw", "-1")); + nMaxFeatures = + atoi(msGetOutputFormatOption(format, "maxfeaturestodraw", "-1")); if (nMaxFeatures < 0 && format) { snprintf(szTmp, sizeof(szTmp), "%d", KML_MAXFEATURES_TODRAW); - msSetOutputFormatOption( format, "maxfeaturestodraw", szTmp); + msSetOutputFormatOption(format, "maxfeaturestodraw", szTmp); } - } /************************************************************************/ @@ -261,15 +262,14 @@ void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) /* */ /* Internal utility function to build name used fo rthe layer. */ /************************************************************************/ -char* KmlRenderer::getLayerName(layerObj *layer) -{ +char *KmlRenderer::getLayerName(layerObj *layer) { char stmp[20]; - const char *name=NULL;; + const char *name = NULL; + ; if (!layer) return NULL; - name = msLookupHashTable(&layer->metadata, "ows_name"); if (name && strlen(name) > 0) return msStrdup(name); @@ -277,13 +277,12 @@ char* KmlRenderer::getLayerName(layerObj *layer) if (layer->name && strlen(layer->name) > 0) return msStrdup(layer->name); - sprintf(stmp, "Layer%d",layer->index); + sprintf(stmp, "Layer%d", layer->index); return msStrdup(stmp); - } -const char* KmlRenderer::getAliasName(layerObj *lp, char *pszItemName, const char *namespaces) -{ +const char *KmlRenderer::getAliasName(layerObj *lp, char *pszItemName, + const char *namespaces) { const char *pszAlias = NULL; if (lp && pszItemName && strlen(pszItemName) > 0) { char szTmp[256]; @@ -293,10 +292,9 @@ const char* KmlRenderer::getAliasName(layerObj *lp, char *pszItemName, const cha return pszAlias; } -int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) -{ - char *layerName=NULL; - const char *value=NULL; +int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) { + char *layerName = NULL; + const char *value = NULL; LayerNode = xmlNewNode(NULL, BAD_CAST "Folder"); @@ -307,25 +305,31 @@ int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) const char *layerVisibility = layer->status != MS_OFF ? "1" : "0"; xmlNewChild(LayerNode, NULL, BAD_CAST "visibility", BAD_CAST layerVisibility); - const char *layerDsiplayFolder = msLookupHashTable(&(layer->metadata), "kml_folder_display"); + const char *layerDsiplayFolder = + msLookupHashTable(&(layer->metadata), "kml_folder_display"); if (layerDsiplayFolder == NULL) - layerDsiplayFolder = msLookupHashTable(&(layer->map->web.metadata), "kml_folder_display"); - if (!layerDsiplayFolder || strlen(layerDsiplayFolder)<=0) { - xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check"); + layerDsiplayFolder = + msLookupHashTable(&(layer->map->web.metadata), "kml_folder_display"); + if (!layerDsiplayFolder || strlen(layerDsiplayFolder) <= 0) { + xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", + BAD_CAST "#LayerFolder_check"); } else { if (strcasecmp(layerDsiplayFolder, "checkHideChildren") == 0) - xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkHideChildren"); + xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", + BAD_CAST "#LayerFolder_checkHideChildren"); else if (strcasecmp(layerDsiplayFolder, "checkOffOnly") == 0) - xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_checkOffOnly"); + xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", + BAD_CAST "#LayerFolder_checkOffOnly"); else if (strcasecmp(layerDsiplayFolder, "radioFolder") == 0) - xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_radioFolder"); + xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", + BAD_CAST "#LayerFolder_radioFolder"); else - xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", BAD_CAST "#LayerFolder_check"); + xmlNewChild(LayerNode, NULL, BAD_CAST "styleUrl", + BAD_CAST "#LayerFolder_check"); } - /*Init few things on the first layer*/ if (FirstLayer) { FirstLayer = MS_FALSE; @@ -338,9 +342,10 @@ int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) checkProjection(layer->map); /*check for image path and image url*/ - if (layer->map->debug && (layer->map->web.imageurl == NULL || layer->map->web.imagepath == NULL)) - msDebug("KmlRenderer::startNewLayer: imagepath and imageurl should be set in the web object\n"); - + if (layer->map->debug && + (layer->map->web.imageurl == NULL || layer->map->web.imagepath == NULL)) + msDebug("KmlRenderer::startNewLayer: imagepath and imageurl should be " + "set in the web object\n"); /*map rect for ground overlay*/ MapExtent = layer->map->extent; @@ -348,16 +353,16 @@ int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) BgColor = layer->map->imagecolor; xmlNewChild(DocNode, NULL, BAD_CAST "name", BAD_CAST layer->map->name); - aggFormat = msSelectOutputFormat( layer->map, "png24"); + aggFormat = msSelectOutputFormat(layer->map, "png24"); aggFormat->transparent = MS_TRUE; - } currentLayer = layer; if (!msLayerIsOpen(layer)) { if (msLayerOpen(layer) != MS_SUCCESS) { - msSetError(MS_MISCERR, "msLayerOpen failed", "KmlRenderer::startNewLayer" ); + msSetError(MS_MISCERR, "msLayerOpen failed", + "KmlRenderer::startNewLayer"); return MS_FAILURE; } } @@ -369,45 +374,46 @@ int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) processLayer(layer, NULL); if (msLookupHashTable(&layer->metadata, "kml_description")) - pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "kml_description"); + pszLayerDescMetadata = + msLookupHashTable(&layer->metadata, "kml_description"); else if (msLookupHashTable(&layer->metadata, "ows_description")) - pszLayerDescMetadata = msLookupHashTable(&layer->metadata, "ows_description"); + pszLayerDescMetadata = + msLookupHashTable(&layer->metadata, "ows_description"); - value=msLookupHashTable(&layer->metadata, "kml_include_items"); + value = msLookupHashTable(&layer->metadata, "kml_include_items"); if (!value) - value=msLookupHashTable(&layer->metadata, "ows_include_items"); + value = msLookupHashTable(&layer->metadata, "ows_include_items"); if (value) papszLayerIncludeItems = msStringSplit(value, ',', &nIncludeItems); - value=msLookupHashTable(&layer->metadata, "kml_exclude_items"); + value = msLookupHashTable(&layer->metadata, "kml_exclude_items"); if (!value) - value=msLookupHashTable(&layer->metadata, "ows_exclude_items"); + value = msLookupHashTable(&layer->metadata, "ows_exclude_items"); if (value) papszLayerExcludeItems = msStringSplit(value, ',', &nExcludeItems); - if (msLookupHashTable(&layer->metadata, "kml_name_item")) - pszLayerNameAttributeMetadata = msLookupHashTable(&layer->metadata, "kml_name_item"); + pszLayerNameAttributeMetadata = + msLookupHashTable(&layer->metadata, "kml_name_item"); /*get all attributes*/ - if(msLayerWhichItems(layer, MS_TRUE, NULL) != MS_SUCCESS) { + if (msLayerWhichItems(layer, MS_TRUE, NULL) != MS_SUCCESS) { return MS_FAILURE; } - NumItems = layer->numitems; if (NumItems) { Items = (char **)msSmallCalloc(NumItems, sizeof(char *)); - for (int i=0; iitems[i]); } - - const char* elevationAttribute = msLookupHashTable(&layer->metadata, "kml_elevation_attribute"); - if( elevationAttribute ) { + const char *elevationAttribute = + msLookupHashTable(&layer->metadata, "kml_elevation_attribute"); + if (elevationAttribute) { mElevationFromAttribute = true; - for( int i = 0; i < layer->numitems; ++i ) { - if( strcasecmp( layer->items[i], elevationAttribute ) == 0 ) { + for (int i = 0; i < layer->numitems; ++i) { + if (strcasecmp(layer->items[i], elevationAttribute) == 0) { mElevationAttributeIndex = i; } } @@ -417,13 +423,12 @@ int KmlRenderer::startNewLayer(imageObj *img, layerObj *layer) return MS_SUCCESS; } -int KmlRenderer::closeNewLayer(imageObj *, layerObj *) -{ +int KmlRenderer::closeNewLayer(imageObj *, layerObj *) { flushPlacemark(); xmlAddChild(DocNode, LayerNode); - if(Items) { + if (Items) { msFreeCharArray(Items, NumItems); Items = NULL; NumItems = 0; @@ -434,33 +439,32 @@ int KmlRenderer::closeNewLayer(imageObj *, layerObj *) if (pszLayerNameAttributeMetadata) pszLayerNameAttributeMetadata = NULL; - if (papszLayerIncludeItems && nIncludeItems>0) + if (papszLayerIncludeItems && nIncludeItems > 0) msFreeCharArray(papszLayerIncludeItems, nIncludeItems); - papszLayerIncludeItems=NULL; + papszLayerIncludeItems = NULL; - if (papszLayerExcludeItems && nExcludeItems>0) + if (papszLayerExcludeItems && nExcludeItems > 0) msFreeCharArray(papszLayerExcludeItems, nExcludeItems); - papszLayerExcludeItems=NULL; + papszLayerExcludeItems = NULL; return MS_SUCCESS; } -int KmlRenderer::mergeRasterBuffer(imageObj *image, rasterBufferObj *rb) -{ +int KmlRenderer::mergeRasterBuffer(imageObj *image, rasterBufferObj *rb) { assert(rb && rb->type == MS_BUFFER_BYTE_RGBA); char *tmpFileName = NULL; char *tmpUrl = NULL; FILE *tmpFile = NULL; tmpFileName = msTmpFile(NULL, MapPath, image->imagepath, "png"); - tmpFile = fopen(tmpFileName,"wb"); + tmpFile = fopen(tmpFileName, "wb"); if (tmpFile) { if (!aggFormat->vtable) msInitializeRendererVTable(aggFormat); - msSaveRasterBuffer(map,rb,tmpFile,aggFormat); - tmpUrl = msStrdup( image->imageurl); + msSaveRasterBuffer(map, rb, tmpFile, aggFormat); + tmpUrl = msStrdup(image->imageurl); tmpUrl = msStringConcatenate(tmpUrl, (char *)(msGetBasename(tmpFileName))); tmpUrl = msStringConcatenate(tmpUrl, ".png"); @@ -470,24 +474,25 @@ int KmlRenderer::mergeRasterBuffer(imageObj *image, rasterBufferObj *rb) fclose(tmpFile); return MS_SUCCESS; } else { - msSetError(MS_IOERR,"Failed to create file for kml overlay","KmlRenderer::mergeRasterBuffer()"); + msSetError(MS_IOERR, "Failed to create file for kml overlay", + "KmlRenderer::mergeRasterBuffer()"); return MS_FAILURE; } } -void KmlRenderer::setupRenderingParams(hashTableObj *layerMetadata) -{ +void KmlRenderer::setupRenderingParams(hashTableObj *layerMetadata) { AltitudeMode = 0; Extrude = 0; Tessellate = 0; - const char *altitudeModeVal = msLookupHashTable(layerMetadata, "kml_altitudeMode"); + const char *altitudeModeVal = + msLookupHashTable(layerMetadata, "kml_altitudeMode"); if (altitudeModeVal) { - if(strcasecmp(altitudeModeVal, "absolute") == 0) + if (strcasecmp(altitudeModeVal, "absolute") == 0) AltitudeMode = absolute; - else if(strcasecmp(altitudeModeVal, "relativeToGround") == 0) + else if (strcasecmp(altitudeModeVal, "relativeToGround") == 0) AltitudeMode = relativeToGround; - else if(strcasecmp(altitudeModeVal, "clampToGround") == 0) + else if (strcasecmp(altitudeModeVal, "clampToGround") == 0) AltitudeMode = clampToGround; } @@ -496,31 +501,31 @@ void KmlRenderer::setupRenderingParams(hashTableObj *layerMetadata) Extrude = atoi(extrudeVal); } - const char *tessellateVal = msLookupHashTable(layerMetadata, "kml_tessellate"); + const char *tessellateVal = + msLookupHashTable(layerMetadata, "kml_tessellate"); if (tessellateVal) { Tessellate = atoi(tessellateVal); } - } -int KmlRenderer::checkProjection(mapObj *map) -{ - projectionObj *projection= &map->projection; - if (projection && projection->numargs > 0 && msProjIsGeographicCRS(projection)) { +int KmlRenderer::checkProjection(mapObj *map) { + projectionObj *projection = &map->projection; + if (projection && projection->numargs > 0 && + msProjIsGeographicCRS(projection)) { return MS_SUCCESS; } else { char epsg_string[100]; rectObj sRect; projectionObj out; - /* for layer the do not have any projection set, set them with the current map - projection*/ + /* for layer the do not have any projection set, set them with the current + map projection*/ if (projection && projection->numargs > 0) { layerObj *lp = NULL; - int i =0; + int i = 0; char *pszMapProjectString = msGetProjectionString(projection); if (pszMapProjectString) { - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { lp = GET_LAYER(map, i); if (lp->projection.numargs == 0 && lp->transform == MS_TRUE) { msFreeProjection(&lp->projection); @@ -530,7 +535,7 @@ int KmlRenderer::checkProjection(mapObj *map) msFree(pszMapProjectString); } } - strcpy(epsg_string, "epsg:4326" ); + strcpy(epsg_string, "epsg:4326"); msInitProjection(&out); msProjectionInheritContextFrom(&out, projection); msLoadProjectionString(&out, epsg_string); @@ -544,22 +549,24 @@ int KmlRenderer::checkProjection(mapObj *map) map->extent = sRect; map->units = MS_DD; - if (map->debug) - msDebug("KmlRenderer::checkProjection: Mapfile projection set to epsg:4326\n"); + msDebug("KmlRenderer::checkProjection: Mapfile projection set to " + "epsg:4326\n"); return MS_SUCCESS; } } -xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl) -{ - xmlNodePtr placemarkNode = xmlNewChild(parentNode, NULL, BAD_CAST "Placemark", NULL); +xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, + char *styleUrl) { + xmlNodePtr placemarkNode = + xmlNewChild(parentNode, NULL, BAD_CAST "Placemark", NULL); /*always add a name. It will be replaced by a text value if available*/ char tmpid[100]; - char *stmp=NULL, *layerName=NULL; - if (CurrentShapeName && strlen(CurrentShapeName)>0) { - xmlNewChild(placemarkNode, NULL, BAD_CAST "name", BAD_CAST CurrentShapeName); + char *stmp = NULL, *layerName = NULL; + if (CurrentShapeName && strlen(CurrentShapeName) > 0) { + xmlNewChild(placemarkNode, NULL, BAD_CAST "name", + BAD_CAST CurrentShapeName); } else { sprintf(tmpid, ".%d", CurrentShapeIndex); layerName = getLayerName(currentLayer); @@ -575,8 +582,7 @@ xmlNodePtr KmlRenderer::createPlacemarkNode(xmlNodePtr parentNode, char *styleUr return placemarkNode; } -void KmlRenderer::renderLine(imageObj*, shapeObj *p, strokeStyleObj *style) -{ +void KmlRenderer::renderLine(imageObj *, shapeObj *p, strokeStyleObj *style) { if (p->numlines == 0) return; @@ -599,8 +605,9 @@ void KmlRenderer::renderLine(imageObj*, shapeObj *p, strokeStyleObj *style) /* more than one line => MultiGeometry*/ if (p->numlines > 1) { geomNode = getGeomParentNode("LineString"); // returns MultiGeom Node - for (int i=1; inumlines; i++) { - xmlNodePtr lineStringNode = xmlNewChild(geomNode, NULL, BAD_CAST "LineString", NULL); + for (int i = 1; i < p->numlines; i++) { + xmlNodePtr lineStringNode = + xmlNewChild(geomNode, NULL, BAD_CAST "LineString", NULL); addAddRenderingSpecifications(lineStringNode); addCoordsNode(lineStringNode, p->line[i].point, p->line[i].numpoints); } @@ -608,11 +615,9 @@ void KmlRenderer::renderLine(imageObj*, shapeObj *p, strokeStyleObj *style) CurrentDrawnShapeIndex = p->index; } - } -void KmlRenderer::renderPolygon(imageObj*, shapeObj *p, colorObj *color) -{ +void KmlRenderer::renderPolygon(imageObj *, shapeObj *p, colorObj *color) { if (PlacemarkNode == NULL) PlacemarkNode = createPlacemarkNode(LayerNode, NULL); @@ -622,40 +627,42 @@ void KmlRenderer::renderPolygon(imageObj*, shapeObj *p, colorObj *color) memcpy(&PolygonColor, color, sizeof(colorObj)); SymbologyFlag[Polygon] = 1; - if (p->index != CurrentDrawnShapeIndex) { xmlNodePtr geomParentNode = getGeomParentNode("Polygon"); - for (int i=0; inumlines; i++) { + for (int i = 0; i < p->numlines; i++) { xmlNodePtr bdryNode = NULL; - if (i==0) /* __TODO__ check ring order*/ - bdryNode = xmlNewChild(geomParentNode, NULL, BAD_CAST "outerBoundaryIs", NULL); + if (i == 0) /* __TODO__ check ring order*/ + bdryNode = + xmlNewChild(geomParentNode, NULL, BAD_CAST "outerBoundaryIs", NULL); else - bdryNode = xmlNewChild(geomParentNode, NULL, BAD_CAST "innerBoundaryIs", NULL); + bdryNode = + xmlNewChild(geomParentNode, NULL, BAD_CAST "innerBoundaryIs", NULL); - xmlNodePtr ringNode = xmlNewChild(bdryNode, NULL, BAD_CAST "LinearRing", NULL); + xmlNodePtr ringNode = + xmlNewChild(bdryNode, NULL, BAD_CAST "LinearRing", NULL); addAddRenderingSpecifications(ringNode); addCoordsNode(ringNode, p->line[i].point, p->line[i].numpoints); } CurrentDrawnShapeIndex = p->index; - } - } -void KmlRenderer::addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts) -{ +void KmlRenderer::addCoordsNode(xmlNodePtr parentNode, pointObj *pts, + int numPts) { char lineBuf[128]; - xmlNodePtr coordsNode = xmlNewChild(parentNode, NULL, BAD_CAST "coordinates", NULL); + xmlNodePtr coordsNode = + xmlNewChild(parentNode, NULL, BAD_CAST "coordinates", NULL); xmlNodeAddContent(coordsNode, BAD_CAST "\n"); - for (int i=0; iannotext == NULL || ts->textpath->numglyphs == 0 ) +void KmlRenderer::renderGlyphs(imageObj *, const textSymbolObj *ts, + colorObj *clr, colorObj * /*oc*/, int /*ow*/) { + if (ts->annotext == NULL || ts->textpath->numglyphs == 0) return; if (PlacemarkNode == NULL) @@ -686,7 +693,7 @@ void KmlRenderer::renderGlyphs(imageObj *, const textSymbolObj *ts, colorObj *cl continue; if (strcmp((char *)node->name, "name") == 0) { - xmlNodeSetContent(node, BAD_CAST ts->annotext); + xmlNodeSetContent(node, BAD_CAST ts->annotext); break; } } @@ -702,8 +709,7 @@ void KmlRenderer::renderGlyphs(imageObj *, const textSymbolObj *ts, colorObj *cl addCoordsNode(geomNode, &pt, 1); } -void KmlRenderer::addAddRenderingSpecifications(xmlNodePtr node) -{ +void KmlRenderer::addAddRenderingSpecifications(xmlNodePtr node) { /* 0 0 @@ -719,48 +725,50 @@ void KmlRenderer::addAddRenderingSpecifications(xmlNodePtr node) if (AltitudeMode == absolute) xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "absolute"); else if (AltitudeMode == relativeToGround) - xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "relativeToGround"); + xmlNewChild(node, NULL, BAD_CAST "altitudeMode", + BAD_CAST "relativeToGround"); else if (AltitudeMode == clampToGround) xmlNewChild(node, NULL, BAD_CAST "altitudeMode", BAD_CAST "clampToGround"); } +imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, + colorObj *bg); -imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorObj * bg); - -int KmlRenderer::createIconImage(char *fileName, symbolObj *symbol, symbolStyleObj *symstyle) -{ +int KmlRenderer::createIconImage(char *fileName, symbolObj *symbol, + symbolStyleObj *symstyle) { pointObj p; int status; imageObj *tmpImg = NULL; - tmpImg = agg2CreateImage((int)(symbol->sizex*symstyle->scale), - (int)(symbol->sizey*symstyle->scale), - aggFormat, NULL); + tmpImg = + agg2CreateImage((int)(symbol->sizex * symstyle->scale), + (int)(symbol->sizey * symstyle->scale), aggFormat, NULL); tmpImg->format = aggFormat; if (!aggFormat->vtable) msInitializeRendererVTable(aggFormat); p.x = symbol->sizex * symstyle->scale / 2; - p.y = symbol->sizey *symstyle->scale / 2; + p.y = symbol->sizey * symstyle->scale / 2; p.z = 0.0; - status = msDrawMarkerSymbol(map,tmpImg, &p, symstyle->style, 1); - if( status != MS_SUCCESS ) + status = msDrawMarkerSymbol(map, tmpImg, &p, symstyle->style, 1); + if (status != MS_SUCCESS) return status; return msSaveImage(map, tmpImg, fileName); } -void KmlRenderer::renderSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) -{ +void KmlRenderer::renderSymbol(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { if (PlacemarkNode == NULL) PlacemarkNode = createPlacemarkNode(LayerNode, NULL); if (!PlacemarkNode) return; - snprintf(SymbolUrl, sizeof(SymbolUrl), "%s", lookupSymbolUrl(img, symbol, style)); + snprintf(SymbolUrl, sizeof(SymbolUrl), "%s", + lookupSymbolUrl(img, symbol, style)); SymbologyFlag[Symbol] = 1; xmlNodePtr geomNode = getGeomParentNode("Point"); @@ -772,32 +780,31 @@ void KmlRenderer::renderSymbol(imageObj *img, double x, double y, symbolObj *sym addCoordsNode(geomNode, &pt, 1); } -void KmlRenderer::renderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +void KmlRenderer::renderPixmapSymbol(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { renderSymbol(img, x, y, symbol, style); } -void KmlRenderer::renderVectorSymbol(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +void KmlRenderer::renderVectorSymbol(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style) { renderSymbol(img, x, y, symbol, style); } -void KmlRenderer::renderEllipseSymbol(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +void KmlRenderer::renderEllipseSymbol(imageObj *img, double x, double y, + symbolObj *symbol, + symbolStyleObj *style) { renderSymbol(img, x, y, symbol, style); } -void KmlRenderer::renderTruetypeSymbol(imageObj *img, double x, double y, symbolObj *symbol, - symbolStyleObj *style) -{ +void KmlRenderer::renderTruetypeSymbol(imageObj *img, double x, double y, + symbolObj *symbol, + symbolStyleObj *style) { renderSymbol(img, x, y, symbol, style); } -xmlNodePtr KmlRenderer::createGroundOverlayNode(xmlNodePtr parentNode, char *imageHref, layerObj *layer) -{ +xmlNodePtr KmlRenderer::createGroundOverlayNode(xmlNodePtr parentNode, + char *imageHref, + layerObj *layer) { /* @@ -821,21 +828,26 @@ xmlNodePtr KmlRenderer::createGroundOverlayNode(xmlNodePtr parentNode, char *ima */ - char layerHexColor[32]; - xmlNodePtr groundOverlayNode = xmlNewChild(parentNode, NULL, BAD_CAST "GroundOverlay", NULL); + char layerHexColor[32]; + xmlNodePtr groundOverlayNode = + xmlNewChild(parentNode, NULL, BAD_CAST "GroundOverlay", NULL); char *layerName = getLayerName(layer); xmlNewChild(groundOverlayNode, NULL, BAD_CAST "name", BAD_CAST layerName); - if (layer->compositer && layer->compositer->opacity > 0 && layer->compositer->opacity < 100) { - sprintf(layerHexColor, "%02xffffff", (unsigned int)MS_NINT(layer->compositer->opacity*2.55)); - xmlNewChild(groundOverlayNode, NULL, BAD_CAST "color", BAD_CAST layerHexColor); + if (layer->compositer && layer->compositer->opacity > 0 && + layer->compositer->opacity < 100) { + sprintf(layerHexColor, "%02xffffff", + (unsigned int)MS_NINT(layer->compositer->opacity * 2.55)); + xmlNewChild(groundOverlayNode, NULL, BAD_CAST "color", + BAD_CAST layerHexColor); } else xmlNewChild(groundOverlayNode, NULL, BAD_CAST "color", BAD_CAST "ffffffff"); char stmp[20]; - sprintf(stmp, "%d",layer->index); + sprintf(stmp, "%d", layer->index); xmlNewChild(groundOverlayNode, NULL, BAD_CAST "drawOrder", BAD_CAST stmp); if (imageHref) { - xmlNodePtr iconNode = xmlNewChild(groundOverlayNode, NULL, BAD_CAST "Icon", NULL); + xmlNodePtr iconNode = + xmlNewChild(groundOverlayNode, NULL, BAD_CAST "Icon", NULL); xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST imageHref); } @@ -846,7 +858,8 @@ xmlNodePtr KmlRenderer::createGroundOverlayNode(xmlNodePtr parentNode, char *ima else mapextent = currentLayer->map->extent; - xmlNodePtr latLonBoxNode = xmlNewChild(groundOverlayNode, NULL, BAD_CAST "LatLonBox", NULL); + xmlNodePtr latLonBoxNode = + xmlNewChild(groundOverlayNode, NULL, BAD_CAST "LatLonBox", NULL); sprintf(crdStr, "%.8f", mapextent.maxy); xmlNewChild(latLonBoxNode, NULL, BAD_CAST "north", BAD_CAST crdStr); @@ -864,17 +877,17 @@ xmlNodePtr KmlRenderer::createGroundOverlayNode(xmlNodePtr parentNode, char *ima return groundOverlayNode; } -void KmlRenderer::startShape(imageObj *, shapeObj *shape) -{ +void KmlRenderer::startShape(imageObj *, shapeObj *shape) { if (PlacemarkNode) flushPlacemark(); - CurrentShapeIndex=-1; + CurrentShapeIndex = -1; CurrentDrawnShapeIndex = -1; - CurrentShapeName=NULL; + CurrentShapeName = NULL; - /*should be done at endshape but the plugin architecture does not call endshape yet*/ - if(LineStyle) { + /*should be done at endshape but the plugin architecture does not call + * endshape yet*/ + if (LineStyle) { msFree(LineStyle); LineStyle = NULL; @@ -883,8 +896,10 @@ void KmlRenderer::startShape(imageObj *, shapeObj *shape) CurrentShapeIndex = shape->index; if (pszLayerNameAttributeMetadata) { - for (int i=0; inumitems; i++) { - if (strcasecmp(currentLayer->items[i], pszLayerNameAttributeMetadata) == 0 && shape->values[i]) { + for (int i = 0; i < currentLayer->numitems; i++) { + if (strcasecmp(currentLayer->items[i], pszLayerNameAttributeMetadata) == + 0 && + shape->values[i]) { CurrentShapeName = msStrdup(shape->values[i]); break; } @@ -895,33 +910,33 @@ void KmlRenderer::startShape(imageObj *, shapeObj *shape) DescriptionNode = createDescriptionNode(shape); - if( mElevationFromAttribute && shape->numvalues > mElevationAttributeIndex && - mElevationAttributeIndex >= 0 && shape->values[mElevationAttributeIndex]) { - mCurrentElevationValue = atof( shape->values[mElevationAttributeIndex] ); + if (mElevationFromAttribute && shape->numvalues > mElevationAttributeIndex && + mElevationAttributeIndex >= 0 && + shape->values[mElevationAttributeIndex]) { + mCurrentElevationValue = atof(shape->values[mElevationAttributeIndex]); } - memset(SymbologyFlag, 0, NumSymbologyFlag); } -void KmlRenderer::endShape(imageObj*, shapeObj*) -{ +void KmlRenderer::endShape(imageObj *, shapeObj *) { CurrentShapeIndex = -1; if (CurrentShapeName) msFree(CurrentShapeName); CurrentShapeName = NULL; } -xmlNodePtr KmlRenderer::getGeomParentNode(const char *geomName) -{ +xmlNodePtr KmlRenderer::getGeomParentNode(const char *geomName) { /*we do not need a multi-geometry for point layers*/ - if (currentLayer->type != MS_LAYER_POINT && currentLayer->type != MS_LAYER_ANNOTATION && GeomNode) { + if (currentLayer->type != MS_LAYER_POINT && + currentLayer->type != MS_LAYER_ANNOTATION && GeomNode) { /*placemark geometry already defined, we need multigeometry node*/ xmlNodePtr multiGeomNode = xmlNewNode(NULL, BAD_CAST "MultiGeometry"); xmlAddChild(multiGeomNode, GeomNode); GeomNode = multiGeomNode; - xmlNodePtr geomNode = xmlNewChild(multiGeomNode, NULL, BAD_CAST geomName, NULL); + xmlNodePtr geomNode = + xmlNewChild(multiGeomNode, NULL, BAD_CAST geomName, NULL); return geomNode; } else { GeomNode = xmlNewNode(NULL, BAD_CAST geomName); @@ -929,9 +944,9 @@ xmlNodePtr KmlRenderer::getGeomParentNode(const char *geomName) } } -const char* KmlRenderer::lookupSymbolUrl(imageObj *img, symbolObj *symbol, symbolStyleObj *symstyle) -{ - char symbolHexColor[32]; +const char *KmlRenderer::lookupSymbolUrl(imageObj *img, symbolObj *symbol, + symbolStyleObj *symstyle) { + char symbolHexColor[32]; /* */ - sprintf(symbolHexColor,"%02x%02x%02x%02x", symstyle->style->color.alpha, symstyle->style->color.blue, - symstyle->style->color.green, symstyle->style->color.red); - snprintf(SymbolName, sizeof(SymbolName), "symbol_%s_%.1f_%s", symbol->name, symstyle->scale, symbolHexColor); + sprintf(symbolHexColor, "%02x%02x%02x%02x", symstyle->style->color.alpha, + symstyle->style->color.blue, symstyle->style->color.green, + symstyle->style->color.red); + snprintf(SymbolName, sizeof(SymbolName), "symbol_%s_%.1f_%s", symbol->name, + symstyle->scale, symbolHexColor); const char *symbolUrl = msLookupHashTable(StyleHashTable, SymbolName); if (!symbolUrl) { @@ -959,16 +976,19 @@ const char* KmlRenderer::lookupSymbolUrl(imageObj *img, symbolObj *symbol, symbo snprintf(iconFileName, sizeof(iconFileName), "%s", tmpFileName); msFree(tmpFileName); } else { - sprintf(iconFileName, "symbol_%s_%.1f.%s", symbol->name, symstyle->scale, "png"); + sprintf(iconFileName, "symbol_%s_%.1f.%s", symbol->name, symstyle->scale, + "png"); } if (createIconImage(iconFileName, symbol, symstyle) != MS_SUCCESS) { - msSetError(MS_IOERR, "Error creating icon file '%s'", "KmlRenderer::lookupSymbolStyle()", iconFileName); + msSetError(MS_IOERR, "Error creating icon file '%s'", + "KmlRenderer::lookupSymbolStyle()", iconFileName); return NULL; } if (img->imageurl) - sprintf(iconUrl, "%s%s.%s", img->imageurl, msGetBasename(iconFileName), "png"); + sprintf(iconUrl, "%s%s.%s", img->imageurl, msGetBasename(iconFileName), + "png"); else snprintf(iconUrl, sizeof(iconUrl), "%s", iconFileName); @@ -979,12 +999,11 @@ const char* KmlRenderer::lookupSymbolUrl(imageObj *img, symbolObj *symbol, symbo return symbolUrl; } -const char* KmlRenderer::lookupPlacemarkStyle() -{ - char lineHexColor[32]; - char polygonHexColor[32]; - char labelHexColor[32]; - char *styleName=NULL; +const char *KmlRenderer::lookupPlacemarkStyle() { + char lineHexColor[32]; + char polygonHexColor[32]; + char labelHexColor[32]; + char *styleName = NULL; styleName = msStringConcatenate(styleName, "style"); @@ -993,23 +1012,29 @@ const char* KmlRenderer::lookupPlacemarkStyle() ffffffff - normal + normal 1 */ - for (int i=0; icompositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && + for (int i = 0; i < numLineStyle; i++) { + if (currentLayer && currentLayer->compositer && + currentLayer->compositer->opacity > 0 && + currentLayer->compositer->opacity < 100 && LineStyle[i].color->alpha == 255) - LineStyle[i].color->alpha = MS_NINT(currentLayer->compositer->opacity*2.55); + LineStyle[i].color->alpha = + MS_NINT(currentLayer->compositer->opacity * 2.55); - sprintf(lineHexColor,"%02x%02x%02x%02x", LineStyle[i].color->alpha, LineStyle[0].color->blue, - LineStyle[i].color->green, LineStyle[i].color->red); + sprintf(lineHexColor, "%02x%02x%02x%02x", LineStyle[i].color->alpha, + LineStyle[0].color->blue, LineStyle[i].color->green, + LineStyle[i].color->red); char lineStyleName[64]; - snprintf(lineStyleName, sizeof(lineStyleName), "_line_%s_w%.1f", lineHexColor, LineStyle[i].width); + snprintf(lineStyleName, sizeof(lineStyleName), "_line_%s_w%.1f", + lineHexColor, LineStyle[i].width); styleName = msStringConcatenate(styleName, lineStyleName); } } @@ -1019,7 +1044,8 @@ const char* KmlRenderer::lookupPlacemarkStyle() ffffffff - normal + normal 1 @@ -1027,10 +1053,12 @@ const char* KmlRenderer::lookupPlacemarkStyle() */ - if (currentLayer && currentLayer->compositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && - PolygonColor.alpha == 255) - PolygonColor.alpha = MS_NINT(currentLayer->compositer->opacity*2.55); - sprintf(polygonHexColor,"%02x%02x%02x%02x", PolygonColor.alpha, PolygonColor.blue, PolygonColor.green, PolygonColor.red); + if (currentLayer && currentLayer->compositer && + currentLayer->compositer->opacity > 0 && + currentLayer->compositer->opacity < 100 && PolygonColor.alpha == 255) + PolygonColor.alpha = MS_NINT(currentLayer->compositer->opacity * 2.55); + sprintf(polygonHexColor, "%02x%02x%02x%02x", PolygonColor.alpha, + PolygonColor.blue, PolygonColor.green, PolygonColor.red); char polygonStyleName[64]; sprintf(polygonStyleName, "_polygon_%s", polygonHexColor); @@ -1042,17 +1070,20 @@ const char* KmlRenderer::lookupPlacemarkStyle() ffffffff - normal + normal 1 */ - if (currentLayer && currentLayer->compositer && currentLayer->compositer->opacity > 0 && currentLayer->compositer->opacity < 100 && - LabelColor.alpha == 255) - LabelColor.alpha = MS_NINT(currentLayer->compositer->opacity*2.55); - sprintf(labelHexColor,"%02x%02x%02x%02x", LabelColor.alpha, LabelColor.blue, LabelColor.green, LabelColor.red); + if (currentLayer && currentLayer->compositer && + currentLayer->compositer->opacity > 0 && + currentLayer->compositer->opacity < 100 && LabelColor.alpha == 255) + LabelColor.alpha = MS_NINT(currentLayer->compositer->opacity * 2.55); + sprintf(labelHexColor, "%02x%02x%02x%02x", LabelColor.alpha, + LabelColor.blue, LabelColor.green, LabelColor.red); // __TODO__ add label scale @@ -1083,7 +1114,7 @@ const char* KmlRenderer::lookupPlacemarkStyle() const char *styleUrl = msLookupHashTable(StyleHashTable, styleName); if (!styleUrl) { - char *styleValue=NULL; + char *styleValue = NULL; styleValue = msStringConcatenate(styleValue, "#"); styleValue = msStringConcatenate(styleValue, styleName); hashObj *hash = msInsertHashTable(StyleHashTable, styleName, styleValue); @@ -1095,16 +1126,21 @@ const char* KmlRenderer::lookupPlacemarkStyle() xmlNewProp(styleNode, BAD_CAST "id", BAD_CAST styleName); if (SymbologyFlag[Polygon]) { - xmlNodePtr polyStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "PolyStyle", NULL); - xmlNewChild(polyStyleNode, NULL, BAD_CAST "color", BAD_CAST polygonHexColor); + xmlNodePtr polyStyleNode = + xmlNewChild(styleNode, NULL, BAD_CAST "PolyStyle", NULL); + xmlNewChild(polyStyleNode, NULL, BAD_CAST "color", + BAD_CAST polygonHexColor); } if (SymbologyFlag[Line]) { - for (int i=0; ialpha, LineStyle[i].color->blue, - LineStyle[i].color->green, LineStyle[i].color->red); - xmlNewChild(lineStyleNode, NULL, BAD_CAST "color", BAD_CAST lineHexColor); + for (int i = 0; i < numLineStyle; i++) { + xmlNodePtr lineStyleNode = + xmlNewChild(styleNode, NULL, BAD_CAST "LineStyle", NULL); + sprintf(lineHexColor, "%02x%02x%02x%02x", LineStyle[i].color->alpha, + LineStyle[i].color->blue, LineStyle[i].color->green, + LineStyle[i].color->red); + xmlNewChild(lineStyleNode, NULL, BAD_CAST "color", + BAD_CAST lineHexColor); char width[16]; sprintf(width, "%.1f", LineStyle[i].width); @@ -1113,27 +1149,34 @@ const char* KmlRenderer::lookupPlacemarkStyle() } if (SymbologyFlag[Symbol]) { - xmlNodePtr iconStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); + xmlNodePtr iconStyleNode = + xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); - xmlNodePtr iconNode = xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); + xmlNodePtr iconNode = + xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST SymbolUrl); /*char scale[16]; sprintf(scale, "%.1f", style->scale); xmlNewChild(iconStyleNode, NULL, BAD_CAST "scale", BAD_CAST scale);*/ } else { - const char *value=msLookupHashTable(¤tLayer->metadata, "kml_default_symbol_href"); + const char *value = + msLookupHashTable(¤tLayer->metadata, "kml_default_symbol_href"); if (value && strlen(value) > 0) { - xmlNodePtr iconStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); + xmlNodePtr iconStyleNode = + xmlNewChild(styleNode, NULL, BAD_CAST "IconStyle", NULL); - xmlNodePtr iconNode = xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); + xmlNodePtr iconNode = + xmlNewChild(iconStyleNode, NULL, BAD_CAST "Icon", NULL); xmlNewChild(iconNode, NULL, BAD_CAST "href", BAD_CAST value); } } if (SymbologyFlag[Label]) { - xmlNodePtr labelStyleNode = xmlNewChild(styleNode, NULL, BAD_CAST "LabelStyle", NULL); - xmlNewChild(labelStyleNode, NULL, BAD_CAST "color", BAD_CAST labelHexColor); + xmlNodePtr labelStyleNode = + xmlNewChild(styleNode, NULL, BAD_CAST "LabelStyle", NULL); + xmlNewChild(labelStyleNode, NULL, BAD_CAST "color", + BAD_CAST labelHexColor); /*char scale[16]; sprintf(scale, "%.1f", style->scale); @@ -1147,8 +1190,7 @@ const char* KmlRenderer::lookupPlacemarkStyle() return styleUrl; } -void KmlRenderer::flushPlacemark() -{ +void KmlRenderer::flushPlacemark() { if (PlacemarkNode) { const char *styleUrl = lookupPlacemarkStyle(); xmlNewChild(PlacemarkNode, NULL, BAD_CAST "styleUrl", BAD_CAST styleUrl); @@ -1161,9 +1203,7 @@ void KmlRenderer::flushPlacemark() } } - -xmlNodePtr KmlRenderer::createDescriptionNode(shapeObj *shape) -{ +xmlNodePtr KmlRenderer::createDescriptionNode(shapeObj *shape) { /* */ - /*description nodes for vector layers: - if kml_description is set, use it - if not, dump the attributes */ if (pszLayerDescMetadata) { - char *pszTmp=NULL; + char *pszTmp = NULL; char *pszTmpDesc = NULL; size_t bufferSize = 0; pszTmpDesc = msStrdup(pszLayerDescMetadata); - for (int i=0; inumitems; i++) { + for (int i = 0; i < currentLayer->numitems; i++) { bufferSize = strlen(currentLayer->items[i]) + 3; pszTmp = (char *)msSmallMalloc(bufferSize); - snprintf(pszTmp, bufferSize, "%%%s%%",currentLayer->items[i]); + snprintf(pszTmp, bufferSize, "%%%s%%", currentLayer->items[i]); if (strcasestr(pszTmpDesc, pszTmp)) - pszTmpDesc = msCaseReplaceSubstring(pszTmpDesc, pszTmp, shape->values[i]); + pszTmpDesc = + msCaseReplaceSubstring(pszTmpDesc, pszTmp, shape->values[i]); msFree(pszTmp); } xmlNodePtr descriptionNode = xmlNewNode(NULL, BAD_CAST "description"); @@ -1204,38 +1244,43 @@ xmlNodePtr KmlRenderer::createDescriptionNode(shapeObj *shape) xmlNodePtr extendedDataNode = xmlNewNode(NULL, BAD_CAST "ExtendedData"); xmlNodePtr dataNode = NULL; - const char*pszAlias=NULL; + const char *pszAlias = NULL; int bIncludeAll = MS_FALSE; - if(papszLayerIncludeItems && nIncludeItems == 1 && + if (papszLayerIncludeItems && nIncludeItems == 1 && strcasecmp(papszLayerIncludeItems[0], "all") == 0) bIncludeAll = MS_TRUE; - for (int i=0; inumitems; i++) { - int j=0,k=0; + for (int i = 0; i < currentLayer->numitems; i++) { + int j = 0, k = 0; /*TODO optimize to calculate this only once per layer*/ - for (j=0; jitems[i], papszLayerIncludeItems[j]) == 0) break; } - if (j 0) { - for (k=0; kitems[i], papszLayerExcludeItems[k]) == 0) + for (k = 0; k < nExcludeItems; k++) { + if (strcasecmp(currentLayer->items[i], papszLayerExcludeItems[k]) == + 0) break; } } if (nExcludeItems == 0 || k == nExcludeItems) { dataNode = xmlNewNode(NULL, BAD_CAST "Data"); - xmlNewProp(dataNode, BAD_CAST "name", BAD_CAST currentLayer->items[i]); + xmlNewProp(dataNode, BAD_CAST "name", + BAD_CAST currentLayer->items[i]); pszAlias = getAliasName(currentLayer, currentLayer->items[i], "GO"); if (pszAlias) - xmlNewChild(dataNode, NULL, BAD_CAST "displayName", BAD_CAST pszAlias); + xmlNewChild(dataNode, NULL, BAD_CAST "displayName", + BAD_CAST pszAlias); else - xmlNewChild(dataNode, NULL, BAD_CAST "displayName", BAD_CAST currentLayer->items[i]); + xmlNewChild(dataNode, NULL, BAD_CAST "displayName", + BAD_CAST currentLayer->items[i]); if (shape->values[i] && strlen(shape->values[i])) - xmlNewChild(dataNode, NULL, BAD_CAST "value", BAD_CAST shape->values[i]); + xmlNewChild(dataNode, NULL, BAD_CAST "value", + BAD_CAST shape->values[i]); else xmlNewChild(dataNode, NULL, BAD_CAST "value", NULL); xmlAddChild(extendedDataNode, dataNode); @@ -1244,19 +1289,16 @@ xmlNodePtr KmlRenderer::createDescriptionNode(shapeObj *shape) } return extendedDataNode; - - } return NULL; } -void KmlRenderer::addLineStyleToList(strokeStyleObj *style) -{ +void KmlRenderer::addLineStyleToList(strokeStyleObj *style) { /*actually this is not necessary. kml only uses the last LineStyle so we should not bother keeping them all*/ - int i =0; - for (i=0; iwidth == LineStyle[i].width && LineStyle[i].color->alpha == style->color->alpha && LineStyle[i].color->red == style->color->red && @@ -1269,11 +1311,11 @@ void KmlRenderer::addLineStyleToList(strokeStyleObj *style) if (LineStyle == NULL) LineStyle = (strokeStyleObj *)msSmallMalloc(sizeof(strokeStyleObj)); else - LineStyle = (strokeStyleObj *)msSmallRealloc(LineStyle, sizeof(strokeStyleObj)*numLineStyle); + LineStyle = (strokeStyleObj *)msSmallRealloc( + LineStyle, sizeof(strokeStyleObj) * numLineStyle); - memcpy(&LineStyle[numLineStyle-1], style, sizeof(strokeStyleObj)); + memcpy(&LineStyle[numLineStyle - 1], style, sizeof(strokeStyleObj)); } - } #endif diff --git a/mapkmlrenderer.h b/mapkmlrenderer.h index 59df347e7e..ded9df9f11 100644 --- a/mapkmlrenderer.h +++ b/mapkmlrenderer.h @@ -27,7 +27,6 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ - #ifndef MAPKMLRENDERER_H #define MAPKMLRENDERER_H @@ -37,9 +36,7 @@ #include "mapserver.h" #include "maplibxml2.h" - -class KmlRenderer -{ +class KmlRenderer { private: const char *pszLayerDescMetadata = nullptr; /*if the kml_description is set*/ char **papszLayerIncludeItems = nullptr; @@ -49,74 +46,78 @@ class KmlRenderer const char *pszLayerNameAttributeMetadata = nullptr; protected: - // map properties - int Width = 0, Height = 0; - rectObj MapExtent = {0,0,0,0}; - double MapCellsize = 0; - colorObj BgColor = {0,0,0,0}; - char MapPath[MS_MAXPATHLEN] = {0}; + int Width = 0, Height = 0; + rectObj MapExtent = {0, 0, 0, 0}; + double MapCellsize = 0; + colorObj BgColor = {0, 0, 0, 0}; + char MapPath[MS_MAXPATHLEN] = {0}; // xml nodes pointers xmlDocPtr XmlDoc = nullptr; - xmlNodePtr DocNode = nullptr; - xmlNodePtr LayerNode = nullptr; - xmlNodePtr GroundOverlayNode = nullptr; + xmlNodePtr DocNode = nullptr; + xmlNodePtr LayerNode = nullptr; + xmlNodePtr GroundOverlayNode = nullptr; - xmlNodePtr PlacemarkNode = nullptr; - xmlNodePtr GeomNode = nullptr; - xmlNodePtr DescriptionNode = nullptr; + xmlNodePtr PlacemarkNode = nullptr; + xmlNodePtr GeomNode = nullptr; + xmlNodePtr DescriptionNode = nullptr; - int CurrentShapeIndex = 0; - int CurrentDrawnShapeIndex = 0; - char *CurrentShapeName = nullptr; - char **Items = nullptr; - int NumItems = 0; - int DumpAttributes = 0; + int CurrentShapeIndex = 0; + int CurrentDrawnShapeIndex = 0; + char *CurrentShapeName = nullptr; + char **Items = nullptr; + int NumItems = 0; + int DumpAttributes = 0; // placemark symbology - hashTableObj *StyleHashTable = nullptr; + hashTableObj *StyleHashTable = nullptr; - colorObj LabelColor = {0,0,0,0}; - strokeStyleObj *LineStyle = nullptr; - int numLineStyle = 0; - colorObj PolygonColor = {0,0,0,0}; + colorObj LabelColor = {0, 0, 0, 0}; + strokeStyleObj *LineStyle = nullptr; + int numLineStyle = 0; + colorObj PolygonColor = {0, 0, 0, 0}; - char SymbolName[128] = {0}; - char SymbolUrl[128] = {0}; + char SymbolName[128] = {0}; + char SymbolUrl[128] = {0}; - enum { NumSymbologyFlag = 4}; - char SymbologyFlag[NumSymbologyFlag] = {0,0,0,0}; + enum { NumSymbologyFlag = 4 }; + char SymbologyFlag[NumSymbologyFlag] = {0, 0, 0, 0}; - enum symbFlagsEnum { Label, Line, Polygon, Symbol }; + enum symbFlagsEnum { Label, Line, Polygon, Symbol }; - int FirstLayer = 0; + int FirstLayer = 0; - mapObj *map = nullptr; - layerObj *currentLayer = nullptr; + mapObj *map = nullptr; + layerObj *currentLayer = nullptr; - int AltitudeMode = 0; - int Tessellate = 0; - int Extrude = 0; + int AltitudeMode = 0; + int Tessellate = 0; + int Extrude = 0; - enum altitudeModeEnum { undefined, clampToGround, relativeToGround, absolute }; + enum altitudeModeEnum { + undefined, + clampToGround, + relativeToGround, + absolute + }; /**True if elevation is taken from a feature attribute*/ bool mElevationFromAttribute = false; /**Attribute index of elevation (or -1 if elevation is not attribute driven*/ int mElevationAttributeIndex = 0; double mCurrentElevationValue = 0; - outputFormatObj *aggFormat = nullptr; protected: - - imageObj* createInternalImage(); + imageObj *createInternalImage(); xmlNodePtr createPlacemarkNode(xmlNodePtr parentNode, char *styleUrl); - xmlNodePtr createGroundOverlayNode(xmlNodePtr parentNode, char *imageHref, layerObj *layer); + xmlNodePtr createGroundOverlayNode(xmlNodePtr parentNode, char *imageHref, + layerObj *layer); xmlNodePtr createDescriptionNode(shapeObj *shape); - const char* lookupSymbolUrl(imageObj *img, symbolObj *symbol, symbolStyleObj *style); + const char *lookupSymbolUrl(imageObj *img, symbolObj *symbol, + symbolStyleObj *style); void addCoordsNode(xmlNodePtr parentNode, pointObj *pts, int numPts); @@ -127,27 +128,30 @@ class KmlRenderer int createIconImage(char *fileName, symbolObj *symbol, symbolStyleObj *style); - void renderSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); + void renderSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style); ////////////////////////////////////////////////////////////////////////////// void renderLineVector(imageObj *img, shapeObj *p, strokeStyleObj *style); void renderPolygonVector(imageObj *img, shapeObj *p, colorObj *color); - const char* lookupPlacemarkStyle(); + const char *lookupPlacemarkStyle(); void flushPlacemark(); xmlNodePtr getGeomParentNode(const char *geomName); - char* getLayerName(layerObj *layer); + char *getLayerName(layerObj *layer); void processLayer(layerObj *layer, outputFormatObj *format); void addLineStyleToList(strokeStyleObj *style); - const char *getAliasName(layerObj *lp, char *pszItemName, const char *namespaces); + const char *getAliasName(layerObj *lp, char *pszItemName, + const char *namespaces); public: - - KmlRenderer(int width, int height, outputFormatObj *format, colorObj* color = NULL); + KmlRenderer(int width, int height, outputFormatObj *format, + colorObj *color = NULL); virtual ~KmlRenderer(); - imageObj* createImage(int width, int height, outputFormatObj *format, colorObj* bg); + imageObj *createImage(int width, int height, outputFormatObj *format, + colorObj *bg); int saveImage(imageObj *img, FILE *fp, outputFormatObj *format); int startNewLayer(imageObj *img, layerObj *layer); @@ -159,15 +163,22 @@ class KmlRenderer void renderLine(imageObj *img, shapeObj *p, strokeStyleObj *style); void renderPolygon(imageObj *img, shapeObj *p, colorObj *color); - void renderGlyphs(imageObj *img, const textSymbolObj *ts, colorObj *c, colorObj *oc, int ow); + void renderGlyphs(imageObj *img, const textSymbolObj *ts, colorObj *c, + colorObj *oc, int ow); // Symbols - void renderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); - void renderVectorSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); - void renderEllipseSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); - void renderTruetypeSymbol(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style); - - int getTruetypeTextBBox(imageObj *img,char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances); + void renderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style); + void renderVectorSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style); + void renderEllipseSymbol(imageObj *img, double x, double y, symbolObj *symbol, + symbolStyleObj *style); + void renderTruetypeSymbol(imageObj *img, double x, double y, + symbolObj *symbol, symbolStyleObj *style); + + int getTruetypeTextBBox(imageObj *img, char **fonts, int numfonts, + double size, char *string, rectObj *rect, + double **advances); int mergeRasterBuffer(imageObj *image, rasterBufferObj *rb); }; diff --git a/maplabel.c b/maplabel.c index 41d237a530..7780216c2a 100644 --- a/maplabel.c +++ b/maplabel.c @@ -40,24 +40,20 @@ #include "cpl_vsi.h" #include "cpl_string.h" +void initTextPath(textPathObj *ts) { memset(ts, 0, sizeof(*ts)); } - - - -void initTextPath(textPathObj *ts) { - memset(ts,0,sizeof(*ts)); -} - -int WARN_UNUSED msLayoutTextSymbol(mapObj *map, textSymbolObj *ts, textPathObj *tgret); +int WARN_UNUSED msLayoutTextSymbol(mapObj *map, textSymbolObj *ts, + textPathObj *tgret); #if defined(USE_EXTENDED_DEBUG) && 0 static void msDebugTextPath(textSymbolObj *ts) { int i; - msDebug("text: %s\n",ts->annotext); - if(ts->textpath) { - for(i=0;itextpath->numglyphs; i++) { + msDebug("text: %s\n", ts->annotext); + if (ts->textpath) { + for (i = 0; i < ts->textpath->numglyphs; i++) { glyphObj *g = &ts->textpath->glyphs[i]; - msDebug("glyph %d: pos: %f %f\n",g->glyph->key.codepoint,g->pnt.x,g->pnt.y); + msDebug("glyph %d: pos: %f %f\n", g->glyph->key.codepoint, g->pnt.x, + g->pnt.y); } } else { msDebug("no glyphs\n"); @@ -73,39 +69,37 @@ int msComputeTextPath(mapObj *map, textSymbolObj *ts) { ts->textpath = tgret; tgret->absolute = 0; tgret->glyph_size = ts->label->size * ts->scalefactor; - tgret->glyph_size = MS_MAX(tgret->glyph_size, ts->label->minsize * ts->resolutionfactor); - tgret->glyph_size = MS_NINT(MS_MIN(tgret->glyph_size, ts->label->maxsize * ts->resolutionfactor)); + tgret->glyph_size = + MS_MAX(tgret->glyph_size, ts->label->minsize * ts->resolutionfactor); + tgret->glyph_size = MS_NINT( + MS_MIN(tgret->glyph_size, ts->label->maxsize * ts->resolutionfactor)); tgret->line_height = ceil(tgret->glyph_size * 1.33); - return msLayoutTextSymbol(map,ts,tgret); + return msLayoutTextSymbol(map, ts, tgret); } -void initTextSymbol(textSymbolObj *ts) { - memset(ts,0,sizeof(*ts)); -} +void initTextSymbol(textSymbolObj *ts) { memset(ts, 0, sizeof(*ts)); } void freeTextPath(textPathObj *tp) { free(tp->glyphs); - if(tp->bounds.poly) { + if (tp->bounds.poly) { free(tp->bounds.poly->point); free(tp->bounds.poly); } } -void freeTextSymbol(textSymbolObj *ts) { - freeTextSymbolEx(ts, MS_TRUE); -} +void freeTextSymbol(textSymbolObj *ts) { freeTextSymbolEx(ts, MS_TRUE); } void freeTextSymbolEx(textSymbolObj *ts, int doFreeLabel) { - if(ts->textpath) { + if (ts->textpath) { freeTextPath(ts->textpath); free(ts->textpath); } - if(ts->label->numstyles) { - if(ts->style_bounds) { + if (ts->label->numstyles) { + if (ts->style_bounds) { int i; - for(i=0;ilabel->numstyles; i++) { - if(ts->style_bounds[i]) { - if(ts->style_bounds[i]->poly) { + for (i = 0; i < ts->label->numstyles; i++) { + if (ts->style_bounds[i]) { + if (ts->style_bounds[i]->poly) { free(ts->style_bounds[i]->poly->point); free(ts->style_bounds[i]->poly); } @@ -116,7 +110,7 @@ void freeTextSymbolEx(textSymbolObj *ts, int doFreeLabel) { } } free(ts->annotext); - if(doFreeLabel && freeLabel(ts->label) == MS_SUCCESS) { + if (doFreeLabel && freeLabel(ts->label) == MS_SUCCESS) { free(ts->label); } } @@ -124,19 +118,20 @@ void freeTextSymbolEx(textSymbolObj *ts, int doFreeLabel) { void msCopyTextPath(textPathObj *dst, textPathObj *src) { int i; *dst = *src; - if(src->bounds.poly) { + if (src->bounds.poly) { dst->bounds.poly = msSmallMalloc(sizeof(lineObj)); dst->bounds.poly->numpoints = src->bounds.poly->numpoints; - dst->bounds.poly->point = msSmallMalloc(src->bounds.poly->numpoints * sizeof(pointObj)); - for(i=0; ibounds.poly->numpoints; i++) { + dst->bounds.poly->point = + msSmallMalloc(src->bounds.poly->numpoints * sizeof(pointObj)); + for (i = 0; i < src->bounds.poly->numpoints; i++) { dst->bounds.poly->point[i] = src->bounds.poly->point[i]; } } else { dst->bounds.poly = NULL; } - if(dst->numglyphs > 0) { + if (dst->numglyphs > 0) { dst->glyphs = msSmallMalloc(dst->numglyphs * sizeof(glyphObj)); - for(i=0; inumglyphs; i++) + for (i = 0; i < dst->numglyphs; i++) dst->glyphs[i] = src->glyphs[i]; } } @@ -145,15 +140,16 @@ void msCopyTextSymbol(textSymbolObj *dst, textSymbolObj *src) { *dst = *src; MS_REFCNT_INCR(src->label); dst->annotext = msStrdup(src->annotext); - if(src->textpath) { + if (src->textpath) { dst->textpath = msSmallMalloc(sizeof(textPathObj)); - msCopyTextPath(dst->textpath,src->textpath); + msCopyTextPath(dst->textpath, src->textpath); } - if(src->style_bounds) { + if (src->style_bounds) { int i; - dst->style_bounds = msSmallCalloc(src->label->numstyles, sizeof(label_bounds*)); - for(i=0; ilabel->numstyles; i++) { - if(src->style_bounds[i]) { + dst->style_bounds = + msSmallCalloc(src->label->numstyles, sizeof(label_bounds *)); + for (i = 0; i < src->label->numstyles; i++) { + if (src->style_bounds[i]) { dst->style_bounds[i] = msSmallMalloc(sizeof(label_bounds)); copyLabelBounds(dst->style_bounds[i], src->style_bounds[i]); } @@ -163,27 +159,31 @@ void msCopyTextSymbol(textSymbolObj *dst, textSymbolObj *src) { static int labelNeedsDeepCopy(labelObj *label) { int i; - if(label->numbindings > 0) return MS_TRUE; - for(i=0; inumstyles; i++) { - if(label->styles[i]->numbindings>0) { + if (label->numbindings > 0) + return MS_TRUE; + for (i = 0; i < label->numstyles; i++) { + if (label->styles[i]->numbindings > 0) { return MS_TRUE; } } return MS_FALSE; } -void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char *string, double scalefactor, double resolutionfactor, label_cache_mode cache) { - if(cache == duplicate_always) { +void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, + char *string, double scalefactor, + double resolutionfactor, + label_cache_mode cache) { + if (cache == duplicate_always) { ts->label = msSmallMalloc(sizeof(labelObj)); initLabel(ts->label); - msCopyLabel(ts->label,l); - } else if(cache == duplicate_never) { + msCopyLabel(ts->label, l); + } else if (cache == duplicate_never) { ts->label = l; MS_REFCNT_INCR(l); - } else if(cache == duplicate_if_needed && labelNeedsDeepCopy(l)) { + } else if (cache == duplicate_if_needed && labelNeedsDeepCopy(l)) { ts->label = msSmallMalloc(sizeof(labelObj)); initLabel(ts->label); - msCopyLabel(ts->label,l); + msCopyLabel(ts->label, l); } else { ts->label = l; MS_REFCNT_INCR(l); @@ -194,14 +194,15 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char ts->rotation = l->angle * MS_DEG_TO_RAD; } -int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classindex, shapeObj *shape, pointObj *point, double featuresize) -{ - int l,s, priority; +int msAddLabelGroup(mapObj *map, imageObj *image, layerObj *layer, + int classindex, shapeObj *shape, pointObj *point, + double featuresize) { + int l, s, priority; labelCacheSlotObj *cacheslot; - labelCacheMemberObj *cachePtr=NULL; - layerObj *layerPtr=NULL; - classObj *classPtr=NULL; + labelCacheMemberObj *cachePtr = NULL; + layerObj *layerPtr = NULL; + classObj *classPtr = NULL; int numtextsymbols = 0; textSymbolObj **textsymbols, *ts; int layerindex = layer->index; @@ -211,69 +212,82 @@ int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classinde layerPtr = layer; classPtr = layer->class[classindex]; - if(classPtr->numlabels == 0) return MS_SUCCESS; /* not an error just nothing to do */ + if (classPtr->numlabels == 0) + return MS_SUCCESS; /* not an error just nothing to do */ /* check that the label intersects the layer mask */ - if(layerPtr->mask) { - int maskLayerIdx = msGetLayerIndex(map,layerPtr->mask); - layerObj *maskLayer = GET_LAYER(map,maskLayerIdx); + if (layerPtr->mask) { + int maskLayerIdx = msGetLayerIndex(map, layerPtr->mask); + layerObj *maskLayer = GET_LAYER(map, maskLayerIdx); unsigned char *alphapixptr; - if(maskLayer->maskimage && MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { + if (maskLayer->maskimage && + MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { rasterBufferObj rb; - int x,y; - memset(&rb,0,sizeof(rasterBufferObj)); - if(MS_UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,&rb))) { + int x, y; + memset(&rb, 0, sizeof(rasterBufferObj)); + if (MS_UNLIKELY(MS_FAILURE == + MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, &rb))) { return MS_FAILURE; } x = MS_NINT(point->x); y = MS_NINT(point->y); - /* Using label repeatdistance, we might have a point with x/y below 0. See #4764 */ + /* Using label repeatdistance, we might have a point with x/y below 0. See + * #4764 */ if (x >= 0 && x < (int)rb.width && y >= 0 && y < (int)rb.height) { assert(rb.type == MS_BUFFER_BYTE_RGBA); - alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; - if(!*alphapixptr) { + alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + + rb.data.rgba.pixel_step * x; + if (!*alphapixptr) { /* label point does not intersect mask */ return MS_SUCCESS; } } else { - return MS_SUCCESS; /* label point does not intersect image extent, we cannot know if it intersects - mask, so we discard it (#5237)*/ + return MS_SUCCESS; /* label point does not intersect image extent, we + cannot know if it intersects mask, so we discard it + (#5237)*/ } } else { - msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msAddLabelGroup()", layerPtr->name); + msSetError(MS_MISCERR, + "Layer (%s) references references a mask layer, but the " + "selected renderer does not support them", + "msAddLabelGroup()", layerPtr->name); return (MS_FAILURE); } } - textsymbols = msSmallMalloc(classPtr->numlabels * sizeof(textSymbolObj*)); + textsymbols = msSmallMalloc(classPtr->numlabels * sizeof(textSymbolObj *)); - for(l=0; lnumlabels; l++) { + for (l = 0; l < classPtr->numlabels; l++) { labelObj *lbl = classPtr->labels[l]; char *annotext; - if(msGetLabelStatus(map,layerPtr,shape,lbl) == MS_OFF) { + if (msGetLabelStatus(map, layerPtr, shape, lbl) == MS_OFF) { continue; } - annotext = msShapeGetLabelAnnotation(layerPtr,shape,lbl); - if(!annotext) { - for(s=0;snumstyles;s++) { - if(lbl->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) - break; /* we have a "symbol only label, so we shouldn't skip this label */ + annotext = msShapeGetLabelAnnotation(layerPtr, shape, lbl); + if (!annotext) { + for (s = 0; s < lbl->numstyles; s++) { + if (lbl->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) + break; /* we have a "symbol only label, so we shouldn't skip this + label */ } - if(s == lbl->numstyles) { + if (s == lbl->numstyles) { continue; /* no anno text, and no label symbols */ } } ts = msSmallMalloc(sizeof(textSymbolObj)); initTextSymbol(ts); - msPopulateTextSymbolForLabelAndString(ts,lbl,annotext,layerPtr->scalefactor,image->resolutionfactor, 1); + msPopulateTextSymbolForLabelAndString( + ts, lbl, annotext, layerPtr->scalefactor, image->resolutionfactor, 1); - if(annotext && *annotext && lbl->autominfeaturesize && featuresize > 0) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) { + if (annotext && *annotext && lbl->autominfeaturesize && featuresize > 0) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) { freeTextSymbol(ts); free(ts); return MS_FAILURE; } - if(featuresize < (ts->textpath->bounds.bbox.maxx - ts->textpath->bounds.bbox.minx)) { + if (featuresize < + (ts->textpath->bounds.bbox.maxx - ts->textpath->bounds.bbox.minx)) { /* feature is too big to be drawn, skip it */ freeTextSymbol(ts); free(ts); @@ -284,29 +298,37 @@ int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classinde numtextsymbols++; } - if(numtextsymbols == 0) { + if (numtextsymbols == 0) { free(textsymbols); return MS_SUCCESS; } /* Validate label priority value and get ref on label cache for it */ - priority = classPtr->labels[0]->priority; /* take priority from the first label */ + priority = + classPtr->labels[0]->priority; /* take priority from the first label */ if (priority < 1) priority = 1; else if (priority > MS_MAX_LABEL_PRIORITY) priority = MS_MAX_LABEL_PRIORITY; - cacheslot = &(map->labelcache.slots[priority-1]); - - if(cacheslot->numlabels == cacheslot->cachesize) { /* just add it to the end */ - cacheslot->labels = (labelCacheMemberObj *) realloc(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); - MS_CHECK_ALLOC(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); + cacheslot = &(map->labelcache.slots[priority - 1]); + + if (cacheslot->numlabels == + cacheslot->cachesize) { /* just add it to the end */ + cacheslot->labels = (labelCacheMemberObj *)realloc( + cacheslot->labels, sizeof(labelCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT)); + MS_CHECK_ALLOC(cacheslot->labels, + sizeof(labelCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT), + MS_FAILURE); cacheslot->cachesize += MS_LABELCACHEINCREMENT; } cachePtr = &(cacheslot->labels[cacheslot->numlabels]); - cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */ + cachePtr->layerindex = + layerindex; /* so we can get back to this *raw* data if necessary */ cachePtr->classindex = classindex; @@ -319,24 +341,35 @@ int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classinde cachePtr->status = MS_FALSE; - if(layerPtr->type == MS_LAYER_POINT && classPtr->numstyles > 0) { + if (layerPtr->type == MS_LAYER_POINT && classPtr->numstyles > 0) { /* cache the marker placement, it's already on the map */ - /* TO DO: at the moment only checks the bottom style, perhaps should check all of them */ + /* TO DO: at the moment only checks the bottom style, perhaps should check + * all of them */ /* #2347: after RFC-24 classPtr->styles could be NULL so we check it */ double w, h; - if(msGetMarkerSize(map, classPtr->styles[0], &w, &h, layerPtr->scalefactor) != MS_SUCCESS) - return(MS_FAILURE); + if (msGetMarkerSize(map, classPtr->styles[0], &w, &h, + layerPtr->scalefactor) != MS_SUCCESS) + return (MS_FAILURE); - if(cacheslot->nummarkers == cacheslot->markercachesize) { /* just add it to the end */ - cacheslot->markers = (markerCacheMemberObj *) realloc(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); - MS_CHECK_ALLOC(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); - cacheslot->markercachesize+=MS_LABELCACHEINCREMENT; + if (cacheslot->nummarkers == + cacheslot->markercachesize) { /* just add it to the end */ + cacheslot->markers = (markerCacheMemberObj *)realloc( + cacheslot->markers, + sizeof(markerCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT)); + MS_CHECK_ALLOC(cacheslot->markers, + sizeof(markerCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT), + MS_FAILURE); + cacheslot->markercachesize += MS_LABELCACHEINCREMENT; } cacheslot->markers[cacheslot->nummarkers].bounds.minx = (point->x - .5 * w); cacheslot->markers[cacheslot->nummarkers].bounds.miny = (point->y - .5 * h); - cacheslot->markers[cacheslot->nummarkers].bounds.maxx = cacheslot->markers[cacheslot->nummarkers].bounds.minx + (w-1); - cacheslot->markers[cacheslot->nummarkers].bounds.maxy = cacheslot->markers[cacheslot->nummarkers].bounds.miny + (h-1); + cacheslot->markers[cacheslot->nummarkers].bounds.maxx = + cacheslot->markers[cacheslot->nummarkers].bounds.minx + (w - 1); + cacheslot->markers[cacheslot->nummarkers].bounds.maxy = + cacheslot->markers[cacheslot->nummarkers].bounds.miny + (h - 1); cacheslot->markers[cacheslot->nummarkers].id = cacheslot->numlabels; cachePtr->markerid = cacheslot->nummarkers; @@ -347,21 +380,21 @@ int msAddLabelGroup(mapObj *map, imageObj *image, layerObj* layer, int classinde cacheslot->numlabels++; - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, int classindex, - shapeObj *shape, pointObj *point, double featuresize, textSymbolObj *ts) -{ +int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, + int classindex, shapeObj *shape, pointObj *point, + double featuresize, textSymbolObj *ts) { int i; labelCacheSlotObj *cacheslot; - labelCacheMemberObj *cachePtr=NULL; + labelCacheMemberObj *cachePtr = NULL; const char *annotext = NULL; char *annotextToFree = NULL; layerObj *layerPtr; classObj *classPtr; - layerPtr=GET_LAYER(map,layerindex); + layerPtr = GET_LAYER(map, layerindex); assert(layerPtr); assert(classindex < layerPtr->numclasses); @@ -369,23 +402,22 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in assert(label); - if(ts) + if (ts) annotext = ts->annotext; - else if(shape) - { - annotextToFree = msShapeGetLabelAnnotation(layerPtr,shape,label); + else if (shape) { + annotextToFree = msShapeGetLabelAnnotation(layerPtr, shape, label); annotext = annotextToFree; } - if(!annotext) { + if (!annotext) { /* check if we have a labelpnt style */ - for(i=0; inumstyles; i++) { - if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) + for (i = 0; i < label->numstyles; i++) { + if (label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) break; } - if(i==label->numstyles) { + if (i == label->numstyles) { /* label has no text or marker symbols */ - if(ts) { + if (ts) { freeTextSymbol(ts); free(ts); } @@ -393,9 +425,10 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in } } - if(classPtr->leader) { - if(ts && ts->textpath && ts->textpath->absolute) { - msSetError(MS_MISCERR, "LEADERs are not supported on ANGLE FOLLOW labels", "msAddLabel()"); + if (classPtr->leader) { + if (ts && ts->textpath && ts->textpath->absolute) { + msSetError(MS_MISCERR, "LEADERs are not supported on ANGLE FOLLOW labels", + "msAddLabel()"); return MS_FAILURE; } } @@ -405,10 +438,13 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in int maskLayerIdx = msGetLayerIndex(map, layerPtr->mask); layerObj *maskLayer = GET_LAYER(map, maskLayerIdx); unsigned char *alphapixptr; - if (maskLayer->maskimage && MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { + if (maskLayer->maskimage && + MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { rasterBufferObj rb; - memset(&rb, 0, sizeof (rasterBufferObj)); - if(MS_UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage, &rb))) { + memset(&rb, 0, sizeof(rasterBufferObj)); + if (MS_UNLIKELY(MS_FAILURE == + MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, &rb))) { msFree(annotextToFree); return MS_FAILURE; } @@ -416,12 +452,14 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in if (point) { int x = MS_NINT(point->x); int y = MS_NINT(point->y); - /* Using label repeatdistance, we might have a point with x/y below 0. See #4764 */ + /* Using label repeatdistance, we might have a point with x/y below 0. + * See #4764 */ if (x >= 0 && x < (int)rb.width && y >= 0 && y < (int)rb.height) { - alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; - if(!*alphapixptr) { + alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + + rb.data.rgba.pixel_step * x; + if (!*alphapixptr) { /* label point does not intersect mask */ - if(ts) { + if (ts) { freeTextSymbol(ts); free(ts); } @@ -430,8 +468,9 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in } } else { msFree(annotextToFree); - return MS_SUCCESS; /* label point does not intersect image extent, we cannot know if it intersects - mask, so we discard it (#5237)*/ + return MS_SUCCESS; /* label point does not intersect image extent, we + cannot know if it intersects mask, so we discard + it (#5237)*/ } } else if (ts && ts->textpath) { int i = 0; @@ -439,7 +478,8 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in int x = MS_NINT(ts->textpath->glyphs[i].pnt.x); int y = MS_NINT(ts->textpath->glyphs[i].pnt.y); if (x >= 0 && x < (int)rb.width && y >= 0 && y < (int)rb.height) { - alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + rb.data.rgba.pixel_step*x; + alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + + rb.data.rgba.pixel_step * x; if (!*alphapixptr) { freeTextSymbol(ts); free(ts); @@ -450,34 +490,41 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in freeTextSymbol(ts); free(ts); msFree(annotextToFree); - return MS_SUCCESS; /* label point does not intersect image extent, we cannot know if it intersects - mask, so we discard it (#5237)*/ + return MS_SUCCESS; /* label point does not intersect image extent, + we cannot know if it intersects mask, so we + discard it (#5237)*/ } } } } else { - msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msAddLabel()", layerPtr->name); + msSetError(MS_MISCERR, + "Layer (%s) references references a mask layer, but the " + "selected renderer does not support them", + "msAddLabel()", layerPtr->name); msFree(annotextToFree); return (MS_FAILURE); } } - if(!ts) { + if (!ts) { ts = msSmallMalloc(sizeof(textSymbolObj)); initTextSymbol(ts); - msPopulateTextSymbolForLabelAndString(ts,label,annotextToFree,layerPtr->scalefactor,image->resolutionfactor, 1); + msPopulateTextSymbolForLabelAndString(ts, label, annotextToFree, + layerPtr->scalefactor, + image->resolutionfactor, 1); // annotextToFree = NULL; } - if(annotext && label->autominfeaturesize && featuresize > 0) { - if(!ts->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) + if (annotext && label->autominfeaturesize && featuresize > 0) { + if (!ts->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) return MS_FAILURE; } - if(!ts->textpath) { + if (!ts->textpath) { return MS_FAILURE; } - if(featuresize > (ts->textpath->bounds.bbox.maxx - ts->textpath->bounds.bbox.minx)) { + if (featuresize > + (ts->textpath->bounds.bbox.maxx - ts->textpath->bounds.bbox.minx)) { /* feature is too big to be drawn, skip it */ freeTextSymbol(ts); free(ts); @@ -485,67 +532,89 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in } } - - /* Validate label priority value and get ref on label cache for it */ if (label->priority < 1) label->priority = 1; else if (label->priority > MS_MAX_LABEL_PRIORITY) label->priority = MS_MAX_LABEL_PRIORITY; - cacheslot = &(map->labelcache.slots[label->priority-1]); - - if(cacheslot->numlabels == cacheslot->cachesize) { /* just add it to the end */ - cacheslot->labels = (labelCacheMemberObj *) realloc(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); - MS_CHECK_ALLOC(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); + cacheslot = &(map->labelcache.slots[label->priority - 1]); + + if (cacheslot->numlabels == + cacheslot->cachesize) { /* just add it to the end */ + cacheslot->labels = (labelCacheMemberObj *)realloc( + cacheslot->labels, sizeof(labelCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT)); + MS_CHECK_ALLOC(cacheslot->labels, + sizeof(labelCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT), + MS_FAILURE); cacheslot->cachesize += MS_LABELCACHEINCREMENT; } cachePtr = &(cacheslot->labels[cacheslot->numlabels]); - cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */ + cachePtr->layerindex = + layerindex; /* so we can get back to this *raw* data if necessary */ cachePtr->classindex = classindex; cachePtr->leaderline = NULL; cachePtr->leaderbbox = NULL; /* Store the label point or the label path (Bug #1620) */ - if ( point ) { + if (point) { cachePtr->point = *point; /* the actual label point */ } else { - assert(ts && ts->textpath && ts->textpath->absolute && ts->textpath->numglyphs>0); + assert(ts && ts->textpath && ts->textpath->absolute && + ts->textpath->numglyphs > 0); /* Use the middle point of the labelpath for mindistance calculations */ - cachePtr->point = ts->textpath->glyphs[ts->textpath->numglyphs/2].pnt; + cachePtr->point = ts->textpath->glyphs[ts->textpath->numglyphs / 2].pnt; } /* copy the label */ cachePtr->numtextsymbols = 1; - cachePtr->textsymbols = (textSymbolObj **) msSmallMalloc(sizeof(textSymbolObj*)); + cachePtr->textsymbols = + (textSymbolObj **)msSmallMalloc(sizeof(textSymbolObj *)); cachePtr->textsymbols[0] = ts; cachePtr->markerid = -1; cachePtr->status = MS_FALSE; - if(layerPtr->type == MS_LAYER_POINT && classPtr->numstyles > 0) { /* cache the marker placement, it's already on the map */ + if (layerPtr->type == MS_LAYER_POINT && + classPtr->numstyles > + 0) { /* cache the marker placement, it's already on the map */ double w, h; - if(cacheslot->nummarkers == cacheslot->markercachesize) { /* just add it to the end */ - cacheslot->markers = (markerCacheMemberObj *) realloc(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); - MS_CHECK_ALLOC(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); - cacheslot->markercachesize+=MS_LABELCACHEINCREMENT; + if (cacheslot->nummarkers == + cacheslot->markercachesize) { /* just add it to the end */ + cacheslot->markers = (markerCacheMemberObj *)realloc( + cacheslot->markers, + sizeof(markerCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT)); + MS_CHECK_ALLOC(cacheslot->markers, + sizeof(markerCacheMemberObj) * + (cacheslot->cachesize + MS_LABELCACHEINCREMENT), + MS_FAILURE); + cacheslot->markercachesize += MS_LABELCACHEINCREMENT; } i = cacheslot->nummarkers; - /* TO DO: at the moment only checks the bottom style, perhaps should check all of them */ + /* TO DO: at the moment only checks the bottom style, perhaps should check + * all of them */ /* #2347: after RFC-24 classPtr->styles could be NULL so we check it */ - if(classPtr->styles != NULL) { - if(msGetMarkerSize(map, classPtr->styles[0], &w, &h, layerPtr->scalefactor) != MS_SUCCESS) - return(MS_FAILURE); + if (classPtr->styles != NULL) { + if (msGetMarkerSize(map, classPtr->styles[0], &w, &h, + layerPtr->scalefactor) != MS_SUCCESS) + return (MS_FAILURE); assert(point); - cacheslot->markers[cacheslot->nummarkers].bounds.minx = (point->x - .5 * w); - cacheslot->markers[cacheslot->nummarkers].bounds.miny = (point->y - .5 * h); - cacheslot->markers[cacheslot->nummarkers].bounds.maxx = cacheslot->markers[cacheslot->nummarkers].bounds.minx + (w-1); - cacheslot->markers[cacheslot->nummarkers].bounds.maxy = cacheslot->markers[cacheslot->nummarkers].bounds.miny + (h-1); + cacheslot->markers[cacheslot->nummarkers].bounds.minx = + (point->x - .5 * w); + cacheslot->markers[cacheslot->nummarkers].bounds.miny = + (point->y - .5 * h); + cacheslot->markers[cacheslot->nummarkers].bounds.maxx = + cacheslot->markers[cacheslot->nummarkers].bounds.minx + (w - 1); + cacheslot->markers[cacheslot->nummarkers].bounds.maxy = + cacheslot->markers[cacheslot->nummarkers].bounds.miny + (h - 1); cacheslot->markers[i].id = cacheslot->numlabels; cachePtr->markerid = i; @@ -556,7 +625,7 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in cacheslot->numlabels++; - return(MS_SUCCESS); + return (MS_SUCCESS); } /* @@ -564,80 +633,87 @@ int msAddLabel(mapObj *map, imageObj *image, labelObj *label, int layerindex, in ** image for no labels (effectively making image larger. The gutter can be ** negative in cases where a label has a buffer around it. */ -static int labelInImage(int width, int height, lineObj *lpoly, rectObj *bounds, int gutter) -{ +static int labelInImage(int width, int height, lineObj *lpoly, rectObj *bounds, + int gutter) { int j; /* do a bbox test first */ - if(bounds->minx >= gutter && - bounds->miny >= gutter && - bounds->maxx < width-gutter && - bounds->maxy < height-gutter) { + if (bounds->minx >= gutter && bounds->miny >= gutter && + bounds->maxx < width - gutter && bounds->maxy < height - gutter) { return MS_TRUE; } - if(lpoly) { - for(j=1; jnumpoints; j++) { - if(lpoly->point[j].x < gutter) return(MS_FALSE); - if(lpoly->point[j].x >= width-gutter) return(MS_FALSE); - if(lpoly->point[j].y < gutter) return(MS_FALSE); - if(lpoly->point[j].y >= height-gutter) return(MS_FALSE); + if (lpoly) { + for (j = 1; j < lpoly->numpoints; j++) { + if (lpoly->point[j].x < gutter) + return (MS_FALSE); + if (lpoly->point[j].x >= width - gutter) + return (MS_FALSE); + if (lpoly->point[j].y < gutter) + return (MS_FALSE); + if (lpoly->point[j].y >= height - gutter) + return (MS_FALSE); } } else { /* if no poly, then return false as the boundong box intersected */ return MS_FALSE; } - return(MS_TRUE); + return (MS_TRUE); } void insertRenderedLabelMember(mapObj *map, labelCacheMemberObj *cachePtr) { - if(map->labelcache.num_rendered_members == map->labelcache.num_allocated_rendered_members) { - if(map->labelcache.num_rendered_members == 0) { + if (map->labelcache.num_rendered_members == + map->labelcache.num_allocated_rendered_members) { + if (map->labelcache.num_rendered_members == 0) { map->labelcache.num_allocated_rendered_members = 50; } else { map->labelcache.num_allocated_rendered_members *= 2; } - map->labelcache.rendered_text_symbols = msSmallRealloc(map->labelcache.rendered_text_symbols, - map->labelcache.num_allocated_rendered_members * sizeof(labelCacheMemberObj*)); + map->labelcache.rendered_text_symbols = + msSmallRealloc(map->labelcache.rendered_text_symbols, + map->labelcache.num_allocated_rendered_members * + sizeof(labelCacheMemberObj *)); } - map->labelcache.rendered_text_symbols[map->labelcache.num_rendered_members++] = cachePtr; + map->labelcache + .rendered_text_symbols[map->labelcache.num_rendered_members++] = cachePtr; } -static inline int testSegmentLabelBBoxIntersection(const rectObj *leaderbbox, const pointObj *lp1, - const pointObj *lp2, const label_bounds *test) { - if(msRectOverlap(leaderbbox, &test->bbox)) { - if(test->poly) { +static inline int testSegmentLabelBBoxIntersection(const rectObj *leaderbbox, + const pointObj *lp1, + const pointObj *lp2, + const label_bounds *test) { + if (msRectOverlap(leaderbbox, &test->bbox)) { + if (test->poly) { int pp; - for(pp=1; pppoly->numpoints; pp++) { - if(msIntersectSegments( - &(test->poly->point[pp-1]), - &(test->poly->point[pp]), - lp1,lp2) == MS_TRUE) { - return(MS_FALSE); + for (pp = 1; pp < test->poly->numpoints; pp++) { + if (msIntersectSegments(&(test->poly->point[pp - 1]), + &(test->poly->point[pp]), lp1, + lp2) == MS_TRUE) { + return (MS_FALSE); } } } else { - pointObj tp1 = {0},tp2 = {0}; + pointObj tp1 = {0}, tp2 = {0}; tp1.x = test->bbox.minx; tp1.y = test->bbox.miny; tp2.x = test->bbox.minx; tp2.y = test->bbox.maxy; - if(msIntersectSegments(lp1,lp2,&tp1,&tp2)) + if (msIntersectSegments(lp1, lp2, &tp1, &tp2)) return MS_FALSE; tp2.x = test->bbox.maxx; tp2.y = test->bbox.miny; - if(msIntersectSegments(lp1,lp2,&tp1,&tp2)) + if (msIntersectSegments(lp1, lp2, &tp1, &tp2)) return MS_FALSE; tp1.x = test->bbox.maxx; tp1.y = test->bbox.maxy; tp2.x = test->bbox.minx; tp2.y = test->bbox.maxy; - if(msIntersectSegments(lp1,lp2,&tp1,&tp2)) + if (msIntersectSegments(lp1, lp2, &tp1, &tp2)) return MS_FALSE; tp2.x = test->bbox.maxx; tp2.y = test->bbox.miny; - if(msIntersectSegments(lp1,lp2,&tp1,&tp2)) + if (msIntersectSegments(lp1, lp2, &tp1, &tp2)) return MS_FALSE; } } @@ -647,35 +723,41 @@ static inline int testSegmentLabelBBoxIntersection(const rectObj *leaderbbox, co int msTestLabelCacheLeaderCollision(mapObj *map, pointObj *lp1, pointObj *lp2) { int p; rectObj leaderbbox; - leaderbbox.minx = MS_MIN(lp1->x,lp2->x); - leaderbbox.maxx = MS_MAX(lp1->x,lp2->x); - leaderbbox.miny = MS_MIN(lp1->y,lp2->y); - leaderbbox.maxy = MS_MAX(lp1->y,lp2->y); - for(p=0; plabelcache.num_rendered_members; p++) { - labelCacheMemberObj *curCachePtr= map->labelcache.rendered_text_symbols[p]; - if(msRectOverlap(&leaderbbox, &(curCachePtr->bbox))) { - /* leaderbbox interesects with the curCachePtr's global bbox */ + leaderbbox.minx = MS_MIN(lp1->x, lp2->x); + leaderbbox.maxx = MS_MAX(lp1->x, lp2->x); + leaderbbox.miny = MS_MIN(lp1->y, lp2->y); + leaderbbox.maxy = MS_MAX(lp1->y, lp2->y); + for (p = 0; p < map->labelcache.num_rendered_members; p++) { + labelCacheMemberObj *curCachePtr = map->labelcache.rendered_text_symbols[p]; + if (msRectOverlap(&leaderbbox, &(curCachePtr->bbox))) { + /* leaderbbox interesects with the curCachePtr's global bbox */ int t; - for(t=0; tnumtextsymbols; t++) { + for (t = 0; t < curCachePtr->numtextsymbols; t++) { int s; textSymbolObj *ts = curCachePtr->textsymbols[t]; /* check for intersect with textpath */ - if(ts->textpath && testSegmentLabelBBoxIntersection(&leaderbbox, lp1, lp2, &ts->textpath->bounds) == MS_FALSE) { + if (ts->textpath && + testSegmentLabelBBoxIntersection( + &leaderbbox, lp1, lp2, &ts->textpath->bounds) == MS_FALSE) { return MS_FALSE; } /* check for intersect with label's labelpnt styles */ - if(ts->style_bounds) { - for(s=0; slabel->numstyles; s++) { - if(ts->label->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - if(testSegmentLabelBBoxIntersection(&leaderbbox, lp1,lp2, ts->style_bounds[s]) == MS_FALSE) { + if (ts->style_bounds) { + for (s = 0; s < ts->label->numstyles; s++) { + if (ts->label->styles[s]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + if (testSegmentLabelBBoxIntersection( + &leaderbbox, lp1, lp2, ts->style_bounds[s]) == MS_FALSE) { return MS_FALSE; } } } } } - if(curCachePtr->leaderbbox) { - if(msIntersectSegments(lp1,lp2,&(curCachePtr->leaderline->point[0]), &(curCachePtr->leaderline->point[1])) == MS_TRUE) { + if (curCachePtr->leaderbbox) { + if (msIntersectSegments(lp1, lp2, &(curCachePtr->leaderline->point[0]), + &(curCachePtr->leaderline->point[1])) == + MS_TRUE) { return MS_FALSE; } } @@ -686,25 +768,28 @@ int msTestLabelCacheLeaderCollision(mapObj *map, pointObj *lp1, pointObj *lp2) { /* msTestLabelCacheCollisions() ** -** Compares label bounds (in *bounds) against labels already drawn and markers from cache and -** returns MS_FALSE if it collides with another label, or collides with a marker. +** Compares label bounds (in *bounds) against labels already drawn and markers +from cache and +** returns MS_FALSE if it collides with another label, or collides with a +marker. ** ** This function is used by the various msDrawLabelCacheXX() implementations. -int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, label_bounds *bounds, - int current_priority, int current_label); +int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, +label_bounds *bounds, int current_priority, int current_label); */ -int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, label_bounds *lb, - int current_priority, int current_label) -{ +int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, + label_bounds *lb, int current_priority, + int current_label) { labelCacheObj *labelcache = &(map->labelcache); int i, p, ll; /* * Check against image bounds first */ - if(!cachePtr->textsymbols[0]->label->partials) { - if(labelInImage(map->width, map->height, lb->poly, &lb->bbox, labelcache->gutter) == MS_FALSE) { + if (!cachePtr->textsymbols[0]->label->partials) { + if (labelInImage(map->width, map->height, lb->poly, &lb->bbox, + labelcache->gutter) == MS_FALSE) { return MS_FALSE; } } @@ -712,33 +797,43 @@ int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, label /* Compare against all rendered markers from this priority level and higher. ** Labels can overlap their own marker and markers from lower priority levels */ - for (p=current_priority; p < MS_MAX_LABEL_PRIORITY; p++) { + for (p = current_priority; p < MS_MAX_LABEL_PRIORITY; p++) { labelCacheSlotObj *markerslot; markerslot = &(labelcache->slots[p]); - for ( ll = 0; ll < markerslot->nummarkers; ll++ ) { - if ( !(p == current_priority && current_label == markerslot->markers[ll].id ) ) { /* labels can overlap their own marker */ - if ( intersectLabelPolygons(NULL, &markerslot->markers[ll].bounds, lb->poly, &lb->bbox ) == MS_TRUE ) { + for (ll = 0; ll < markerslot->nummarkers; ll++) { + if (!(p == current_priority && + current_label == + markerslot->markers[ll] + .id)) { /* labels can overlap their own marker */ + if (intersectLabelPolygons(NULL, &markerslot->markers[ll].bounds, + lb->poly, &lb->bbox) == MS_TRUE) { return MS_FALSE; } } } } - for(p=0; pnum_rendered_members; p++) { - labelCacheMemberObj *curCachePtr= labelcache->rendered_text_symbols[p]; - if(msRectOverlap(&curCachePtr->bbox,&lb->bbox)) { - for(i=0; inumtextsymbols; i++) { + for (p = 0; p < labelcache->num_rendered_members; p++) { + labelCacheMemberObj *curCachePtr = labelcache->rendered_text_symbols[p]; + if (msRectOverlap(&curCachePtr->bbox, &lb->bbox)) { + for (i = 0; i < curCachePtr->numtextsymbols; i++) { int j; textSymbolObj *ts = curCachePtr->textsymbols[i]; - if(ts->textpath && intersectLabelPolygons(ts->textpath->bounds.poly, &ts->textpath->bounds.bbox, lb->poly, &lb->bbox) == MS_TRUE ) { + if (ts->textpath && + intersectLabelPolygons(ts->textpath->bounds.poly, + &ts->textpath->bounds.bbox, lb->poly, + &lb->bbox) == MS_TRUE) { return MS_FALSE; } - if(ts->style_bounds) { - for(j=0;jlabel->numstyles;j++) { - if(ts->style_bounds[j] && ts->label->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - if(intersectLabelPolygons(ts->style_bounds[j]->poly, &ts->style_bounds[j]->bbox, - lb->poly, &lb->bbox)) { + if (ts->style_bounds) { + for (j = 0; j < ts->label->numstyles; j++) { + if (ts->style_bounds[j] && + ts->label->styles[j]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT) { + if (intersectLabelPolygons(ts->style_bounds[j]->poly, + &ts->style_bounds[j]->bbox, lb->poly, + &lb->bbox)) { return MS_FALSE; } } @@ -746,9 +841,10 @@ int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, label } } } - if(curCachePtr->leaderline) { - if(testSegmentLabelBBoxIntersection(curCachePtr->leaderbbox, &curCachePtr->leaderline->point[0], - &curCachePtr->leaderline->point[1], lb) == MS_FALSE) { + if (curCachePtr->leaderline) { + if (testSegmentLabelBBoxIntersection( + curCachePtr->leaderbbox, &curCachePtr->leaderline->point[0], + &curCachePtr->leaderline->point[1], lb) == MS_FALSE) { return MS_FALSE; } } @@ -756,23 +852,23 @@ int msTestLabelCacheCollisions(mapObj *map, labelCacheMemberObj *cachePtr, label return MS_TRUE; } -/* utility function to get the rect of a string outside of a rendering loop, i.e. - without going through textpath layouts */ -int msGetStringSize(mapObj *map, labelObj *label, int size, char *string, rectObj *r) { +/* utility function to get the rect of a string outside of a rendering loop, + i.e. without going through textpath layouts */ +int msGetStringSize(mapObj *map, labelObj *label, int size, char *string, + rectObj *r) { textSymbolObj ts; double lsize = label->size; initTextSymbol(&ts); label->size = size; - msPopulateTextSymbolForLabelAndString(&ts,label,msStrdup(string),1,1,0); - if(MS_UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map,&ts,r))) + msPopulateTextSymbolForLabelAndString(&ts, label, msStrdup(string), 1, 1, 0); + if (MS_UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map, &ts, r))) return MS_FAILURE; label->size = lsize; freeTextSymbol(&ts); return MS_SUCCESS; } -int msInitFontSet(fontSetObj *fontset) -{ +int msInitFontSet(fontSetObj *fontset) { fontset->filename = NULL; /* fontset->fonts = NULL; */ @@ -780,11 +876,10 @@ int msInitFontSet(fontSetObj *fontset) fontset->numfonts = 0; fontset->map = NULL; - return( 0 ); + return (0); } -int msFreeFontSet(fontSetObj *fontset) -{ +int msFreeFontSet(fontSetObj *fontset) { if (fontset->filename) free(fontset->filename); fontset->filename = NULL; @@ -793,24 +888,23 @@ int msFreeFontSet(fontSetObj *fontset) /* fontset->fonts = NULL; */ fontset->numfonts = 0; - return( 0 ); + return (0); } -int msLoadFontSet(fontSetObj *fontset, mapObj *map) -{ +int msLoadFontSet(fontSetObj *fontset, mapObj *map) { VSILFILE *stream; - const char* line; + const char *line; char *path; char szPath[MS_MAXPATHLEN]; int i; int bFullPath = 0; - const char* realpath; + const char *realpath; - if(fontset->numfonts != 0) /* already initialized */ - return(0); + if (fontset->numfonts != 0) /* already initialized */ + return (0); - if(!fontset->filename) - return(0); + if (!fontset->filename) + return (0); fontset->map = (mapObj *)map; @@ -818,41 +912,43 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) /* fontset->fonts = msCreateHashTable(); // create font hash */ /* if(!fontset->fonts) { */ - /* msSetError(MS_HASHERR, "Error initializing font hash.", "msLoadFontSet()"); */ + /* msSetError(MS_HASHERR, "Error initializing font hash.", "msLoadFontSet()"); + */ /* return(-1); */ /* } */ realpath = msBuildPath(szPath, fontset->map->mappath, fontset->filename); - if( !realpath ) { + if (!realpath) { free(path); return -1; } - stream = VSIFOpenL( realpath, "rb"); - if(!stream) { + stream = VSIFOpenL(realpath, "rb"); + if (!stream) { msSetError(MS_IOERR, "Error opening fontset %s.", "msLoadFontset()", fontset->filename); free(path); - return(-1); + return (-1); } i = 0; - while( (line = CPLReadLineL(stream)) != NULL ) { /* while there's something to load */ + while ((line = CPLReadLineL(stream)) != + NULL) { /* while there's something to load */ - if(line[0] == '#' || line[0] == '\n' || line[0] == '\r' || line[0] == ' ') + if (line[0] == '#' || line[0] == '\n' || line[0] == '\r' || line[0] == ' ') continue; /* skip comments and blank lines */ char alias[64]; snprintf(alias, sizeof(alias), "%s", line); - char* ptr = strpbrk(alias, " \t"); - if( !ptr ) - continue; + char *ptr = strpbrk(alias, " \t"); + if (!ptr) + continue; *ptr = '\0'; - const char* file1StartPtr = line + (ptr - alias); - file1StartPtr ++; + const char *file1StartPtr = line + (ptr - alias); + file1StartPtr++; /* Skip leading spaces */ - while( isspace((int)*file1StartPtr) ) - file1StartPtr ++; + while (isspace((int)*file1StartPtr)) + file1StartPtr++; if (!(*file1StartPtr) || !(*alias)) continue; @@ -861,10 +957,9 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) snprintf(file1, sizeof(file1), "%s", file1StartPtr); /* Remove trailing spaces */ ptr = file1 + strlen(file1) - 1; - while( ptr >= file1 && isspace((int)*ptr) ) - { - *ptr = '\0'; - --ptr; + while (ptr >= file1 && isspace((int)*ptr)) { + *ptr = '\0'; + --ptr; } bFullPath = 0; @@ -872,11 +967,11 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) if (file1[0] == '\\' || (strlen(file1) > 1 && (file1[1] == ':'))) bFullPath = 1; #else - if(file1[0] == '/') + if (file1[0] == '/') bFullPath = 1; #endif - if(bFullPath) { /* already full path */ + if (bFullPath) { /* already full path */ msInsertHashTable(&(fontset->fonts), alias, file1); } else { char file2[MS_PATH_LENGTH]; @@ -890,7 +985,6 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) */ msInsertHashTable(&(fontset->fonts), alias, msBuildPath(szPath, fontset->map->mappath, file2)); - } i++; @@ -900,93 +994,94 @@ int msLoadFontSet(fontSetObj *fontset, mapObj *map) VSIFCloseL(stream); /* close the file */ free(path); - return(0); + return (0); } - int msGetTextSymbolSize(mapObj *map, textSymbolObj *ts, rectObj *r) { - if(!ts->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) + if (!ts->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) return MS_FAILURE; } - if(!ts->textpath) + if (!ts->textpath) return MS_FAILURE; *r = ts->textpath->bounds.bbox; return MS_SUCCESS; } /* -** Note: All these routines assume a reference point at the LL corner of the text. GD's -** bitmapped fonts use UL and this is compensated for. Note the rect is relative to the +** Note: All these routines assume a reference point at the LL corner of the +*text. GD's +** bitmapped fonts use UL and this is compensated for. Note the rect is relative +*to the ** LL corner of the text to be rendered, this is first line for TrueType fonts. */ #define MARKER_SLOP 2 -pointObj get_metrics(pointObj *p, int position, textPathObj *tp, int ox, int oy, double rotation, int buffer, label_bounds *bounds) -{ +pointObj get_metrics(pointObj *p, int position, textPathObj *tp, int ox, int oy, + double rotation, int buffer, label_bounds *bounds) { pointObj q = {0}; // initialize - double x1=0, y1=0, x2=0, y2=0; - double sin_a,cos_a; + double x1 = 0, y1 = 0, x2 = 0, y2 = 0; + double sin_a, cos_a; double w, h, x, y; w = tp->bounds.bbox.maxx - tp->bounds.bbox.minx; h = tp->bounds.bbox.maxy - tp->bounds.bbox.miny; - switch(position) { - case MS_UL: - x1 = -w - ox; - y1 = -oy; - break; - case MS_UC: - x1 = -(w/2.0); - y1 = -oy - MARKER_SLOP; - break; - case MS_UR: - x1 = ox; - y1 = -oy; - break; - case MS_CL: - x1 = -w - ox - MARKER_SLOP; - if(oy > 0 && tp->numlines == 1) - y1 = oy; - else - y1 = (h/2.0); - break; - case MS_CC: - x1 = -(w/2.0) + ox; - y1 = (h/2.0) + oy; - break; - case MS_CR: - x1 = ox + MARKER_SLOP; - if(oy > 0 && tp->numlines == 1) - y1 = oy; - else - y1 = (h/2.0); - break; - case MS_LL: - x1 = -w - ox; - y1 = h + oy; - break; - case MS_LC: - x1 = -(w/2.0); - y1 = h + oy + MARKER_SLOP; - break; - case MS_LR: - x1 = ox; - y1 = h + oy; - break; + switch (position) { + case MS_UL: + x1 = -w - ox; + y1 = -oy; + break; + case MS_UC: + x1 = -(w / 2.0); + y1 = -oy - MARKER_SLOP; + break; + case MS_UR: + x1 = ox; + y1 = -oy; + break; + case MS_CL: + x1 = -w - ox - MARKER_SLOP; + if (oy > 0 && tp->numlines == 1) + y1 = oy; + else + y1 = (h / 2.0); + break; + case MS_CC: + x1 = -(w / 2.0) + ox; + y1 = (h / 2.0) + oy; + break; + case MS_CR: + x1 = ox + MARKER_SLOP; + if (oy > 0 && tp->numlines == 1) + y1 = oy; + else + y1 = (h / 2.0); + break; + case MS_LL: + x1 = -w - ox; + y1 = h + oy; + break; + case MS_LC: + x1 = -(w / 2.0); + y1 = h + oy + MARKER_SLOP; + break; + case MS_LR: + x1 = ox; + y1 = h + oy; + break; } - if(rotation) { + if (rotation) { sin_a = sin(rotation); cos_a = cos(rotation); x = x1 - tp->bounds.bbox.minx; y = tp->bounds.bbox.maxy - y1; - q.x = p->x + (x * cos_a - (y) * sin_a); - q.y = p->y - (x * sin_a + (y) * cos_a); + q.x = p->x + (x * cos_a - (y)*sin_a); + q.y = p->y - (x * sin_a + (y)*cos_a); - if(bounds) { + if (bounds) { x2 = x1 - buffer; /* ll */ y2 = y1 + buffer; bounds->poly->point[0].x = p->x + (x2 * cos_a - (-y2) * sin_a); @@ -1009,37 +1104,39 @@ pointObj get_metrics(pointObj *p, int position, textPathObj *tp, int ox, int oy, bounds->poly->point[4].x = bounds->poly->point[0].x; bounds->poly->point[4].y = bounds->poly->point[0].y; - fastComputeBounds(bounds->poly,&bounds->bbox); + fastComputeBounds(bounds->poly, &bounds->bbox); } - } - else { + } else { q.x = p->x + x1 - tp->bounds.bbox.minx; q.y = p->y + y1 - tp->bounds.bbox.maxy; - if(bounds) { + if (bounds) { /* no rotation, we only need to return a bbox */ bounds->poly = NULL; - bounds->bbox.minx = q.x - buffer; bounds->bbox.maxy = q.y + buffer + tp->bounds.bbox.maxy; bounds->bbox.maxx = q.x + w + buffer; - bounds->bbox.miny = bounds->bbox.maxy - h - buffer*2; + bounds->bbox.miny = bounds->bbox.maxy - h - buffer * 2; } } - return(q); + return (q); } int intersectTextSymbol(textSymbolObj *ts, label_bounds *lb) { - if(ts->textpath && ts->textpath->absolute) { - if(intersectLabelPolygons(lb->poly,&lb->bbox,ts->textpath->bounds.poly,&ts->textpath->bounds.bbox)) + if (ts->textpath && ts->textpath->absolute) { + if (intersectLabelPolygons(lb->poly, &lb->bbox, ts->textpath->bounds.poly, + &ts->textpath->bounds.bbox)) return MS_TRUE; } - if(ts->style_bounds) { + if (ts->style_bounds) { int s; - for(s=0; slabel->numstyles; s++) { - if(ts->style_bounds[s] && ts->label->styles[s]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT && - intersectLabelPolygons(lb->poly,&lb->bbox,ts->style_bounds[s]->poly, &ts->style_bounds[s]->bbox)) + for (s = 0; s < ts->label->numstyles; s++) { + if (ts->style_bounds[s] && + ts->label->styles[s]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT && + intersectLabelPolygons(lb->poly, &lb->bbox, ts->style_bounds[s]->poly, + &ts->style_bounds[s]->bbox)) return MS_TRUE; } } @@ -1047,25 +1144,24 @@ int intersectTextSymbol(textSymbolObj *ts, label_bounds *lb) { } /* -** Variation on msIntersectPolygons. Label polygons aren't like shapefile polygons. They +** Variation on msIntersectPolygons. Label polygons aren't like shapefile +*polygons. They ** have no holes, and often do have overlapping parts (i.e. road symbols). */ -int intersectLabelPolygons(lineObj *l1, rectObj *r1, lineObj *l2, rectObj *r2) -{ - int v1,v2; +int intersectLabelPolygons(lineObj *l1, rectObj *r1, lineObj *l2, rectObj *r2) { + int v1, v2; pointObj *point; - lineObj *p1,*p2,sp1,sp2; - pointObj pnts1[5],pnts2[5]; - + lineObj *p1, *p2, sp1, sp2; + pointObj pnts1[5], pnts2[5]; /* STEP 0: check bounding boxes */ - if(!msRectOverlap(r1,r2)) { /* from alans@wunderground.com */ - return(MS_FALSE); + if (!msRectOverlap(r1, r2)) { /* from alans@wunderground.com */ + return (MS_FALSE); } - if(!l1 && !l2) + if (!l1 && !l2) return MS_TRUE; - if(!l1) { + if (!l1) { p1 = &sp1; p1->numpoints = 5; p1->point = pnts1; @@ -1076,7 +1172,7 @@ int intersectLabelPolygons(lineObj *l1, rectObj *r1, lineObj *l2, rectObj *r2) } else { p1 = l1; } - if(!l2) { + if (!l2) { p2 = &sp2; p2->numpoints = 5; p2->point = pnts2; @@ -1087,42 +1183,58 @@ int intersectLabelPolygons(lineObj *l1, rectObj *r1, lineObj *l2, rectObj *r2) } else { p2 = l2; } - (void)pnts1[0].x; (void)pnts1[0].y; - (void)pnts1[1].x; (void)pnts1[1].y; - (void)pnts1[2].x; (void)pnts1[2].y; - (void)pnts1[3].x; (void)pnts1[3].y; - (void)pnts1[4].x; (void)pnts1[4].y; - (void)pnts2[0].x; (void)pnts2[0].y; - (void)pnts2[1].x; (void)pnts2[1].y; - (void)pnts2[2].x; (void)pnts2[2].y; - (void)pnts2[3].x; (void)pnts2[3].y; - (void)pnts2[4].x; (void)pnts2[4].y; + (void)pnts1[0].x; + (void)pnts1[0].y; + (void)pnts1[1].x; + (void)pnts1[1].y; + (void)pnts1[2].x; + (void)pnts1[2].y; + (void)pnts1[3].x; + (void)pnts1[3].y; + (void)pnts1[4].x; + (void)pnts1[4].y; + (void)pnts2[0].x; + (void)pnts2[0].y; + (void)pnts2[1].x; + (void)pnts2[1].y; + (void)pnts2[2].x; + (void)pnts2[2].y; + (void)pnts2[3].x; + (void)pnts2[3].y; + (void)pnts2[4].x; + (void)pnts2[4].y; /* STEP 1: look for intersecting line segments */ - for(v1=1; v1numpoints; v1++) - for(v2=1; v2numpoints; v2++) - if(msIntersectSegments(&(p1->point[v1-1]), &(p1->point[v1]), &(p2->point[v2-1]), &(p2->point[v2])) == MS_TRUE) { - return(MS_TRUE); - } + for (v1 = 1; v1 < p1->numpoints; v1++) + for (v2 = 1; v2 < p2->numpoints; v2++) + if (msIntersectSegments(&(p1->point[v1 - 1]), &(p1->point[v1]), + &(p2->point[v2 - 1]), + &(p2->point[v2])) == MS_TRUE) { + return (MS_TRUE); + } - /* STEP 2: polygon one completely contains two (only need to check one point from each part) */ + /* STEP 2: polygon one completely contains two (only need to check one point + * from each part) */ point = &(p2->point[0]); - if(msPointInPolygon(point, p1) == MS_TRUE) /* ok, the point is in a polygon */ - return(MS_TRUE); + if (msPointInPolygon(point, p1) == + MS_TRUE) /* ok, the point is in a polygon */ + return (MS_TRUE); - /* STEP 3: polygon two completely contains one (only need to check one point from each part) */ + /* STEP 3: polygon two completely contains one (only need to check one point + * from each part) */ point = &(p1->point[0]); - if(msPointInPolygon(point, p2) == MS_TRUE) /* ok, the point is in a polygon */ - return(MS_TRUE); + if (msPointInPolygon(point, p2) == + MS_TRUE) /* ok, the point is in a polygon */ + return (MS_TRUE); - return(MS_FALSE); + return (MS_FALSE); } /* For MapScript, exactly the same the msInsertStyle */ -int msInsertLabelStyle(labelObj *label, styleObj *style, int nStyleIndex) -{ +int msInsertLabelStyle(labelObj *label, styleObj *style, int nStyleIndex) { if (!style) { - msSetError(MS_CHILDERR, "Can't insert a NULL Style", "msInsertLabelStyle()"); + msSetError(MS_CHILDERR, "Can't insert a NULL Style", + "msInsertLabelStyle()"); return -1; } @@ -1132,20 +1244,21 @@ int msInsertLabelStyle(labelObj *label, styleObj *style, int nStyleIndex) } /* Catch attempt to insert past end of styles array */ else if (nStyleIndex >= label->numstyles) { - msSetError(MS_CHILDERR, "Cannot insert style beyond index %d", "insertLabelStyle()", label->numstyles-1); + msSetError(MS_CHILDERR, "Cannot insert style beyond index %d", + "insertLabelStyle()", label->numstyles - 1); return -1; } else if (nStyleIndex < 0) { /* Insert at the end by default */ - label->styles[label->numstyles]=style; + label->styles[label->numstyles] = style; MS_REFCNT_INCR(style); label->numstyles++; - return label->numstyles-1; + return label->numstyles - 1; } else { /* Move styles existing at the specified nStyleIndex or greater */ /* to a higher nStyleIndex */ - for (int i=label->numstyles-1; i>=nStyleIndex; i--) { - label->styles[i+1] = label->styles[i]; + for (int i = label->numstyles - 1; i >= nStyleIndex; i--) { + label->styles[i + 1] = label->styles[i]; } - label->styles[nStyleIndex]=style; + label->styles[nStyleIndex] = style; MS_REFCNT_INCR(style); label->numstyles++; return nStyleIndex; @@ -1155,46 +1268,41 @@ int msInsertLabelStyle(labelObj *label, styleObj *style, int nStyleIndex) /** * Move the style up inside the array of styles. */ -int msMoveLabelStyleUp(labelObj *label, int nStyleIndex) -{ - if (label && nStyleIndex < label->numstyles && nStyleIndex >0) { - styleObj* psTmpStyle = (styleObj *)malloc(sizeof(styleObj)); +int msMoveLabelStyleUp(labelObj *label, int nStyleIndex) { + if (label && nStyleIndex < label->numstyles && nStyleIndex > 0) { + styleObj *psTmpStyle = (styleObj *)malloc(sizeof(styleObj)); initStyle(psTmpStyle); msCopyStyle(psTmpStyle, label->styles[nStyleIndex]); - msCopyStyle(label->styles[nStyleIndex], - label->styles[nStyleIndex-1]); + msCopyStyle(label->styles[nStyleIndex], label->styles[nStyleIndex - 1]); - msCopyStyle(label->styles[nStyleIndex-1], psTmpStyle); + msCopyStyle(label->styles[nStyleIndex - 1], psTmpStyle); - return(MS_SUCCESS); + return (MS_SUCCESS); } msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveLabelStyleUp()", nStyleIndex); return (MS_FAILURE); } - /** * Move the style down inside the array of styles. */ -int msMoveLabelStyleDown(labelObj *label, int nStyleIndex) -{ +int msMoveLabelStyleDown(labelObj *label, int nStyleIndex) { styleObj *psTmpStyle = NULL; - if (label && nStyleIndex < label->numstyles-1 && nStyleIndex >=0) { + if (label && nStyleIndex < label->numstyles - 1 && nStyleIndex >= 0) { psTmpStyle = (styleObj *)malloc(sizeof(styleObj)); initStyle(psTmpStyle); msCopyStyle(psTmpStyle, label->styles[nStyleIndex]); - msCopyStyle(label->styles[nStyleIndex], - label->styles[nStyleIndex+1]); + msCopyStyle(label->styles[nStyleIndex], label->styles[nStyleIndex + 1]); - msCopyStyle(label->styles[nStyleIndex+1], psTmpStyle); + msCopyStyle(label->styles[nStyleIndex + 1], psTmpStyle); - return(MS_SUCCESS); + return (MS_SUCCESS); } msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveLabelStyleDown()", nStyleIndex); @@ -1205,36 +1313,35 @@ int msMoveLabelStyleDown(labelObj *label, int nStyleIndex) * Delete the style identified by the index and shift * styles that follows the deleted style. */ -int msDeleteLabelStyle(labelObj *label, int nStyleIndex) -{ - if (label && nStyleIndex < label->numstyles && nStyleIndex >=0) { +int msDeleteLabelStyle(labelObj *label, int nStyleIndex) { + if (label && nStyleIndex < label->numstyles && nStyleIndex >= 0) { if (freeStyle(label->styles[nStyleIndex]) == MS_SUCCESS) msFree(label->styles[nStyleIndex]); - for (int i=nStyleIndex; i< label->numstyles-1; i++) { - label->styles[i] = label->styles[i+1]; + for (int i = nStyleIndex; i < label->numstyles - 1; i++) { + label->styles[i] = label->styles[i + 1]; } - label->styles[label->numstyles-1] = NULL; + label->styles[label->numstyles - 1] = NULL; label->numstyles--; - return(MS_SUCCESS); + return (MS_SUCCESS); } msSetError(MS_CHILDERR, "Invalid index: %d", "msDeleteLabelStyle()", nStyleIndex); return (MS_FAILURE); } -styleObj *msRemoveLabelStyle(labelObj *label, int nStyleIndex) -{ +styleObj *msRemoveLabelStyle(labelObj *label, int nStyleIndex) { int i; styleObj *style; if (nStyleIndex < 0 || nStyleIndex >= label->numstyles) { - msSetError(MS_CHILDERR, "Cannot remove style, invalid nStyleIndex %d", "removeLabelStyle()", nStyleIndex); + msSetError(MS_CHILDERR, "Cannot remove style, invalid nStyleIndex %d", + "removeLabelStyle()", nStyleIndex); return NULL; } else { - style=label->styles[nStyleIndex]; - for (i=nStyleIndex; inumstyles-1; i++) { - label->styles[i]=label->styles[i+1]; + style = label->styles[nStyleIndex]; + for (i = nStyleIndex; i < label->numstyles - 1; i++) { + label->styles[i] = label->styles[i + 1]; } - label->styles[label->numstyles-1]=NULL; + label->styles[label->numstyles - 1] = NULL; label->numstyles--; MS_REFCNT_DECR(style); return style; diff --git a/maplayer.c b/maplayer.c index 2c29dd6ead..ab219bb6f9 100644 --- a/maplayer.c +++ b/maplayer.c @@ -38,23 +38,29 @@ #include #ifndef cppcheck_assert -#define cppcheck_assert(x) do {} while(0) +#define cppcheck_assert(x) \ + do { \ + } while (0) #endif static int populateVirtualTable(layerVTableObj *vtable); /* -** Iteminfo is a layer parameter that holds information necessary to retrieve an individual item for -** a particular source. It is an array built from a list of items. The type of iteminfo will vary by -** source. For shapefiles and OGR it is simply an array of integers where each value is an index for -** the item. For SDE it's a ESRI specific type that contains index and column type information. Two -** helper functions below initialize and free that structure member which is used locally by layer +** Iteminfo is a layer parameter that holds information necessary to retrieve an +*individual item for +** a particular source. It is an array built from a list of items. The type of +*iteminfo will vary by +** source. For shapefiles and OGR it is simply an array of integers where each +*value is an index for +** the item. For SDE it's a ESRI specific type that contains index and column +*type information. Two +** helper functions below initialize and free that structure member which is +*used locally by layer ** specific functions. */ -int msLayerInitItemInfo(layerObj *layer) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +int msLayerInitItemInfo(layerObj *layer) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -62,11 +68,10 @@ int msLayerInitItemInfo(layerObj *layer) return layer->vtable->LayerInitItemInfo(layer); } -void msLayerFreeItemInfo(layerObj *layer) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); - if( rv != MS_SUCCESS ) +void msLayerFreeItemInfo(layerObj *layer) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); + if (rv != MS_SUCCESS) return; } cppcheck_assert(layer->vtable); @@ -80,167 +85,184 @@ void msLayerFreeItemInfo(layerObj *layer) msLayerFreeExpressions(layer); } -int msLayerRestoreFromScaletokens(layerObj *layer) -{ - if(!layer->scaletokens || !layer->orig_st) { +int msLayerRestoreFromScaletokens(layerObj *layer) { + if (!layer->scaletokens || !layer->orig_st) { return MS_SUCCESS; } - if(layer->orig_st->data) { + if (layer->orig_st->data) { msFree(layer->data); layer->data = layer->orig_st->data; } - if(layer->orig_st->tileindex) { + if (layer->orig_st->tileindex) { msFree(layer->tileindex); layer->tileindex = layer->orig_st->tileindex; } - if(layer->orig_st->tileitem) { + if (layer->orig_st->tileitem) { msFree(layer->tileitem); layer->tileitem = layer->orig_st->tileitem; } - if(layer->orig_st->filter) { - msLoadExpressionString(&(layer->filter),layer->orig_st->filter); + if (layer->orig_st->filter) { + msLoadExpressionString(&(layer->filter), layer->orig_st->filter); msFree(layer->orig_st->filter); } - if(layer->orig_st->filteritem) { + if (layer->orig_st->filteritem) { msFree(layer->filteritem); layer->filteritem = layer->orig_st->filteritem; } - if(layer->orig_st->n_processing) { + if (layer->orig_st->n_processing) { int i; - for(i=0;iorig_st->n_processing;i++) { + for (i = 0; i < layer->orig_st->n_processing; i++) { msFree(layer->processing[layer->orig_st->processing_idx[i]]); - layer->processing[layer->orig_st->processing_idx[i]] = layer->orig_st->processing[i]; + layer->processing[layer->orig_st->processing_idx[i]] = + layer->orig_st->processing[i]; } msFree(layer->orig_st->processing); msFree(layer->orig_st->processing_idx); } msFree(layer->orig_st); layer->orig_st = NULL; - return MS_SUCCESS; + return MS_SUCCESS; } -#define check_st_alloc(l) if(!l->orig_st) l->orig_st=msSmallCalloc(1,sizeof(originalScaleTokenStrings)); -int msLayerApplyScaletokens(layerObj *layer, double scale) -{ - int i,p; - if(!layer->scaletokens) { +#define check_st_alloc(l) \ + if (!l->orig_st) \ + l->orig_st = msSmallCalloc(1, sizeof(originalScaleTokenStrings)); +int msLayerApplyScaletokens(layerObj *layer, double scale) { + int i, p; + if (!layer->scaletokens) { return MS_SUCCESS; } msLayerRestoreFromScaletokens(layer); - for(i=0;inumscaletokens;i++) { + for (i = 0; i < layer->numscaletokens; i++) { scaleTokenObj *st = &layer->scaletokens[i]; scaleTokenEntryObj *ste = NULL; - if(scale<=0) { - ste = &(st->tokens[0]); + if (scale <= 0) { + ste = &(st->tokens[0]); /* no scale defined, use first entry */ } else { - int tokenindex=0; - while(tokenindexn_entries) { + int tokenindex = 0; + while (tokenindex < st->n_entries) { ste = &(st->tokens[tokenindex]); - if(scale < ste->maxscale && scale >= ste->minscale) break; /* current token is the correct one */ + if (scale < ste->maxscale && scale >= ste->minscale) + break; /* current token is the correct one */ tokenindex++; ste = NULL; } } assert(ste); - if(layer->data && strstr(layer->data,st->name)) { - if(layer->debug >= MS_DEBUGLEVEL_DEBUG) { - msDebug("replacing scaletoken (%s) with (%s) in layer->data (%s) for scale=%f\n", - st->name,ste->value,layer->name,scale); + if (layer->data && strstr(layer->data, st->name)) { + if (layer->debug >= MS_DEBUGLEVEL_DEBUG) { + msDebug("replacing scaletoken (%s) with (%s) in layer->data (%s) for " + "scale=%f\n", + st->name, ste->value, layer->name, scale); } check_st_alloc(layer); layer->orig_st->data = layer->data; layer->data = msStrdup(layer->data); - layer->data = msReplaceSubstring(layer->data,st->name,ste->value); + layer->data = msReplaceSubstring(layer->data, st->name, ste->value); } - if(layer->tileindex && strstr(layer->tileindex,st->name)) { - if(layer->debug >= MS_DEBUGLEVEL_DEBUG) { - msDebug("replacing scaletoken (%s) with (%s) in layer->tileindex (%s) for scale=%f\n", - st->name,ste->value,layer->name,scale); + if (layer->tileindex && strstr(layer->tileindex, st->name)) { + if (layer->debug >= MS_DEBUGLEVEL_DEBUG) { + msDebug("replacing scaletoken (%s) with (%s) in layer->tileindex (%s) " + "for scale=%f\n", + st->name, ste->value, layer->name, scale); } check_st_alloc(layer); layer->orig_st->tileindex = layer->tileindex; layer->tileindex = msStrdup(layer->tileindex); - layer->tileindex = msReplaceSubstring(layer->tileindex,st->name,ste->value); + layer->tileindex = + msReplaceSubstring(layer->tileindex, st->name, ste->value); } - if(layer->tileitem && strstr(layer->tileitem,st->name)) { - if(layer->debug >= MS_DEBUGLEVEL_DEBUG) { - msDebug("replacing scaletoken (%s) with (%s) in layer->tileitem (%s) for scale=%f\n", - st->name,ste->value,layer->name,scale); + if (layer->tileitem && strstr(layer->tileitem, st->name)) { + if (layer->debug >= MS_DEBUGLEVEL_DEBUG) { + msDebug("replacing scaletoken (%s) with (%s) in layer->tileitem (%s) " + "for scale=%f\n", + st->name, ste->value, layer->name, scale); } check_st_alloc(layer); layer->orig_st->tileitem = layer->tileitem; layer->tileitem = msStrdup(layer->tileitem); - layer->tileitem = msReplaceSubstring(layer->tileitem,st->name,ste->value); + layer->tileitem = + msReplaceSubstring(layer->tileitem, st->name, ste->value); } - if(layer->filteritem && strstr(layer->filteritem,st->name)) { - if(layer->debug >= MS_DEBUGLEVEL_DEBUG) { - msDebug("replacing scaletoken (%s) with (%s) in layer->filteritem (%s) for scale=%f\n", - st->name,ste->value,layer->name,scale); + if (layer->filteritem && strstr(layer->filteritem, st->name)) { + if (layer->debug >= MS_DEBUGLEVEL_DEBUG) { + msDebug("replacing scaletoken (%s) with (%s) in layer->filteritem (%s) " + "for scale=%f\n", + st->name, ste->value, layer->name, scale); } check_st_alloc(layer); layer->orig_st->filteritem = layer->filteritem; layer->filteritem = msStrdup(layer->filteritem); - layer->filteritem = msReplaceSubstring(layer->filteritem,st->name,ste->value); + layer->filteritem = + msReplaceSubstring(layer->filteritem, st->name, ste->value); } - if(layer->filter.string && strstr(layer->filter.string,st->name)) { + if (layer->filter.string && strstr(layer->filter.string, st->name)) { char *tmpval; - if(layer->debug >= MS_DEBUGLEVEL_DEBUG) { - msDebug("replacing scaletoken (%s) with (%s) in layer->filter (%s) for scale=%f\n", - st->name,ste->value,layer->name,scale); + if (layer->debug >= MS_DEBUGLEVEL_DEBUG) { + msDebug("replacing scaletoken (%s) with (%s) in layer->filter (%s) for " + "scale=%f\n", + st->name, ste->value, layer->name, scale); } check_st_alloc(layer); layer->orig_st->filter = msStrdup(layer->filter.string); tmpval = msStrdup(layer->filter.string); - tmpval = msReplaceSubstring(tmpval,st->name,ste->value); - if(msLoadExpressionString(&(layer->filter),tmpval) == -1) return(MS_FAILURE); /* msLoadExpressionString() cleans up previously allocated expression */ + tmpval = msReplaceSubstring(tmpval, st->name, ste->value); + if (msLoadExpressionString(&(layer->filter), tmpval) == -1) + return (MS_FAILURE); /* msLoadExpressionString() cleans up previously + allocated expression */ msFree(tmpval); } - for(p=0;pnumprocessing;p++) { - if(strstr(layer->processing[p],st->name)) { + for (p = 0; p < layer->numprocessing; p++) { + if (strstr(layer->processing[p], st->name)) { check_st_alloc(layer); layer->orig_st->n_processing++; - layer->orig_st->processing = msSmallRealloc(layer->orig_st->processing, layer->orig_st->n_processing * sizeof(char*)); - layer->orig_st->processing_idx = msSmallRealloc(layer->orig_st->processing_idx, layer->orig_st->n_processing * sizeof(int)); - layer->orig_st->processing[layer->orig_st->n_processing-1] = layer->processing[p]; - layer->orig_st->processing_idx[layer->orig_st->n_processing-1] = p; + layer->orig_st->processing = + msSmallRealloc(layer->orig_st->processing, + layer->orig_st->n_processing * sizeof(char *)); + layer->orig_st->processing_idx = + msSmallRealloc(layer->orig_st->processing_idx, + layer->orig_st->n_processing * sizeof(int)); + layer->orig_st->processing[layer->orig_st->n_processing - 1] = + layer->processing[p]; + layer->orig_st->processing_idx[layer->orig_st->n_processing - 1] = p; layer->processing[p] = msStrdup(layer->processing[p]); - layer->processing[p] = msReplaceSubstring(layer->processing[p],st->name,ste->value); + layer->processing[p] = + msReplaceSubstring(layer->processing[p], st->name, ste->value); } } - } return MS_SUCCESS; } - /* ** Does exactly what it implies, readies a layer for processing. */ -int msLayerOpen(layerObj *layer) -{ +int msLayerOpen(layerObj *layer) { int rv; /* RFC-86 Scale dependant token replacements*/ - rv = msLayerApplyScaletokens(layer,(layer->map)?layer->map->scaledenom:-1); - if (rv != MS_SUCCESS) return rv; + rv = msLayerApplyScaletokens(layer, + (layer->map) ? layer->map->scaledenom : -1); + if (rv != MS_SUCCESS) + return rv; /* RFC-69 clustering support */ if (layer->cluster.region) return msClusterLayerOpen(layer); - if(layer->features && layer->connectiontype != MS_GRATICULE ) + if (layer->features && layer->connectiontype != MS_GRATICULE) layer->connectiontype = MS_INLINE; - if(layer->tileindex && layer->connectiontype == MS_SHAPEFILE) + if (layer->tileindex && layer->connectiontype == MS_SHAPEFILE) layer->connectiontype = MS_TILED_SHAPEFILE; - if(layer->type == MS_LAYER_RASTER && layer->connectiontype != MS_WMS - && layer->connectiontype != MS_KERNELDENSITY) + if (layer->type == MS_LAYER_RASTER && layer->connectiontype != MS_WMS && + layer->connectiontype != MS_KERNELDENSITY) layer->connectiontype = MS_RASTER; - if ( ! layer->vtable) { - rv = msInitializeVirtualTable(layer); + if (!layer->vtable) { + rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -249,12 +271,12 @@ int msLayerOpen(layerObj *layer) } /* -** Returns MS_TRUE if layer has been opened using msLayerOpen(), MS_FALSE otherwise +** Returns MS_TRUE if layer has been opened using msLayerOpen(), MS_FALSE +*otherwise */ -int msLayerIsOpen(layerObj *layer) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +int msLayerIsOpen(layerObj *layer) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -263,12 +285,12 @@ int msLayerIsOpen(layerObj *layer) } /* -** Returns MS_TRUE is a layer supports the common expression/filter syntax (RFC 64) and MS_FALSE otherwise. +** Returns MS_TRUE is a layer supports the common expression/filter syntax (RFC +*64) and MS_FALSE otherwise. */ -int msLayerSupportsCommonFilters(layerObj *layer) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +int msLayerSupportsCommonFilters(layerObj *layer) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -276,10 +298,10 @@ int msLayerSupportsCommonFilters(layerObj *layer) return layer->vtable->LayerSupportsCommonFilters(layer); } -int msLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ +int msLayerTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { if (!layer->vtable) { - int rv = msInitializeVirtualTable(layer); + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -288,22 +310,26 @@ int msLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteri } /* -** Performs a spatial, and optionally an attribute based feature search. The function basically -** prepares things so that candidate features can be accessed by query or drawing functions. For -** OGR and shapefiles this sets an internal bit vector that indicates whether a particular feature -** is to processed. For SDE it executes an SQL statement on the SDE server. Once run the msLayerNextShape +** Performs a spatial, and optionally an attribute based feature search. The +*function basically +** prepares things so that candidate features can be accessed by query or +*drawing functions. For +** OGR and shapefiles this sets an internal bit vector that indicates whether a +*particular feature +** is to processed. For SDE it executes an SQL statement on the SDE server. Once +*run the msLayerNextShape ** function should be called to actually access the shapes. ** -** Note that for shapefiles we apply any maxfeatures constraint at this point. That may be the only +** Note that for shapefiles we apply any maxfeatures constraint at this point. +*That may be the only ** connection type where this is feasible. */ -int msLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ - if(!msLayerSupportsCommonFilters(layer)) +int msLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { + if (!msLayerSupportsCommonFilters(layer)) msLayerTranslateFilter(layer, &layer->filter, layer->filteritem); - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -312,17 +338,17 @@ int msLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) } /* -** Called after msWhichShapes has been called to actually retrieve shapes within a given area +** Called after msWhichShapes has been called to actually retrieve shapes within +*a given area ** and matching a vendor specific filter (i.e. layer FILTER attribute). ** ** Shapefiles: NULL shapes (shapes with attributes but NO vertices are skipped) */ -int msLayerNextShape(layerObj *layer, shapeObj *shape) -{ +int msLayerNextShape(layerObj *layer, shapeObj *shape) { int rv, filter_passed; - - if ( ! layer->vtable) { - rv = msInitializeVirtualTable(layer); + + if (!layer->vtable) { + rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -330,53 +356,58 @@ int msLayerNextShape(layerObj *layer, shapeObj *shape) #ifdef USE_V8_MAPSCRIPT /* we need to force the GetItems for the geomtransform attributes */ - if(!layer->items && - layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION && - strstr(layer->_geomtransform.string, "javascript")) - msLayerGetItems(layer); + if (!layer->items && + layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION && + strstr(layer->_geomtransform.string, "javascript")) + msLayerGetItems(layer); #endif /* At the end of switch case (default -> break; -> return MS_FAILURE), * was following TODO ITEM: * * TO DO! This is where dynamic joins will happen. Joined attributes will be - * tagged on to the main attributes with the naming scheme [join name].[item name]. - * We need to leverage the iteminfo (I think) at this point + * tagged on to the main attributes with the naming scheme [join name].[item + * name]. We need to leverage the iteminfo (I think) at this point */ /* RFC 91: MapServer-based filtering is done at a more general level. */ do { rv = layer->vtable->LayerNextShape(layer, shape); - if(rv != MS_SUCCESS) return rv; + if (rv != MS_SUCCESS) + return rv; - /* attributes need to be iconv'd to UTF-8 before any filter logic is applied */ - if(layer->encoding) { - rv = msLayerEncodeShapeAttributes(layer,shape); - if(rv != MS_SUCCESS) + /* attributes need to be iconv'd to UTF-8 before any filter logic is applied + */ + if (layer->encoding) { + rv = msLayerEncodeShapeAttributes(layer, shape); + if (rv != MS_SUCCESS) return rv; } - filter_passed = msEvalExpression(layer, shape, &(layer->filter), layer->filteritemindex); + filter_passed = msEvalExpression(layer, shape, &(layer->filter), + layer->filteritemindex); - if(!filter_passed) msFreeShape(shape); - } while(!filter_passed); + if (!filter_passed) + msFreeShape(shape); + } while (!filter_passed); /* RFC89 Apply Layer GeomTransform */ - if(layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE && rv == MS_SUCCESS) { - rv = msGeomTransformShape(layer->map, layer, shape); - if(rv != MS_SUCCESS) + if (layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE && rv == MS_SUCCESS) { + rv = msGeomTransformShape(layer->map, layer, shape); + if (rv != MS_SUCCESS) return rv; } - return rv; } /* -** Used to retrieve a shape from a result set by index. Result sets are created by the various +** Used to retrieve a shape from a result set by index. Result sets are created +*by the various ** msQueryBy...() functions. The index is assigned by the data source. */ -/* int msLayerResultsGetShape(layerObj *layer, shapeObj *shape, int tile, long record) +/* int msLayerResultsGetShape(layerObj *layer, shapeObj *shape, int tile, long +record) { if ( ! layer->vtable) { int rv = msInitializeVirtualTable(layer); @@ -388,39 +419,40 @@ int msLayerNextShape(layerObj *layer, shapeObj *shape) } */ /* -** Used to retrieve a shape by index. All data sources must be capable of random access using +** Used to retrieve a shape by index. All data sources must be capable of random +*access using ** a record number(s) of some sort. */ -int msLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ +int msLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { int rv; - - if( ! layer->vtable) { - rv = msInitializeVirtualTable(layer); - if(rv != MS_SUCCESS) + + if (!layer->vtable) { + rv = msInitializeVirtualTable(layer); + if (rv != MS_SUCCESS) return rv; } cppcheck_assert(layer->vtable); /* ** TODO: This is where dynamic joins could happen. Joined attributes would be - ** tagged on to the main attributes with the naming scheme [join name].[item name]. + ** tagged on to the main attributes with the naming scheme [join name].[item + *name]. */ rv = layer->vtable->LayerGetShape(layer, shape, record); - if(rv != MS_SUCCESS) + if (rv != MS_SUCCESS) return rv; /* RFC89 Apply Layer GeomTransform */ - if(layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE) { - rv = msGeomTransformShape(layer->map, layer, shape); - if(rv != MS_SUCCESS) + if (layer->_geomtransform.type != MS_GEOMTRANSFORM_NONE) { + rv = msGeomTransformShape(layer->map, layer, shape); + if (rv != MS_SUCCESS) return rv; } - if(layer->encoding) { - rv = msLayerEncodeShapeAttributes(layer,shape); - if(rv != MS_SUCCESS) + if (layer->encoding) { + rv = msLayerEncodeShapeAttributes(layer, shape); + if (rv != MS_SUCCESS) return rv; } @@ -429,21 +461,21 @@ int msLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) /* ** Returns the number of shapes that match the potential filter and extent. - * rectProjection is the projection in which rect is expressed, or can be NULL if - * rect should be considered in the layer projection. - * This should be equivalent to calling msLayerWhichShapes() and counting the - * number of shapes returned by msLayerNextShape(), honouring layer->maxfeatures - * limitation if layer->maxfeatures>=0, and honouring layer->startindex if - * layer->startindex >= 1 and paging is enabled. - * Returns -1 in case of failure. - */ -int msLayerGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProjection) -{ +* rectProjection is the projection in which rect is expressed, or can be NULL if +* rect should be considered in the layer projection. +* This should be equivalent to calling msLayerWhichShapes() and counting the +* number of shapes returned by msLayerNextShape(), honouring layer->maxfeatures +* limitation if layer->maxfeatures>=0, and honouring layer->startindex if +* layer->startindex >= 1 and paging is enabled. +* Returns -1 in case of failure. +*/ +int msLayerGetShapeCount(layerObj *layer, rectObj rect, + projectionObj *rectProjection) { int rv; - if( ! layer->vtable) { + if (!layer->vtable) { rv = msInitializeVirtualTable(layer); - if(rv != MS_SUCCESS) + if (rv != MS_SUCCESS) return -1; } cppcheck_assert(layer->vtable); @@ -451,21 +483,20 @@ int msLayerGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProje return layer->vtable->LayerGetShapeCount(layer, rect, rectProjection); } - /* ** Closes resources used by a particular layer. */ -void msLayerClose(layerObj *layer) -{ +void msLayerClose(layerObj *layer) { /* no need for items once the layer is closed */ msLayerFreeItemInfo(layer); - if(layer->items) { + if (layer->items) { msFreeCharArray(layer->items, layer->numitems); layer->items = NULL; layer->numitems = 0; } - /* clear out items used as part of expressions (bug #2702) -- what about the layer filter? */ + /* clear out items used as part of expressions (bug #2702) -- what about the + * layer filter? */ msLayerFreeExpressions(layer); if (layer->vtable) { @@ -477,43 +508,43 @@ void msLayerClose(layerObj *layer) /* ** Clear out items used as part of expressions. */ -void msLayerFreeExpressions(layerObj *layer) -{ - int i,j,k; +void msLayerFreeExpressions(layerObj *layer) { + int i, j, k; msFreeExpressionTokens(&(layer->filter)); msFreeExpressionTokens(&(layer->cluster.group)); msFreeExpressionTokens(&(layer->cluster.filter)); - for(i=0; inumclasses; i++) { - msFreeExpressionTokens(&(layer->class[i]->expression)); - msFreeExpressionTokens(&(layer->class[i]->text)); - for(j=0; jclass[i]->numstyles; j++) - msFreeExpressionTokens(&(layer->class[i]->styles[j]->_geomtransform)); - for(k=0; kclass[i]->numlabels; k++) { - msFreeExpressionTokens(&(layer->class[i]->labels[k]->expression)); - msFreeExpressionTokens(&(layer->class[i]->labels[k]->text)); + for (i = 0; i < layer->numclasses; i++) { + msFreeExpressionTokens(&(layer->class[i] -> expression)); + msFreeExpressionTokens(&(layer->class[i] -> text)); + for (j = 0; j < layer->class[i] -> numstyles; j++) + msFreeExpressionTokens(&(layer->class[i] -> styles[j] -> _geomtransform)); + for (k = 0; k < layer->class[i] -> numlabels; k++) { + msFreeExpressionTokens(&(layer->class[i] -> labels[k] -> expression)); + msFreeExpressionTokens(&(layer->class[i] -> labels[k] -> text)); } } } /* -** Retrieves a list of attributes available for this layer. Most sources also set the iteminfo array -** at this point. This function is used when processing query results to expose attributes to query +** Retrieves a list of attributes available for this layer. Most sources also +*set the iteminfo array +** at this point. This function is used when processing query results to expose +*attributes to query ** templates. At that point all attributes are fair game. */ -int msLayerGetItems(layerObj *layer) -{ +int msLayerGetItems(layerObj *layer) { const char *itemNames; /* clean up any previously allocated instances */ msLayerFreeItemInfo(layer); - if(layer->items) { + if (layer->items) { msFreeCharArray(layer->items, layer->numitems); layer->items = NULL; layer->numitems = 0; } - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -522,8 +553,9 @@ int msLayerGetItems(layerObj *layer) /* At the end of switch case (default -> break; -> return MS_FAILURE), * was following TODO ITEM: */ - /* TO DO! Need to add any joined itemd on to the core layer items, one long list! */ - itemNames = msLayerGetProcessingKey( layer, "ITEMS" ); + /* TO DO! Need to add any joined itemd on to the core layer items, one long + * list! */ + itemNames = msLayerGetProcessingKey(layer, "ITEMS"); if (itemNames) { layer->items = msStringSplit(itemNames, ',', &layer->numitems); /* populate the iteminfo array */ @@ -543,8 +575,7 @@ int msLayerGetItems(layerObj *layer) ** ** Returns MS_SUCCESS/MS_FAILURE. */ -int msLayerGetExtent(layerObj *layer, rectObj *extent) -{ +int msLayerGetExtent(layerObj *layer, rectObj *extent) { int need_to_close = MS_FALSE, status = MS_SUCCESS; if (MS_VALID_EXTENT(layer->extent)) { @@ -558,8 +589,8 @@ int msLayerGetExtent(layerObj *layer, rectObj *extent) need_to_close = MS_TRUE; } - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) { if (need_to_close) msLayerClose(layer); @@ -570,34 +601,33 @@ int msLayerGetExtent(layerObj *layer, rectObj *extent) status = layer->vtable->LayerGetExtent(layer, extent); if (status == MS_SUCCESS) { - layer->extent = *extent; + layer->extent = *extent; } if (need_to_close) msLayerClose(layer); - return(status); + return (status); } -int msLayerGetItemIndex(layerObj *layer, char *item) -{ +int msLayerGetItemIndex(layerObj *layer, char *item) { int i; - for(i=0; inumitems; i++) { - if(strcasecmp(layer->items[i], item) == 0) return(i); + for (i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], item) == 0) + return (i); } return -1; /* item not found */ } -static int string2list(char **list, int *listsize, char *string) -{ +static int string2list(char **list, int *listsize, char *string) { int i; - for(i=0; i<(*listsize); i++) { - if(strcasecmp(list[i], string) == 0) { + for (i = 0; i < (*listsize); i++) { + if (strcasecmp(list[i], string) == 0) { /* printf("string2list (duplicate): %s %d\n", string, i); */ - return(i); + return (i); } } @@ -606,7 +636,7 @@ static int string2list(char **list, int *listsize, char *string) /* printf("string2list: %s %d\n", string, i); */ - return(i); + return (i); } extern int msyylex(void); @@ -619,72 +649,118 @@ extern double msyynumber; /* token containers */ extern char *msyystring_buffer; const char *msExpressionTokenToString(int token) { - switch(token) { - case '(': return "("; - case ')': return ")"; - case ',': return ","; - case '+': return "+"; - case '-': return "-"; - case '/': return "/"; - case '*': return "*"; - case '%': return "%"; - - case MS_TOKEN_LOGICAL_AND: return " and "; - case MS_TOKEN_LOGICAL_OR: return " or "; - case MS_TOKEN_LOGICAL_NOT: return " not "; - - case MS_TOKEN_COMPARISON_EQ: return " = "; - case MS_TOKEN_COMPARISON_NE: return " != "; - case MS_TOKEN_COMPARISON_GT: return " > "; - case MS_TOKEN_COMPARISON_GE: return " >= "; - case MS_TOKEN_COMPARISON_LT: return " < "; - case MS_TOKEN_COMPARISON_LE: return " <= "; - case MS_TOKEN_COMPARISON_IEQ: return ""; - case MS_TOKEN_COMPARISON_RE: return " ~ "; - case MS_TOKEN_COMPARISON_IRE: return " ~* "; - case MS_TOKEN_COMPARISON_IN: return " in "; - case MS_TOKEN_COMPARISON_LIKE: return " like "; - - case MS_TOKEN_COMPARISON_INTERSECTS: return "intersects"; - case MS_TOKEN_COMPARISON_DISJOINT: return "disjoint"; - case MS_TOKEN_COMPARISON_TOUCHES: return "touches"; - case MS_TOKEN_COMPARISON_OVERLAPS: return "overlaps"; - case MS_TOKEN_COMPARISON_CROSSES: return "crosses"; - case MS_TOKEN_COMPARISON_WITHIN: return "within"; - case MS_TOKEN_COMPARISON_CONTAINS: return "contains"; - case MS_TOKEN_COMPARISON_EQUALS: return "equals"; - case MS_TOKEN_COMPARISON_BEYOND: return "beyond"; - case MS_TOKEN_COMPARISON_DWITHIN: return "dwithin"; - - case MS_TOKEN_FUNCTION_LENGTH: return "length"; - case MS_TOKEN_FUNCTION_TOSTRING: return "tostring"; - case MS_TOKEN_FUNCTION_COMMIFY: return "commify"; - case MS_TOKEN_FUNCTION_AREA: return "area"; - case MS_TOKEN_FUNCTION_ROUND: return "round"; - case MS_TOKEN_FUNCTION_BUFFER: return "buffer"; - case MS_TOKEN_FUNCTION_DIFFERENCE: return "difference"; - case MS_TOKEN_FUNCTION_SIMPLIFY: return "simplify"; - // case MS_TOKEN_FUNCTION_SIMPLIFYPT: - case MS_TOKEN_FUNCTION_GENERALIZE: return "generalize"; - default: return NULL; - } -} - -int msTokenizeExpression(expressionObj *expression, char **list, int *listsize) -{ + switch (token) { + case '(': + return "("; + case ')': + return ")"; + case ',': + return ","; + case '+': + return "+"; + case '-': + return "-"; + case '/': + return "/"; + case '*': + return "*"; + case '%': + return "%"; + + case MS_TOKEN_LOGICAL_AND: + return " and "; + case MS_TOKEN_LOGICAL_OR: + return " or "; + case MS_TOKEN_LOGICAL_NOT: + return " not "; + + case MS_TOKEN_COMPARISON_EQ: + return " = "; + case MS_TOKEN_COMPARISON_NE: + return " != "; + case MS_TOKEN_COMPARISON_GT: + return " > "; + case MS_TOKEN_COMPARISON_GE: + return " >= "; + case MS_TOKEN_COMPARISON_LT: + return " < "; + case MS_TOKEN_COMPARISON_LE: + return " <= "; + case MS_TOKEN_COMPARISON_IEQ: + return ""; + case MS_TOKEN_COMPARISON_RE: + return " ~ "; + case MS_TOKEN_COMPARISON_IRE: + return " ~* "; + case MS_TOKEN_COMPARISON_IN: + return " in "; + case MS_TOKEN_COMPARISON_LIKE: + return " like "; + + case MS_TOKEN_COMPARISON_INTERSECTS: + return "intersects"; + case MS_TOKEN_COMPARISON_DISJOINT: + return "disjoint"; + case MS_TOKEN_COMPARISON_TOUCHES: + return "touches"; + case MS_TOKEN_COMPARISON_OVERLAPS: + return "overlaps"; + case MS_TOKEN_COMPARISON_CROSSES: + return "crosses"; + case MS_TOKEN_COMPARISON_WITHIN: + return "within"; + case MS_TOKEN_COMPARISON_CONTAINS: + return "contains"; + case MS_TOKEN_COMPARISON_EQUALS: + return "equals"; + case MS_TOKEN_COMPARISON_BEYOND: + return "beyond"; + case MS_TOKEN_COMPARISON_DWITHIN: + return "dwithin"; + + case MS_TOKEN_FUNCTION_LENGTH: + return "length"; + case MS_TOKEN_FUNCTION_TOSTRING: + return "tostring"; + case MS_TOKEN_FUNCTION_COMMIFY: + return "commify"; + case MS_TOKEN_FUNCTION_AREA: + return "area"; + case MS_TOKEN_FUNCTION_ROUND: + return "round"; + case MS_TOKEN_FUNCTION_BUFFER: + return "buffer"; + case MS_TOKEN_FUNCTION_DIFFERENCE: + return "difference"; + case MS_TOKEN_FUNCTION_SIMPLIFY: + return "simplify"; + // case MS_TOKEN_FUNCTION_SIMPLIFYPT: + case MS_TOKEN_FUNCTION_GENERALIZE: + return "generalize"; + default: + return NULL; + } +} + +int msTokenizeExpression(expressionObj *expression, char **list, + int *listsize) { tokenListNodeObjPtr node; int token; - /* TODO: make sure the constants can't somehow reference invalid expression types */ - /* if(expression->type != MS_EXPRESSION && expression->type != MS_GEOMTRANSFORM_EXPRESSION) return MS_SUCCESS; */ + /* TODO: make sure the constants can't somehow reference invalid expression + * types */ + /* if(expression->type != MS_EXPRESSION && expression->type != + * MS_GEOMTRANSFORM_EXPRESSION) return MS_SUCCESS; */ msAcquireLock(TLOCK_PARSER); msyystate = MS_TOKENIZE_EXPRESSION; msyystring = expression->string; /* the thing we're tokenizing */ - while((token = msyylex()) != 0) { /* keep processing tokens until the end of the string (\0) */ + while ((token = msyylex()) != + 0) { /* keep processing tokens until the end of the string (\0) */ - if((node = (tokenListNodeObjPtr) malloc(sizeof(tokenListNodeObj))) == NULL) { + if ((node = (tokenListNodeObjPtr)malloc(sizeof(tokenListNodeObj))) == + NULL) { msSetError(MS_MEMERR, NULL, "msTokenizeExpression()"); goto parse_error; } @@ -694,86 +770,99 @@ int msTokenizeExpression(expressionObj *expression, char **list, int *listsize) node->tailifhead = NULL; node->next = NULL; - switch(token) { - case MS_TOKEN_LITERAL_BOOLEAN: - case MS_TOKEN_LITERAL_NUMBER: - node->token = token; - node->tokenval.dblval = msyynumber; - break; - case MS_TOKEN_LITERAL_STRING: - node->token = token; - node->tokenval.strval = msStrdup(msyystring_buffer); - break; - case MS_TOKEN_LITERAL_TIME: - node->tokensrc = msStrdup(msyystring_buffer); - node->token = token; - msTimeInit(&(node->tokenval.tmval)); - if(msParseTime(msyystring_buffer, &(node->tokenval.tmval)) != MS_TRUE) { - msSetError(MS_PARSEERR, "Parsing time value failed.", "msTokenizeExpression()"); - free(node); - goto parse_error; - } - break; - case MS_TOKEN_BINDING_DOUBLE: /* we've encountered an attribute (binding) reference */ - case MS_TOKEN_BINDING_INTEGER: - case MS_TOKEN_BINDING_STRING: - case MS_TOKEN_BINDING_TIME: - node->token = token; /* binding type */ - node->tokenval.bindval.item = msStrdup(msyystring_buffer); - if(list) node->tokenval.bindval.index = string2list(list, listsize, msyystring_buffer); - break; - case MS_TOKEN_BINDING_SHAPE: - node->token = token; - break; - case MS_TOKEN_BINDING_MAP_CELLSIZE: - node->token = token; - break; - case MS_TOKEN_BINDING_DATA_CELLSIZE: - node->token = token; - break; - case MS_TOKEN_FUNCTION_FROMTEXT: /* we want to process a shape from WKT once and not for every feature being evaluated */ - if((token = msyylex()) != 40) { /* ( */ - msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()"); - free(node); - goto parse_error; - } + switch (token) { + case MS_TOKEN_LITERAL_BOOLEAN: + case MS_TOKEN_LITERAL_NUMBER: + node->token = token; + node->tokenval.dblval = msyynumber; + break; + case MS_TOKEN_LITERAL_STRING: + node->token = token; + node->tokenval.strval = msStrdup(msyystring_buffer); + break; + case MS_TOKEN_LITERAL_TIME: + node->tokensrc = msStrdup(msyystring_buffer); + node->token = token; + msTimeInit(&(node->tokenval.tmval)); + if (msParseTime(msyystring_buffer, &(node->tokenval.tmval)) != MS_TRUE) { + msSetError(MS_PARSEERR, "Parsing time value failed.", + "msTokenizeExpression()"); + free(node); + goto parse_error; + } + break; + case MS_TOKEN_BINDING_DOUBLE: /* we've encountered an attribute (binding) + reference */ + case MS_TOKEN_BINDING_INTEGER: + case MS_TOKEN_BINDING_STRING: + case MS_TOKEN_BINDING_TIME: + node->token = token; /* binding type */ + node->tokenval.bindval.item = msStrdup(msyystring_buffer); + if (list) + node->tokenval.bindval.index = + string2list(list, listsize, msyystring_buffer); + break; + case MS_TOKEN_BINDING_SHAPE: + node->token = token; + break; + case MS_TOKEN_BINDING_MAP_CELLSIZE: + node->token = token; + break; + case MS_TOKEN_BINDING_DATA_CELLSIZE: + node->token = token; + break; + case MS_TOKEN_FUNCTION_FROMTEXT: /* we want to process a shape from WKT once + and not for every feature being + evaluated */ + if ((token = msyylex()) != 40) { /* ( */ + msSetError(MS_PARSEERR, "Parsing fromText function failed.", + "msTokenizeExpression()"); + free(node); + goto parse_error; + } - if((token = msyylex()) != MS_TOKEN_LITERAL_STRING) { - msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()"); - free(node); - goto parse_error; - } + if ((token = msyylex()) != MS_TOKEN_LITERAL_STRING) { + msSetError(MS_PARSEERR, "Parsing fromText function failed.", + "msTokenizeExpression()"); + free(node); + goto parse_error; + } - node->token = MS_TOKEN_LITERAL_SHAPE; - node->tokenval.shpval = msShapeFromWKT(msyystring_buffer); + node->token = MS_TOKEN_LITERAL_SHAPE; + node->tokenval.shpval = msShapeFromWKT(msyystring_buffer); - if(!node->tokenval.shpval) { - msSetError(MS_PARSEERR, "Parsing fromText function failed, WKT processing failed.", "msTokenizeExpression()"); - free(node); - goto parse_error; - } + if (!node->tokenval.shpval) { + msSetError(MS_PARSEERR, + "Parsing fromText function failed, WKT processing failed.", + "msTokenizeExpression()"); + free(node); + goto parse_error; + } - /* todo: perhaps process optional args (e.g. projection) */ + /* todo: perhaps process optional args (e.g. projection) */ - if((token = msyylex()) != 41) { /* ) */ - msSetError(MS_PARSEERR, "Parsing fromText function failed.", "msTokenizeExpression()"); - msFreeShape(node->tokenval.shpval); - free(node->tokenval.shpval); - free(node); - goto parse_error; - } - break; - default: - node->token = token; /* for everything else */ - break; + if ((token = msyylex()) != 41) { /* ) */ + msSetError(MS_PARSEERR, "Parsing fromText function failed.", + "msTokenizeExpression()"); + msFreeShape(node->tokenval.shpval); + free(node->tokenval.shpval); + free(node); + goto parse_error; + } + break; + default: + node->token = token; /* for everything else */ + break; } /* add node to token list */ - if(expression->tokens == NULL) { + if (expression->tokens == NULL) { expression->tokens = node; } else { - if(expression->tokens->tailifhead != NULL) /* this should never be NULL, but just in case */ - expression->tokens->tailifhead->next = node; /* put the node at the end of the list */ + if (expression->tokens->tailifhead != + NULL) /* this should never be NULL, but just in case */ + expression->tokens->tailifhead->next = + node; /* put the node at the end of the list */ } /* repoint the head of the list to the end - our new element @@ -792,114 +881,166 @@ int msTokenizeExpression(expressionObj *expression, char **list, int *listsize) return MS_FAILURE; } - -static void buildLayerItemList(layerObj *layer) -{ +static void buildLayerItemList(layerObj *layer) { int i, j, k, l; /* - ** build layer item list, compute item indexes for explicity item references (e.g. classitem) or item bindings + ** build layer item list, compute item indexes for explicity item references + *(e.g. classitem) or item bindings */ /* layer items */ - if(layer->classitem) layer->classitemindex = string2list(layer->items, &(layer->numitems), layer->classitem); - if(layer->filteritem) layer->filteritemindex = string2list(layer->items, &(layer->numitems), layer->filteritem); - if(layer->styleitem && (strcasecmp(layer->styleitem, "AUTO") != 0) && (strncasecmp(layer->styleitem, "javascript://",13) != 0)) - layer->styleitemindex = string2list(layer->items, &(layer->numitems), layer->styleitem); - if(layer->labelitem) layer->labelitemindex = string2list(layer->items, &(layer->numitems), layer->labelitem); - if(layer->utfitem) layer->utfitemindex = string2list(layer->items, &(layer->numitems), layer->utfitem); + if (layer->classitem) + layer->classitemindex = + string2list(layer->items, &(layer->numitems), layer->classitem); + if (layer->filteritem) + layer->filteritemindex = + string2list(layer->items, &(layer->numitems), layer->filteritem); + if (layer->styleitem && (strcasecmp(layer->styleitem, "AUTO") != 0) && + (strncasecmp(layer->styleitem, "javascript://", 13) != 0)) + layer->styleitemindex = + string2list(layer->items, &(layer->numitems), layer->styleitem); + if (layer->labelitem) + layer->labelitemindex = + string2list(layer->items, &(layer->numitems), layer->labelitem); + if (layer->utfitem) + layer->utfitemindex = + string2list(layer->items, &(layer->numitems), layer->utfitem); /* layer classes */ - for(i=0; inumclasses; i++) { - - if(layer->class[i]->expression.type == MS_EXPRESSION) /* class expression */ - msTokenizeExpression(&(layer->class[i]->expression), layer->items, &(layer->numitems)); + for (i = 0; i < layer->numclasses; i++) { + + if (layer->class[i] -> expression.type == + MS_EXPRESSION) /* class expression */ + msTokenizeExpression(&(layer->class[i] -> expression), layer->items, + &(layer->numitems)); /* class styles (items, bindings, geomtransform) */ - for(j=0; jclass[i]->numstyles; j++) { - if(layer->class[i]->styles[j]->rangeitem) - layer->class[i]->styles[j]->rangeitemindex = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->rangeitem); - for(k=0; kclass[i]->styles[j]->bindings[k].item) - layer->class[i]->styles[j]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->styles[j]->bindings[k].item); - if (layer->class[i]->styles[j]->exprBindings[k].type == MS_EXPRESSION) - { + for (j = 0; j < layer->class[i] -> numstyles; j++) { + if (layer->class[i] -> styles[j] -> rangeitem) + layer->class[i]->styles[j]->rangeitemindex = + string2list(layer->items, &(layer->numitems), + layer->class[i] -> styles[j] -> rangeitem); + for (k = 0; k < MS_STYLE_BINDING_LENGTH; k++) { + if (layer->class[i] -> styles[j] -> bindings[k].item) + layer->class[i]->styles[j]->bindings[k].index = + string2list(layer->items, &(layer->numitems), + layer->class[i] -> styles[j] -> bindings[k].item); + if (layer->class[i] -> styles[j] -> exprBindings[k].type == + MS_EXPRESSION) { msTokenizeExpression( - &(layer->class[i]->styles[j]->exprBindings[k]), - layer->items, &(layer->numitems)); + &(layer->class[i] -> styles[j] -> exprBindings[k]), layer->items, + &(layer->numitems)); } } - if(layer->class[i]->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) - msTokenizeExpression(&(layer->class[i]->styles[j]->_geomtransform), layer->items, &(layer->numitems)); + if (layer->class[i] -> styles[j] -> _geomtransform.type == + MS_GEOMTRANSFORM_EXPRESSION) + msTokenizeExpression(&(layer->class[i] -> styles[j] -> _geomtransform), + layer->items, &(layer->numitems)); } /* class labels and label styles (items, bindings, geomtransform) */ - for(l=0; lclass[i]->numlabels; l++) { - for(j=0; jclass[i]->labels[l]->numstyles; j++) { - if(layer->class[i]->labels[l]->styles[j]->rangeitem) - layer->class[i]->labels[l]->styles[j]->rangeitemindex = string2list(layer->items, &(layer->numitems), layer->class[i]->labels[l]->styles[j]->rangeitem); - for(k=0; kclass[i]->labels[l]->styles[j]->bindings[k].item) - layer->class[i]->labels[l]->styles[j]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->labels[l]->styles[j]->bindings[k].item); - if(layer->class[i]->labels[l]->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) - msTokenizeExpression(&(layer->class[i]->labels[l]->styles[j]->_geomtransform), layer->items, &(layer->numitems)); + for (l = 0; l < layer->class[i] -> numlabels; l++) { + for (j = 0; j < layer->class[i] -> labels[l] -> numstyles; j++) { + if (layer->class[i] -> labels[l] -> styles[j] -> rangeitem) + layer->class[i]->labels[l]->styles[j]->rangeitemindex = string2list( + layer->items, &(layer->numitems), + layer->class[i] -> labels[l] -> styles[j] -> rangeitem); + for (k = 0; k < MS_STYLE_BINDING_LENGTH; k++) { + if (layer->class[i] -> labels[l] -> styles[j] -> bindings[k].item) + layer->class[i]->labels[l]->styles[j]->bindings[k].index = + string2list(layer->items, &(layer->numitems), + layer->class[i] -> labels[l] -> styles[j] + -> bindings[k].item); + if (layer->class[i] -> labels[l] -> styles[j] + -> _geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) + msTokenizeExpression( + &(layer->class[i] -> labels[l] -> styles[j] -> _geomtransform), + layer->items, &(layer->numitems)); } } - for(k=0; kclass[i]->labels[l]->bindings[k].item) - layer->class[i]->labels[l]->bindings[k].index = string2list(layer->items, &(layer->numitems), layer->class[i]->labels[l]->bindings[k].item); - if (layer->class[i]->labels[l]->exprBindings[k].type == MS_EXPRESSION) - { + for (k = 0; k < MS_LABEL_BINDING_LENGTH; k++) { + if (layer->class[i] -> labels[l] -> bindings[k].item) + layer->class[i]->labels[l]->bindings[k].index = + string2list(layer->items, &(layer->numitems), + layer->class[i] -> labels[l] -> bindings[k].item); + if (layer->class[i] -> labels[l] -> exprBindings[k].type == + MS_EXPRESSION) { msTokenizeExpression( - &(layer->class[i]->labels[l]->exprBindings[k]), - layer->items, &(layer->numitems)); + &(layer->class[i] -> labels[l] -> exprBindings[k]), layer->items, + &(layer->numitems)); } } - /* label expression */ - if(layer->class[i]->labels[l]->expression.type == MS_EXPRESSION) msTokenizeExpression(&(layer->class[i]->labels[l]->expression), layer->items, &(layer->numitems)); + /* label expression */ + if (layer->class[i] -> labels[l] -> expression.type == MS_EXPRESSION) + msTokenizeExpression(&(layer->class[i] -> labels[l] -> expression), + layer->items, &(layer->numitems)); /* label text */ - if(layer->class[i]->labels[l]->text.type == MS_EXPRESSION || (layer->class[i]->labels[l]->text.string && strchr(layer->class[i]->labels[l]->text.string,'[') != NULL && strchr(layer->class[i]->labels[l]->text.string,']') != NULL)) - msTokenizeExpression(&(layer->class[i]->labels[l]->text), layer->items, &(layer->numitems)); + if (layer->class[i] -> labels[l] + -> text.type == MS_EXPRESSION || + (layer->class[i] -> labels[l] + -> text.string &&strchr( + layer->class[i] -> labels[l] -> text.string, '[') != + NULL && + strchr(layer->class[i] -> labels[l] -> text.string, + ']') != NULL)) + msTokenizeExpression(&(layer->class[i] -> labels[l] -> text), + layer->items, &(layer->numitems)); } /* class text */ - if(layer->class[i]->text.type == MS_EXPRESSION || (layer->class[i]->text.string && strchr(layer->class[i]->text.string,'[') != NULL && strchr(layer->class[i]->text.string,']') != NULL)) - msTokenizeExpression(&(layer->class[i]->text), layer->items, &(layer->numitems)); + if (layer->class[i] + -> text.type == MS_EXPRESSION || + (layer->class[i] + -> text.string &&strchr(layer->class[i] -> text.string, '[') != + NULL && + strchr(layer->class[i] -> text.string, ']') != NULL)) + msTokenizeExpression(&(layer->class[i] -> text), layer->items, + &(layer->numitems)); } /* layer filter */ - if(layer->filter.type == MS_EXPRESSION) msTokenizeExpression(&(layer->filter), layer->items, &(layer->numitems)); + if (layer->filter.type == MS_EXPRESSION) + msTokenizeExpression(&(layer->filter), layer->items, &(layer->numitems)); /* cluster expressions */ - if(layer->cluster.group.type == MS_EXPRESSION) msTokenizeExpression(&(layer->cluster.group), layer->items, &(layer->numitems)); - if(layer->cluster.filter.type == MS_EXPRESSION) msTokenizeExpression(&(layer->cluster.filter), layer->items, &(layer->numitems)); + if (layer->cluster.group.type == MS_EXPRESSION) + msTokenizeExpression(&(layer->cluster.group), layer->items, + &(layer->numitems)); + if (layer->cluster.filter.type == MS_EXPRESSION) + msTokenizeExpression(&(layer->cluster.filter), layer->items, + &(layer->numitems)); /* utfdata */ - if(layer->utfdata.type == MS_EXPRESSION || (layer->utfdata.string && strchr(layer->utfdata.string,'[') != NULL && strchr(layer->utfdata.string,']') != NULL)) { + if (layer->utfdata.type == MS_EXPRESSION || + (layer->utfdata.string && strchr(layer->utfdata.string, '[') != NULL && + strchr(layer->utfdata.string, ']') != NULL)) { msTokenizeExpression(&(layer->utfdata), layer->items, &(layer->numitems)); } } /* -** This function builds a list of items necessary to draw or query a particular layer by -** examining the contents of the various xxxxitem parameters and expressions. That list is +** This function builds a list of items necessary to draw or query a particular +*layer by +** examining the contents of the various xxxxitem parameters and expressions. +*That list is ** then used to set the iteminfo variable. */ -int msLayerWhichItems(layerObj *layer, int get_all, const char *metadata) -{ +int msLayerWhichItems(layerObj *layer, int get_all, const char *metadata) { int i, j, k, l, rv; - int nt=0; + int nt = 0; if (!layer->vtable) { - rv = msInitializeVirtualTable(layer); - if (rv != MS_SUCCESS) return rv; + rv = msInitializeVirtualTable(layer); + if (rv != MS_SUCCESS) + return rv; } cppcheck_assert(layer->vtable); /* Cleanup any previous item selection */ msLayerFreeItemInfo(layer); - if(layer->items) { + if (layer->items) { msFreeCharArray(layer->items, layer->numitems); layer->items = NULL; layer->numitems = 0; @@ -916,130 +1057,163 @@ int msLayerWhichItems(layerObj *layer, int get_all, const char *metadata) layer->labelitemindex = -1; layer->utfitemindex = -1; - if(layer->classitem) nt++; - if(layer->filteritem) nt++; - if(layer->styleitem && - (strcasecmp(layer->styleitem, "AUTO") != 0) && - (strncasecmp(layer->styleitem, "javascript://", 13) != 0)) nt++; - - if(layer->filter.type == MS_EXPRESSION) + if (layer->classitem) + nt++; + if (layer->filteritem) + nt++; + if (layer->styleitem && (strcasecmp(layer->styleitem, "AUTO") != 0) && + (strncasecmp(layer->styleitem, "javascript://", 13) != 0)) + nt++; + + if (layer->filter.type == MS_EXPRESSION) nt += msCountChars(layer->filter.string, '['); - if(layer->cluster.group.type == MS_EXPRESSION) + if (layer->cluster.group.type == MS_EXPRESSION) nt += msCountChars(layer->cluster.group.string, '['); - if(layer->cluster.filter.type == MS_EXPRESSION) + if (layer->cluster.filter.type == MS_EXPRESSION) nt += msCountChars(layer->cluster.filter.string, '['); - if(layer->labelitem) nt++; - if(layer->utfitem) nt++; + if (layer->labelitem) + nt++; + if (layer->utfitem) + nt++; - if(layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) - msTokenizeExpression(&layer->_geomtransform, layer->items, &(layer->numitems)); + if (layer->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) + msTokenizeExpression(&layer->_geomtransform, layer->items, + &(layer->numitems)); /* class level counts */ - for(i=0; inumclasses; i++) { + for (i = 0; i < layer->numclasses; i++) { - for(j=0; jclass[i]->numstyles; j++) { - if(layer->class[i]->styles[j]->rangeitem) nt++; + for (j = 0; j < layer->class[i] -> numstyles; j++) { + if (layer->class[i] -> styles[j] -> rangeitem) + nt++; nt += layer->class[i]->styles[j]->numbindings; - if(layer->class[i]->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) - nt += msCountChars(layer->class[i]->styles[j]->_geomtransform.string, '['); - for(k=0; kclass[i]->styles[j]->exprBindings[k].type == MS_EXPRESSION) - { - nt += msCountChars(layer->class[i]->styles[j]->exprBindings[k].string, '['); + if (layer->class[i] -> styles[j] -> _geomtransform.type == + MS_GEOMTRANSFORM_EXPRESSION) + nt += msCountChars( + layer->class[i] -> styles[j] -> _geomtransform.string, '['); + for (k = 0; k < MS_STYLE_BINDING_LENGTH; k++) { + if (layer->class[i] -> styles[j] -> exprBindings[k].type == + MS_EXPRESSION) { + nt += msCountChars( + layer->class[i] -> styles[j] -> exprBindings[k].string, '['); } } } - if(layer->class[i]->expression.type == MS_EXPRESSION) - nt += msCountChars(layer->class[i]->expression.string, '['); + if (layer->class[i] -> expression.type == MS_EXPRESSION) + nt += msCountChars(layer->class[i] -> expression.string, '['); - for(l=0; lclass[i]->numlabels; l++) { + for (l = 0; l < layer->class[i] -> numlabels; l++) { nt += layer->class[i]->labels[l]->numbindings; - for(j=0; jclass[i]->labels[l]->numstyles; j++) { - if(layer->class[i]->labels[l]->styles[j]->rangeitem) nt++; + for (j = 0; j < layer->class[i] -> labels[l] -> numstyles; j++) { + if (layer->class[i] -> labels[l] -> styles[j] -> rangeitem) + nt++; nt += layer->class[i]->labels[l]->styles[j]->numbindings; - if(layer->class[i]->labels[l]->styles[j]->_geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) - nt += msCountChars(layer->class[i]->labels[l]->styles[j]->_geomtransform.string, '['); + if (layer->class[i] -> labels[l] -> styles[j] + -> _geomtransform.type == MS_GEOMTRANSFORM_EXPRESSION) + nt += msCountChars(layer->class[i] -> labels[l] -> styles[j] + -> _geomtransform.string, + '['); } - for(k=0; kclass[i]->labels[l]->exprBindings[k].type == MS_EXPRESSION) - { - nt += msCountChars(layer->class[i]->labels[l]->exprBindings[k].string, '['); + for (k = 0; k < MS_LABEL_BINDING_LENGTH; k++) { + if (layer->class[i] -> labels[l] -> exprBindings[k].type == + MS_EXPRESSION) { + nt += msCountChars( + layer->class[i] -> labels[l] -> exprBindings[k].string, '['); } } - if(layer->class[i]->labels[l]->expression.type == MS_EXPRESSION) - nt += msCountChars(layer->class[i]->labels[l]->expression.string, '['); - if(layer->class[i]->labels[l]->text.type == MS_EXPRESSION || (layer->class[i]->labels[l]->text.string && strchr(layer->class[i]->labels[l]->text.string,'[') != NULL && strchr(layer->class[i]->labels[l]->text.string,']') != NULL)) - nt += msCountChars(layer->class[i]->labels[l]->text.string, '['); + if (layer->class[i] -> labels[l] -> expression.type == MS_EXPRESSION) + nt += msCountChars(layer->class[i] -> labels[l] -> expression.string, + '['); + if (layer->class[i] -> labels[l] + -> text.type == MS_EXPRESSION || + (layer->class[i] -> labels[l] + -> text.string &&strchr( + layer->class[i] -> labels[l] -> text.string, '[') != + NULL && + strchr(layer->class[i] -> labels[l] -> text.string, + ']') != NULL)) + nt += msCountChars(layer->class[i] -> labels[l] -> text.string, '['); } - if(layer->class[i]->text.type == MS_EXPRESSION || (layer->class[i]->text.string && strchr(layer->class[i]->text.string,'[') != NULL && strchr(layer->class[i]->text.string,']') != NULL)) - nt += msCountChars(layer->class[i]->text.string, '['); + if (layer->class[i] + -> text.type == MS_EXPRESSION || + (layer->class[i] + -> text.string &&strchr(layer->class[i] -> text.string, '[') != + NULL && + strchr(layer->class[i] -> text.string, ']') != NULL)) + nt += msCountChars(layer->class[i] -> text.string, '['); } /* utfgrid count */ - if(layer->utfdata.type == MS_EXPRESSION || (layer->utfdata.string && strchr(layer->utfdata.string,'[') != NULL && strchr(layer->utfdata.string,']') != NULL)) + if (layer->utfdata.type == MS_EXPRESSION || + (layer->utfdata.string && strchr(layer->utfdata.string, '[') != NULL && + strchr(layer->utfdata.string, ']') != NULL)) nt += msCountChars(layer->utfdata.string, '['); - // if we are using a GetMap request with a WMS filter we don't need to return all items + // if we are using a GetMap request with a WMS filter we don't need to return + // all items if (msOWSLookupMetadata(&(layer->metadata), "G", "wmsfilter_flag") != NULL) { - get_all = MS_FALSE; + get_all = MS_FALSE; } - if(metadata == NULL){ - // check item set by mapwfs.cpp to restrict the number of columns selected - metadata = msOWSLookupMetadata(&(layer->metadata), "G", "select_items"); - if (metadata) { - /* get only selected items */ - get_all = MS_FALSE; - } + if (metadata == NULL) { + // check item set by mapwfs.cpp to restrict the number of columns selected + metadata = msOWSLookupMetadata(&(layer->metadata), "G", "select_items"); + if (metadata) { + /* get only selected items */ + get_all = MS_FALSE; + } } /* always retrieve all items in some cases */ - if(layer->connectiontype == MS_INLINE || - (layer->map->outputformat && layer->map->outputformat->renderer == MS_RENDER_WITH_KML)) { + if (layer->connectiontype == MS_INLINE || + (layer->map->outputformat && + layer->map->outputformat->renderer == MS_RENDER_WITH_KML)) { get_all = MS_TRUE; } /* ** allocate space for the item list (worse case size) */ - if( get_all ) { + if (get_all) { rv = msLayerGetItems(layer); - if(nt > 0) /* need to realloc the array to accept the possible new items*/ - layer->items = (char **)msSmallRealloc(layer->items, sizeof(char *)*(layer->numitems + nt)); + if (nt > 0) /* need to realloc the array to accept the possible new items*/ + layer->items = (char **)msSmallRealloc( + layer->items, sizeof(char *) * (layer->numitems + nt)); } else { rv = layer->vtable->LayerCreateItems(layer, nt); } - if(rv != MS_SUCCESS) + if (rv != MS_SUCCESS) return rv; buildLayerItemList(layer); - if(metadata) { + if (metadata) { char **tokens; int n = 0; int j; tokens = msStringSplit(metadata, ',', &n); - if(tokens) { - for(i=0; inumitems; j++) { - if(strcasecmp(tokens[i], layer->items[j]) == 0) { + for (j = 0; j < layer->numitems; j++) { + if (strcasecmp(tokens[i], layer->items[j]) == 0) { bFound = 1; break; } } - if(!bFound) { + if (!bFound) { layer->numitems++; - layer->items = (char **)msSmallRealloc(layer->items, sizeof(char *)*(layer->numitems)); - layer->items[layer->numitems-1] = msStrdup(tokens[i]); + layer->items = (char **)msSmallRealloc( + layer->items, sizeof(char *) * (layer->numitems)); + layer->items[layer->numitems - 1] = msStrdup(tokens[i]); } } msFreeCharArray(tokens, n); @@ -1049,99 +1223,93 @@ int msLayerWhichItems(layerObj *layer, int get_all, const char *metadata) /* order of the layer->items array is consistent with it. This is */ /* important so that WFS DescribeFeatureType and GetFeature requests */ /* return items in the same order */ - if( !get_all && layer->numitems ) { - char** unsorted_items = layer->items; - int numitems = layer->numitems; - - /* Retrieve all items */ - layer->items = NULL; - layer->numitems = 0; - rv = msLayerGetItems(layer); - if( rv != MS_SUCCESS ) { - msFreeCharArray(unsorted_items, numitems); - return rv; - } + if (!get_all && layer->numitems) { + char **unsorted_items = layer->items; + int numitems = layer->numitems; + + /* Retrieve all items */ + layer->items = NULL; + layer->numitems = 0; + rv = msLayerGetItems(layer); + if (rv != MS_SUCCESS) { + msFreeCharArray(unsorted_items, numitems); + return rv; + } - /* Sort unsorted_items in the order of layer->items */ - char** sorted_items = (char **)msSmallMalloc(sizeof(char*) * numitems); - int num_sorted_items = 0; - for( i = 0; i < layer->numitems; i++ ) - { - if( layer->items[i] ) - { - for( j = 0; j < numitems; j++ ) - { - if( unsorted_items[j] && - strcasecmp(layer->items[i], unsorted_items[j]) == 0 ) - { - sorted_items[num_sorted_items] = layer->items[i]; - num_sorted_items ++; - - layer->items[i] = NULL; - msFree(unsorted_items[j]); - unsorted_items[j] = NULL; - break; - } - } + /* Sort unsorted_items in the order of layer->items */ + char **sorted_items = (char **)msSmallMalloc(sizeof(char *) * numitems); + int num_sorted_items = 0; + for (i = 0; i < layer->numitems; i++) { + if (layer->items[i]) { + for (j = 0; j < numitems; j++) { + if (unsorted_items[j] && + strcasecmp(layer->items[i], unsorted_items[j]) == 0) { + sorted_items[num_sorted_items] = layer->items[i]; + num_sorted_items++; + + layer->items[i] = NULL; + msFree(unsorted_items[j]); + unsorted_items[j] = NULL; + break; } + } } + } - /* Add items that are not returned by msLayerGetItems() (not sure if that can happen) */ - for( j = 0; j < numitems; j++ ) - { - if( unsorted_items[j] ) - { - sorted_items[num_sorted_items] = unsorted_items[j]; - num_sorted_items ++; - } + /* Add items that are not returned by msLayerGetItems() (not sure if that + * can happen) */ + for (j = 0; j < numitems; j++) { + if (unsorted_items[j]) { + sorted_items[num_sorted_items] = unsorted_items[j]; + num_sorted_items++; } + } - if(layer->numitems > 0) { - msFreeCharArray(layer->items, layer->numitems); - } - msFreeCharArray(unsorted_items, numitems); + if (layer->numitems > 0) { + msFreeCharArray(layer->items, layer->numitems); + } + msFreeCharArray(unsorted_items, numitems); - layer->items = sorted_items; - layer->numitems = numitems; + layer->items = sorted_items; + layer->numitems = numitems; - /* Re-run buildLayerItemList() with the now correctly sorted items */ - buildLayerItemList(layer); + /* Re-run buildLayerItemList() with the now correctly sorted items */ + buildLayerItemList(layer); } - } /* populate the iteminfo array */ - if(layer->numitems == 0) - return(MS_SUCCESS); + if (layer->numitems == 0) + return (MS_SUCCESS); - return(msLayerInitItemInfo(layer)); + return (msLayerInitItemInfo(layer)); } /* -** A helper function to set the items to be retrieved with a particular shape. Unused at the moment but will be used +** A helper function to set the items to be retrieved with a particular shape. +*Unused at the moment but will be used ** from within MapScript. Should not need modification. */ -int msLayerSetItems(layerObj *layer, char **items, int numitems) -{ +int msLayerSetItems(layerObj *layer, char **items, int numitems) { int i; /* Cleanup any previous item selection */ msLayerFreeItemInfo(layer); - if(layer->items) { + if (layer->items) { msFreeCharArray(layer->items, layer->numitems); layer->items = NULL; layer->numitems = 0; } /* now allocate and set the layer item parameters */ - layer->items = (char **)malloc(sizeof(char *)*numitems); - MS_CHECK_ALLOC(layer->items, sizeof(char *)*numitems, MS_FAILURE); + layer->items = (char **)malloc(sizeof(char *) * numitems); + MS_CHECK_ALLOC(layer->items, sizeof(char *) * numitems, MS_FAILURE); - for(i=0; iitems[i] = msStrdup(items[i]); layer->numitems = numitems; /* populate the iteminfo array */ - return(msLayerInitItemInfo(layer)); + return (msLayerInitItemInfo(layer)); } /* @@ -1152,10 +1320,10 @@ int msLayerSetItems(layerObj *layer, char **items, int numitems) ** twice. ** */ -int msLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* shape) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +int msLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, + shapeObj *shape) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -1168,37 +1336,38 @@ int msLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* sha ** with STYLEITEM "attribute" when rendering shapes. ** */ -int msLayerGetFeatureStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* shape) -{ - char* stylestring = NULL; - if (layer->styleitem && layer->styleitemindex >=0) { +int msLayerGetFeatureStyle(mapObj *map, layerObj *layer, classObj *c, + shapeObj *shape) { + char *stylestring = NULL; + if (layer->styleitem && layer->styleitemindex >= 0) { stylestring = msStrdup(shape->values[layer->styleitemindex]); - } - else if (layer->styleitem && strncasecmp(layer->styleitem,"javascript://",13) == 0) { + } else if (layer->styleitem && + strncasecmp(layer->styleitem, "javascript://", 13) == 0) { #ifdef USE_V8_MAPSCRIPT - char *filename = layer->styleitem+13; + char *filename = layer->styleitem + 13; if (!map->v8context) { msV8CreateContext(map); - if (!map->v8context) - { - msSetError(MS_V8ERR, "Unable to create v8 context.", "msLayerGetFeatureStyle()"); + if (!map->v8context) { + msSetError(MS_V8ERR, "Unable to create v8 context.", + "msLayerGetFeatureStyle()"); return MS_FAILURE; } } if (*filename == '\0') { - msSetError(MS_V8ERR, "Invalid javascript filename: \"%s\".", "msLayerGetFeatureStyle()", layer->styleitem); + msSetError(MS_V8ERR, "Invalid javascript filename: \"%s\".", + "msLayerGetFeatureStyle()", layer->styleitem); return MS_FAILURE; } - + stylestring = msV8GetFeatureStyle(map, filename, layer, shape); #else - msSetError(MS_V8ERR, "V8 Javascript support is not available.", "msLayerGetFeatureStyle()"); - return MS_FAILURE; + msSetError(MS_V8ERR, "V8 Javascript support is not available.", + "msLayerGetFeatureStyle()"); + return MS_FAILURE; #endif - } - else { /* unknown styleitem */ + } else { /* unknown styleitem */ return MS_FAILURE; } @@ -1206,32 +1375,36 @@ int msLayerGetFeatureStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* if (!stylestring) return MS_FAILURE; - if (strncasecmp(stylestring,"style",5) == 0) { + if (strncasecmp(stylestring, "style", 5) == 0) { resetClassStyle(c); c->layer = layer; if (msMaybeAllocateClassStyle(c, 0)) { free(stylestring); - return(MS_FAILURE); + return (MS_FAILURE); } msUpdateStyleFromString(c->styles[0], stylestring); - if(c->styles[0]->symbolname) { - if((c->styles[0]->symbol = msGetSymbolIndex(&(map->symbolset), c->styles[0]->symbolname, MS_TRUE)) == -1) { - msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class of layer %s.", "msLayerGetFeatureStyle()", - c->styles[0]->symbolname, layer->name); + if (c->styles[0]->symbolname) { + if ((c->styles[0]->symbol = msGetSymbolIndex( + &(map->symbolset), c->styles[0]->symbolname, MS_TRUE)) == -1) { + msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class of layer %s.", + "msLayerGetFeatureStyle()", c->styles[0]->symbolname, + layer->name); free(stylestring); return MS_FAILURE; } } - } else if (strncasecmp(stylestring,"class",5) == 0) { + } else if (strncasecmp(stylestring, "class", 5) == 0) { if (strcasestr(stylestring, " style ") != NULL) { /* reset style if stylestring contains style definitions */ resetClassStyle(c); c->layer = layer; } msUpdateClassFromString(c, stylestring); - } else if (strncasecmp(stylestring,"pen",3) == 0 || strncasecmp(stylestring,"brush",5) == 0 || - strncasecmp(stylestring,"symbol",6) == 0 || strncasecmp(stylestring,"label",5) == 0) { + } else if (strncasecmp(stylestring, "pen", 3) == 0 || + strncasecmp(stylestring, "brush", 5) == 0 || + strncasecmp(stylestring, "symbol", 6) == 0 || + strncasecmp(stylestring, "label", 5) == 0) { msOGRUpdateStyleFromString(map, layer, c, stylestring); } else { resetClassStyle(c); @@ -1241,62 +1414,60 @@ int msLayerGetFeatureStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* return MS_SUCCESS; } - /* Returns the number of inline feature of a layer */ -int msLayerGetNumFeatures(layerObj *layer) -{ - int need_to_close = MS_FALSE, result = -1; +int msLayerGetNumFeatures(layerObj *layer) { + int need_to_close = MS_FALSE, result = -1; - if (!msLayerIsOpen(layer)) { - if (msLayerOpen(layer) != MS_SUCCESS) - return result; - need_to_close = MS_TRUE; - } + if (!msLayerIsOpen(layer)) { + if (msLayerOpen(layer) != MS_SUCCESS) + return result; + need_to_close = MS_TRUE; + } - if (!layer->vtable) { - int rv = msInitializeVirtualTable(layer); - if (rv != MS_SUCCESS) - return result; - } - cppcheck_assert(layer->vtable); + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); + if (rv != MS_SUCCESS) + return result; + } + cppcheck_assert(layer->vtable); - result = layer->vtable->LayerGetNumFeatures(layer); + result = layer->vtable->LayerGetNumFeatures(layer); - if (need_to_close) - msLayerClose(layer); + if (need_to_close) + msLayerClose(layer); - return(result); + return (result); } -void -msLayerSetProcessingKey( layerObj *layer, const char *key, const char *value) +void msLayerSetProcessingKey(layerObj *layer, const char *key, + const char *value) { int len = strlen(key); int i; char *directive = NULL; - if( value != NULL ) { - directive = (char *) msSmallMalloc(strlen(key)+strlen(value)+2); - sprintf( directive, "%s=%s", key, value ); + if (value != NULL) { + directive = (char *)msSmallMalloc(strlen(key) + strlen(value) + 2); + sprintf(directive, "%s=%s", key, value); } - for( i = 0; i < layer->numprocessing; i++ ) { - if( strncasecmp( key, layer->processing[i], len ) == 0 - && layer->processing[i][len] == '=' ) { - free( layer->processing[i] ); + for (i = 0; i < layer->numprocessing; i++) { + if (strncasecmp(key, layer->processing[i], len) == 0 && + layer->processing[i][len] == '=') { + free(layer->processing[i]); /* ** Either replace the existing entry with a new one or ** clear the entry. */ - if( directive != NULL ) + if (directive != NULL) layer->processing[i] = directive; else { - layer->processing[i] = layer->processing[layer->numprocessing-1]; - layer->processing[layer->numprocessing-1] = NULL; + layer->processing[i] = layer->processing[layer->numprocessing - 1]; + layer->processing[layer->numprocessing - 1] = NULL; layer->numprocessing--; } return; @@ -1305,55 +1476,56 @@ msLayerSetProcessingKey( layerObj *layer, const char *key, const char *value) /* otherwise add the directive at the end. */ - if( directive != NULL ) { - msLayerAddProcessing( layer, directive ); - free( directive ); + if (directive != NULL) { + msLayerAddProcessing(layer, directive); + free(directive); } } -void msLayerSubstituteProcessing( layerObj *layer, const char *from, const char *to ) { +void msLayerSubstituteProcessing(layerObj *layer, const char *from, + const char *to) { int i; - for( i = 0; i < layer->numprocessing; i++ ) { - layer->processing[i] = msCaseReplaceSubstring(layer->processing[i], from, to); + for (i = 0; i < layer->numprocessing; i++) { + layer->processing[i] = + msCaseReplaceSubstring(layer->processing[i], from, to); } } -void msLayerAddProcessing( layerObj *layer, const char *directive ) +void msLayerAddProcessing(layerObj *layer, const char *directive) { layer->numprocessing++; - if( layer->numprocessing == 1 ) - layer->processing = (char **) msSmallMalloc(2*sizeof(char *)); + if (layer->numprocessing == 1) + layer->processing = (char **)msSmallMalloc(2 * sizeof(char *)); else - layer->processing = (char **) msSmallRealloc(layer->processing, sizeof(char*) * (layer->numprocessing+1) ); - layer->processing[layer->numprocessing-1] = msStrdup(directive); + layer->processing = (char **)msSmallRealloc( + layer->processing, sizeof(char *) * (layer->numprocessing + 1)); + layer->processing[layer->numprocessing - 1] = msStrdup(directive); layer->processing[layer->numprocessing] = NULL; } -const char *msLayerGetProcessing( const layerObj *layer, int proc_index) -{ +const char *msLayerGetProcessing(const layerObj *layer, int proc_index) { if (proc_index < 0 || proc_index >= layer->numprocessing) { - msSetError(MS_CHILDERR, "Invalid processing index.", "msLayerGetProcessing()"); + msSetError(MS_CHILDERR, "Invalid processing index.", + "msLayerGetProcessing()"); return NULL; } else { return layer->processing[proc_index]; } } -const char *msLayerGetProcessingKey( const layerObj *layer, const char *key ) -{ +const char *msLayerGetProcessingKey(const layerObj *layer, const char *key) { int i, len = strlen(key); - for( i = 0; i < layer->numprocessing; i++ ) { - if( strncasecmp(layer->processing[i],key,len) == 0 - && layer->processing[i][len] == '=' ) + for (i = 0; i < layer->numprocessing; i++) { + if (strncasecmp(layer->processing[i], key, len) == 0 && + layer->processing[i][len] == '=') return layer->processing[i] + len + 1; } return NULL; } - /************************************************************************/ /* msLayerGetMaxFeaturesToDraw */ /* */ @@ -1361,8 +1533,7 @@ const char *msLayerGetProcessingKey( const layerObj *layer, const char *key ) /* output format option. Used for vector layers to limit the */ /* number of fatures rendered. */ /************************************************************************/ -int msLayerGetMaxFeaturesToDraw(layerObj *layer, outputFormatObj *format) -{ +int msLayerGetMaxFeaturesToDraw(layerObj *layer, outputFormatObj *format) { int nMaxFeatures = -1; const char *pszTmp = NULL; if (layer) { @@ -1371,39 +1542,34 @@ int msLayerGetMaxFeaturesToDraw(layerObj *layer, outputFormatObj *format) if (pszTmp) nMaxFeatures = atoi(pszTmp); else { - pszTmp = msLookupHashTable(&layer->map->web.metadata, "maxfeaturestodraw"); + pszTmp = + msLookupHashTable(&layer->map->web.metadata, "maxfeaturestodraw"); if (pszTmp) nMaxFeatures = atoi(pszTmp); } } - if(format) { + if (format) { if (nMaxFeatures < 0) - nMaxFeatures = atoi(msGetOutputFormatOption( format, "maxfeaturestodraw", "-1")); + nMaxFeatures = + atoi(msGetOutputFormatOption(format, "maxfeaturestodraw", "-1")); } return nMaxFeatures; - } -int msLayerClearProcessing( layerObj *layer ) -{ +int msLayerClearProcessing(layerObj *layer) { if (layer->numprocessing > 0) { - msFreeCharArray( layer->processing, layer->numprocessing ); + msFreeCharArray(layer->processing, layer->numprocessing); layer->processing = NULL; layer->numprocessing = 0; } return layer->numprocessing; } - -int -makeTimeFilter(layerObj *lp, - const char *timestring, - const char *timefield, - const int addtimebacktics) -{ +int makeTimeFilter(layerObj *lp, const char *timestring, const char *timefield, + const int addtimebacktics) { char **atimes, **tokens = NULL; - int numtimes,i, ntmp = 0; + int numtimes, i, ntmp = 0; char *pszBuffer = NULL; int bOnlyExistingFilter = 0; @@ -1426,22 +1592,22 @@ makeTimeFilter(layerObj *lp, /* if the filter is set and it's a sting type, concatenate it with the time. If not just free it */ if (lp->filter.string && lp->filter.type == MS_STRING) { - pszBuffer = msStringConcatenate(pszBuffer, "(("); - pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); - pszBuffer = msStringConcatenate(pszBuffer, ") and "); + pszBuffer = msStringConcatenate(pszBuffer, "(("); + pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); + pszBuffer = msStringConcatenate(pszBuffer, ") and "); } else if (lp->filter.string && lp->filter.type == MS_EXPRESSION) { - char* pszExpressionString = msGetExpressionString(&(lp->filter)); - pszBuffer = msStringConcatenate(pszBuffer, "("); - pszBuffer = msStringConcatenate(pszBuffer, pszExpressionString); - pszBuffer = msStringConcatenate(pszBuffer, " and "); - msFree(pszExpressionString); + char *pszExpressionString = msGetExpressionString(&(lp->filter)); + pszBuffer = msStringConcatenate(pszBuffer, "("); + pszBuffer = msStringConcatenate(pszBuffer, pszExpressionString); + pszBuffer = msStringConcatenate(pszBuffer, " and "); + msFree(pszExpressionString); } else { - msFreeExpression(&lp->filter); + msFreeExpression(&lp->filter); } pszBuffer = msStringConcatenate(pszBuffer, "("); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "["); @@ -1449,29 +1615,28 @@ makeTimeFilter(layerObj *lp, if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "]"); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); - + pszBuffer = msStringConcatenate(pszBuffer, "`"); pszBuffer = msStringConcatenate(pszBuffer, " = "); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, (char *)timestring); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, ")"); - /* if there was a filter, It was concatenate with an And ans should be closed*/ + /* if there was a filter, It was concatenate with an And ans should be + * closed*/ if (lp->filter.string && - (lp->filter.type == MS_STRING || lp->filter.type == MS_EXPRESSION)) + (lp->filter.type == MS_STRING || lp->filter.type == MS_EXPRESSION)) pszBuffer = msStringConcatenate(pszBuffer, ")"); - msLoadExpressionString(&lp->filter, pszBuffer); if (pszBuffer) @@ -1481,7 +1646,7 @@ makeTimeFilter(layerObj *lp, atimes = msStringSplit(timestring, ',', &numtimes); if (atimes == NULL || numtimes < 1) { - msFreeCharArray(atimes,numtimes); + msFreeCharArray(atimes, numtimes); return MS_FALSE; } @@ -1494,7 +1659,7 @@ makeTimeFilter(layerObj *lp, added to the buffer */ bOnlyExistingFilter = 1; } else if (lp->filter.string && lp->filter.type == MS_EXPRESSION) { - char* pszExpressionString = msGetExpressionString(&(lp->filter)); + char *pszExpressionString = msGetExpressionString(&(lp->filter)); pszBuffer = msStringConcatenate(pszBuffer, "("); pszBuffer = msStringConcatenate(pszBuffer, pszExpressionString); pszBuffer = msStringConcatenate(pszBuffer, " and "); @@ -1504,11 +1669,11 @@ makeTimeFilter(layerObj *lp, msFreeExpression(&lp->filter); /* check to see if we have ranges by parsing the first entry */ - tokens = msStringSplit(atimes[0], '/', &ntmp); + tokens = msStringSplit(atimes[0], '/', &ntmp); if (ntmp == 2) { /* ranges */ msFreeCharArray(tokens, ntmp); - for (i=0; i 0 && bOnlyExistingFilter == 0) pszBuffer = msStringConcatenate(pszBuffer, " OR "); @@ -1519,7 +1684,7 @@ makeTimeFilter(layerObj *lp, pszBuffer = msStringConcatenate(pszBuffer, "("); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "["); @@ -1528,23 +1693,23 @@ makeTimeFilter(layerObj *lp, pszBuffer = msStringConcatenate(pszBuffer, "]"); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); pszBuffer = msStringConcatenate(pszBuffer, " >= "); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, tokens[0]); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, " AND "); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "["); @@ -1552,19 +1717,19 @@ makeTimeFilter(layerObj *lp, if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "]"); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); pszBuffer = msStringConcatenate(pszBuffer, " <= "); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, tokens[1]); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, ")"); } @@ -1575,7 +1740,7 @@ makeTimeFilter(layerObj *lp, } else if (ntmp == 1) { /* multiple times */ msFreeCharArray(tokens, ntmp); pszBuffer = msStringConcatenate(pszBuffer, "("); - for (i=0; i 0) pszBuffer = msStringConcatenate(pszBuffer, " OR "); @@ -1597,12 +1762,12 @@ makeTimeFilter(layerObj *lp, if (addtimebacktics) pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, atimes[i]); if (addtimebacktics) - pszBuffer = msStringConcatenate(pszBuffer, "`"); + pszBuffer = msStringConcatenate(pszBuffer, "`"); else - pszBuffer = msStringConcatenate(pszBuffer, "'"); + pszBuffer = msStringConcatenate(pszBuffer, "'"); pszBuffer = msStringConcatenate(pszBuffer, ")"); } pszBuffer = msStringConcatenate(pszBuffer, ")"); @@ -1617,7 +1782,8 @@ makeTimeFilter(layerObj *lp, /* load the string to the filter */ if (pszBuffer && strlen(pszBuffer) > 0) { - if(lp->filter.string && (lp->filter.type == MS_STRING || lp->filter.type == MS_EXPRESSION )) + if (lp->filter.string && + (lp->filter.type == MS_STRING || lp->filter.type == MS_EXPRESSION)) pszBuffer = msStringConcatenate(pszBuffer, ")"); /* if(lp->filteritem) @@ -1626,7 +1792,6 @@ makeTimeFilter(layerObj *lp, */ msLoadExpressionString(&lp->filter, pszBuffer); - } msFree(pszBuffer); return MS_TRUE; @@ -1637,10 +1802,9 @@ makeTimeFilter(layerObj *lp, **/ int msLayerSetTimeFilter(layerObj *layer, const char *timestring, - const char *timefield) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); + const char *timefield) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } @@ -1648,141 +1812,124 @@ int msLayerSetTimeFilter(layerObj *layer, const char *timestring, return layer->vtable->LayerSetTimeFilter(layer, timestring, timefield); } -int -msLayerMakeBackticsTimeFilter(layerObj *lp, const char *timestring, - const char *timefield) -{ +int msLayerMakeBackticsTimeFilter(layerObj *lp, const char *timestring, + const char *timefield) { return makeTimeFilter(lp, timestring, timefield, MS_TRUE); } -int -msLayerMakePlainTimeFilter(layerObj *lp, const char *timestring, - const char *timefield) -{ +int msLayerMakePlainTimeFilter(layerObj *lp, const char *timestring, + const char *timefield) { return makeTimeFilter(lp, timestring, timefield, MS_FALSE); } - /* * Dummies / default actions for layers */ -int LayerDefaultInitItemInfo(layerObj *layer) -{ +int LayerDefaultInitItemInfo(layerObj *layer) { (void)layer; return MS_SUCCESS; } -void LayerDefaultFreeItemInfo(layerObj *layer) -{ - (void)layer; -} +void LayerDefaultFreeItemInfo(layerObj *layer) { (void)layer; } -int LayerDefaultOpen(layerObj *layer) -{ +int LayerDefaultOpen(layerObj *layer) { (void)layer; return MS_FAILURE; } -int LayerDefaultIsOpen(layerObj *layer) -{ +int LayerDefaultIsOpen(layerObj *layer) { (void)layer; return MS_FALSE; } -int LayerDefaultWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int LayerDefaultWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)layer; (void)rect; (void)isQuery; return MS_SUCCESS; } -int LayerDefaultNextShape(layerObj *layer, shapeObj *shape) -{ +int LayerDefaultNextShape(layerObj *layer, shapeObj *shape) { (void)layer; (void)shape; return MS_FAILURE; } -int LayerDefaultGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ +int LayerDefaultGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { (void)layer; (void)shape; (void)record; return MS_FAILURE; } -int LayerDefaultGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProjection) -{ +int LayerDefaultGetShapeCount(layerObj *layer, rectObj rect, + projectionObj *rectProjection) { int status; shapeObj shape, searchshape; int nShapeCount = 0; rectObj searchrect = rect; - reprojectionObj* reprojector = NULL; + reprojectionObj *reprojector = NULL; msInitShape(&searchshape); msRectToPolygon(searchrect, &searchshape); - if( rectProjection != NULL ) - { - if(layer->project && msProjectionsDiffer(&(layer->projection), rectProjection)) - msProjectRect(rectProjection, &(layer->projection), &searchrect); /* project the searchrect to source coords */ + if (rectProjection != NULL) { + if (layer->project && + msProjectionsDiffer(&(layer->projection), rectProjection)) + msProjectRect(rectProjection, &(layer->projection), + &searchrect); /* project the searchrect to source coords */ else layer->project = MS_FALSE; } - status = msLayerWhichShapes(layer, searchrect, MS_TRUE) ; - if( status == MS_FAILURE ) - { + status = msLayerWhichShapes(layer, searchrect, MS_TRUE); + if (status == MS_FAILURE) { msFreeShape(&searchshape); return -1; - } - else if( status == MS_DONE ) - { + } else if (status == MS_DONE) { msFreeShape(&searchshape); return 0; } msInitShape(&shape); - while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) - { - if( rectProjection != NULL ) - { - if(layer->project && msProjectionsDiffer(&(layer->projection), rectProjection)) - { - if( reprojector == NULL ) - reprojector = msProjectCreateReprojector(&(layer->projection), rectProjection); - if( reprojector ) - msProjectShapeEx(reprojector, &shape); - } - else + while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { + if (rectProjection != NULL) { + if (layer->project && + msProjectionsDiffer(&(layer->projection), rectProjection)) { + if (reprojector == NULL) + reprojector = + msProjectCreateReprojector(&(layer->projection), rectProjection); + if (reprojector) + msProjectShapeEx(reprojector, &shape); + } else layer->project = MS_FALSE; - if(msRectContained(&shape.bounds, &rect) == MS_TRUE) { /* if the whole shape is in, don't intersect */ + if (msRectContained(&shape.bounds, &rect) == + MS_TRUE) { /* if the whole shape is in, don't intersect */ status = MS_TRUE; } else { - switch(shape.type) { /* make sure shape actually intersects the qrect (ADD FUNCTIONS SPECIFIC TO RECTOBJ) */ - case MS_SHAPE_POINT: - status = msIntersectMultipointPolygon(&shape, &searchshape); - break; - case MS_SHAPE_LINE: - status = msIntersectPolylinePolygon(&shape, &searchshape); - break; - case MS_SHAPE_POLYGON: - status = msIntersectPolygons(&shape, &searchshape); - break; - default: - break; + switch (shape.type) { /* make sure shape actually intersects the qrect + (ADD FUNCTIONS SPECIFIC TO RECTOBJ) */ + case MS_SHAPE_POINT: + status = msIntersectMultipointPolygon(&shape, &searchshape); + break; + case MS_SHAPE_LINE: + status = msIntersectPolylinePolygon(&shape, &searchshape); + break; + case MS_SHAPE_POLYGON: + status = msIntersectPolygons(&shape, &searchshape); + break; + default: + break; } } - } - else + } else status = MS_TRUE; - if( status == MS_TRUE ) - nShapeCount++ ; + if (status == MS_TRUE) + nShapeCount++; msFreeShape(&shape); - if(layer->maxfeatures > 0 && layer->maxfeatures == nShapeCount) + if (layer->maxfeatures > 0 && layer->maxfeatures == nShapeCount) break; } @@ -1792,48 +1939,46 @@ int LayerDefaultGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rect return nShapeCount; } -int LayerDefaultClose(layerObj *layer) -{ +int LayerDefaultClose(layerObj *layer) { (void)layer; return MS_SUCCESS; } -int LayerDefaultGetItems(layerObj *layer) -{ +int LayerDefaultGetItems(layerObj *layer) { (void)layer; return MS_SUCCESS; /* returning no items is legit */ } -int -msLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, - int iLayerIndex) -{ +int msLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex) { return FLTLayerApplyCondSQLFilterToLayer(psNode, map, iLayerIndex); } -int msLayerSupportsPaging(layerObj *layer) -{ - if (layer && - ((layer->connectiontype == MS_ORACLESPATIAL) || - (layer->connectiontype == MS_POSTGIS)) ) +int msLayerSupportsPaging(layerObj *layer) { + if (layer && ((layer->connectiontype == MS_ORACLESPATIAL) || + (layer->connectiontype == MS_POSTGIS))) return MS_TRUE; return MS_FALSE; } -int msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex); +int msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex); /* * msLayerSupportsSorting() * * Returns MS_TRUE if the layer supports sorting/ordering. */ -int msLayerSupportsSorting(layerObj *layer) -{ - if (layer && ( - (layer->connectiontype == MS_OGR) || (layer->connectiontype == MS_POSTGIS) || (layer->connectiontype == MS_ORACLESPATIAL) || ((layer->connectiontype == MS_PLUGIN) && (strstr(layer->plugin_library,"msplugin_oracle") != NULL)) || ((layer->connectiontype == MS_PLUGIN) && (strstr(layer->plugin_library,"msplugin_mssql2008") != NULL)) - ) - ) +int msLayerSupportsSorting(layerObj *layer) { + if (layer && + ((layer->connectiontype == MS_OGR) || + (layer->connectiontype == MS_POSTGIS) || + (layer->connectiontype == MS_ORACLESPATIAL) || + ((layer->connectiontype == MS_PLUGIN) && + (strstr(layer->plugin_library, "msplugin_oracle") != NULL)) || + ((layer->connectiontype == MS_PLUGIN) && + (strstr(layer->plugin_library, "msplugin_mssql2008") != NULL)))) return MS_TRUE; return MS_FALSE; @@ -1844,20 +1989,20 @@ int msLayerSupportsSorting(layerObj *layer) * * Copy the sortBy clause passed as an argument into the layer sortBy member. */ -void msLayerSetSort(layerObj *layer, const sortByClause* sortBy) -{ +void msLayerSetSort(layerObj *layer, const sortByClause *sortBy) { int i; - for(i=0;isortBy.nProperties;i++) + for (i = 0; i < layer->sortBy.nProperties; i++) msFree(layer->sortBy.properties[i].item); msFree(layer->sortBy.properties); layer->sortBy.nProperties = sortBy->nProperties; - layer->sortBy.properties = (sortByProperties*) msSmallMalloc(sortBy->nProperties * sizeof(sortByProperties)); - for(i=0;isortBy.nProperties;i++) { + layer->sortBy.properties = (sortByProperties *)msSmallMalloc( + sortBy->nProperties * sizeof(sortByProperties)); + for (i = 0; i < layer->sortBy.nProperties; i++) { layer->sortBy.properties[i].item = msStrdup(sortBy->properties[i].item); layer->sortBy.properties[i].sortOrder = sortBy->properties[i].sortOrder; } - } +} /* * msLayerBuildSQLOrderBy() @@ -1865,17 +2010,17 @@ void msLayerSetSort(layerObj *layer, const sortByClause* sortBy) * Returns the content of a SQL ORDER BY clause from the sortBy member of * the layer. The string does not contain the "ORDER BY" keywords itself. */ -char* msLayerBuildSQLOrderBy(layerObj *layer) -{ - char* strOrderBy = NULL; - if( layer->sortBy.nProperties > 0 ) { +char *msLayerBuildSQLOrderBy(layerObj *layer) { + char *strOrderBy = NULL; + if (layer->sortBy.nProperties > 0) { int i; - for(i=0;isortBy.nProperties;i++) { - char* escaped = msLayerEscapePropertyName(layer, layer->sortBy.properties[i].item); - if( i > 0 ) + for (i = 0; i < layer->sortBy.nProperties; i++) { + char *escaped = + msLayerEscapePropertyName(layer, layer->sortBy.properties[i].item); + if (i > 0) strOrderBy = msStringConcatenate(strOrderBy, ", "); strOrderBy = msStringConcatenate(strOrderBy, escaped); - if( layer->sortBy.properties[i].sortOrder == SORT_DESC ) + if (layer->sortBy.properties[i].sortOrder == SORT_DESC) strOrderBy = msStringConcatenate(strOrderBy, " DESC"); msFree(escaped); } @@ -1883,18 +2028,17 @@ char* msLayerBuildSQLOrderBy(layerObj *layer) return strOrderBy; } -int -msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex) -{ +int msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex) { return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex); } -int msLayerGetPaging(layerObj *layer) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +int msLayerGetPaging(layerObj *layer) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) { - msSetError(MS_MISCERR, "Unable to initialize virtual table", "msLayerGetPaging()"); + msSetError(MS_MISCERR, "Unable to initialize virtual table", + "msLayerGetPaging()"); return MS_FAILURE; } } @@ -1902,12 +2046,12 @@ int msLayerGetPaging(layerObj *layer) return layer->vtable->LayerGetPaging(layer); } -void msLayerEnablePaging(layerObj *layer, int value) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +void msLayerEnablePaging(layerObj *layer, int value) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) { - msSetError(MS_MISCERR, "Unable to initialize virtual table", "msLayerEnablePaging()"); + msSetError(MS_MISCERR, "Unable to initialize virtual table", + "msLayerEnablePaging()"); return; } } @@ -1915,52 +2059,48 @@ void msLayerEnablePaging(layerObj *layer, int value) layer->vtable->LayerEnablePaging(layer, value); } -/** Returns a cached reprojector from the layer projection to the map projection */ -reprojectionObj* msLayerGetReprojectorToMap(layerObj* layer, mapObj* map) -{ - if( layer->reprojectorLayerToMap != NULL && - !msProjectIsReprojectorStillValid(layer->reprojectorLayerToMap) ) - { +/** Returns a cached reprojector from the layer projection to the map projection + */ +reprojectionObj *msLayerGetReprojectorToMap(layerObj *layer, mapObj *map) { + if (layer->reprojectorLayerToMap != NULL && + !msProjectIsReprojectorStillValid(layer->reprojectorLayerToMap)) { msProjectDestroyReprojector(layer->reprojectorLayerToMap); layer->reprojectorLayerToMap = NULL; } - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); + if (layer->reprojectorLayerToMap == NULL) { + layer->reprojectorLayerToMap = + msProjectCreateReprojector(&layer->projection, &map->projection); } return layer->reprojectorLayerToMap; } - -int LayerDefaultGetExtent(layerObj *layer, rectObj *extent) -{ +int LayerDefaultGetExtent(layerObj *layer, rectObj *extent) { (void)layer; (void)extent; return MS_FAILURE; } -int LayerDefaultGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj *shape) -{ +int LayerDefaultGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, + shapeObj *shape) { (void)map; (void)layer; (void)c; (void)shape; - msSetError(MS_MISCERR, "'STYLEITEM AUTO' not supported for this data source.", "msLayerGetAutoStyle()"); + msSetError(MS_MISCERR, "'STYLEITEM AUTO' not supported for this data source.", + "msLayerGetAutoStyle()"); return MS_FAILURE; } -int LayerDefaultCloseConnection(layerObj *layer) -{ +int LayerDefaultCloseConnection(layerObj *layer) { (void)layer; return MS_SUCCESS; } -int LayerDefaultCreateItems(layerObj *layer, const int nt) -{ +int LayerDefaultCreateItems(layerObj *layer, const int nt) { if (nt > 0) { - layer->items = (char **)calloc(nt, sizeof(char *)); /* should be more than enough space */ + layer->items = (char **)calloc( + nt, sizeof(char *)); /* should be more than enough space */ MS_CHECK_ALLOC(layer->items, sizeof(char *), MS_FAILURE); layer->numitems = 0; @@ -1968,80 +2108,79 @@ int LayerDefaultCreateItems(layerObj *layer, const int nt) return MS_SUCCESS; } -int LayerDefaultGetNumFeatures(layerObj *layer) -{ - rectObj extent; - int status; - int result; - shapeObj shape; - - /* calculate layer extent */ - if (!MS_VALID_EXTENT(layer->extent)) { - if (msLayerGetExtent(layer, &extent) != MS_SUCCESS) { - msSetError(MS_MISCERR, "Unable to get layer extent", "LayerDefaultGetNumFeatures()"); - return -1; - } +int LayerDefaultGetNumFeatures(layerObj *layer) { + rectObj extent; + int status; + int result; + shapeObj shape; + + /* calculate layer extent */ + if (!MS_VALID_EXTENT(layer->extent)) { + if (msLayerGetExtent(layer, &extent) != MS_SUCCESS) { + msSetError(MS_MISCERR, "Unable to get layer extent", + "LayerDefaultGetNumFeatures()"); + return -1; } - else - extent = layer->extent; + } else + extent = layer->extent; - /* Cleanup any previous item selection */ - msLayerFreeItemInfo(layer); - if (layer->items) { - msFreeCharArray(layer->items, layer->numitems); - layer->items = NULL; - layer->numitems = 0; - } + /* Cleanup any previous item selection */ + msLayerFreeItemInfo(layer); + if (layer->items) { + msFreeCharArray(layer->items, layer->numitems); + layer->items = NULL; + layer->numitems = 0; + } - status = msLayerWhichShapes(layer, extent, MS_FALSE); - if (status == MS_DONE) { /* no overlap */ - return 0; - } - else if (status != MS_SUCCESS) { - return -1; - } + status = msLayerWhichShapes(layer, extent, MS_FALSE); + if (status == MS_DONE) { /* no overlap */ + return 0; + } else if (status != MS_SUCCESS) { + return -1; + } - result = 0; - while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { - ++result; - msFreeShape(&shape); - } + result = 0; + while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { + ++result; + msFreeShape(&shape); + } - return result; + return result; } -int LayerDefaultAutoProjection(layerObj *layer, projectionObj* projection) -{ +int LayerDefaultAutoProjection(layerObj *layer, projectionObj *projection) { (void)layer; (void)projection; - msSetError(MS_MISCERR, "This data driver does not implement AUTO projection support", "LayerDefaultAutoProjection()"); + msSetError(MS_MISCERR, + "This data driver does not implement AUTO projection support", + "LayerDefaultAutoProjection()"); return MS_FAILURE; } -int LayerDefaultSupportsCommonFilters(layerObj *layer) -{ +int LayerDefaultSupportsCommonFilters(layerObj *layer) { (void)layer; return MS_FALSE; } -int LayerDefaultTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ +int LayerDefaultTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { (void)layer; (void)filteritem; - if(!filter->string) return MS_SUCCESS; /* nothing to do, not an error */ + if (!filter->string) + return MS_SUCCESS; /* nothing to do, not an error */ - msSetError(MS_MISCERR, "This data driver does not implement filter translation support", "LayerDefaultTranslateFilter()"); + msSetError(MS_MISCERR, + "This data driver does not implement filter translation support", + "LayerDefaultTranslateFilter()"); return MS_FAILURE; } -int msLayerDefaultGetPaging(layerObj *layer) -{ +int msLayerDefaultGetPaging(layerObj *layer) { (void)layer; return MS_FALSE; } -void msLayerDefaultEnablePaging(layerObj *layer, int value) -{ +void msLayerDefaultEnablePaging(layerObj *layer, int value) { (void)layer; (void)value; } @@ -2053,17 +2192,16 @@ void msLayerDefaultEnablePaging(layerObj *layer, int value) /* injection. Specific drivers should redefine if an escaping */ /* function is available in the driver. */ /************************************************************************/ -char *LayerDefaultEscapeSQLParam(layerObj *layer, const char* pszString) -{ +char *LayerDefaultEscapeSQLParam(layerObj *layer, const char *pszString) { (void)layer; - char *pszEscapedStr=NULL; + char *pszEscapedStr = NULL; if (pszString) { int nSrcLen; char c; - int i=0, j=0; + int i = 0, j = 0; nSrcLen = (int)strlen(pszString); - pszEscapedStr = (char*) msSmallMalloc( 2 * nSrcLen + 1); - for(i = 0, j = 0; i < nSrcLen; i++) { + pszEscapedStr = (char *)msSmallMalloc(2 * nSrcLen + 1); + for (i = 0, j = 0; i < nSrcLen; i++) { c = pszString[i]; if (c == '\'') { pszEscapedStr[j++] = '\''; @@ -2084,22 +2222,21 @@ char *LayerDefaultEscapeSQLParam(layerObj *layer, const char* pszString) /* */ /* Return the property name in a properly escaped and quoted form. */ /************************************************************************/ -char *LayerDefaultEscapePropertyName(layerObj *layer, const char* pszString) -{ - char* pszEscapedStr=NULL; +char *LayerDefaultEscapePropertyName(layerObj *layer, const char *pszString) { + char *pszEscapedStr = NULL; int i, j = 0; if (layer && pszString && strlen(pszString) > 0) { int nLength = strlen(pszString); - pszEscapedStr = (char*) msSmallMalloc( 1 + 2 * nLength + 1 + 1); + pszEscapedStr = (char *)msSmallMalloc(1 + 2 * nLength + 1 + 1); pszEscapedStr[j++] = '"'; - for (i=0; iconnectiontype = connectiontype; /* For internal types, library_str is ignored */ if (connectiontype == MS_PLUGIN) { @@ -2135,17 +2268,15 @@ int msConnectLayer(layerObj *layer, layer->plugin_library_original = msStrdup(library_str); rv = msBuildPluginLibraryPath(&layer->plugin_library, - layer->plugin_library_original, - layer->map); + layer->plugin_library_original, layer->map); if (rv != MS_SUCCESS) { return rv; } } - return msInitializeVirtualTable(layer) ; + return msInitializeVirtualTable(layer); } -static int populateVirtualTable(layerVTableObj *vtable) -{ +static int populateVirtualTable(layerVTableObj *vtable) { assert(vtable != NULL); vtable->LayerSupportsCommonFilters = LayerDefaultSupportsCommonFilters; @@ -2187,94 +2318,92 @@ static int populateVirtualTable(layerVTableObj *vtable) return MS_SUCCESS; } -static int createVirtualTable(layerVTableObj **vtable) -{ +static int createVirtualTable(layerVTableObj **vtable) { *vtable = malloc(sizeof(**vtable)); MS_CHECK_ALLOC(*vtable, sizeof(**vtable), MS_FAILURE); return populateVirtualTable(*vtable); } -static int destroyVirtualTable(layerVTableObj **vtable) -{ +static int destroyVirtualTable(layerVTableObj **vtable) { memset(*vtable, 0, sizeof(**vtable)); msFree(*vtable); *vtable = NULL; return MS_SUCCESS; } -int msInitializeVirtualTable(layerObj *layer) -{ +int msInitializeVirtualTable(layerObj *layer) { if (layer->vtable) { destroyVirtualTable(&layer->vtable); } createVirtualTable(&layer->vtable); - if(layer->features && layer->connectiontype != MS_GRATICULE ) + if (layer->features && layer->connectiontype != MS_GRATICULE) layer->connectiontype = MS_INLINE; - if(layer->tileindex && layer->connectiontype == MS_SHAPEFILE) + if (layer->tileindex && layer->connectiontype == MS_SHAPEFILE) layer->connectiontype = MS_TILED_SHAPEFILE; - if(layer->type == MS_LAYER_RASTER && layer->connectiontype != MS_WMS - && layer->connectiontype != MS_KERNELDENSITY) + if (layer->type == MS_LAYER_RASTER && layer->connectiontype != MS_WMS && + layer->connectiontype != MS_KERNELDENSITY) layer->connectiontype = MS_RASTER; - switch(layer->connectiontype) { - case(MS_INLINE): - return(msINLINELayerInitializeVirtualTable(layer)); - break; - case(MS_SHAPEFILE): - return(msSHPLayerInitializeVirtualTable(layer)); - break; - case(MS_TILED_SHAPEFILE): - return(msTiledSHPLayerInitializeVirtualTable(layer)); - break; - case(MS_OGR): - return(msOGRLayerInitializeVirtualTable(layer)); - break; - case(MS_FLATGEOBUF): - return(msFlatGeobufLayerInitializeVirtualTable(layer)); - break; - case(MS_POSTGIS): - return(msPostGISLayerInitializeVirtualTable(layer)); - break; - case(MS_WMS): - /* WMS should be treated as a raster layer */ - return(msRASTERLayerInitializeVirtualTable(layer)); - break; - case(MS_KERNELDENSITY): - /* KERNELDENSITY should be treated as a raster layer */ - return(msRASTERLayerInitializeVirtualTable(layer)); - break; - case(MS_ORACLESPATIAL): - return(msOracleSpatialLayerInitializeVirtualTable(layer)); - break; - case(MS_WFS): - return(msWFSLayerInitializeVirtualTable(layer)); - break; - case(MS_GRATICULE): - return(msGraticuleLayerInitializeVirtualTable(layer)); - break; - case(MS_RASTER): - return(msRASTERLayerInitializeVirtualTable(layer)); - break; - case(MS_PLUGIN): - return(msPluginLayerInitializeVirtualTable(layer)); - break; - case(MS_UNION): - return(msUnionLayerInitializeVirtualTable(layer)); - break; - case(MS_UVRASTER): - return(msUVRASTERLayerInitializeVirtualTable(layer)); - break; - case(MS_CONTOUR): - return(msContourLayerInitializeVirtualTable(layer)); - break; - default: - msSetError(MS_MISCERR, "Unknown connectiontype, it was %d", "msInitializeVirtualTable()", layer->connectiontype); - return MS_FAILURE; - break; + switch (layer->connectiontype) { + case (MS_INLINE): + return (msINLINELayerInitializeVirtualTable(layer)); + break; + case (MS_SHAPEFILE): + return (msSHPLayerInitializeVirtualTable(layer)); + break; + case (MS_TILED_SHAPEFILE): + return (msTiledSHPLayerInitializeVirtualTable(layer)); + break; + case (MS_OGR): + return (msOGRLayerInitializeVirtualTable(layer)); + break; + case (MS_FLATGEOBUF): + return (msFlatGeobufLayerInitializeVirtualTable(layer)); + break; + case (MS_POSTGIS): + return (msPostGISLayerInitializeVirtualTable(layer)); + break; + case (MS_WMS): + /* WMS should be treated as a raster layer */ + return (msRASTERLayerInitializeVirtualTable(layer)); + break; + case (MS_KERNELDENSITY): + /* KERNELDENSITY should be treated as a raster layer */ + return (msRASTERLayerInitializeVirtualTable(layer)); + break; + case (MS_ORACLESPATIAL): + return (msOracleSpatialLayerInitializeVirtualTable(layer)); + break; + case (MS_WFS): + return (msWFSLayerInitializeVirtualTable(layer)); + break; + case (MS_GRATICULE): + return (msGraticuleLayerInitializeVirtualTable(layer)); + break; + case (MS_RASTER): + return (msRASTERLayerInitializeVirtualTable(layer)); + break; + case (MS_PLUGIN): + return (msPluginLayerInitializeVirtualTable(layer)); + break; + case (MS_UNION): + return (msUnionLayerInitializeVirtualTable(layer)); + break; + case (MS_UVRASTER): + return (msUVRASTERLayerInitializeVirtualTable(layer)); + break; + case (MS_CONTOUR): + return (msContourLayerInitializeVirtualTable(layer)); + break; + default: + msSetError(MS_MISCERR, "Unknown connectiontype, it was %d", + "msInitializeVirtualTable()", layer->connectiontype); + return MS_FAILURE; + break; } /* not reached */ @@ -2288,53 +2417,49 @@ int msInitializeVirtualTable(layerObj *layer) typedef struct { rectObj searchrect; int is_relative; /* relative coordinates? */ -} -msINLINELayerInfo; +} msINLINELayerInfo; -int msINLINELayerIsOpen(layerObj *layer) -{ +int msINLINELayerIsOpen(layerObj *layer) { if (layer->layerinfo) - return(MS_TRUE); + return (MS_TRUE); else - return(MS_FALSE); + return (MS_FALSE); } -msINLINELayerInfo *msINLINECreateLayerInfo(void) -{ +msINLINELayerInfo *msINLINECreateLayerInfo(void) { msINLINELayerInfo *layerinfo = msSmallMalloc(sizeof(msINLINELayerInfo)); layerinfo->searchrect.minx = -1.0; layerinfo->searchrect.miny = -1.0; layerinfo->searchrect.maxx = -1.0; layerinfo->searchrect.maxy = -1.0; layerinfo->is_relative = MS_FALSE; - return layerinfo; + return layerinfo; } -int msINLINELayerOpen(layerObj *layer) -{ - msINLINELayerInfo *layerinfo; +int msINLINELayerOpen(layerObj *layer) { + msINLINELayerInfo *layerinfo; if (layer->layerinfo) { if (layer->debug) { msDebug("msINLINELayerOpen: Layer is already open!\n"); } - return MS_SUCCESS; /* already open */ + return MS_SUCCESS; /* already open */ } - + /* ** Initialize the layerinfo **/ layerinfo = msINLINECreateLayerInfo(); - - layer->currentfeature = layer->features; /* point to the begining of the feature list */ - layer->layerinfo = (void*)layerinfo; - - return(MS_SUCCESS); + layer->currentfeature = + layer->features; /* point to the begining of the feature list */ + + layer->layerinfo = (void *)layerinfo; + + return (MS_SUCCESS); } -int msINLINELayerClose(layerObj *layer) -{ +int msINLINELayerClose(layerObj *layer) { if (layer->layerinfo) { free(layer->layerinfo); layer->layerinfo = NULL; @@ -2343,43 +2468,47 @@ int msINLINELayerClose(layerObj *layer) return MS_SUCCESS; } -int msINLINELayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msINLINELayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)isQuery; - msINLINELayerInfo *layerinfo = NULL; - layerinfo = (msINLINELayerInfo*) layer->layerinfo; + msINLINELayerInfo *layerinfo = NULL; + layerinfo = (msINLINELayerInfo *)layer->layerinfo; layerinfo->searchrect = rect; - layerinfo->is_relative = (layer->transform != MS_FALSE && layer->transform != MS_TRUE); - + layerinfo->is_relative = + (layer->transform != MS_FALSE && layer->transform != MS_TRUE); + return MS_SUCCESS; } /* Author: Cristoph Spoerri and Sean Gillies */ -int msINLINELayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - int i=0; +int msINLINELayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { + int i = 0; featureListNodeObjPtr current; int shapeindex = record->shapeindex; /* only index necessary */ current = layer->features; - while (current!=NULL && i!=shapeindex) { + while (current != NULL && i != shapeindex) { i++; current = current->next; } if (current == NULL) { - msSetError(MS_SHPERR, "No inline feature with this index.", "msINLINELayerGetShape()"); + msSetError(MS_SHPERR, "No inline feature with this index.", + "msINLINELayerGetShape()"); return MS_FAILURE; } if (msCopyShape(&(current->shape), shape) != MS_SUCCESS) { - msSetError(MS_SHPERR, "Cannot retrieve inline shape. There some problem with the shape", "msINLINELayerGetShape()"); + msSetError( + MS_SHPERR, + "Cannot retrieve inline shape. There some problem with the shape", + "msINLINELayerGetShape()"); return MS_FAILURE; } /* check for the expected size of the values array */ if (layer->numitems > shape->numvalues) { - shape->values = (char **)msSmallRealloc(shape->values, sizeof(char *)*(layer->numitems)); + shape->values = (char **)msSmallRealloc(shape->values, + sizeof(char *) * (layer->numitems)); for (i = shape->numvalues; i < layer->numitems; i++) shape->values[i] = msStrdup(""); } @@ -2387,32 +2516,33 @@ int msINLINELayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) return MS_SUCCESS; } -int msINLINELayerNextShape(layerObj *layer, shapeObj *shape) -{ - msINLINELayerInfo *layerinfo = NULL; - shapeObj * s; - - layerinfo = (msINLINELayerInfo*) layer->layerinfo; - +int msINLINELayerNextShape(layerObj *layer, shapeObj *shape) { + msINLINELayerInfo *layerinfo = NULL; + shapeObj *s; + + layerinfo = (msINLINELayerInfo *)layer->layerinfo; + while (1) { - if( ! (layer->currentfeature)) { + if (!(layer->currentfeature)) { /* out of features */ - return(MS_DONE); + return (MS_DONE); } s = &(layer->currentfeature->shape); layer->currentfeature = layer->currentfeature->next; msComputeBounds(s); - if (layerinfo->is_relative || msRectOverlap(&s->bounds, &layerinfo->searchrect)) { - + if (layerinfo->is_relative || + msRectOverlap(&s->bounds, &layerinfo->searchrect)) { + msCopyShape(s, shape); /* check for the expected size of the values array */ if (layer->numitems > shape->numvalues) { int i; - shape->values = (char **)msSmallRealloc(shape->values, sizeof(char *)*(layer->numitems)); + shape->values = (char **)msSmallRealloc( + shape->values, sizeof(char *) * (layer->numitems)); for (i = shape->numvalues; i < layer->numitems; i++) shape->values[i] = msStrdup(""); shape->numvalues = layer->numitems; @@ -2420,14 +2550,12 @@ int msINLINELayerNextShape(layerObj *layer, shapeObj *shape) break; } - } - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msINLINELayerGetNumFeatures(layerObj *layer) -{ +int msINLINELayerGetNumFeatures(layerObj *layer) { int i = 0; featureListNodeObjPtr current; @@ -2439,15 +2567,12 @@ int msINLINELayerGetNumFeatures(layerObj *layer) return i; } - - /* Returns an escaped string */ -char *msLayerEscapeSQLParam(layerObj *layer, const char*pszString) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +char *msLayerEscapeSQLParam(layerObj *layer, const char *pszString) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return ""; } @@ -2455,10 +2580,9 @@ char *msLayerEscapeSQLParam(layerObj *layer, const char*pszString) return layer->vtable->LayerEscapeSQLParam(layer, pszString); } -char *msLayerEscapePropertyName(layerObj *layer, const char*pszString) -{ - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); +char *msLayerEscapePropertyName(layerObj *layer, const char *pszString) { + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return ""; } @@ -2466,10 +2590,7 @@ char *msLayerEscapePropertyName(layerObj *layer, const char*pszString) return layer->vtable->LayerEscapePropertyName(layer, pszString); } - -int -msINLINELayerInitializeVirtualTable(layerObj *layer) -{ +int msINLINELayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); @@ -2507,5 +2628,3 @@ msINLINELayerInitializeVirtualTable(layerObj *layer) return MS_SUCCESS; } - - diff --git a/maplegend.c b/maplegend.c index 1f1b84533f..781c082b62 100644 --- a/maplegend.c +++ b/maplegend.c @@ -29,57 +29,51 @@ #include "mapserver.h" - - #define PSF .8 #define VMARGIN 5 /* margin at top and bottom of legend graphic */ #define HMARGIN 5 /* margin at left and right of legend graphic */ - -static int msDrawGradientSymbol(rendererVTableObj* renderer, - imageObj* image_draw, - double x_center, - double y_center, - int width, - int height, - styleObj* style) -{ - unsigned char *r,*g,*b,*a; - symbolObj symbol; - rasterBufferObj* rb; - symbolStyleObj symbolStyle; - int ret; - - initSymbol(&symbol); - rb = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj)); - symbol.pixmap_buffer = rb; - rb->type = MS_BUFFER_BYTE_RGBA; - rb->width = width; - rb->height = height; - rb->data.rgba.row_step = rb->width * 4; - rb->data.rgba.pixel_step = 4; - rb->data.rgba.pixels = (unsigned char*)malloc( - rb->width*rb->height*4*sizeof(unsigned char)); - b = rb->data.rgba.b = &rb->data.rgba.pixels[0]; - g = rb->data.rgba.g = &rb->data.rgba.pixels[1]; - r = rb->data.rgba.r = &rb->data.rgba.pixels[2]; - a = rb->data.rgba.a = &rb->data.rgba.pixels[3]; - for( unsigned j = 0; j < rb->height; j++ ) - { - for( unsigned i = 0; i < rb->width; i++ ) - { - msValueToRange(style, style->minvalue + - (double)i / rb->width * (style->maxvalue - style->minvalue), MS_COLORSPACE_RGB); - b[4*(j * rb->width + i)] = style->color.blue; - g[4*(j * rb->width + i)] = style->color.green; - r[4*(j * rb->width + i)] = style->color.red; - a[4*(j * rb->width + i)] = style->color.alpha; - } +static int msDrawGradientSymbol(rendererVTableObj *renderer, + imageObj *image_draw, double x_center, + double y_center, int width, int height, + styleObj *style) { + unsigned char *r, *g, *b, *a; + symbolObj symbol; + rasterBufferObj *rb; + symbolStyleObj symbolStyle; + int ret; + + initSymbol(&symbol); + rb = (rasterBufferObj *)calloc(1, sizeof(rasterBufferObj)); + symbol.pixmap_buffer = rb; + rb->type = MS_BUFFER_BYTE_RGBA; + rb->width = width; + rb->height = height; + rb->data.rgba.row_step = rb->width * 4; + rb->data.rgba.pixel_step = 4; + rb->data.rgba.pixels = (unsigned char *)malloc(rb->width * rb->height * 4 * + sizeof(unsigned char)); + b = rb->data.rgba.b = &rb->data.rgba.pixels[0]; + g = rb->data.rgba.g = &rb->data.rgba.pixels[1]; + r = rb->data.rgba.r = &rb->data.rgba.pixels[2]; + a = rb->data.rgba.a = &rb->data.rgba.pixels[3]; + for (unsigned j = 0; j < rb->height; j++) { + for (unsigned i = 0; i < rb->width; i++) { + msValueToRange(style, + style->minvalue + (double)i / rb->width * + (style->maxvalue - style->minvalue), + MS_COLORSPACE_RGB); + b[4 * (j * rb->width + i)] = style->color.blue; + g[4 * (j * rb->width + i)] = style->color.green; + r[4 * (j * rb->width + i)] = style->color.red; + a[4 * (j * rb->width + i)] = style->color.alpha; } - INIT_SYMBOL_STYLE(symbolStyle); - ret = renderer->renderPixmapSymbol(image_draw, x_center, y_center, &symbol, &symbolStyle); - msFreeSymbol(&symbol); - return ret; + } + INIT_SYMBOL_STYLE(symbolStyle); + ret = renderer->renderPixmapSymbol(image_draw, x_center, y_center, &symbol, + &symbolStyle); + msFreeSymbol(&symbol); + return ret; } /* @@ -87,78 +81,84 @@ static int msDrawGradientSymbol(rendererVTableObj* renderer, * renderer specific drawing functions shouldn't be called directly, but through * this function */ -int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, - int width, int height, imageObj *image, int dstX, int dstY, - int scale_independant, class_hittest *hittest) -{ - int i, type, hasmarkersymbol, ret=MS_SUCCESS; +int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, int width, + int height, imageObj *image, int dstX, int dstY, + int scale_independant, class_hittest *hittest) { + int i, type, hasmarkersymbol, ret = MS_SUCCESS; double offset; - double polygon_contraction = 0.5; /* used to account for the width of a polygon's outline */ + double polygon_contraction = + 0.5; /* used to account for the width of a polygon's outline */ shapeObj box, zigzag; - lineObj box_line,zigzag_line; + lineObj box_line, zigzag_line; pointObj box_point[5], zigzag_point[4]; pointObj marker; char szPath[MS_MAXPATHLEN]; styleObj outline_style; imageObj *image_draw = image; rendererVTableObj *renderer; - outputFormatObj *transFormat = NULL, *altFormat=NULL; + outputFormatObj *transFormat = NULL, *altFormat = NULL; const char *alternativeFormatString = NULL; - if(!MS_RENDERER_PLUGIN(image->format)) { - msSetError(MS_MISCERR,"unsupported image format","msDrawLegendIcon()"); + if (!MS_RENDERER_PLUGIN(image->format)) { + msSetError(MS_MISCERR, "unsupported image format", "msDrawLegendIcon()"); return MS_FAILURE; } alternativeFormatString = msLayerGetProcessingKey(lp, "RENDERER"); - if (MS_RENDERER_PLUGIN(image_draw->format) && alternativeFormatString!=NULL && - (altFormat= msSelectOutputFormat(map, alternativeFormatString))) { + if (MS_RENDERER_PLUGIN(image_draw->format) && + alternativeFormatString != NULL && + (altFormat = msSelectOutputFormat(map, alternativeFormatString))) { msInitializeRendererVTable(altFormat); - image_draw = msImageCreate(image->width, image->height, - altFormat, image->imagepath, image->imageurl, map->resolution, map->defresolution, &map->imagecolor); + image_draw = msImageCreate( + image->width, image->height, altFormat, image->imagepath, + image->imageurl, map->resolution, map->defresolution, &map->imagecolor); image_draw->map = map; renderer = MS_IMAGE_RENDERER(image_draw); } else { renderer = MS_IMAGE_RENDERER(image_draw); if (lp->compositer && renderer->compositeRasterBuffer) { - image_draw = msImageCreate(image->width, image->height, - image->format, image->imagepath, image->imageurl, map->resolution, map->defresolution, NULL); + image_draw = msImageCreate(image->width, image->height, image->format, + image->imagepath, image->imageurl, + map->resolution, map->defresolution, NULL); if (!image_draw) { - msSetError(MS_MISCERR, "Unable to initialize temporary transparent image.", - "msDrawLegendIcon()"); + msSetError(MS_MISCERR, + "Unable to initialize temporary transparent image.", + "msDrawLegendIcon()"); return (MS_FAILURE); } image_draw->map = map; } } - - if(renderer->supports_clipping && MS_VALID_COLOR(map->legend.outlinecolor)) { + if (renderer->supports_clipping && MS_VALID_COLOR(map->legend.outlinecolor)) { /* keep GD specific code here for now as it supports clipping */ rectObj clip; clip.maxx = dstX + width - 1; - clip.maxy = dstY + height -1; + clip.maxy = dstY + height - 1; clip.minx = dstX; clip.miny = dstY; - renderer->setClip(image_draw,clip); + renderer->setClip(image_draw, clip); } - + /* if the class has a keyimage, treat it as a point layer * (the keyimage will be treated there) */ - if(theclass->keyimage != NULL) { + if (theclass->keyimage != NULL) { type = MS_LAYER_POINT; } else { - /* some polygon layers may be better drawn using zigzag if there is no fill */ + /* some polygon layers may be better drawn using zigzag if there is no fill + */ type = lp->type; - if(type == MS_LAYER_POLYGON) { + if (type == MS_LAYER_POLYGON) { type = MS_LAYER_LINE; - for(i=0; inumstyles; i++) { - if(MS_VALID_COLOR(theclass->styles[i]->color)) { /* there is a fill */ + for (i = 0; i < theclass->numstyles; i++) { + if (MS_VALID_COLOR(theclass->styles[i]->color)) { /* there is a fill */ type = MS_LAYER_POLYGON; } - if(MS_VALID_COLOR(theclass->styles[i]->outlinecolor)) { /* there is an outline */ - polygon_contraction = MS_MAX(polygon_contraction, theclass->styles[i]->width / 2.0); + if (MS_VALID_COLOR( + theclass->styles[i]->outlinecolor)) { /* there is an outline */ + polygon_contraction = + MS_MAX(polygon_contraction, theclass->styles[i]->width / 2.0); } } } @@ -183,180 +183,211 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, box.line[0].point[4].x = box.line[0].point[0].x; box.line[0].point[4].y = box.line[0].point[0].y; - - /* ** now draw the appropriate color/symbol/size combination */ /* Scalefactor will be infinity when SIZEUNITS is set in LAYER */ - if(lp->sizeunits != MS_PIXELS) { - lp->scalefactor = 1.0; + if (lp->sizeunits != MS_PIXELS) { + lp->scalefactor = 1.0; } - switch(type) { - case MS_LAYER_POINT: - marker.x = dstX + MS_NINT(width / 2.0); - marker.y = dstY + MS_NINT(height / 2.0); - if(theclass->keyimage != NULL) { - int symbolNum; - styleObj imgStyle; - symbolObj *symbol=NULL; - symbolNum = msAddImageSymbol(&(map->symbolset), msBuildPath(szPath, map->mappath, theclass->keyimage)); - if(symbolNum == -1) { - msSetError(MS_IMGERR, "Failed to open legend key image", "msCreateLegendIcon()"); - return(MS_FAILURE); - } + switch (type) { + case MS_LAYER_POINT: + marker.x = dstX + MS_NINT(width / 2.0); + marker.y = dstY + MS_NINT(height / 2.0); + if (theclass->keyimage != NULL) { + int symbolNum; + styleObj imgStyle; + symbolObj *symbol = NULL; + symbolNum = + msAddImageSymbol(&(map->symbolset), msBuildPath(szPath, map->mappath, + theclass->keyimage)); + if (symbolNum == -1) { + msSetError(MS_IMGERR, "Failed to open legend key image", + "msCreateLegendIcon()"); + return (MS_FAILURE); + } - symbol = map->symbolset.symbol[symbolNum]; + symbol = map->symbolset.symbol[symbolNum]; - initStyle(&imgStyle); - /*set size so that symbol will be scaled properly #3296*/ - if (width/symbol->sizex < height/symbol->sizey) - imgStyle.size = symbol->sizey*(width/symbol->sizex); - else - imgStyle.size = symbol->sizey*(height/symbol->sizey); + initStyle(&imgStyle); + /*set size so that symbol will be scaled properly #3296*/ + if (width / symbol->sizex < height / symbol->sizey) + imgStyle.size = symbol->sizey * (width / symbol->sizex); + else + imgStyle.size = symbol->sizey * (height / symbol->sizey); - if (imgStyle.size > imgStyle.maxsize) - imgStyle.maxsize = imgStyle.size; + if (imgStyle.size > imgStyle.maxsize) + imgStyle.maxsize = imgStyle.size; - imgStyle.symbol = symbolNum; - ret = msDrawMarkerSymbol(map ,image_draw,&marker,&imgStyle, 1.0); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - /* TO DO: we may want to handle this differently depending on the relative size of the keyimage */ - } else { - for(i=0; inumstyles; i++) { - if(!scale_independant && map->scaledenom > 0) { - styleObj *lp = theclass->styles[i]; - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; - } - if(hittest && hittest->stylehits[i].status == 0) continue; - ret = msDrawMarkerSymbol(map, image_draw, &marker, theclass->styles[i], lp->scalefactor * image->resolutionfactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + imgStyle.symbol = symbolNum; + ret = msDrawMarkerSymbol(map, image_draw, &marker, &imgStyle, 1.0); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + /* TO DO: we may want to handle this differently depending on the relative + * size of the keyimage */ + } else { + for (i = 0; i < theclass->numstyles; i++) { + if (!scale_independant && map->scaledenom > 0) { + styleObj *lp = theclass->styles[i]; + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } + if (hittest && hittest->stylehits[i].status == 0) + continue; + ret = msDrawMarkerSymbol(map, image_draw, &marker, theclass->styles[i], + lp->scalefactor * image->resolutionfactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } - break; - case MS_LAYER_LINE: - offset = 1; - /* To set the offset, we only check the size/width parameter of the first style */ - if (theclass->numstyles > 0) { - if (theclass->styles[0]->symbol > 0 && theclass->styles[0]->symbol < map->symbolset.numsymbols && - map->symbolset.symbol[theclass->styles[0]->symbol]->type != MS_SYMBOL_SIMPLE) - offset = theclass->styles[0]->size/2; - else - offset = theclass->styles[0]->width/2; + } + break; + case MS_LAYER_LINE: + offset = 1; + /* To set the offset, we only check the size/width parameter of the first + * style */ + if (theclass->numstyles > 0) { + if (theclass->styles[0]->symbol > 0 && + theclass->styles[0]->symbol < map->symbolset.numsymbols && + map->symbolset.symbol[theclass->styles[0]->symbol]->type != + MS_SYMBOL_SIMPLE) + offset = theclass->styles[0]->size / 2; + else + offset = theclass->styles[0]->width / 2; + } + msInitShape(&zigzag); + zigzag.line = &zigzag_line; + zigzag.numlines = 1; + zigzag.line[0].point = zigzag_point; + zigzag.line[0].numpoints = 4; + zigzag.type = MS_SHAPE_LINE; + + zigzag.line[0].point[0].x = dstX + offset; + zigzag.line[0].point[0].y = dstY + height - offset; + zigzag.line[0].point[1].x = dstX + MS_NINT(width / 3.0) - 1; + zigzag.line[0].point[1].y = dstY + offset; + zigzag.line[0].point[2].x = dstX + MS_NINT(2.0 * width / 3.0) - 1; + zigzag.line[0].point[2].y = dstY + height - offset; + zigzag.line[0].point[3].x = dstX + width - offset; + zigzag.line[0].point[3].y = dstY + offset; + + for (i = 0; i < theclass->numstyles; i++) { + if (!scale_independant && map->scaledenom > 0) { + styleObj *lp = theclass->styles[i]; + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } - msInitShape(&zigzag); - zigzag.line = &zigzag_line; - zigzag.numlines = 1; - zigzag.line[0].point = zigzag_point; - zigzag.line[0].numpoints = 4; - zigzag.type = MS_SHAPE_LINE; - - zigzag.line[0].point[0].x = dstX + offset; - zigzag.line[0].point[0].y = dstY + height - offset; - zigzag.line[0].point[1].x = dstX + MS_NINT(width / 3.0) - 1; - zigzag.line[0].point[1].y = dstY + offset; - zigzag.line[0].point[2].x = dstX + MS_NINT(2.0 * width / 3.0) - 1; - zigzag.line[0].point[2].y = dstY + height - offset; - zigzag.line[0].point[3].x = dstX + width - offset; - zigzag.line[0].point[3].y = dstY + offset; - - for(i=0; inumstyles; i++) { - if(!scale_independant && map->scaledenom > 0) { - styleObj *lp = theclass->styles[i]; - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; - } - if(hittest && hittest->stylehits[i].status == 0) continue; - if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE || - theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT || - theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - if (theclass->styles[i]->outlinewidth > 0) { - /* Swap the style contents to render the outline first, - * and then restore the style to render the interior of the line - */ - msOutlineRenderingPrepareStyle(theclass->styles[i], map, lp, image); - ret = msDrawLineSymbol(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor); - msOutlineRenderingRestoreStyle(theclass->styles[i], map, lp, image); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - } - ret = msDrawLineSymbol(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + if (hittest && hittest->stylehits[i].status == 0) + continue; + if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE || + theclass->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT || + theclass->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + if (theclass->styles[i]->outlinewidth > 0) { + /* Swap the style contents to render the outline first, + * and then restore the style to render the interior of the line + */ + msOutlineRenderingPrepareStyle(theclass->styles[i], map, lp, image); + ret = + msDrawLineSymbol(map, image_draw, &zigzag, theclass->styles[i], + lp->scalefactor * image_draw->resolutionfactor); + msOutlineRenderingRestoreStyle(theclass->styles[i], map, lp, image); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } - else { - if (theclass->styles[i]->outlinewidth > 0) { - /* Swap the style contents to render the outline first, - * and then restore the style to render the interior of the line - */ - msOutlineRenderingPrepareStyle(theclass->styles[i], map, lp, image); - ret = msDrawTransformedShape(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor); - msOutlineRenderingRestoreStyle(theclass->styles[i], map, lp, image); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - } - ret = msDrawTransformedShape(map, image_draw, &zigzag, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + ret = msDrawLineSymbol(map, image_draw, &zigzag, theclass->styles[i], + lp->scalefactor * image_draw->resolutionfactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + } else { + if (theclass->styles[i]->outlinewidth > 0) { + /* Swap the style contents to render the outline first, + * and then restore the style to render the interior of the line + */ + msOutlineRenderingPrepareStyle(theclass->styles[i], map, lp, image); + ret = msDrawTransformedShape( + map, image_draw, &zigzag, theclass->styles[i], + lp->scalefactor * image_draw->resolutionfactor); + msOutlineRenderingRestoreStyle(theclass->styles[i], map, lp, image); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } + ret = msDrawTransformedShape( + map, image_draw, &zigzag, theclass->styles[i], + lp->scalefactor * image_draw->resolutionfactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } + } - break; - case MS_LAYER_CIRCLE: - case MS_LAYER_RASTER: - case MS_LAYER_CHART: - case MS_LAYER_POLYGON: - for(i=0; inumstyles; i++) { - if(!scale_independant && map->scaledenom > 0) { - styleObj *lp = theclass->styles[i]; - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; - } - if(hittest && hittest->stylehits[i].status == 0) continue; - if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE || - theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT || - theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) { - - if (MS_VALID_COLOR(theclass->styles[i]->mincolor)) - { - ret = msDrawGradientSymbol(renderer, - image_draw, - dstX + width / 2., - dstY + height / 2.0, - width - 2 * polygon_contraction, - height - 2 * polygon_contraction, - theclass->styles[i]); - } - else - { - ret = msDrawShadeSymbol(map, image_draw, &box, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor); - } - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - } - else { - ret = msDrawTransformedShape(map, image_draw, &box, - theclass->styles[i], lp->scalefactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + break; + case MS_LAYER_CIRCLE: + case MS_LAYER_RASTER: + case MS_LAYER_CHART: + case MS_LAYER_POLYGON: + for (i = 0; i < theclass->numstyles; i++) { + if (!scale_independant && map->scaledenom > 0) { + styleObj *lp = theclass->styles[i]; + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; + } + if (hittest && hittest->stylehits[i].status == 0) + continue; + if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE || + theclass->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOINT || + theclass->styles[i]->_geomtransform.type == + MS_GEOMTRANSFORM_LABELPOLY) { + + if (MS_VALID_COLOR(theclass->styles[i]->mincolor)) { + ret = msDrawGradientSymbol( + renderer, image_draw, dstX + width / 2., dstY + height / 2.0, + width - 2 * polygon_contraction, height - 2 * polygon_contraction, + theclass->styles[i]); + } else { + ret = + msDrawShadeSymbol(map, image_draw, &box, theclass->styles[i], + lp->scalefactor * image_draw->resolutionfactor); } + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + } else { + ret = msDrawTransformedShape(map, image_draw, &box, theclass->styles[i], + lp->scalefactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } - break; - default: - return MS_FAILURE; - break; + } + break; + default: + return MS_FAILURE; + break; } /* end symbol drawing */ /* handle label styles */ - for(i=0; inumlabels; i++) { + for (i = 0; i < theclass->numlabels; i++) { labelObj *l = theclass->labels[i]; - if(!scale_independant && map->scaledenom > 0) { - if(msScaleInBounds(map->scaledenom, l->minscaledenom, l->maxscaledenom)) { + if (!scale_independant && map->scaledenom > 0) { + if (msScaleInBounds(map->scaledenom, l->minscaledenom, + l->maxscaledenom)) { int j; - for(j=0; jnumstyles; j++) { + for (j = 0; j < l->numstyles; j++) { styleObj *s = l->styles[j]; marker.x = dstX + MS_NINT(width / 2.0); marker.y = dstY + MS_NINT(height / 2.0); - if(s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { - ret = msDrawMarkerSymbol(map, image_draw, &marker, s, lp->scalefactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + if (s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { + ret = msDrawMarkerSymbol(map, image_draw, &marker, s, + lp->scalefactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } } } @@ -365,15 +396,16 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, /* handle "pure" text layers, i.e. layers with no symbology */ hasmarkersymbol = 0; - if(theclass->numstyles == 0) { - for(i=0; inumlabels; i++) { + if (theclass->numstyles == 0) { + for (i = 0; i < theclass->numlabels; i++) { labelObj *l = theclass->labels[i]; - if(!scale_independant && map->scaledenom > 0) { - if(msScaleInBounds(map->scaledenom, l->minscaledenom, l->maxscaledenom)) { + if (!scale_independant && map->scaledenom > 0) { + if (msScaleInBounds(map->scaledenom, l->minscaledenom, + l->maxscaledenom)) { int j; - for(j=0; jnumstyles; j++) { + for (j = 0; j < l->numstyles; j++) { styleObj *s = l->styles[j]; - if(s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { + if (s->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) { hasmarkersymbol = 1; } } @@ -384,33 +416,38 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, hasmarkersymbol = 1; } - if(!hasmarkersymbol && theclass->numlabels>0) { + if (!hasmarkersymbol && theclass->numlabels > 0) { textSymbolObj ts; pointObj textstartpt; marker.x = dstX + MS_NINT(width / 2.0); marker.y = dstY + MS_NINT(height / 2.0); initTextSymbol(&ts); - msPopulateTextSymbolForLabelAndString(&ts,theclass->labels[0],msStrdup("Az"),lp->scalefactor*image_draw->resolutionfactor,image_draw->resolutionfactor, duplicate_always); + msPopulateTextSymbolForLabelAndString( + &ts, theclass->labels[0], msStrdup("Az"), + lp->scalefactor * image_draw->resolutionfactor, + image_draw->resolutionfactor, duplicate_always); ts.label->size = height - 1; ts.rotation = 0; - ret = msComputeTextPath(map,&ts); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - textstartpt = get_metrics(&marker,MS_CC,ts.textpath,0,0,0,0,NULL); - ret = msDrawTextSymbol(map,image_draw, textstartpt, &ts); + ret = msComputeTextPath(map, &ts); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + textstartpt = get_metrics(&marker, MS_CC, ts.textpath, 0, 0, 0, 0, NULL); + ret = msDrawTextSymbol(map, image_draw, textstartpt, &ts); freeTextSymbol(&ts); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; } - /* handle an outline if necessary */ - if(MS_VALID_COLOR(map->legend.outlinecolor)) { + if (MS_VALID_COLOR(map->legend.outlinecolor)) { initStyle(&outline_style); outline_style.color = map->legend.outlinecolor; - ret = msDrawLineSymbol(map, image_draw, &box, &outline_style, image_draw->resolutionfactor); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + ret = msDrawLineSymbol(map, image_draw, &box, &outline_style, + image_draw->resolutionfactor); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; /* reset clipping rectangle */ - if(renderer->supports_clipping) + if (renderer->supports_clipping) renderer->resetClip(image_draw); } @@ -418,74 +455,84 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass, rendererVTableObj *renderer = MS_IMAGE_RENDERER(image); rendererVTableObj *altrenderer = MS_IMAGE_RENDERER(image_draw); rasterBufferObj rb; - memset(&rb,0,sizeof(rasterBufferObj)); - - ret = altrenderer->getRasterBufferHandle(image_draw,&rb); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - ret = renderer->mergeRasterBuffer(image,&rb,((lp->compositer)?lp->compositer->opacity*0.01:1.0),0,0,0,0,rb.width,rb.height); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + memset(&rb, 0, sizeof(rasterBufferObj)); + + ret = altrenderer->getRasterBufferHandle(image_draw, &rb); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + ret = renderer->mergeRasterBuffer( + image, &rb, ((lp->compositer) ? lp->compositer->opacity * 0.01 : 1.0), + 0, 0, 0, 0, rb.width, rb.height); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; /* - * hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain - * symbols that reference it. We want to remove those references before the altFormat is destroyed - * to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking + * hack to work around bug #3834: if we have use an alternate renderer, the + * symbolset may contain symbols that reference it. We want to remove those + * references before the altFormat is destroyed to avoid a segfault and/or a + * leak, and so the the main renderer doesn't pick the cache up thinking * it's for him. */ - for(i=0; isymbolset.numsymbols; i++) { - if (map->symbolset.symbol[i]!=NULL) { + for (i = 0; i < map->symbolset.numsymbols; i++) { + if (map->symbolset.symbol[i] != NULL) { symbolObj *s = map->symbolset.symbol[i]; - if(s->renderer == altrenderer) { + if (s->renderer == altrenderer) { altrenderer->freeSymbol(s); s->renderer = NULL; } } } - } else if(image != image_draw) { + } else if (image != image_draw) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image_draw); rasterBufferObj rb; - memset(&rb,0,sizeof(rasterBufferObj)); + memset(&rb, 0, sizeof(rasterBufferObj)); - ret = renderer->getRasterBufferHandle(image_draw,&rb); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; - ret = renderer->mergeRasterBuffer(image,&rb,((lp->compositer)?lp->compositer->opacity*0.01:1.0),0,0,0,0,rb.width,rb.height); - if(MS_UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup; + ret = renderer->getRasterBufferHandle(image_draw, &rb); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; + ret = renderer->mergeRasterBuffer( + image, &rb, ((lp->compositer) ? lp->compositer->opacity * 0.01 : 1.0), + 0, 0, 0, 0, rb.width, rb.height); + if (MS_UNLIKELY(ret == MS_FAILURE)) + goto legend_icon_cleanup; /* deref and possibly free temporary transparent output format. */ - msApplyOutputFormat( &transFormat, NULL, MS_NOOVERRIDE); - + msApplyOutputFormat(&transFormat, NULL, MS_NOOVERRIDE); } legend_icon_cleanup: - if(image != image_draw) { + if (image != image_draw) { msFreeImage(image_draw); } return ret; } -imageObj *msCreateLegendIcon(mapObj* map, layerObj* lp, classObj* class, int width, int height, int scale_independant) -{ +imageObj *msCreateLegendIcon(mapObj *map, layerObj *lp, classObj *class, + int width, int height, int scale_independant) { imageObj *image; outputFormatObj *format = NULL; rendererVTableObj *renderer = MS_MAP_RENDERER(map); - if( !renderer ) { + if (!renderer) { msSetError(MS_MISCERR, "invalid map outputformat", "msCreateLegendIcon()"); - return(NULL); + return (NULL); } /* ensure we have an image format representing the options for the legend */ msApplyOutputFormat(&format, map->outputformat, map->legend.transparent); - image = msImageCreate(width,height,format,map->web.imagepath, map->web.imageurl, - map->resolution, map->defresolution, &(map->legend.imagecolor)); + image = msImageCreate(width, height, format, map->web.imagepath, + map->web.imageurl, map->resolution, map->defresolution, + &(map->legend.imagecolor)); /* drop this reference to output format */ - msApplyOutputFormat( &format, NULL, MS_NOOVERRIDE); + msApplyOutputFormat(&format, NULL, MS_NOOVERRIDE); - if(image == NULL) { - msSetError(MS_IMGERR, "Unable to initialize image.","msCreateLegendIcon()"); - return(NULL); + if (image == NULL) { + msSetError(MS_IMGERR, "Unable to initialize image.", + "msCreateLegendIcon()"); + return (NULL); } image->map = map; @@ -495,13 +542,18 @@ imageObj *msCreateLegendIcon(mapObj* map, layerObj* lp, classObj* class, int wid /* Fev 2004 by AY) */ if (lp) { if (class) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLegendIcon(map, lp, class, width, height, image, 0, 0, scale_independant, NULL))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLegendIcon(map, lp, class, width, height, image, 0, + 0, scale_independant, NULL))) { msFreeImage(image); return NULL; } } else { - for (int i=0; inumclasses; i++) { - if(MS_UNLIKELY(MS_FAILURE == msDrawLegendIcon(map, lp, lp->class[i], width, height, image, 0, 0, scale_independant, NULL))) { + for (int i = 0; i < lp->numclasses; i++) { + if (MS_UNLIKELY(MS_FAILURE == msDrawLegendIcon(map, lp, lp->class[i], + width, height, image, 0, + 0, scale_independant, + NULL))) { msFreeImage(image); return NULL; } @@ -521,38 +573,39 @@ imageObj *msCreateLegendIcon(mapObj* map, layerObj* lp, classObj* class, int wid * MS_SUCCESS * MS_FAILURE */ -int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, int *size_y, - int *layer_index, int num_layers, map_hittest *hittest, - double resolutionfactor) -{ +int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, + int *size_y, int *layer_index, int num_layers, + map_hittest *hittest, double resolutionfactor) { int i, j; - int status, maxwidth=0, nLegendItems=0; + int status, maxwidth = 0, nLegendItems = 0; char *text; layerObj *lp; rectObj rect; - int current_layers=0; + int current_layers = 0; /* reset sizes */ *size_x = 0; *size_y = 0; /* enable scale-dependent calculations */ - if(!scale_independent) { + if (!scale_independent) { map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - status = msCalculateScale(map->extent, map->units, map->width, map->height, map->resolution, &map->scaledenom); - if(status != MS_SUCCESS) return MS_FAILURE; + status = msCalculateScale(map->extent, map->units, map->width, map->height, + map->resolution, &map->scaledenom); + if (status != MS_SUCCESS) + return MS_FAILURE; } /* * step through all map classes, and for each one that will be displayed * calculate the label size */ - if (layer_index != NULL && num_layers >0) - current_layers = num_layers; + if (layer_index != NULL && num_layers > 0) + current_layers = num_layers; else current_layers = map->numlayers; - for(i=0; i< current_layers; i++) { + for (i = 0; i < current_layers; i++) { int layerindex; if (layer_index != NULL && num_layers > 0) layerindex = layer_index[i]; @@ -561,36 +614,53 @@ int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, int *size_ lp = (GET_LAYER(map, layerindex)); - if((lp->status == MS_OFF && (layer_index == NULL || num_layers <= 0)) || (lp->type == MS_LAYER_QUERY)) /* skip it */ + if ((lp->status == MS_OFF && (layer_index == NULL || num_layers <= 0)) || + (lp->type == MS_LAYER_QUERY)) /* skip it */ continue; - if(hittest && hittest->layerhits[layerindex].status == 0) continue; + if (hittest && hittest->layerhits[layerindex].status == 0) + continue; - if(!scale_independent && map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (!scale_independent && map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } - for(j=lp->numclasses-1; j>=0; j--) { + for (j = lp->numclasses - 1; j >= 0; j--) { textSymbolObj ts; - text = lp->class[j]->title?lp->class[j]->title:lp->class[j]->name; /* point to the right legend text, title takes precedence */ - if(!text) continue; /* skip it */ + text = lp->class[j]->title + ? lp->class[j]->title + : lp->class[j]->name; /* point to the right legend text, title + takes precedence */ + if (!text) + continue; /* skip it */ /* skip the class if the classgroup is defined */ - if(lp->classgroup && (lp->class[j]->group == NULL || strcasecmp(lp->class[j]->group, lp->classgroup) != 0)) + if (lp->classgroup && + (lp->class[j] -> group == NULL || strcasecmp(lp->class[j] -> group, + lp -> classgroup) != 0)) continue; /* verify class scale */ - if(!scale_independent && map->scaledenom > 0) { - if((lp->class[j]->maxscaledenom > 0) && (map->scaledenom > lp->class[j]->maxscaledenom)) continue; - if((lp->class[j]->minscaledenom > 0) && (map->scaledenom <= lp->class[j]->minscaledenom)) continue; + if (!scale_independent && map->scaledenom > 0) { + if ((lp->class[j] -> maxscaledenom > 0) && + (map->scaledenom > lp->class[j] -> maxscaledenom)) + continue; + if ((lp->class[j] -> minscaledenom > 0) && + (map->scaledenom <= lp->class[j] -> minscaledenom)) + continue; } - if(hittest && hittest->layerhits[layerindex].classhits[j].status == 0) continue; + if (hittest && hittest->layerhits[layerindex].classhits[j].status == 0) + continue; - if(*text) { + if (*text) { initTextSymbol(&ts); - msPopulateTextSymbolForLabelAndString(&ts,&map->legend.label,msStrdup(text),resolutionfactor,resolutionfactor, 0); - if(MS_UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map,&ts,&rect))) { + msPopulateTextSymbolForLabelAndString(&ts, &map->legend.label, + msStrdup(text), resolutionfactor, + resolutionfactor, 0); + if (MS_UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map, &ts, &rect))) { freeTextSymbol(&ts); return MS_FAILURE; } @@ -607,11 +677,12 @@ int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, int *size_ /* Calculate the size of the legend: */ /* - account for the Y keyspacing */ - *size_y += (2*VMARGIN) + ((nLegendItems-1) * map->legend.keyspacingy); + *size_y += (2 * VMARGIN) + ((nLegendItems - 1) * map->legend.keyspacingy); /* - determine the legend width */ - *size_x = (2*HMARGIN) + maxwidth + map->legend.keyspacingx + map->legend.keysizex; + *size_x = + (2 * HMARGIN) + maxwidth + map->legend.keyspacingx + map->legend.keysizex; - if(*size_y <=0 || *size_x <=0) + if (*size_y <= 0 || *size_x <= 0) return MS_FAILURE; return MS_SUCCESS; @@ -627,11 +698,11 @@ int msLegendCalcSize(mapObj *map, int scale_independent, int *size_x, int *size_ ** and maxscale are ignored and layers that are currently out of scale still ** show up in the legend. */ -imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) -{ - int i,j,ret=MS_SUCCESS; /* loop counters */ +imageObj *msDrawLegend(mapObj *map, int scale_independent, + map_hittest *hittest) { + int i, j, ret = MS_SUCCESS; /* loop counters */ pointObj pnt; - int size_x, size_y=0; + int size_x, size_y = 0; layerObj *lp; rectObj rect; imageObj *image = NULL; @@ -642,78 +713,110 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) int height; textSymbolObj ts; int layerindex, classindex; - struct legend_struct* pred; + struct legend_struct *pred; }; typedef struct legend_struct legendlabel; - legendlabel *head=NULL,*cur=NULL; + legendlabel *head = NULL, *cur = NULL; - if(!MS_RENDERER_PLUGIN(map->outputformat)) { - msSetError(MS_MISCERR,"unsupported output format","msDrawLegend()"); + if (!MS_RENDERER_PLUGIN(map->outputformat)) { + msSetError(MS_MISCERR, "unsupported output format", "msDrawLegend()"); return NULL; } - if(msValidateContexts(map) != MS_SUCCESS) return NULL; /* make sure there are no recursive REQUIRES or LABELREQUIRES expressions */ - if(msLegendCalcSize(map, scale_independent, &size_x, &size_y, NULL, 0, hittest, map->resolution/map->defresolution) != MS_SUCCESS) return NULL; + if (msValidateContexts(map) != MS_SUCCESS) + return NULL; /* make sure there are no recursive REQUIRES or LABELREQUIRES + expressions */ + if (msLegendCalcSize(map, scale_independent, &size_x, &size_y, NULL, 0, + hittest, + map->resolution / map->defresolution) != MS_SUCCESS) + return NULL; /* * step through all map classes, and for each one that will be displayed * keep a reference to its label size and text */ - - for(i=0; inumlayers; i++) { + + for (i = 0; i < map->numlayers; i++) { lp = (GET_LAYER(map, map->layerorder[i])); - if((lp->status == MS_OFF) || (lp->type == MS_LAYER_QUERY)) /* skip it */ + if ((lp->status == MS_OFF) || (lp->type == MS_LAYER_QUERY)) /* skip it */ continue; - if(hittest && hittest->layerhits[map->layerorder[i]].status == 0) + if (hittest && hittest->layerhits[map->layerorder[i]].status == 0) continue; - if(!scale_independent && map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (!scale_independent && map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } - if(!scale_independent && lp->maxscaledenom <=0 && lp->minscaledenom <=0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if (!scale_independent && lp->maxscaledenom <= 0 && + lp->minscaledenom <= 0) { + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } - - /* set the scale factor so that scale dependant symbols are drawn in the legend with their default size */ - if(lp->sizeunits != MS_PIXELS) { + + /* set the scale factor so that scale dependant symbols are drawn in the + * legend with their default size */ + if (lp->sizeunits != MS_PIXELS) { map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - lp->scalefactor = (msInchesPerUnit(lp->sizeunits,0)/msInchesPerUnit(map->units,0)) / map->cellsize; + lp->scalefactor = + (msInchesPerUnit(lp->sizeunits, 0) / msInchesPerUnit(map->units, 0)) / + map->cellsize; } - for(j=lp->numclasses-1; j>=0; j--) { - text = lp->class[j]->title?lp->class[j]->title:lp->class[j]->name; /* point to the right legend text, title takes precedence */ - if(!text) continue; /* skip it */ + for (j = lp->numclasses - 1; j >= 0; j--) { + text = lp->class[j]->title + ? lp->class[j]->title + : lp->class[j]->name; /* point to the right legend text, title + takes precedence */ + if (!text) + continue; /* skip it */ /* skip the class if the classgroup is defined */ - if(lp->classgroup && (lp->class[j]->group == NULL || strcasecmp(lp->class[j]->group, lp->classgroup) != 0)) + if (lp->classgroup && + (lp->class[j] -> group == NULL || strcasecmp(lp->class[j] -> group, + lp -> classgroup) != 0)) continue; - if(!scale_independent && map->scaledenom > 0) { /* verify class scale here */ - if((lp->class[j]->maxscaledenom > 0) && (map->scaledenom > lp->class[j]->maxscaledenom)) continue; - if((lp->class[j]->minscaledenom > 0) && (map->scaledenom <= lp->class[j]->minscaledenom)) continue; + if (!scale_independent && + map->scaledenom > 0) { /* verify class scale here */ + if ((lp->class[j] -> maxscaledenom > 0) && + (map->scaledenom > lp->class[j] -> maxscaledenom)) + continue; + if ((lp->class[j] -> minscaledenom > 0) && + (map->scaledenom <= lp->class[j] -> minscaledenom)) + continue; } - if(hittest && hittest->layerhits[map->layerorder[i]].classhits[j].status == 0) { - continue; + if (hittest && + hittest->layerhits[map->layerorder[i]].classhits[j].status == 0) { + continue; } - cur = (legendlabel*) msSmallMalloc(sizeof(legendlabel)); + cur = (legendlabel *)msSmallMalloc(sizeof(legendlabel)); initTextSymbol(&cur->ts); - if(*text) { - msPopulateTextSymbolForLabelAndString(&cur->ts,&map->legend.label,msStrdup(text),map->resolution/map->defresolution,map->resolution/map->defresolution, 0); - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,&cur->ts))) { + if (*text) { + msPopulateTextSymbolForLabelAndString( + &cur->ts, &map->legend.label, msStrdup(text), + map->resolution / map->defresolution, + map->resolution / map->defresolution, 0); + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, &cur->ts))) { ret = MS_FAILURE; goto cleanup; } - if(MS_UNLIKELY(MS_FAILURE == msGetTextSymbolSize(map,&cur->ts,&rect))) { + if (MS_UNLIKELY(MS_FAILURE == + msGetTextSymbolSize(map, &cur->ts, &rect))) { ret = MS_FAILURE; goto cleanup; } - cur->height = MS_MAX(MS_NINT(rect.maxy - rect.miny), map->legend.keysizey); + cur->height = + MS_MAX(MS_NINT(rect.maxy - rect.miny), map->legend.keysizey); } else { cur->height = map->legend.keysizey; } @@ -725,19 +828,21 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) } } - /* ensure we have an image format representing the options for the legend. */ msApplyOutputFormat(&format, map->outputformat, map->legend.transparent); /* initialize the legend image */ - image = msImageCreate(size_x, size_y, format, map->web.imagepath, map->web.imageurl, map->resolution, map->defresolution, &map->legend.imagecolor); - if(!image) { + image = msImageCreate(size_x, size_y, format, map->web.imagepath, + map->web.imageurl, map->resolution, map->defresolution, + &map->legend.imagecolor); + if (!image) { msSetError(MS_MISCERR, "Unable to initialize image.", "msDrawLegend()"); return NULL; } image->map = map; - /* image = renderer->createImage(size_x,size_y,format,&(map->legend.imagecolor)); */ + /* image = + * renderer->createImage(size_x,size_y,format,&(map->legend.imagecolor)); */ /* drop this reference to output format */ msApplyOutputFormat(&format, NULL, MS_NOOVERRIDE); @@ -745,37 +850,45 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) pnt.y = VMARGIN; pnt.x = HMARGIN + map->legend.keysizex + map->legend.keyspacingx; - while(cur) { /* cur initially points on the last legend item, i.e. the one that should be at the top */ + while (cur) { /* cur initially points on the last legend item, i.e. the one + that should be at the top */ class_hittest *ch = NULL; - /* set the scale factor so that scale dependant symbols are drawn in the legend with their default size */ - if(map->layers[cur->layerindex]->sizeunits != MS_PIXELS) { + /* set the scale factor so that scale dependant symbols are drawn in the + * legend with their default size */ + if (map->layers[cur->layerindex]->sizeunits != MS_PIXELS) { map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - map->layers[cur->layerindex]->scalefactor = (msInchesPerUnit(map->layers[cur->layerindex]->sizeunits,0)/msInchesPerUnit(map->units,0)) / map->cellsize; + map->layers[cur->layerindex]->scalefactor = + (msInchesPerUnit(map->layers[cur->layerindex]->sizeunits, 0) / + msInchesPerUnit(map->units, 0)) / + map->cellsize; } - if(hittest) { + if (hittest) { ch = &hittest->layerhits[cur->layerindex].classhits[cur->classindex]; } - ret = msDrawLegendIcon(map, map->layers[cur->layerindex], map->layers[cur->layerindex]->class[cur->classindex], map->legend.keysizex, map->legend.keysizey, image, HMARGIN, (int) pnt.y, scale_independent, ch); - if(MS_UNLIKELY(ret != MS_SUCCESS)) + ret = msDrawLegendIcon(map, map->layers[cur->layerindex], + map->layers[cur->layerindex]->class[cur->classindex], + map -> legend.keysizex, map->legend.keysizey, image, + HMARGIN, (int)pnt.y, scale_independent, ch); + if (MS_UNLIKELY(ret != MS_SUCCESS)) goto cleanup; pnt.y += cur->height; - if(cur->ts.annotext) { + if (cur->ts.annotext) { pointObj textPnt = pnt; textPnt.y -= cur->ts.textpath->bounds.bbox.maxy; textPnt.y += map->legend.label.offsety; textPnt.x += map->legend.label.offsetx; - ret = msDrawTextSymbol(map,image,textPnt,&cur->ts); - if(MS_UNLIKELY(ret == MS_FAILURE)) + ret = msDrawTextSymbol(map, image, textPnt, &cur->ts); + if (MS_UNLIKELY(ret == MS_FAILURE)) goto cleanup; /* Coverity Scan is confused by label refcount, and wrongly believe we */ /* might free &map->legend.label, so make it clear we won't */ freeTextSymbolEx(&cur->ts, MS_FALSE); MS_REFCNT_DECR(cur->ts.label); } - + pnt.y += map->legend.keyspacingy; /* bump y for next label */ /* clean up */ @@ -785,7 +898,7 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) } /* next legend */ cleanup: - while(cur) { + while (cur) { /* Coverity Scan is confused by label refcount, and wrongly believe we */ /* might free &map->legend.label, so make it clear we won't */ freeTextSymbolEx(&cur->ts, MS_FALSE); @@ -794,69 +907,76 @@ imageObj *msDrawLegend(mapObj *map, int scale_independent, map_hittest *hittest) cur = cur->pred; free(head); } - if(MS_UNLIKELY(ret != MS_SUCCESS)) { - if(image) msFreeImage(image); + if (MS_UNLIKELY(ret != MS_SUCCESS)) { + if (image) + msFreeImage(image); return NULL; } - return(image); + return (image); } /* TODO */ -int msEmbedLegend(mapObj *map, imageObj *img) -{ - int s,l; +int msEmbedLegend(mapObj *map, imageObj *img) { + int s, l; pointObj point; imageObj *image = NULL; symbolObj *legendSymbol; - char* imageType = NULL; + char *imageType = NULL; rendererVTableObj *renderer; s = msGetSymbolIndex(&(map->symbolset), "legend", MS_FALSE); - if(s != -1) - msRemoveSymbol(&(map->symbolset), s); /* solves some caching issues in AGG with long-running processes */ + if (s != -1) + msRemoveSymbol( + &(map->symbolset), + s); /* solves some caching issues in AGG with long-running processes */ - if(msGrowSymbolSet(&map->symbolset) == NULL) + if (msGrowSymbolSet(&map->symbolset) == NULL) return -1; s = map->symbolset.numsymbols; legendSymbol = map->symbolset.symbol[s]; map->symbolset.numsymbols++; initSymbol(legendSymbol); - if(!MS_RENDERER_PLUGIN(map->outputformat) || !MS_MAP_RENDERER(map)->supports_pixel_buffer) { + if (!MS_RENDERER_PLUGIN(map->outputformat) || + !MS_MAP_RENDERER(map)->supports_pixel_buffer) { imageType = msStrdup(map->imagetype); /* save format */ - if MS_DRIVER_CAIRO(map->outputformat) - map->outputformat = msSelectOutputFormat( map, "cairopng" ); + if MS_DRIVER_CAIRO (map->outputformat) + map->outputformat = msSelectOutputFormat(map, "cairopng"); else - map->outputformat = msSelectOutputFormat( map, "png" ); - + map->outputformat = msSelectOutputFormat(map, "png"); + msInitializeRendererVTable(map->outputformat); } renderer = MS_MAP_RENDERER(map); /* render the legend. */ image = msDrawLegend(map, MS_FALSE, NULL); - if( image == NULL ) { + if (image == NULL) { msFree(imageType); return MS_FAILURE; } if (imageType) { - map->outputformat = msSelectOutputFormat( map, imageType ); /* restore format */ + map->outputformat = + msSelectOutputFormat(map, imageType); /* restore format */ msFree(imageType); } /* copy renderered legend image into symbol */ - legendSymbol->pixmap_buffer = calloc(1,sizeof(rasterBufferObj)); - MS_CHECK_ALLOC(legendSymbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); + legendSymbol->pixmap_buffer = calloc(1, sizeof(rasterBufferObj)); + MS_CHECK_ALLOC(legendSymbol->pixmap_buffer, sizeof(rasterBufferObj), + MS_FAILURE); - if(MS_SUCCESS != renderer->getRasterBufferCopy(image,legendSymbol->pixmap_buffer)) + if (MS_SUCCESS != + renderer->getRasterBufferCopy(image, legendSymbol->pixmap_buffer)) return MS_FAILURE; legendSymbol->renderer = renderer; - msFreeImage( image ); + msFreeImage(image); - if(!legendSymbol->pixmap_buffer) return(MS_FAILURE); /* something went wrong creating scalebar */ + if (!legendSymbol->pixmap_buffer) + return (MS_FAILURE); /* something went wrong creating scalebar */ legendSymbol->type = MS_SYMBOL_PIXMAP; /* intialize a few things */ legendSymbol->name = msStrdup("legend"); @@ -867,46 +987,48 @@ int msEmbedLegend(mapObj *map, imageObj *img) /* if(map->legend.transparent == MS_ON) */ /* gdImageColorTransparent(legendSymbol->img_deprecated, 0); */ - switch(map->legend.position) { - case(MS_LL): - point.x = MS_NINT(legendSymbol->sizex/2.0); - point.y = map->height - MS_NINT(legendSymbol->sizey/2.0); - break; - case(MS_LR): - point.x = map->width - MS_NINT(legendSymbol->sizex/2.0); - point.y = map->height - MS_NINT(legendSymbol->sizey/2.0); - break; - case(MS_LC): - point.x = MS_NINT(map->width/2.0); - point.y = map->height - MS_NINT(legendSymbol->sizey/2.0); - break; - case(MS_UR): - point.x = map->width - MS_NINT(legendSymbol->sizex/2.0); - point.y = MS_NINT(legendSymbol->sizey/2.0); - break; - case(MS_UL): - point.x = MS_NINT(legendSymbol->sizex/2.0); - point.y = MS_NINT(legendSymbol->sizey/2.0); - break; - case(MS_UC): - point.x = MS_NINT(map->width/2.0); - point.y = MS_NINT(legendSymbol->sizey/2.0); - break; + switch (map->legend.position) { + case (MS_LL): + point.x = MS_NINT(legendSymbol->sizex / 2.0); + point.y = map->height - MS_NINT(legendSymbol->sizey / 2.0); + break; + case (MS_LR): + point.x = map->width - MS_NINT(legendSymbol->sizex / 2.0); + point.y = map->height - MS_NINT(legendSymbol->sizey / 2.0); + break; + case (MS_LC): + point.x = MS_NINT(map->width / 2.0); + point.y = map->height - MS_NINT(legendSymbol->sizey / 2.0); + break; + case (MS_UR): + point.x = map->width - MS_NINT(legendSymbol->sizex / 2.0); + point.y = MS_NINT(legendSymbol->sizey / 2.0); + break; + case (MS_UL): + point.x = MS_NINT(legendSymbol->sizex / 2.0); + point.y = MS_NINT(legendSymbol->sizey / 2.0); + break; + case (MS_UC): + point.x = MS_NINT(map->width / 2.0); + point.y = MS_NINT(legendSymbol->sizey / 2.0); + break; } l = msGetLayerIndex(map, "__embed__legend"); - if(l == -1) { - if(msGrowMapLayers(map) == NULL) - return(-1); + if (l == -1) { + if (msGrowMapLayers(map) == NULL) + return (-1); l = map->numlayers; map->numlayers++; - if(initLayer((GET_LAYER(map, l)), map) == -1) return(-1); + if (initLayer((GET_LAYER(map, l)), map) == -1) + return (-1); GET_LAYER(map, l)->name = msStrdup("__embed__legend"); GET_LAYER(map, l)->type = MS_LAYER_POINT; - if(msGrowLayerClasses( GET_LAYER(map, l) ) == NULL) - return(-1); - if(initClass(GET_LAYER(map, l)->class[0]) == -1) return(-1); + if (msGrowLayerClasses(GET_LAYER(map, l)) == NULL) + return (-1); + if (initClass(GET_LAYER(map, l)->class[0]) == -1) + return (-1); GET_LAYER(map, l)->numclasses = 1; /* so we make sure to free it */ /* update the layer order list with the layer's index. */ @@ -915,33 +1037,45 @@ int msEmbedLegend(mapObj *map, imageObj *img) GET_LAYER(map, l)->status = MS_ON; - if(map->legend.postlabelcache) { /* add it directly to the image */ - if(MS_UNLIKELY(msMaybeAllocateClassStyle(GET_LAYER(map, l)->class[0], 0)==MS_FAILURE)) return MS_FAILURE; + if (map->legend.postlabelcache) { /* add it directly to the image */ + if (MS_UNLIKELY(msMaybeAllocateClassStyle(GET_LAYER(map, l)->class[0], 0) == + MS_FAILURE)) + return MS_FAILURE; GET_LAYER(map, l)->class[0]->styles[0]->symbol = s; - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, img, &point, GET_LAYER(map, l)->class[0]->styles[0], 1.0))) + if (MS_UNLIKELY(MS_FAILURE == + msDrawMarkerSymbol(map, img, &point, + GET_LAYER(map, l)->class[0] -> styles[0], + 1.0))) return MS_FAILURE; } else { - if(!GET_LAYER(map, l)->class[0]->labels) { - if(msGrowClassLabels(GET_LAYER(map, l)->class[0]) == NULL) return MS_FAILURE; - initLabel(GET_LAYER(map, l)->class[0]->labels[0]); + if (!GET_LAYER(map, l)->class[0] -> labels) { + if (msGrowClassLabels(GET_LAYER(map, l)->class[0]) == NULL) + return MS_FAILURE; + initLabel(GET_LAYER(map, l)->class[0] -> labels[0]); GET_LAYER(map, l)->class[0]->numlabels = 1; GET_LAYER(map, l)->class[0]->labels[0]->force = MS_TRUE; - GET_LAYER(map, l)->class[0]->labels[0]->size = MS_MEDIUM; /* must set a size to have a valid label definition */ + GET_LAYER(map, l)->class[0]->labels[0]->size = + MS_MEDIUM; /* must set a size to have a valid label definition */ GET_LAYER(map, l)->class[0]->labels[0]->priority = MS_MAX_LABEL_PRIORITY; } - if(GET_LAYER(map, l)->class[0]->labels[0]->numstyles == 0) { - if(msGrowLabelStyles(GET_LAYER(map,l)->class[0]->labels[0]) == NULL) - return(MS_FAILURE); - GET_LAYER(map,l)->class[0]->labels[0]->numstyles = 1; - initStyle(GET_LAYER(map,l)->class[0]->labels[0]->styles[0]); - GET_LAYER(map,l)->class[0]->labels[0]->styles[0]->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOINT; + if (GET_LAYER(map, l)->class[0] -> labels[0] -> numstyles == 0) { + if (msGrowLabelStyles(GET_LAYER(map, l)->class[0] -> labels[0]) == NULL) + return (MS_FAILURE); + GET_LAYER(map, l)->class[0]->labels[0]->numstyles = 1; + initStyle(GET_LAYER(map, l)->class[0] -> labels[0] -> styles[0]); + GET_LAYER(map, l)->class[0]->labels[0]->styles[0]->_geomtransform.type = + MS_GEOMTRANSFORM_LABELPOINT; } - GET_LAYER(map,l)->class[0]->labels[0]->styles[0]->symbol = s; - if(MS_UNLIKELY(MS_FAILURE == msAddLabel(map, img, GET_LAYER(map, l)->class[0]->labels[0], l, 0, NULL, &point, -1, NULL))) + GET_LAYER(map, l)->class[0]->labels[0]->styles[0]->symbol = s; + if (MS_UNLIKELY(MS_FAILURE == + msAddLabel(map, img, + GET_LAYER(map, l)->class[0] -> labels[0], l, 0, + NULL, &point, -1, NULL))) return MS_FAILURE; } - /* Mark layer as deleted so that it doesn't interfere with html legends or with saving maps */ + /* Mark layer as deleted so that it doesn't interfere with html legends or + * with saving maps */ GET_LAYER(map, l)->status = MS_DELETE; return MS_SUCCESS; diff --git a/maplibxml2.c b/maplibxml2.c index b6a91789f5..8ef7132618 100644 --- a/maplibxml2.c +++ b/maplibxml2.c @@ -31,17 +31,16 @@ #ifdef USE_LIBXML2 -#include -#include -#include -#include - - +#include +#include +#include +#include /** * msLibXml2GenerateList() * - * Convenience function to produce a series of XML elements from a delimited list + * Convenience function to produce a series of XML elements from a delimited + * list * * @param xmlNodePtr psParent the encompassing node * @param xmlNsPtr psNs the namespace object @@ -51,16 +50,17 @@ * */ -void msLibXml2GenerateList(xmlNodePtr psParent, xmlNsPtr psNs, const char *elname, const char *values, char delim) -{ +void msLibXml2GenerateList(xmlNodePtr psParent, xmlNsPtr psNs, + const char *elname, const char *values, char delim) { char **tokens = NULL; int n = 0; int i = 0; tokens = msStringSplit(values, delim, &n); - for (i=0; inodesetval)) { + if (xmlXPathNodeSetIsEmpty(result->nodesetval)) { xmlXPathFreeObject(result); return NULL; } @@ -108,8 +108,7 @@ xmlXPathObjectPtr msLibXml2GetXPath(xmlDocPtr doc, xmlXPathContextPtr context, x * */ -char *msLibXml2GetXPathTree(xmlDocPtr doc, xmlXPathObjectPtr xpath) -{ +char *msLibXml2GetXPathTree(xmlDocPtr doc, xmlXPathObjectPtr xpath) { xmlBufferPtr xbuf; char *result = NULL; diff --git a/maplibxml2.h b/maplibxml2.h index 904eb97070..2307bbf863 100644 --- a/maplibxml2.h +++ b/maplibxml2.h @@ -32,10 +32,10 @@ #ifdef USE_LIBXML2 -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -43,9 +43,11 @@ extern "C" { #endif -xmlXPathObjectPtr msLibXml2GetXPath(xmlDocPtr doc, xmlXPathContextPtr context, xmlChar *xpath); +xmlXPathObjectPtr msLibXml2GetXPath(xmlDocPtr doc, xmlXPathContextPtr context, + xmlChar *xpath); -void msLibXml2GenerateList(xmlNodePtr psParent, xmlNsPtr psNs, const char *elname, const char *values, char delim); +void msLibXml2GenerateList(xmlNodePtr psParent, xmlNsPtr psNs, + const char *elname, const char *values, char delim); char *msLibXml2GetXPathTree(xmlDocPtr doc, xmlXPathObjectPtr xpath); diff --git a/mapmetadata.c b/mapmetadata.c index 1bf015f9bd..00165ef18d 100644 --- a/mapmetadata.c +++ b/mapmetadata.c @@ -31,13 +31,13 @@ #include "mapowscommon.h" #include "maplibxml2.h" -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) #ifdef USE_LIBXML2 -static -int msMetadataParseRequest(cgiRequestObj *request, - metadataParamsObj *metadataparams); +static int msMetadataParseRequest(cgiRequestObj *request, + metadataParamsObj *metadataparams); /************************************************************************/ /* _msMetadataGetCharacterString */ @@ -45,12 +45,15 @@ int msMetadataParseRequest(cgiRequestObj *request, /* Create a gmd:name/gmd:CharacterString element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetCharacterString(xmlNsPtr namespace, const char *name, const char *value, xmlNsPtr* ppsNsGco) { +static xmlNodePtr _msMetadataGetCharacterString(xmlNsPtr namespace, + const char *name, + const char *value, + xmlNsPtr *ppsNsGco) { xmlNodePtr psNode = NULL; - if( *ppsNsGco == NULL ) - *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gco"); + if (*ppsNsGco == NULL) + *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gco"); psNode = xmlNewNode(namespace, BAD_CAST name); @@ -59,22 +62,21 @@ xmlNodePtr _msMetadataGetCharacterString(xmlNsPtr namespace, const char *name, c else xmlNewChild(psNode, *ppsNsGco, BAD_CAST "CharacterString", BAD_CAST value); return psNode; - } - /************************************************************************/ /* _msMetadataGetURL */ /* */ /* Create a gmd:name/gmd:URL element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetURL(xmlNsPtr namespace, const char *name, const char *value, xmlNsPtr* ppsNsGco) { +static xmlNodePtr _msMetadataGetURL(xmlNsPtr namespace, const char *name, + const char *value, xmlNsPtr *ppsNsGco) { xmlNodePtr psNode = NULL; - if( *ppsNsGco == NULL ) - *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gco"); + if (*ppsNsGco == NULL) + *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gco"); psNode = xmlNewNode(namespace, BAD_CAST name); @@ -83,7 +85,6 @@ xmlNodePtr _msMetadataGetURL(xmlNsPtr namespace, const char *name, const char *v else xmlNewChild(psNode, namespace, BAD_CAST "URL", BAD_CAST value); return psNode; - } /************************************************************************/ @@ -92,16 +93,17 @@ xmlNodePtr _msMetadataGetURL(xmlNsPtr namespace, const char *name, const char *v /* Create a gmd:onLine element pattern */ /************************************************************************/ -static char* _stringConcatenateAndEncodeHTML(char* str, const char* appendStr) -{ - char* pszTmp = msEncodeHTMLEntities(appendStr); +static char *_stringConcatenateAndEncodeHTML(char *str, const char *appendStr) { + char *pszTmp = msEncodeHTMLEntities(appendStr); str = msStringConcatenate(str, pszTmp); msFree(pszTmp); return str; } -static -xmlNodePtr _msMetadataGetOnline(xmlNsPtr namespace, layerObj *layer, const char *service, const char *format, const char *desc, const char *url_in, xmlNsPtr* ppsNsGco) { +static xmlNodePtr _msMetadataGetOnline(xmlNsPtr namespace, layerObj *layer, + const char *service, const char *format, + const char *desc, const char *url_in, + xmlNsPtr *ppsNsGco) { int status; char *url = NULL; @@ -119,16 +121,19 @@ xmlNodePtr _msMetadataGetOnline(xmlNsPtr namespace, layerObj *layer, const char url = msStrdup(url_in); if (strcasecmp(service, "M") == 0) { - url = _stringConcatenateAndEncodeHTML(url, "service=WMS&version=1.3.0&request=GetMap&width=500&height=300&styles=&layers="); + url = _stringConcatenateAndEncodeHTML( + url, "service=WMS&version=1.3.0&request=GetMap&width=500&height=300&" + "styles=&layers="); url = _stringConcatenateAndEncodeHTML(url, layer->name); url = _stringConcatenateAndEncodeHTML(url, "&format="); url = _stringConcatenateAndEncodeHTML(url, format); url = _stringConcatenateAndEncodeHTML(url, "&crs="); { - char* epsg_str = NULL; - msOWSGetEPSGProj(&(layer->projection), &(layer->metadata), "MFCSGO", MS_TRUE, &epsg_str); - url = _stringConcatenateAndEncodeHTML(url, epsg_str); - msFree(epsg_str); + char *epsg_str = NULL; + msOWSGetEPSGProj(&(layer->projection), &(layer->metadata), "MFCSGO", + MS_TRUE, &epsg_str); + url = _stringConcatenateAndEncodeHTML(url, epsg_str); + msFree(epsg_str); } link_protocol = "WWW:DOWNLOAD-1.0-http-get-map"; @@ -148,17 +153,17 @@ xmlNodePtr _msMetadataGetOnline(xmlNsPtr namespace, layerObj *layer, const char sprintf(buffer, "%f", rect.maxx); url = msStringConcatenate(url, buffer); } - } - else if (strcasecmp(service, "F") == 0) { + } else if (strcasecmp(service, "F") == 0) { link_protocol = "WWW:DOWNLOAD-1.0-http--download"; - url = _stringConcatenateAndEncodeHTML(url, "service=WFS&version=1.1.0&request=GetFeature&typename="); + url = _stringConcatenateAndEncodeHTML( + url, "service=WFS&version=1.1.0&request=GetFeature&typename="); url = _stringConcatenateAndEncodeHTML(url, layer->name); url = _stringConcatenateAndEncodeHTML(url, "&outputformat="); url = _stringConcatenateAndEncodeHTML(url, format); - } - else if (strcasecmp(service, "C") == 0) { + } else if (strcasecmp(service, "C") == 0) { link_protocol = "WWW:DOWNLOAD-1.0-http--download"; - url = _stringConcatenateAndEncodeHTML(url, "service=WCS&version=2.0.1&request=GetCoverage&coverageid="); + url = _stringConcatenateAndEncodeHTML( + url, "service=WCS&version=2.0.1&request=GetCoverage&coverageid="); url = _stringConcatenateAndEncodeHTML(url, layer->name); url = _stringConcatenateAndEncodeHTML(url, "&format="); url = _stringConcatenateAndEncodeHTML(url, format); @@ -167,31 +172,34 @@ xmlNodePtr _msMetadataGetOnline(xmlNsPtr namespace, layerObj *layer, const char xmlAddChild(psORNode, _msMetadataGetURL(namespace, "linkage", url, ppsNsGco)); msFree(url); - xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "protocol", link_protocol, ppsNsGco)); - xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "name", layer->name, ppsNsGco)); + xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "protocol", + link_protocol, ppsNsGco)); + xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "name", + layer->name, ppsNsGco)); - xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "description", desc, ppsNsGco)); + xmlAddChild(psORNode, _msMetadataGetCharacterString(namespace, "description", + desc, ppsNsGco)); return psNode; } - /************************************************************************/ /* _msMetadataGetInteger */ /* */ /* Create a gmd:name/gmd:Integer element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetInteger(xmlNsPtr namespace, const char *name, int value, xmlNsPtr* ppsNsGco) { +static xmlNodePtr _msMetadataGetInteger(xmlNsPtr namespace, const char *name, + int value, xmlNsPtr *ppsNsGco) { char buffer[8]; xmlNodePtr psNode = NULL; sprintf(buffer, "%d", value); - if( *ppsNsGco == NULL ) - *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gco"); + if (*ppsNsGco == NULL) + *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gco"); psNode = xmlNewNode(namespace, BAD_CAST name); @@ -202,23 +210,23 @@ xmlNodePtr _msMetadataGetInteger(xmlNsPtr namespace, const char *name, int value return psNode; } - /************************************************************************/ /* _msMetadataGetDecimal */ /* */ /* Create a gmd:name/gmd:Decimal element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetDecimal(xmlNsPtr namespace, const char *name, double value, xmlNsPtr* ppsNsGco) { +static xmlNodePtr _msMetadataGetDecimal(xmlNsPtr namespace, const char *name, + double value, xmlNsPtr *ppsNsGco) { char buffer[32]; xmlNodePtr psNode = NULL; snprintf(buffer, sizeof(buffer), "%.6f", value); - if( *ppsNsGco == NULL ) - *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gco"); + if (*ppsNsGco == NULL) + *ppsNsGco = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gco"); psNode = xmlNewNode(namespace, BAD_CAST name); @@ -229,19 +237,21 @@ xmlNodePtr _msMetadataGetDecimal(xmlNsPtr namespace, const char *name, double va return psNode; } - /************************************************************************/ /* _msMetadataGetCodeList */ /* */ /* Create a gmd:name/gmd:* code list element pattern */ /************************************************************************/ -xmlNodePtr _msMetadataGetCodeList(xmlNsPtr namespace, const char *parent_element, const char *name, const char *value) { +xmlNodePtr _msMetadataGetCodeList(xmlNsPtr namespace, + const char *parent_element, const char *name, + const char *value) { char *codelist = NULL; xmlNodePtr psNode = NULL; xmlNodePtr psCodeNode = NULL; - codelist = msStrdup("http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#"); + codelist = msStrdup( + "http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#"); codelist = msStringConcatenate(codelist, name); psNode = xmlNewNode(namespace, BAD_CAST parent_element); @@ -253,20 +263,18 @@ xmlNodePtr _msMetadataGetCodeList(xmlNsPtr namespace, const char *parent_element return psNode; } - /************************************************************************/ /* _msMetadataGetGMLTimePeriod */ /* */ /* Create a gml:TimePeriod element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetGMLTimePeriod(char **temporal) -{ +static xmlNodePtr _msMetadataGetGMLTimePeriod(char **temporal) { xmlNsPtr psNsGml = NULL; xmlNodePtr psNode = NULL; - psNsGml = xmlNewNs(NULL, BAD_CAST "http://www.opengis.net/gml", BAD_CAST "gml"); + psNsGml = + xmlNewNs(NULL, BAD_CAST "http://www.opengis.net/gml", BAD_CAST "gml"); psNode = xmlNewNode(psNsGml, BAD_CAST "TimePeriod"); xmlNewNsProp(psNode, psNsGml, BAD_CAST "id", BAD_CAST "T001"); xmlNewNs(psNode, BAD_CAST "http://www.opengis.net/gml", BAD_CAST "gml"); @@ -277,16 +285,14 @@ xmlNodePtr _msMetadataGetGMLTimePeriod(char **temporal) return psNode; } - /************************************************************************/ /* _msMetadataGetExtent */ /* */ /* Create a gmd:extent element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetExtent(xmlNsPtr namespace, layerObj *layer, xmlNsPtr *ppsNsGco) -{ +static xmlNodePtr _msMetadataGetExtent(xmlNsPtr namespace, layerObj *layer, + xmlNsPtr *ppsNsGco) { int n = 0; int status; char *value = NULL; @@ -305,41 +311,50 @@ xmlNodePtr _msMetadataGetExtent(xmlNsPtr namespace, layerObj *layer, xmlNsPtr *p psEXNode = xmlNewChild(psNode, namespace, BAD_CAST "EX_Extent", NULL); /* scan for geospatial extent */ - status = msLayerGetExtent(layer, &rect); + status = msLayerGetExtent(layer, &rect); if (status == 0) { /* always project to lat long */ msOWSProjectToWGS84(&layer->projection, &rect); - psGNode = xmlNewChild(psEXNode, namespace, BAD_CAST "geographicElement", NULL); - psGNode2 = xmlNewChild(psGNode, namespace, BAD_CAST "EX_GeographicBoundingBox", NULL); - xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "westBoundLongitude", rect.minx, ppsNsGco)); - xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "eastBoundLongitude", rect.maxx, ppsNsGco)); - xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "southBoundLatitude", rect.miny, ppsNsGco)); - xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "northBoundLatitude", rect.maxy, ppsNsGco)); + psGNode = + xmlNewChild(psEXNode, namespace, BAD_CAST "geographicElement", NULL); + psGNode2 = xmlNewChild(psGNode, namespace, + BAD_CAST "EX_GeographicBoundingBox", NULL); + xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "westBoundLongitude", + rect.minx, ppsNsGco)); + xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "eastBoundLongitude", + rect.maxx, ppsNsGco)); + xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "southBoundLatitude", + rect.miny, ppsNsGco)); + xmlAddChild(psGNode2, _msMetadataGetDecimal(namespace, "northBoundLatitude", + rect.maxy, ppsNsGco)); } /* scan for temporal extent */ value = (char *)msOWSLookupMetadata(&(layer->metadata), "MO", "timeextent"); if (value) { /* WMS */ temporal = msStringSplit(value, '/', &n); - } - else { /* WCS */ - value = (char *)msOWSLookupMetadata(&(layer->metadata), "CO", "timeposition"); + } else { /* WCS */ + value = + (char *)msOWSLookupMetadata(&(layer->metadata), "CO", "timeposition"); if (value) { /* split extent */ temporal = msStringSplit(value, ',', &n); } } if (!value) { /* SOS */ - value = (char *)msOWSLookupMetadata(&(layer->metadata), "SO", "offering_timeextent"); - if (value) - temporal = msStringSplit(value, '/', &n); + value = (char *)msOWSLookupMetadata(&(layer->metadata), "SO", + "offering_timeextent"); + if (value) + temporal = msStringSplit(value, '/', &n); } - if (value) { + if (value) { if (temporal && n > 0) { - psTNode = xmlNewChild(psEXNode, namespace, BAD_CAST "temporalElement", NULL); - psTNode2 = xmlNewChild(psTNode, namespace, BAD_CAST "EX_TemporalExtent", NULL); + psTNode = + xmlNewChild(psEXNode, namespace, BAD_CAST "temporalElement", NULL); + psTNode2 = + xmlNewChild(psTNode, namespace, BAD_CAST "EX_TemporalExtent", NULL); psENode = xmlNewChild(psTNode2, namespace, BAD_CAST "extent", NULL); xmlAddChild(psENode, _msMetadataGetGMLTimePeriod(temporal)); } @@ -349,16 +364,15 @@ xmlNodePtr _msMetadataGetExtent(xmlNsPtr namespace, layerObj *layer, xmlNsPtr *p return psNode; } - /************************************************************************/ /* _msMetadataGetReferenceSystemInfo */ /* */ /* Create a gmd:referenceSystemInfo element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetReferenceSystemInfo(xmlNsPtr namespace, layerObj *layer, xmlNsPtr* ppsNsGco) -{ +static xmlNodePtr _msMetadataGetReferenceSystemInfo(xmlNsPtr namespace, + layerObj *layer, + xmlNsPtr *ppsNsGco) { char *epsg_str = NULL; xmlNodePtr psNode = NULL; xmlNodePtr psRSNode = NULL; @@ -366,28 +380,35 @@ xmlNodePtr _msMetadataGetReferenceSystemInfo(xmlNsPtr namespace, layerObj *layer xmlNodePtr psRSINode2 = NULL; psNode = xmlNewNode(namespace, BAD_CAST "referenceSystemInfo"); - psRSNode = xmlNewChild(psNode, namespace, BAD_CAST "MD_ReferenceSystem", NULL); - psRSINode = xmlNewChild(psRSNode, namespace, BAD_CAST "referenceSystemIdentifier", NULL); - psRSINode2 = xmlNewChild(psRSINode, namespace, BAD_CAST "RS_Identifier", NULL); - - msOWSGetEPSGProj(&(layer->projection), &(layer->metadata), "MFCSGO", MS_TRUE, &epsg_str); - xmlAddChild(psRSINode2, _msMetadataGetCharacterString(namespace, "code", epsg_str, ppsNsGco)); - xmlAddChild(psRSINode2, _msMetadataGetCharacterString(namespace, "codeSpace", "http://www.epsg-registry.org", ppsNsGco)); - xmlAddChild(psRSINode2, _msMetadataGetCharacterString(namespace, "version", "6.14", ppsNsGco)); + psRSNode = + xmlNewChild(psNode, namespace, BAD_CAST "MD_ReferenceSystem", NULL); + psRSINode = xmlNewChild(psRSNode, namespace, + BAD_CAST "referenceSystemIdentifier", NULL); + psRSINode2 = + xmlNewChild(psRSINode, namespace, BAD_CAST "RS_Identifier", NULL); + + msOWSGetEPSGProj(&(layer->projection), &(layer->metadata), "MFCSGO", MS_TRUE, + &epsg_str); + xmlAddChild(psRSINode2, _msMetadataGetCharacterString(namespace, "code", + epsg_str, ppsNsGco)); + xmlAddChild(psRSINode2, _msMetadataGetCharacterString( + namespace, "codeSpace", + "http://www.epsg-registry.org", ppsNsGco)); + xmlAddChild(psRSINode2, _msMetadataGetCharacterString(namespace, "version", + "6.14", ppsNsGco)); msFree(epsg_str); return psNode; } - /************************************************************************/ /* _msMetadataGetContact */ /* */ /* Create a gmd:contact element pattern */ /************************************************************************/ -xmlNodePtr _msMetadataGetContact(xmlNsPtr namespace, char *contact_element, mapObj *map, xmlNsPtr* ppsNsGco) -{ +xmlNodePtr _msMetadataGetContact(xmlNsPtr namespace, char *contact_element, + mapObj *map, xmlNsPtr *ppsNsGco) { char *value = NULL; xmlNodePtr psNode = NULL; xmlNodePtr psCNode = NULL; @@ -401,83 +422,111 @@ xmlNodePtr _msMetadataGetContact(xmlNsPtr namespace, char *contact_element, mapO xmlNodePtr psORNode2 = NULL; psNode = xmlNewNode(namespace, BAD_CAST contact_element); - psCNode = xmlNewChild(psNode, namespace, BAD_CAST "CI_ResponsibleParty", NULL); + psCNode = + xmlNewChild(psNode, namespace, BAD_CAST "CI_ResponsibleParty", NULL); xmlNewProp(psCNode, BAD_CAST "id", BAD_CAST contact_element); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactperson"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactperson"); if (value) - xmlAddChild(psCNode, _msMetadataGetCharacterString(namespace, "individualName", value, ppsNsGco)); + xmlAddChild(psCNode, _msMetadataGetCharacterString( + namespace, "individualName", value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactorganization"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactorganization"); if (value) - xmlAddChild(psCNode, _msMetadataGetCharacterString(namespace, "organisationName", value, ppsNsGco)); + xmlAddChild(psCNode, _msMetadataGetCharacterString( + namespace, "organisationName", value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactposition"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactposition"); if (value) - xmlAddChild(psCNode, _msMetadataGetCharacterString(namespace, "positionName", value, ppsNsGco)); + xmlAddChild(psCNode, _msMetadataGetCharacterString( + namespace, "positionName", value, ppsNsGco)); psCINode = xmlNewChild(psCNode, namespace, BAD_CAST "contactInfo", NULL); psCINode2 = xmlNewChild(psCINode, namespace, BAD_CAST "CI_Contact", NULL); psPhoneNode = xmlNewChild(psCINode2, namespace, BAD_CAST "phone", NULL); - psCIPhoneNode = xmlNewChild(psPhoneNode, namespace, BAD_CAST "CI_Telephone", NULL); + psCIPhoneNode = + xmlNewChild(psPhoneNode, namespace, BAD_CAST "CI_Telephone", NULL); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactvoicetelephone"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactvoicetelephone"); if (value) - xmlAddChild(psCIPhoneNode, _msMetadataGetCharacterString(namespace, "voice", value, ppsNsGco)); + xmlAddChild(psCIPhoneNode, _msMetadataGetCharacterString(namespace, "voice", + value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactfacsimiletelephone"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactfacsimiletelephone"); if (value) - xmlAddChild(psCIPhoneNode, _msMetadataGetCharacterString(namespace, "facsimile", value, ppsNsGco)); + xmlAddChild(psCIPhoneNode, _msMetadataGetCharacterString( + namespace, "facsimile", value, ppsNsGco)); psAddressNode = xmlNewChild(psCINode2, namespace, BAD_CAST "address", NULL); - psCIAddressNode = xmlNewChild(psAddressNode, namespace, BAD_CAST "CI_Address", NULL); + psCIAddressNode = + xmlNewChild(psAddressNode, namespace, BAD_CAST "CI_Address", NULL); value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "address"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "deliveryPoint", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, + _msMetadataGetCharacterString(namespace, "deliveryPoint", value, + ppsNsGco)); value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "city"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "city", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString( + namespace, "city", value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "stateorprovince"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "stateorprovince"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "administrativeArea", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, + _msMetadataGetCharacterString(namespace, "administrativeArea", + value, ppsNsGco)); value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "postcode"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "postalCode", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString( + namespace, "postalCode", value, ppsNsGco)); value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "country"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "country", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString( + namespace, "country", value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "contactelectronicmailaddress"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "contactelectronicmailaddress"); if (value) - xmlAddChild(psCIAddressNode, _msMetadataGetCharacterString(namespace, "electronicMailAddress", value, ppsNsGco)); + xmlAddChild(psCIAddressNode, + _msMetadataGetCharacterString( + namespace, "electronicMailAddress", value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", "onlineresource"); + value = (char *)msOWSLookupMetadata(&(map->web.metadata), "MCFO", + "onlineresource"); if (value) { - psORNode = xmlNewChild(psCINode2, namespace, BAD_CAST "onlineResource", NULL); - psORNode2 = xmlNewChild(psORNode, namespace, BAD_CAST "CI_OnlineResource", NULL); - xmlAddChild(psORNode2, _msMetadataGetURL(namespace, "linkage", value, ppsNsGco)); + psORNode = + xmlNewChild(psCINode2, namespace, BAD_CAST "onlineResource", NULL); + psORNode2 = + xmlNewChild(psORNode, namespace, BAD_CAST "CI_OnlineResource", NULL); + xmlAddChild(psORNode2, + _msMetadataGetURL(namespace, "linkage", value, ppsNsGco)); } - xmlAddChild(psCNode, _msMetadataGetCodeList(namespace, "role", "CI_RoleCode", "pointOfContact")); + xmlAddChild(psCNode, _msMetadataGetCodeList(namespace, "role", "CI_RoleCode", + "pointOfContact")); return psNode; } - /************************************************************************/ /* _msMetadataGetIdentificationInfo */ /* */ /* Create a gmd:identificationInfo element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetIdentificationInfo(xmlNsPtr namespace, mapObj *map, layerObj *layer, xmlNsPtr *ppsNsGco) -{ +static xmlNodePtr _msMetadataGetIdentificationInfo(xmlNsPtr namespace, + mapObj *map, layerObj *layer, + xmlNsPtr *ppsNsGco) { char *value; xmlNodePtr psNode = NULL; xmlNodePtr psDINode = NULL; @@ -489,61 +538,74 @@ xmlNodePtr _msMetadataGetIdentificationInfo(xmlNsPtr namespace, mapObj *map, lay psNode = xmlNewNode(namespace, BAD_CAST "identificationInfo"); - psDINode = xmlNewChild(psNode, namespace, BAD_CAST "MD_DataIdentification", NULL); + psDINode = + xmlNewChild(psNode, namespace, BAD_CAST "MD_DataIdentification", NULL); xmlNewProp(psDINode, BAD_CAST "id", BAD_CAST layer->name); psCNode = xmlNewChild(psDINode, namespace, BAD_CAST "citation", NULL); psCINode = xmlNewChild(psCNode, namespace, BAD_CAST "CI_Citation", NULL); value = (char *)msOWSLookupMetadata(&(layer->metadata), "MCFGO", "title"); if (!value) - value = (char *)msOWSLookupMetadata(&(layer->metadata), "S", "offering_name"); - xmlAddChild(psCINode, _msMetadataGetCharacterString(namespace, "title", value, ppsNsGco)); + value = + (char *)msOWSLookupMetadata(&(layer->metadata), "S", "offering_name"); + xmlAddChild(psCINode, _msMetadataGetCharacterString(namespace, "title", value, + ppsNsGco)); psDNode = xmlNewChild(psCINode, namespace, BAD_CAST "date", NULL); xmlNewNsProp(psDNode, *ppsNsGco, BAD_CAST "nilReason", BAD_CAST "missing"); - value = (char *)msOWSLookupMetadata(&(layer->metadata), "MCFGO", "attribution_title"); + value = (char *)msOWSLookupMetadata(&(layer->metadata), "MCFGO", + "attribution_title"); if (value) { - xmlAddChild(psCINode, _msMetadataGetCharacterString(namespace, "otherCitationDetails", value, ppsNsGco)); + xmlAddChild(psCINode, + _msMetadataGetCharacterString(namespace, "otherCitationDetails", + value, ppsNsGco)); } value = (char *)msOWSLookupMetadata(&(layer->metadata), "MCFGO", "abstract"); if (!value) - value = (char *)msOWSLookupMetadata(&(layer->metadata), "S", "offering_description"); - xmlAddChild(psDINode, _msMetadataGetCharacterString(namespace, "abstract", value, ppsNsGco)); + value = (char *)msOWSLookupMetadata(&(layer->metadata), "S", + "offering_description"); + xmlAddChild(psDINode, _msMetadataGetCharacterString(namespace, "abstract", + value, ppsNsGco)); - value = (char *)msOWSLookupMetadata(&(layer->metadata), "MCFSGO", "keywordlist"); + value = + (char *)msOWSLookupMetadata(&(layer->metadata), "MCFSGO", "keywordlist"); if (value) { - psKWNode = xmlNewChild(psDINode, namespace, BAD_CAST "descriptiveKeywords", NULL); + psKWNode = + xmlNewChild(psDINode, namespace, BAD_CAST "descriptiveKeywords", NULL); psMDKNode = xmlNewChild(psKWNode, namespace, BAD_CAST "MD_Keywords", NULL); int n = 0; - char** tokens = msStringSplit(value, ',', &n); + char **tokens = msStringSplit(value, ',', &n); if (tokens && n > 0) { - for (int i=0; itype == MS_LAYER_RASTER) { - psSRNode = xmlNewChild(psNode, namespace, BAD_CAST "MD_GridSpatialRepresentation", NULL); - xmlAddChild(psSRNode, _msMetadataGetInteger(namespace, "numberOfDimensions", 2, ppsNsGco)); - xmlAddChild(psSRNode, _msMetadataGetCodeList(namespace, "cellGeometry", "MD_CellGeometryCode", "area")); - } - else { - psSRNode = xmlNewChild(psNode, namespace, BAD_CAST "MD_VectorSpatialRepresentation", NULL); - xmlAddChild(psSRNode, _msMetadataGetCodeList(namespace, "topologyLevel", "MD_TopologyLevelCode", "geometryOnly")); - psGONode = xmlNewChild(psSRNode, namespace, BAD_CAST "geometricObjects", NULL); - psGONode2 = xmlNewChild(psGONode, namespace, BAD_CAST "MD_GeometricObjects", NULL); + psSRNode = xmlNewChild(psNode, namespace, + BAD_CAST "MD_GridSpatialRepresentation", NULL); + xmlAddChild(psSRNode, _msMetadataGetInteger(namespace, "numberOfDimensions", + 2, ppsNsGco)); + xmlAddChild(psSRNode, + _msMetadataGetCodeList(namespace, "cellGeometry", + "MD_CellGeometryCode", "area")); + } else { + psSRNode = xmlNewChild(psNode, namespace, + BAD_CAST "MD_VectorSpatialRepresentation", NULL); + xmlAddChild(psSRNode, + _msMetadataGetCodeList(namespace, "topologyLevel", + "MD_TopologyLevelCode", "geometryOnly")); + psGONode = + xmlNewChild(psSRNode, namespace, BAD_CAST "geometricObjects", NULL); + psGONode2 = + xmlNewChild(psGONode, namespace, BAD_CAST "MD_GeometricObjects", NULL); if (layer->type == MS_LAYER_POINT) value = "point"; else if (layer->type == MS_LAYER_LINE) @@ -570,24 +640,27 @@ xmlNodePtr _msMetadataGetSpatialRepresentationInfo(xmlNsPtr namespace, layerObj value = "surface"; else value = "complex"; - xmlAddChild(psGONode2, _msMetadataGetCodeList(namespace, "geometricObjectType", "MD_GeometricObjectTypeCode", value)); + xmlAddChild(psGONode2, + _msMetadataGetCodeList(namespace, "geometricObjectType", + "MD_GeometricObjectTypeCode", value)); // TODO: find way to get feature count in a fast way - /* xmlAddChild(psGONode2, _msMetadataGetInteger(namespace, "geometricObjectCount", msLayerGetNumFeatures(layer))); */ + /* xmlAddChild(psGONode2, _msMetadataGetInteger(namespace, + * "geometricObjectCount", msLayerGetNumFeatures(layer))); */ } return psNode; } - /************************************************************************/ /* _msMetadataGetDistributionInfo */ /* */ /* Create a gmd:identificationInfo element pattern */ /************************************************************************/ -static -xmlNodePtr _msMetadataGetDistributionInfo(xmlNsPtr namespace, mapObj *map, layerObj *layer, cgiRequestObj *cgi_request, xmlNsPtr* ppsNsGco) -{ +static xmlNodePtr _msMetadataGetDistributionInfo(xmlNsPtr namespace, + mapObj *map, layerObj *layer, + cgiRequestObj *cgi_request, + xmlNsPtr *ppsNsGco) { char *url = NULL; xmlNodePtr psNode = NULL; xmlNodePtr psMDNode = NULL; @@ -600,35 +673,47 @@ xmlNodePtr _msMetadataGetDistributionInfo(xmlNsPtr namespace, mapObj *map, layer psMDNode = xmlNewChild(psNode, namespace, BAD_CAST "MD_Distribution", NULL); { - char* pszTmp = msOWSGetOnlineResource(map, "MFCSGO", "onlineresource", cgi_request); - url = msEncodeHTMLEntities(pszTmp); - msFree(pszTmp); + char *pszTmp = + msOWSGetOnlineResource(map, "MFCSGO", "onlineresource", cgi_request); + url = msEncodeHTMLEntities(pszTmp); + msFree(pszTmp); } /* gmd:distributor */ psDNode = xmlNewChild(psMDNode, namespace, BAD_CAST "distributor", NULL); psDNode2 = xmlNewChild(psDNode, namespace, BAD_CAST "MD_Distributor", NULL); - xmlAddChild(psDNode2, _msMetadataGetContact(namespace, "distributorContact", map, ppsNsGco)); + xmlAddChild(psDNode2, _msMetadataGetContact(namespace, "distributorContact", + map, ppsNsGco)); /* gmd:transferOptions */ psTONode = xmlNewChild(psMDNode, namespace, BAD_CAST "transferOptions", NULL); - psDTONode = xmlNewChild(psTONode, namespace, BAD_CAST "MD_DigitalTransferOptions", NULL); - xmlAddChild(psDTONode, _msMetadataGetCharacterString(namespace, "unitsOfDistribution", "KB", ppsNsGco)); + psDTONode = xmlNewChild(psTONode, namespace, + BAD_CAST "MD_DigitalTransferOptions", NULL); + xmlAddChild(psDTONode, _msMetadataGetCharacterString( + namespace, "unitsOfDistribution", "KB", ppsNsGco)); /* links */ /* WMS */ - xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "M", "image/png", "PNG Format", url, ppsNsGco)); - xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "M", "image/jpeg", "JPEG Format", url, ppsNsGco)); + xmlAddChild(psDTONode, + _msMetadataGetOnline(namespace, layer, "M", "image/png", + "PNG Format", url, ppsNsGco)); + xmlAddChild(psDTONode, + _msMetadataGetOnline(namespace, layer, "M", "image/jpeg", + "JPEG Format", url, ppsNsGco)); /* WCS */ if (layer->type == MS_LAYER_RASTER) { - xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "C", "image/tiff", "GeoTIFF Format", url, ppsNsGco)); + xmlAddChild(psDTONode, + _msMetadataGetOnline(namespace, layer, "C", "image/tiff", + "GeoTIFF Format", url, ppsNsGco)); } /* WFS */ else { - xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "F", "GML2", "GML2 Format", url, ppsNsGco)); - xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "F", "GML3", "GML3 Format", url, ppsNsGco)); + xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "F", "GML2", + "GML2 Format", url, ppsNsGco)); + xmlAddChild(psDTONode, _msMetadataGetOnline(namespace, layer, "F", "GML3", + "GML3 Format", url, ppsNsGco)); } msFree(url); @@ -642,28 +727,26 @@ xmlNodePtr _msMetadataGetDistributionInfo(xmlNsPtr namespace, mapObj *map, layer /* Generate an OWS Common Exception Report */ /************************************************************************/ -static -xmlNodePtr msMetadataGetExceptionReport(mapObj *map, char *code, char *locator, char *message, xmlNsPtr* ppsNsOws) -{ +static xmlNodePtr msMetadataGetExceptionReport(mapObj *map, char *code, + char *locator, char *message, + xmlNsPtr *ppsNsOws) { char *schemas_location = NULL; xmlNodePtr psRootNode = NULL; schemas_location = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); - *ppsNsOws = xmlNewNs(NULL, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows"); - - psRootNode = msOWSCommonExceptionReport(*ppsNsOws, - OWS_1_1_0, - schemas_location, - "1.1.0", - msOWSGetLanguage(map, "exception"), - code, locator, message); + *ppsNsOws = + xmlNewNs(NULL, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows"); + + psRootNode = msOWSCommonExceptionReport( + *ppsNsOws, OWS_1_1_0, schemas_location, "1.1.0", + msOWSGetLanguage(map, "exception"), code, locator, message); msFree(schemas_location); - xmlNewNs(psRootNode, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows"); + xmlNewNs(psRootNode, BAD_CAST "http://www.opengis.net/ows/1.1", + BAD_CAST "ows"); return psRootNode; - } /************************************************************************/ @@ -672,9 +755,11 @@ xmlNodePtr msMetadataGetExceptionReport(mapObj *map, char *code, char *locator, /* Generate an ISO 19139-1:2019 representation of layer metadata */ /************************************************************************/ -static -xmlNodePtr msMetadataGetLayerMetadata(mapObj *map, metadataParamsObj *paramsObj, cgiRequestObj *cgi_request, xmlNsPtr* ppsNsOws, xmlNsPtr* ppsNsXsi, xmlNsPtr* ppsNsGmd, xmlNsPtr* ppsNsGco) -{ +static xmlNodePtr +msMetadataGetLayerMetadata(mapObj *map, metadataParamsObj *paramsObj, + cgiRequestObj *cgi_request, xmlNsPtr *ppsNsOws, + xmlNsPtr *ppsNsXsi, xmlNsPtr *ppsNsGmd, + xmlNsPtr *ppsNsGco) { int i; int layer_found = MS_FALSE; @@ -682,74 +767,105 @@ xmlNodePtr msMetadataGetLayerMetadata(mapObj *map, metadataParamsObj *paramsObj, layerObj *layer = NULL; - /* Check that layer requested exists in mapfile */ - for (i=0; inumlayers; i++) { - if(strcasecmp(GET_LAYER(map, i)->name, paramsObj->pszLayer) == 0) { - layer_found = MS_TRUE; - layer = GET_LAYER(map, i); - // when checking a layer with clustering msLayerGetExtent does not have access - // to the source layer, so remove clustering first - if (layer->cluster.region) { - layer->cluster.region = NULL; - } - break; + /* Check that layer requested exists in mapfile */ + for (i = 0; i < map->numlayers; i++) { + if (strcasecmp(GET_LAYER(map, i)->name, paramsObj->pszLayer) == 0) { + layer_found = MS_TRUE; + layer = GET_LAYER(map, i); + // when checking a layer with clustering msLayerGetExtent does not have + // access to the source layer, so remove clustering first + if (layer->cluster.region) { + layer->cluster.region = NULL; + } + break; } } if (layer_found == MS_FALSE) { - psRootNode = msMetadataGetExceptionReport(map, "InvalidParameterValue", "layer", "Layer not found", ppsNsOws); + psRootNode = msMetadataGetExceptionReport( + map, "InvalidParameterValue", "layer", "Layer not found", ppsNsOws); } /* Check that outputschema is valid */ - else if (paramsObj->pszOutputSchema && strcasecmp(paramsObj->pszOutputSchema, "http://www.isotc211.org/2005/gmd") != 0) { - psRootNode = msMetadataGetExceptionReport(map, "InvalidParameterValue", "outputschema", "OUTPUTSCHEMA must be \"http://www.isotc211.org/2005/gmd\"", ppsNsOws); + else if (paramsObj->pszOutputSchema && + strcasecmp(paramsObj->pszOutputSchema, + "http://www.isotc211.org/2005/gmd") != 0) { + psRootNode = msMetadataGetExceptionReport( + map, "InvalidParameterValue", "outputschema", + "OUTPUTSCHEMA must be \"http://www.isotc211.org/2005/gmd\"", ppsNsOws); } else { - *ppsNsXsi = xmlNewNs(NULL, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", BAD_CAST "xsi"); - *ppsNsGmd = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gmd"); + *ppsNsXsi = + xmlNewNs(NULL, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", + BAD_CAST "xsi"); + *ppsNsGmd = xmlNewNs(NULL, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gmd"); /* root element */ psRootNode = xmlNewNode(NULL, BAD_CAST "MD_Metadata"); - xmlNewNs(psRootNode, BAD_CAST "http://www.isotc211.org/2005/gmd", BAD_CAST "gmd"); - xmlNewNs(psRootNode, BAD_CAST "http://www.isotc211.org/2005/gco", BAD_CAST "gco"); - xmlNewNs(psRootNode, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", BAD_CAST "xsi"); + xmlNewNs(psRootNode, BAD_CAST "http://www.isotc211.org/2005/gmd", + BAD_CAST "gmd"); + xmlNewNs(psRootNode, BAD_CAST "http://www.isotc211.org/2005/gco", + BAD_CAST "gco"); + xmlNewNs(psRootNode, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", + BAD_CAST "xsi"); xmlSetNs(psRootNode, *ppsNsGmd); - xmlNewNsProp(psRootNode, *ppsNsXsi, BAD_CAST "schemaLocation", BAD_CAST "http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmd/gmd.xsd"); + xmlNewNsProp(psRootNode, *ppsNsXsi, BAD_CAST "schemaLocation", + BAD_CAST "http://www.isotc211.org/2005/gmd " + "http://www.isotc211.org/2005/gmd/gmd.xsd"); /* gmd:identifier */ - xmlAddChild(psRootNode, _msMetadataGetCharacterString(*ppsNsGmd, "fileIdentifier", layer->name, ppsNsGco)); + xmlAddChild(psRootNode, + _msMetadataGetCharacterString(*ppsNsGmd, "fileIdentifier", + layer->name, ppsNsGco)); /* gmd:language */ - xmlAddChild(psRootNode, _msMetadataGetCharacterString(*ppsNsGmd, "language", (char *)msOWSGetLanguage(map, "exception"), ppsNsGco)); + xmlAddChild(psRootNode, + _msMetadataGetCharacterString( + *ppsNsGmd, "language", + (char *)msOWSGetLanguage(map, "exception"), ppsNsGco)); /* gmd:hierarchyLevel */ - xmlAddChild(psRootNode, _msMetadataGetCodeList(*ppsNsGmd, "hierarchyLevel", "MD_ScopeCode", "dataset")); + xmlAddChild(psRootNode, _msMetadataGetCodeList(*ppsNsGmd, "hierarchyLevel", + "MD_ScopeCode", "dataset")); /* gmd:contact */ - xmlAddChild(psRootNode, _msMetadataGetContact(*ppsNsGmd, "contact", map, ppsNsGco)); + xmlAddChild(psRootNode, + _msMetadataGetContact(*ppsNsGmd, "contact", map, ppsNsGco)); /* gmd:dateStamp */ /* TODO: nil for now, find way to derive this automagically */ - xmlAddChild(psRootNode, _msMetadataGetCharacterString(*ppsNsGmd, "dateStamp", NULL, ppsNsGco)); + xmlAddChild(psRootNode, _msMetadataGetCharacterString( + *ppsNsGmd, "dateStamp", NULL, ppsNsGco)); /* gmd:metadataStandardName */ - xmlAddChild(psRootNode, _msMetadataGetCharacterString(*ppsNsGmd, "metadataStandardName", "ISO 19115:2003 - Geographic information - Metadata", ppsNsGco)); + xmlAddChild(psRootNode, + _msMetadataGetCharacterString( + *ppsNsGmd, "metadataStandardName", + "ISO 19115:2003 - Geographic information - Metadata", + ppsNsGco)); /* gmd:metadataStandardVersion */ - xmlAddChild(psRootNode, _msMetadataGetCharacterString(*ppsNsGmd, "metadataStandardVersion", "ISO 19115:2003", ppsNsGco)); + xmlAddChild(psRootNode, _msMetadataGetCharacterString( + *ppsNsGmd, "metadataStandardVersion", + "ISO 19115:2003", ppsNsGco)); /* gmd:spatialRepresentationInfo */ - xmlAddChild(psRootNode, _msMetadataGetSpatialRepresentationInfo(*ppsNsGmd, layer, ppsNsGco)); + xmlAddChild(psRootNode, _msMetadataGetSpatialRepresentationInfo( + *ppsNsGmd, layer, ppsNsGco)); /* gmd:referenceSystemInfo */ - xmlAddChild(psRootNode, _msMetadataGetReferenceSystemInfo(*ppsNsGmd, layer, ppsNsGco)); + xmlAddChild(psRootNode, + _msMetadataGetReferenceSystemInfo(*ppsNsGmd, layer, ppsNsGco)); /* gmd:identificationInfo */ - xmlAddChild(psRootNode, _msMetadataGetIdentificationInfo(*ppsNsGmd, map, layer, ppsNsGco)); + xmlAddChild(psRootNode, _msMetadataGetIdentificationInfo(*ppsNsGmd, map, + layer, ppsNsGco)); /* gmd:distributionInfo */ - xmlAddChild(psRootNode, _msMetadataGetDistributionInfo(*ppsNsGmd, map, layer, cgi_request, ppsNsGco)); + xmlAddChild(psRootNode, _msMetadataGetDistributionInfo( + *ppsNsGmd, map, layer, cgi_request, ppsNsGco)); } return psRootNode; @@ -761,15 +877,14 @@ xmlNodePtr msMetadataGetLayerMetadata(mapObj *map, metadataParamsObj *paramsObj, /* Entry point for metadata requests. */ /* */ /* - If this is a valid request then it is processed and MS_SUCCESS */ -/* is returned on success, or MS_FAILURE on failure. */ +/* is returned on success, or MS_FAILURE on failure. */ /* */ /* - If this does not appear to be a valid WFS request then MS_DONE */ /* is returned and MapServer is expected to process this as a regular */ /* MapServer request. */ /************************************************************************/ -int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) -{ +int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) { int i; int status = MS_SUCCESS; xmlNodePtr psRootNode = NULL; @@ -788,31 +903,37 @@ int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) xml_document = xmlNewDoc(BAD_CAST "1.0"); if (msMetadataParseRequest(cgi_request, paramsObj) == MS_FAILURE) { - psRootNode = msMetadataGetExceptionReport(map, "InvalidRequest", "layer", "Request parsing failed", &psNsOws); + psRootNode = msMetadataGetExceptionReport( + map, "InvalidRequest", "layer", "Request parsing failed", &psNsOws); status = MS_FAILURE; } /* if layer= is not specified, */ - if (paramsObj->pszLayer==NULL || strlen(paramsObj->pszLayer)==0) { - psRootNode = msMetadataGetExceptionReport(map, "MissingParameterValue", "layer", "Missing layer parameter", &psNsOws); + if (paramsObj->pszLayer == NULL || strlen(paramsObj->pszLayer) == 0) { + psRootNode = + msMetadataGetExceptionReport(map, "MissingParameterValue", "layer", + "Missing layer parameter", &psNsOws); status = MS_FAILURE; } if (status == MS_SUCCESS) { /* Start dispatching request */ /* Check that layer requested exists in mapfile */ - for (i=0; inumlayers; i++) { - if(strcasecmp(GET_LAYER(map, i)->name, paramsObj->pszLayer) == 0) { + for (i = 0; i < map->numlayers; i++) { + if (strcasecmp(GET_LAYER(map, i)->name, paramsObj->pszLayer) == 0) { layer = GET_LAYER(map, i); break; } } - if (layer != NULL && msOWSLookupMetadata(&(layer->metadata), "MFCO", "metadataurl_href")) { + if (layer != NULL && + msOWSLookupMetadata(&(layer->metadata), "MFCO", "metadataurl_href")) { msIO_setHeader("Status", "301 Moved Permanently"); - msIO_setHeader("Location", "%s", msOWSLookupMetadata(&(layer->metadata), "MFCO", "metadataurl_href")); + msIO_setHeader( + "Location", "%s", + msOWSLookupMetadata(&(layer->metadata), "MFCO", "metadataurl_href")); msIO_sendHeaders(); - } - else { - psRootNode = msMetadataGetLayerMetadata(map, paramsObj, cgi_request, &psNsOws, &psNsXsi, &psNsGmd, &psNsGco); + } else { + psRootNode = msMetadataGetLayerMetadata( + map, paramsObj, cgi_request, &psNsOws, &psNsXsi, &psNsGmd, &psNsGco); } } @@ -824,24 +945,25 @@ int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) msIO_setHeader("Content-type", "text/xml; charset=UTF-8"); msIO_sendHeaders(); - msIOContext* context = NULL; + msIOContext *context = NULL; context = msIO_getHandler(stdout); - xmlDocDumpFormatMemoryEnc(xml_document, &xml_buffer, &buffersize, "UTF-8", 1); + xmlDocDumpFormatMemoryEnc(xml_document, &xml_buffer, &buffersize, "UTF-8", + 1); msIO_contextWrite(context, xml_buffer, buffersize); xmlFree(xml_buffer); } xmlFreeDoc(xml_document); - if( psNsOws ) - xmlFreeNs(psNsOws); - if( psNsXsi ) - xmlFreeNs(psNsXsi); - if( psNsGmd ) - xmlFreeNs(psNsGmd); - if( psNsGco ) - xmlFreeNs(psNsGco); + if (psNsOws) + xmlFreeNs(psNsOws); + if (psNsXsi) + xmlFreeNs(psNsXsi); + if (psNsGmd) + xmlFreeNs(psNsGmd); + if (psNsGco) + xmlFreeNs(psNsGco); msMetadataFreeParamsObj(paramsObj); @@ -857,9 +979,9 @@ int msMetadataDispatch(mapObj *map, cgiRequestObj *cgi_request) /* The caller should free the object using msMetadataFreeParamsObj. */ /************************************************************************/ -metadataParamsObj *msMetadataCreateParamsObj() -{ - metadataParamsObj *paramsObj = (metadataParamsObj *)calloc(1, sizeof(metadataParamsObj)); +metadataParamsObj *msMetadataCreateParamsObj() { + metadataParamsObj *paramsObj = + (metadataParamsObj *)calloc(1, sizeof(metadataParamsObj)); MS_CHECK_ALLOC(paramsObj, sizeof(metadataParamsObj), NULL); paramsObj->pszLayer = NULL; @@ -867,15 +989,13 @@ metadataParamsObj *msMetadataCreateParamsObj() return paramsObj; } - /************************************************************************/ /* msMetadataFreeParmsObj */ /* */ /* Free params object. */ /************************************************************************/ -void msMetadataFreeParamsObj(metadataParamsObj *metadataparams) -{ +void msMetadataFreeParamsObj(metadataParamsObj *metadataparams) { if (metadataparams) { free(metadataparams->pszRequest); free(metadataparams->pszLayer); @@ -884,22 +1004,19 @@ void msMetadataFreeParamsObj(metadataParamsObj *metadataparams) } } - /************************************************************************/ /* msMetadataParseRequest */ /* */ /* Parse request into the params object. */ /************************************************************************/ -static -int msMetadataParseRequest(cgiRequestObj *request, - metadataParamsObj *metadataparams) -{ +static int msMetadataParseRequest(cgiRequestObj *request, + metadataParamsObj *metadataparams) { if (!request || !metadataparams) return MS_FAILURE; if (request->NumParams > 0) { - for(int i=0; iNumParams; i++) { + for (int i = 0; i < request->NumParams; i++) { if (request->ParamNames[i] && request->ParamValues[i]) { if (strcasecmp(request->ParamNames[i], "LAYER") == 0) metadataparams->pszLayer = msStrdup(request->ParamValues[i]); @@ -917,13 +1034,13 @@ int msMetadataParseRequest(cgiRequestObj *request, /* Parse request into the params object. */ /************************************************************************/ -void msMetadataSetGetMetadataURL(layerObj *lp, const char *url) -{ - char *pszMetadataURL=NULL; +void msMetadataSetGetMetadataURL(layerObj *lp, const char *url) { + char *pszMetadataURL = NULL; pszMetadataURL = msStrdup(url); msDecodeHTMLEntities(pszMetadataURL); - pszMetadataURL = msStringConcatenate(pszMetadataURL, "request=GetMetadata&layer="); + pszMetadataURL = + msStringConcatenate(pszMetadataURL, "request=GetMetadata&layer="); pszMetadataURL = msStringConcatenate(pszMetadataURL, lp->name); msInsertHashTable(&(lp->metadata), "ows_metadataurl_href", pszMetadataURL); diff --git a/mapmssql2008.c b/mapmssql2008.c index 95744a51d2..d59be099b1 100644 --- a/mapmssql2008.c +++ b/mapmssql2008.c @@ -87,9 +87,9 @@ SerializationProps (bitmask) 1 byte 0x10 = IsSingleLineSegment 0x20 = IsLargerThanAHemisphere -Point (2-4)x8 bytes, size depends on SerializationProps & HasZValues & HasMValues - [x][y] - SqlGeometry - [latitude][longitude] - SqlGeography +Point (2-4)x8 bytes, size depends on SerializationProps & HasZValues & +HasMValues [x][y] - SqlGeometry [latitude][longitude] - +SqlGeography Figure [FigureAttribute][PointOffset] @@ -145,7 +145,7 @@ SegmentType (1 byte) #define MSSQLGEOMETRY_WKT 2 /* geometry column types */ -#define MSSQLCOLTYPE_GEOMETRY 0 +#define MSSQLCOLTYPE_GEOMETRY 0 #define MSSQLCOLTYPE_GEOGRAPHY 1 #define MSSQLCOLTYPE_BINARY 2 #define MSSQLCOLTYPE_TEXT 3 @@ -176,27 +176,32 @@ SegmentType (1 byte) #define SMT_FIRSTLINE 2 #define SMT_FIRSTARC 3 -#define ReadInt32(nPos) (*((unsigned int*)(gpi->pszData + (nPos)))) +#define ReadInt32(nPos) (*((unsigned int *)(gpi->pszData + (nPos)))) #define ReadByte(nPos) (gpi->pszData[nPos]) -#define ReadDouble(nPos) (*((double*)(gpi->pszData + (nPos)))) +#define ReadDouble(nPos) (*((double *)(gpi->pszData + (nPos)))) -#define ParentOffset(iShape) (ReadInt32(gpi->nShapePos + (iShape) * 9 )) -#define FigureOffset(iShape) (ReadInt32(gpi->nShapePos + (iShape) * 9 + 4)) -#define ShapeType(iShape) (ReadByte(gpi->nShapePos + (iShape) * 9 + 8)) +#define ParentOffset(iShape) (ReadInt32(gpi->nShapePos + (iShape)*9)) +#define FigureOffset(iShape) (ReadInt32(gpi->nShapePos + (iShape)*9 + 4)) +#define ShapeType(iShape) (ReadByte(gpi->nShapePos + (iShape)*9 + 8)) #define SegmentType(iSegment) (ReadByte(gpi->nSegmentPos + (iSegment))) -#define NextFigureOffset(iShape) (iShape + 1 < gpi->nNumShapes? FigureOffset((iShape) +1) : gpi->nNumFigures) +#define NextFigureOffset(iShape) \ + (iShape + 1 < gpi->nNumShapes ? FigureOffset((iShape) + 1) : gpi->nNumFigures) -#define FigureAttribute(iFigure) (ReadByte(gpi->nFigurePos + (iFigure) * 5)) -#define PointOffset(iFigure) (ReadInt32(gpi->nFigurePos + (iFigure) * 5 + 1)) -#define NextPointOffset(iFigure) (iFigure + 1 < gpi->nNumFigures? PointOffset((iFigure) +1) : (unsigned)gpi->nNumPoints) +#define FigureAttribute(iFigure) (ReadByte(gpi->nFigurePos + (iFigure)*5)) +#define PointOffset(iFigure) (ReadInt32(gpi->nFigurePos + (iFigure)*5 + 1)) +#define NextPointOffset(iFigure) \ + (iFigure + 1 < gpi->nNumFigures ? PointOffset((iFigure) + 1) \ + : (unsigned)gpi->nNumPoints) #define ReadX(iPoint) (ReadDouble(gpi->nPointPos + 16 * (iPoint))) #define ReadY(iPoint) (ReadDouble(gpi->nPointPos + 16 * (iPoint) + 8)) -#define ReadZ(iPoint) (ReadDouble(gpi->nPointPos + 16 * gpi->nNumPoints + 8 * (iPoint))) -#define ReadM(iPoint) (ReadDouble(gpi->nPointPos + 24 * gpi->nNumPoints + 8 * (iPoint))) +#define ReadZ(iPoint) \ + (ReadDouble(gpi->nPointPos + 16 * gpi->nNumPoints + 8 * (iPoint))) +#define ReadM(iPoint) \ + (ReadDouble(gpi->nPointPos + 24 * gpi->nNumPoints + 8 * (iPoint))) #define FP_EPSILON 1e-12 #define SEGMENT_ANGLE 5.0 @@ -204,7 +209,7 @@ SegmentType (1 byte) /* Native geometry parser struct */ typedef struct msGeometryParserInfo_t { - unsigned char* pszData; + unsigned char *pszData; int nLen; /* version */ char chVersion; @@ -234,48 +239,58 @@ typedef struct msGeometryParserInfo_t { double maxy; } msGeometryParserInfo; -/* Structure for connection to an ODBC database (Microsoft preferred way to connect to SQL Server 2005 from c/c++) */ +/* Structure for connection to an ODBC database (Microsoft preferred way to + * connect to SQL Server 2005 from c/c++) */ typedef struct msODBCconn_t { - SQLHENV henv; /* ODBC HENV */ - SQLHDBC hdbc; /* ODBC HDBC */ - SQLHSTMT hstmt; /* ODBC HSTMNT */ - char errorMessage[1024]; /* Last error message if any */ + SQLHENV henv; /* ODBC HENV */ + SQLHDBC hdbc; /* ODBC HDBC */ + SQLHSTMT hstmt; /* ODBC HSTMNT */ + char errorMessage[1024]; /* Last error message if any */ } msODBCconn; typedef struct ms_MSSQL2008_layer_info_t { - char *sql; /* sql query to send to DB */ - long row_num; /* what row is the NEXT to be read (for random access) */ - char *geom_column; /* name of the actual geometry column parsed from the LAYER's DATA field */ - char *geom_column_type; /* the type of the geometry column */ - char *geom_table; /* the table name or sub-select decalred in the LAYER's DATA field */ - char *urid_name; /* name of user-specified unique identifier or OID */ - char *user_srid; /* zero length = calculate, non-zero means using this value! */ - char *index_name; /* hopefully this isn't necessary - but if the optimizer ain't cuttin' it... */ - char *sort_spec; /* the sort by specification which should be applied to the generated select statement */ + char *sql; /* sql query to send to DB */ + long row_num; /* what row is the NEXT to be read (for random access) */ + char *geom_column; /* name of the actual geometry column parsed from the + LAYER's DATA field */ + char *geom_column_type; /* the type of the geometry column */ + char *geom_table; /* the table name or sub-select decalred in the LAYER's DATA + field */ + char *urid_name; /* name of user-specified unique identifier or OID */ + char * + user_srid; /* zero length = calculate, non-zero means using this value! */ + char *index_name; /* hopefully this isn't necessary - but if the optimizer + ain't cuttin' it... */ + char *sort_spec; /* the sort by specification which should be applied to the + generated select statement */ int mssqlversion_major; /* the sql server major version number */ - int paging; /* Driver handling of pagination, enabled by default */ - SQLSMALLINT *itemtypes; /* storing the sql field types for further reference */ + int paging; /* Driver handling of pagination, enabled by default */ + SQLSMALLINT + *itemtypes; /* storing the sql field types for further reference */ - msODBCconn * conn; /* Connection to db */ - msGeometryParserInfo gpi; /* struct for the geometry parser */ - int geometry_format; /* Geometry format to be retrieved from the database */ + msODBCconn *conn; /* Connection to db */ + msGeometryParserInfo gpi; /* struct for the geometry parser */ + int geometry_format; /* Geometry format to be retrieved from the database */ tokenListNodeObjPtr current_node; /* filter expression translation */ } msMSSQL2008LayerInfo; #define SQL_COLUMN_NAME_MAX_LENGTH 128 #define SQL_TABLE_NAME_MAX_LENGTH 128 -#define DATA_ERROR_MESSAGE \ - "%s" \ - "Error with MSSQL2008 data variable. You specified '%s'.
\n" \ - "Standard ways of specifiying are :
\n(1) 'geometry_column from geometry_table'
\n(2) 'geometry_column from (<sub query>) as foo using unique <column name> using SRID=<srid#>'

\n\n" \ - "Make sure you utilize the 'using unique <column name>' and 'using with <index name>' clauses in.\n\n

" \ - "For more help, please see http://www.mapdotnet.com \n\n

" \ - "mapmssql2008.c - version of 2007/7/1.\n" +#define DATA_ERROR_MESSAGE \ + "%s" \ + "Error with MSSQL2008 data variable. You specified '%s'.
\n" \ + "Standard ways of specifiying are :
\n(1) 'geometry_column from " \ + "geometry_table'
\n(2) 'geometry_column from (<sub query>) as " \ + "foo using unique <column name> using SRID=<srid#>' " \ + "

\n\n" \ + "Make sure you utilize the 'using unique <column name>' and 'using " \ + "with <index name>' clauses in.\n\n

" \ + "For more help, please see http://www.mapdotnet.com \n\n

" \ + "mapmssql2008.c - version of 2007/7/1.\n" /* Native geometry parser code */ -void ReadPoint(msGeometryParserInfo* gpi, pointObj* p, int iPoint) -{ +void ReadPoint(msGeometryParserInfo *gpi, pointObj *p, int iPoint) { if (gpi->nColType == MSSQLCOLTYPE_GEOGRAPHY) { p->x = ReadY(iPoint); p->y = ReadX(iPoint); @@ -288,131 +303,130 @@ void ReadPoint(msGeometryParserInfo* gpi, pointObj* p, int iPoint) gpi->minx = gpi->maxx = p->x; gpi->miny = gpi->maxy = p->y; } else { - if (gpi->minx > p->x) gpi->minx = p->x; - else if (gpi->maxx < p->x) gpi->maxx = p->x; - if (gpi->miny > p->y) gpi->miny = p->y; - else if (gpi->maxy < p->y) gpi->maxy = p->y; + if (gpi->minx > p->x) + gpi->minx = p->x; + else if (gpi->maxx < p->x) + gpi->maxx = p->x; + if (gpi->miny > p->y) + gpi->miny = p->y; + else if (gpi->maxy < p->y) + gpi->maxy = p->y; } - if ((gpi->chProps & SP_HASZVALUES) && (gpi->chProps & SP_HASMVALUES)) - { + if ((gpi->chProps & SP_HASZVALUES) && (gpi->chProps & SP_HASMVALUES)) { p->z = ReadZ(iPoint); p->m = ReadM(iPoint); - } - else if (gpi->chProps & SP_HASZVALUES) - { - p->z = ReadZ(iPoint); - p->m = 0.0; - } - else if (gpi->chProps & SP_HASMVALUES) - { - p->z = 0.0; - p->m = ReadZ(iPoint); - } - else - { - p->z = 0.0; - p->m = 0.0; + } else if (gpi->chProps & SP_HASZVALUES) { + p->z = ReadZ(iPoint); + p->m = 0.0; + } else if (gpi->chProps & SP_HASMVALUES) { + p->z = 0.0; + p->m = ReadZ(iPoint); + } else { + p->z = 0.0; + p->m = 0.0; } } -int StrokeArcToLine(msGeometryParserInfo* gpi, lineObj* line, int index) -{ - if (index > 1) { - double x, y, x1, y1, x2, y2, x3, y3, dxa, dya, sxa, sya, dxb, dyb; - double d, sxb, syb, ox, oy, a1, a3, sa, da, a, radius; - int numpoints; - double z; - z = line->point[index].z; /* must be equal for arc segments */ - /* first point */ - x1 = line->point[index - 2].x; - y1 = line->point[index - 2].y; - /* second point */ - x2 = line->point[index - 1].x; - y2 = line->point[index - 1].y; - /* third point */ - x3 = line->point[index].x; - y3 = line->point[index].y; - - sxa = (x1 + x2); - sya = (y1 + y2); - dxa = x2 - x1; - dya = y2 - y1; - - sxb = (x2 + x3); - syb = (y2 + y3); - dxb = x3 - x2; - dyb = y3 - y2; - - d = (dxa * dyb - dya * dxb) * 2; - - if (fabs(d) < FP_EPSILON) { - /* points are colinear, nothing to do here */ - return index; - } - - /* calculating the center of circle */ - ox = ((sya - syb) * dya * dyb + sxa * dyb * dxa - sxb * dya * dxb) / d; - oy = ((sxb - sxa) * dxa * dxb + syb * dyb * dxa - sya * dya * dxb) / d; - - radius = sqrt((x1 - ox) * (x1 - ox) + (y1 - oy) * (y1 - oy)); - - /* calculating the angle to be used */ - a1 = atan2(y1 - oy, x1 - ox); - a3 = atan2(y3 - oy, x3 - ox); - - if (d > 0) { - /* draw counterclockwise */ - if (a3 > a1) /* Wrapping past 180? */ - sa = a3 - a1; - else - sa = a3 - a1 + 2.0 * M_PI ; - } - else { - if (a3 > a1) /* Wrapping past 180? */ - sa = a3 - a1 + 2.0 * M_PI; - else - sa = a3 - a1; - } - - numpoints = (int)floor(fabs(sa) * 180 / SEGMENT_ANGLE / M_PI); - if (numpoints < SEGMENT_MINPOINTS) - numpoints = SEGMENT_MINPOINTS; +int StrokeArcToLine(msGeometryParserInfo *gpi, lineObj *line, int index) { + if (index > 1) { + double x, y, x1, y1, x2, y2, x3, y3, dxa, dya, sxa, sya, dxb, dyb; + double d, sxb, syb, ox, oy, a1, a3, sa, da, a, radius; + int numpoints; + double z; + z = line->point[index].z; /* must be equal for arc segments */ + /* first point */ + x1 = line->point[index - 2].x; + y1 = line->point[index - 2].y; + /* second point */ + x2 = line->point[index - 1].x; + y2 = line->point[index - 1].y; + /* third point */ + x3 = line->point[index].x; + y3 = line->point[index].y; + + sxa = (x1 + x2); + sya = (y1 + y2); + dxa = x2 - x1; + dya = y2 - y1; + + sxb = (x2 + x3); + syb = (y2 + y3); + dxb = x3 - x2; + dyb = y3 - y2; + + d = (dxa * dyb - dya * dxb) * 2; + + if (fabs(d) < FP_EPSILON) { + /* points are colinear, nothing to do here */ + return index; + } - da = sa / numpoints; + /* calculating the center of circle */ + ox = ((sya - syb) * dya * dyb + sxa * dyb * dxa - sxb * dya * dxb) / d; + oy = ((sxb - sxa) * dxa * dxb + syb * dyb * dxa - sya * dya * dxb) / d; - /* extend the point array */ - line->numpoints += numpoints - 2; - line->point = msSmallRealloc(line->point, sizeof(pointObj) * line->numpoints); - --index; + radius = sqrt((x1 - ox) * (x1 - ox) + (y1 - oy) * (y1 - oy)); - a = a1 + da; - while (numpoints > 1) { - line->point[index].x = x = ox + radius * cos(a); - line->point[index].y = y = oy + radius * sin(a); - line->point[index].z = z; + /* calculating the angle to be used */ + a1 = atan2(y1 - oy, x1 - ox); + a3 = atan2(y3 - oy, x3 - ox); - /* calculate bounds */ - if (gpi->minx > x) gpi->minx = x; - else if (gpi->maxx < x) gpi->maxx = x; - if (gpi->miny > y) gpi->miny = y; - else if (gpi->maxy < y) gpi->maxy = y; + if (d > 0) { + /* draw counterclockwise */ + if (a3 > a1) /* Wrapping past 180? */ + sa = a3 - a1; + else + sa = a3 - a1 + 2.0 * M_PI; + } else { + if (a3 > a1) /* Wrapping past 180? */ + sa = a3 - a1 + 2.0 * M_PI; + else + sa = a3 - a1; + } - a += da; - ++index; - --numpoints; - } - /* set last point */ - line->point[index].x = x3; - line->point[index].y = y3; - line->point[index].z = z; + numpoints = (int)floor(fabs(sa) * 180 / SEGMENT_ANGLE / M_PI); + if (numpoints < SEGMENT_MINPOINTS) + numpoints = SEGMENT_MINPOINTS; + + da = sa / numpoints; + + /* extend the point array */ + line->numpoints += numpoints - 2; + line->point = + msSmallRealloc(line->point, sizeof(pointObj) * line->numpoints); + --index; + + a = a1 + da; + while (numpoints > 1) { + line->point[index].x = x = ox + radius * cos(a); + line->point[index].y = y = oy + radius * sin(a); + line->point[index].z = z; + + /* calculate bounds */ + if (gpi->minx > x) + gpi->minx = x; + else if (gpi->maxx < x) + gpi->maxx = x; + if (gpi->miny > y) + gpi->miny = y; + else if (gpi->maxy < y) + gpi->maxy = y; + + a += da; + ++index; + --numpoints; } - return index; + /* set last point */ + line->point[index].x = x3; + line->point[index].y = y3; + line->point[index].z = z; + } + return index; } -int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) -{ - msGeometryParserInfo* gpi = &layerinfo->gpi; +int ParseSqlGeometry(msMSSQL2008LayerInfo *layerinfo, shapeObj *shape) { + msGeometryParserInfo *gpi = &layerinfo->gpi; gpi->nNumPointsRead = 0; @@ -435,13 +449,13 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) gpi->nPointSize = 16; - if ( gpi->chProps & SP_HASMVALUES ) + if (gpi->chProps & SP_HASMVALUES) gpi->nPointSize += 8; - if ( gpi->chProps & SP_HASZVALUES ) + if (gpi->chProps & SP_HASZVALUES) gpi->nPointSize += 8; - if ( gpi->chProps & SP_ISSINGLEPOINT ) { + if (gpi->chProps & SP_ISSINGLEPOINT) { // single point geometry gpi->nNumPoints = 1; if (gpi->nLen < 6 + gpi->nPointSize) { @@ -450,14 +464,14 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) } shape->type = MS_SHAPE_POINT; - shape->line = (lineObj *) msSmallMalloc(sizeof(lineObj)); + shape->line = (lineObj *)msSmallMalloc(sizeof(lineObj)); shape->numlines = 1; - shape->line[0].point = (pointObj *) msSmallMalloc(sizeof(pointObj)); + shape->line[0].point = (pointObj *)msSmallMalloc(sizeof(pointObj)); shape->line[0].numpoints = 1; gpi->nPointPos = 6; ReadPoint(gpi, &shape->line[0].point[0], 0); - } else if ( gpi->chProps & SP_ISSINGLELINESEGMENT ) { + } else if (gpi->chProps & SP_ISSINGLELINESEGMENT) { // single line segment with 2 points gpi->nNumPoints = 2; if (gpi->nLen < 6 + 2 * gpi->nPointSize) { @@ -466,9 +480,9 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) } shape->type = MS_SHAPE_LINE; - shape->line = (lineObj *) msSmallMalloc(sizeof(lineObj)); + shape->line = (lineObj *)msSmallMalloc(sizeof(lineObj)); shape->numlines = 1; - shape->line[0].point = (pointObj *) msSmallMalloc(sizeof(pointObj) * 2); + shape->line[0].point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 2); shape->line[0].numpoints = 2; gpi->nPointPos = 6; @@ -479,7 +493,7 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) // complex geometries gpi->nNumPoints = ReadInt32(6); - if ( gpi->nNumPoints <= 0 ) { + if (gpi->nNumPoints <= 0) { return NOERROR; } @@ -496,7 +510,7 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) gpi->nNumFigures = ReadInt32(gpi->nFigurePos - 4); - if ( gpi->nNumFigures <= 0 ) { + if (gpi->nNumFigures <= 0) { return NOERROR; } @@ -515,12 +529,12 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) return NOT_ENOUGH_DATA; } - if ( gpi->nNumShapes <= 0 ) { + if (gpi->nNumShapes <= 0) { return NOERROR; } // pick up the root shape - if ( ParentOffset(0) != 0xFFFFFFFF) { + if (ParentOffset(0) != 0xFFFFFFFF) { msDebug("ParseSqlGeometry CORRUPT_DATA\n"); return CORRUPT_DATA; } @@ -531,19 +545,20 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) if (shapeType == ST_POINT || shapeType == ST_MULTIPOINT) { shape->type = MS_SHAPE_POINT; break; - } else if (shapeType == ST_LINESTRING || shapeType == ST_MULTILINESTRING || - shapeType == ST_CIRCULARSTRING || shapeType == ST_COMPOUNDCURVE) { + } else if (shapeType == ST_LINESTRING || + shapeType == ST_MULTILINESTRING || + shapeType == ST_CIRCULARSTRING || + shapeType == ST_COMPOUNDCURVE) { shape->type = MS_SHAPE_LINE; break; - } else if (shapeType == ST_POLYGON || shapeType == ST_MULTIPOLYGON || - shapeType == ST_CURVEPOLYGON) - { + } else if (shapeType == ST_POLYGON || shapeType == ST_MULTIPOLYGON || + shapeType == ST_CURVEPOLYGON) { shape->type = MS_SHAPE_POLYGON; break; } } - shape->line = (lineObj *) msSmallMalloc(sizeof(lineObj) * gpi->nNumFigures); + shape->line = (lineObj *)msSmallMalloc(sizeof(lineObj) * gpi->nNumFigures); shape->numlines = gpi->nNumFigures; gpi->nNumSegments = 0; @@ -553,61 +568,63 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) iPoint = PointOffset(iFigure); iNextPoint = NextPointOffset(iFigure); - shape->line[iFigure].point = (pointObj *) msSmallMalloc(sizeof(pointObj)*(iNextPoint - iPoint)); + shape->line[iFigure].point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * (iNextPoint - iPoint)); shape->line[iFigure].numpoints = iNextPoint - iPoint; i = 0; if (gpi->chVersion == 0x02 && FigureAttribute(iFigure) >= 0x02) { - int nPointPrepared = 0; - lineObj* line = &shape->line[iFigure]; - if (FigureAttribute(iFigure) == 0x03) { - if (gpi->nNumSegments == 0) { - /* position of the segment types */ - gpi->nSegmentPos = gpi->nShapePos + 9 * gpi->nNumShapes + 4; - gpi->nNumSegments = ReadInt32(gpi->nSegmentPos - 4); - if (gpi->nLen < gpi->nSegmentPos + gpi->nNumSegments) { - msDebug("ParseSqlGeometry NOT_ENOUGH_DATA\n"); - return NOT_ENOUGH_DATA; - } - iSegment = 0; - } - - while (iPoint < iNextPoint && iSegment < gpi->nNumSegments) { - ReadPoint(gpi, &line->point[i], iPoint); - ++iPoint; - ++nPointPrepared; - - if (nPointPrepared == 2 && (SegmentType(iSegment) == SMT_FIRSTLINE || SegmentType(iSegment) == SMT_LINE)) { - ++iSegment; - nPointPrepared = 1; - } - else if (nPointPrepared == 3 && (SegmentType(iSegment) == SMT_FIRSTARC || SegmentType(iSegment) == SMT_ARC)) { - i = StrokeArcToLine(gpi, line, i); - ++iSegment; - nPointPrepared = 1; - } - ++i; - } + int nPointPrepared = 0; + lineObj *line = &shape->line[iFigure]; + if (FigureAttribute(iFigure) == 0x03) { + if (gpi->nNumSegments == 0) { + /* position of the segment types */ + gpi->nSegmentPos = gpi->nShapePos + 9 * gpi->nNumShapes + 4; + gpi->nNumSegments = ReadInt32(gpi->nSegmentPos - 4); + if (gpi->nLen < gpi->nSegmentPos + gpi->nNumSegments) { + msDebug("ParseSqlGeometry NOT_ENOUGH_DATA\n"); + return NOT_ENOUGH_DATA; + } + iSegment = 0; } - else { - while (iPoint < iNextPoint) { - ReadPoint(gpi, &line->point[i], iPoint); - ++iPoint; - ++nPointPrepared; - if (nPointPrepared == 3) { - i = StrokeArcToLine(gpi, line, i); - nPointPrepared = 1; - } - ++i; - } + + while (iPoint < iNextPoint && iSegment < gpi->nNumSegments) { + ReadPoint(gpi, &line->point[i], iPoint); + ++iPoint; + ++nPointPrepared; + + if (nPointPrepared == 2 && + (SegmentType(iSegment) == SMT_FIRSTLINE || + SegmentType(iSegment) == SMT_LINE)) { + ++iSegment; + nPointPrepared = 1; + } else if (nPointPrepared == 3 && + (SegmentType(iSegment) == SMT_FIRSTARC || + SegmentType(iSegment) == SMT_ARC)) { + i = StrokeArcToLine(gpi, line, i); + ++iSegment; + nPointPrepared = 1; + } + ++i; } - } - else { + } else { while (iPoint < iNextPoint) { - ReadPoint(gpi, &shape->line[iFigure].point[i], iPoint); - ++iPoint; - ++i; + ReadPoint(gpi, &line->point[i], iPoint); + ++iPoint; + ++nPointPrepared; + if (nPointPrepared == 3) { + i = StrokeArcToLine(gpi, line, i); + nPointPrepared = 1; + } + ++i; } + } + } else { + while (iPoint < iNextPoint) { + ReadPoint(gpi, &shape->line[iFigure].point[i], iPoint); + ++iPoint; + ++i; + } } } } @@ -623,22 +640,20 @@ int ParseSqlGeometry(msMSSQL2008LayerInfo* layerinfo, shapeObj *shape) /* MS SQL driver code*/ -msMSSQL2008LayerInfo *getMSSQL2008LayerInfo(const layerObj *layer) -{ +msMSSQL2008LayerInfo *getMSSQL2008LayerInfo(const layerObj *layer) { return layer->layerinfo; } -void setMSSQL2008LayerInfo(layerObj *layer, msMSSQL2008LayerInfo *MSSQL2008layerinfo) -{ - layer->layerinfo = (void*) MSSQL2008layerinfo; +void setMSSQL2008LayerInfo(layerObj *layer, + msMSSQL2008LayerInfo *MSSQL2008layerinfo) { + layer->layerinfo = (void *)MSSQL2008layerinfo; } -void handleSQLError(layerObj *layer) -{ - SQLCHAR SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH]; - SQLINTEGER NativeError; - SQLSMALLINT i, MsgLen; - SQLRETURN rc; +void handleSQLError(layerObj *layer) { + SQLCHAR SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH]; + SQLINTEGER NativeError; + SQLSMALLINT i, MsgLen; + SQLRETURN rc; msMSSQL2008LayerInfo *layerinfo = getMSSQL2008LayerInfo(layer); if (layerinfo == NULL) @@ -646,9 +661,10 @@ void handleSQLError(layerObj *layer) // Get the status records. i = 1; - while ((rc = SQLGetDiagRec(SQL_HANDLE_STMT, layerinfo->conn->hstmt, i, SqlState, &NativeError, - Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) { - if(layer->debug) { + while ((rc = SQLGetDiagRec(SQL_HANDLE_STMT, layerinfo->conn->hstmt, i, + SqlState, &NativeError, Msg, sizeof(Msg), + &MsgLen)) != SQL_NO_DATA) { + if (layer->debug) { msDebug("SQLError: %s\n", Msg); } i++; @@ -656,33 +672,32 @@ void handleSQLError(layerObj *layer) } /* TODO Take a look at glibc's strcasestr */ -static char *strstrIgnoreCase(const char *haystack, const char *needle) -{ - char *hay_lower; - char *needle_lower; - size_t len_hay,len_need, match; - int found = MS_FALSE; - char *loc; +static char *strstrIgnoreCase(const char *haystack, const char *needle) { + char *hay_lower; + char *needle_lower; + size_t len_hay, len_need, match; + int found = MS_FALSE; + char *loc; len_hay = strlen(haystack); len_need = strlen(needle); - hay_lower = (char*) msSmallMalloc(len_hay + 1); - needle_lower =(char*) msSmallMalloc(len_need + 1); + hay_lower = (char *)msSmallMalloc(len_hay + 1); + needle_lower = (char *)msSmallMalloc(len_need + 1); size_t t; - for(t = 0; t < len_hay; t++) { + for (t = 0; t < len_hay; t++) { hay_lower[t] = (char)tolower(haystack[t]); } hay_lower[t] = 0; - for(t = 0; t < len_need; t++) { + for (t = 0; t < len_need; t++) { needle_lower[t] = (char)tolower(needle[t]); } needle_lower[t] = 0; loc = strstr(hay_lower, needle_lower); - if(loc) { + if (loc) { match = loc - hay_lower; found = MS_TRUE; } @@ -690,15 +705,18 @@ static char *strstrIgnoreCase(const char *haystack, const char *needle) msFree(hay_lower); msFree(needle_lower); - return (char *) (found == MS_FALSE ? NULL : haystack + match); + return (char *)(found == MS_FALSE ? NULL : haystack + match); } -static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, char **geom_column_type, char **table_name, char **urid_name, char **user_srid, char **index_name, char **sort_spec, int debug); +static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, + char **geom_column_type, char **table_name, + char **urid_name, char **user_srid, + char **index_name, char **sort_spec, + int debug); /* Close connection and handles */ -static void msMSSQL2008CloseConnection(void *conn_handle) -{ - msODBCconn * conn = (msODBCconn *) conn_handle; +static void msMSSQL2008CloseConnection(void *conn_handle) { + msODBCconn *conn = (msODBCconn *)conn_handle; if (!conn) { return; @@ -719,69 +737,72 @@ static void msMSSQL2008CloseConnection(void *conn_handle) } /* Set the error string for the connection */ -static void setConnError(msODBCconn *conn) -{ +static void setConnError(msODBCconn *conn) { SQLSMALLINT len; - SQLGetDiagField(SQL_HANDLE_DBC, conn->hdbc, 1, SQL_DIAG_MESSAGE_TEXT, (SQLPOINTER) conn->errorMessage, sizeof(conn->errorMessage), &len); + SQLGetDiagField(SQL_HANDLE_DBC, conn->hdbc, 1, SQL_DIAG_MESSAGE_TEXT, + (SQLPOINTER)conn->errorMessage, sizeof(conn->errorMessage), + &len); conn->errorMessage[len] = 0; } #ifdef USE_ICONV -static SQLWCHAR* convertCwchartToSQLWCHAR(const wchar_t* inStr) -{ - SQLWCHAR* outStr; - int i, len; - for( len = 0; inStr[len] != 0; ++len ) - { - /* do nothing */ - } - outStr = (SQLWCHAR*)msSmallMalloc(sizeof(SQLWCHAR) * (len + 1)); - for( i = 0; i <= len; i++ ) - { - outStr[i] = (SQLWCHAR)inStr[i]; - } - return outStr; +static SQLWCHAR *convertCwchartToSQLWCHAR(const wchar_t *inStr) { + SQLWCHAR *outStr; + int i, len; + for (len = 0; inStr[len] != 0; ++len) { + /* do nothing */ + } + outStr = (SQLWCHAR *)msSmallMalloc(sizeof(SQLWCHAR) * (len + 1)); + for (i = 0; i <= len; i++) { + outStr[i] = (SQLWCHAR)inStr[i]; + } + return outStr; } #endif /* Connect to db */ -static msODBCconn * mssql2008Connect(const char * connString) -{ +static msODBCconn *mssql2008Connect(const char *connString) { SQLSMALLINT outConnStringLen; SQLRETURN rc; - msODBCconn * conn = msSmallMalloc(sizeof(msODBCconn)); + msODBCconn *conn = msSmallMalloc(sizeof(msODBCconn)); char fullConnString[1024]; memset(conn, 0, sizeof(*conn)); SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &conn->henv); - SQLSetEnvAttr(conn->henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0); + SQLSetEnvAttr(conn->henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, conn->henv, &conn->hdbc); - if (strcasestr(connString, "DRIVER=") == 0) - { - snprintf(fullConnString, sizeof(fullConnString), "DRIVER={SQL Server};%s", connString); + if (strcasestr(connString, "DRIVER=") == 0) { + snprintf(fullConnString, sizeof(fullConnString), "DRIVER={SQL Server};%s", + connString); - connString = fullConnString; + connString = fullConnString; } { #ifdef USE_ICONV - wchar_t *decodedConnString = msConvertWideStringFromUTF8(connString, "UCS-2LE"); - SQLWCHAR outConnString[1024]; - SQLWCHAR* decodedConnStringSQLWCHAR = convertCwchartToSQLWCHAR(decodedConnString); - rc = SQLDriverConnectW(conn->hdbc, NULL, decodedConnStringSQLWCHAR, SQL_NTS, outConnString, 1024, &outConnStringLen, SQL_DRIVER_NOPROMPT); - msFree(decodedConnString); - msFree(decodedConnStringSQLWCHAR); + wchar_t *decodedConnString = + msConvertWideStringFromUTF8(connString, "UCS-2LE"); + SQLWCHAR outConnString[1024]; + SQLWCHAR *decodedConnStringSQLWCHAR = + convertCwchartToSQLWCHAR(decodedConnString); + rc = SQLDriverConnectW(conn->hdbc, NULL, decodedConnStringSQLWCHAR, SQL_NTS, + outConnString, 1024, &outConnStringLen, + SQL_DRIVER_NOPROMPT); + msFree(decodedConnString); + msFree(decodedConnStringSQLWCHAR); #else - SQLCHAR outConnString[1024]; - rc = SQLDriverConnect(conn->hdbc, NULL, (SQLCHAR*)connString, SQL_NTS, outConnString, 1024, &outConnStringLen, SQL_DRIVER_NOPROMPT); + SQLCHAR outConnString[1024]; + rc = SQLDriverConnect(conn->hdbc, NULL, (SQLCHAR *)connString, SQL_NTS, + outConnString, 1024, &outConnStringLen, + SQL_DRIVER_NOPROMPT); #endif - } + } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { setConnError(conn); @@ -795,18 +816,18 @@ static msODBCconn * mssql2008Connect(const char * connString) } /* Set the error string for the statement execution */ -static void setStmntError(msODBCconn *conn) -{ +static void setStmntError(msODBCconn *conn) { SQLSMALLINT len; - SQLGetDiagField(SQL_HANDLE_STMT, conn->hstmt, 1, SQL_DIAG_MESSAGE_TEXT, (SQLPOINTER) conn->errorMessage, sizeof(conn->errorMessage), &len); + SQLGetDiagField(SQL_HANDLE_STMT, conn->hstmt, 1, SQL_DIAG_MESSAGE_TEXT, + (SQLPOINTER)conn->errorMessage, sizeof(conn->errorMessage), + &len); conn->errorMessage[len] = 0; } /* Execute SQL against connection. Set error string if failed */ -static int executeSQL(msODBCconn *conn, const char * sql) -{ +static int executeSQL(msODBCconn *conn, const char *sql) { SQLRETURN rc; SQLCloseCursor(conn->hstmt); @@ -814,13 +835,13 @@ static int executeSQL(msODBCconn *conn, const char * sql) #ifdef USE_ICONV { wchar_t *decodedSql = msConvertWideStringFromUTF8(sql, "UCS-2LE"); - SQLWCHAR* decodedSqlSQLWCHAR = convertCwchartToSQLWCHAR(decodedSql); + SQLWCHAR *decodedSqlSQLWCHAR = convertCwchartToSQLWCHAR(decodedSql); rc = SQLExecDirectW(conn->hstmt, decodedSqlSQLWCHAR, SQL_NTS); msFree(decodedSql); msFree(decodedSqlSQLWCHAR); } #else - rc = SQLExecDirect(conn->hstmt, (SQLCHAR *) sql, SQL_NTS); + rc = SQLExecDirect(conn->hstmt, (SQLCHAR *)sql, SQL_NTS); #endif if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { @@ -832,8 +853,9 @@ static int executeSQL(msODBCconn *conn, const char * sql) } /* Get columns name from query results */ -static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLength, layerObj *layer, char pass_field_def, SQLSMALLINT *itemType) -{ +static int columnName(msODBCconn *conn, int index, char *buffer, + int bufferLength, layerObj *layer, char pass_field_def, + SQLSMALLINT *itemType) { SQLRETURN rc; SQLCHAR columnName[SQL_COLUMN_NAME_MAX_LENGTH + 1]; @@ -843,16 +865,9 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt SQLSMALLINT decimalDigits; SQLSMALLINT nullable; - rc = SQLDescribeCol( - conn->hstmt, - (SQLUSMALLINT)index, - columnName, - SQL_COLUMN_NAME_MAX_LENGTH, - &columnNameLen, - &dataType, - &columnSize, - &decimalDigits, - &nullable); + rc = SQLDescribeCol(conn->hstmt, (SQLUSMALLINT)index, columnName, + SQL_COLUMN_NAME_MAX_LENGTH, &columnNameLen, &dataType, + &columnSize, &decimalDigits, &nullable); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { if (bufferLength < SQL_COLUMN_NAME_MAX_LENGTH + 1) @@ -869,50 +884,51 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt gml_width[0] = '\0'; gml_precision[0] = '\0'; - switch( dataType ) { - case SQL_INTEGER: - case SQL_SMALLINT: - case SQL_TINYINT: - gml_type = "Integer"; - break; - - case SQL_BIGINT: - gml_type = "Long"; - break; - - case SQL_REAL: - case SQL_FLOAT: - case SQL_DOUBLE: - case SQL_DECIMAL: - case SQL_NUMERIC: - gml_type = "Real"; - if( decimalDigits > 0 ) - sprintf( gml_precision, "%d", decimalDigits ); - break; - - case SQL_TYPE_DATE: - gml_type = "Date"; - break; - case SQL_TYPE_TIME: - gml_type = "Time"; - break; - case SQL_TYPE_TIMESTAMP: - gml_type = "DateTime"; - break; - - case SQL_BIT: - gml_type = "Boolean"; - break; - - default: - gml_type = "Character"; - break; + switch (dataType) { + case SQL_INTEGER: + case SQL_SMALLINT: + case SQL_TINYINT: + gml_type = "Integer"; + break; + + case SQL_BIGINT: + gml_type = "Long"; + break; + + case SQL_REAL: + case SQL_FLOAT: + case SQL_DOUBLE: + case SQL_DECIMAL: + case SQL_NUMERIC: + gml_type = "Real"; + if (decimalDigits > 0) + sprintf(gml_precision, "%d", decimalDigits); + break; + + case SQL_TYPE_DATE: + gml_type = "Date"; + break; + case SQL_TYPE_TIME: + gml_type = "Time"; + break; + case SQL_TYPE_TIMESTAMP: + gml_type = "DateTime"; + break; + + case SQL_BIT: + gml_type = "Boolean"; + break; + + default: + gml_type = "Character"; + break; } - if( columnSize > 0 ) - sprintf( gml_width, "%u", (unsigned int)columnSize ); + if (columnSize > 0) + sprintf(gml_width, "%u", (unsigned int)columnSize); - msUpdateGMLFieldMetadata(layer, buffer, gml_type, gml_width, gml_precision, (const short) nullable); + msUpdateGMLFieldMetadata(layer, buffer, gml_type, gml_width, + gml_precision, (const short)nullable); } return 1; } else { @@ -921,38 +937,43 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt } } -/* open up a connection to the MS SQL 2008 database using the connection string in layer->connection */ -/* ie. "driver=;server=;database=;integrated security=?;user id=;password=" */ -int msMSSQL2008LayerOpen(layerObj *layer) -{ - msMSSQL2008LayerInfo *layerinfo; +/* open up a connection to the MS SQL 2008 database using the connection string + * in layer->connection */ +/* ie. "driver=;server=;database=;integrated + * security=?;user id=;password=" */ +int msMSSQL2008LayerOpen(layerObj *layer) { + msMSSQL2008LayerInfo *layerinfo; char *conn_decrypted = NULL; - if(layer->debug) { + if (layer->debug) { msDebug("msMSSQL2008LayerOpen called datastatement: %s\n", layer->data); } - if(getMSSQL2008LayerInfo(layer)) { - if(layer->debug) { + if (getMSSQL2008LayerInfo(layer)) { + if (layer->debug) { msDebug("msMSSQL2008LayerOpen :: layer is already open!!\n"); } - return MS_SUCCESS; /* already open */ + return MS_SUCCESS; /* already open */ } - if(!layer->data) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerOpen()", "", "Error parsing MSSQL2008 data variable: nothing specified in DATA statement.

\n\nMore Help:

\n\n"); + if (!layer->data) { + msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerOpen()", "", + "Error parsing MSSQL2008 data variable: nothing specified in " + "DATA statement.

\n\nMore Help:

\n\n"); return MS_FAILURE; } - if(!layer->connection) { - msSetError( MS_QUERYERR, "MSSQL connection parameter not specified.", "msMSSQL2008LayerOpen()"); + if (!layer->connection) { + msSetError(MS_QUERYERR, "MSSQL connection parameter not specified.", + "msMSSQL2008LayerOpen()"); return MS_FAILURE; } /* have to setup a connection to the database */ - layerinfo = (msMSSQL2008LayerInfo*) msSmallMalloc(sizeof(msMSSQL2008LayerInfo)); + layerinfo = + (msMSSQL2008LayerInfo *)msSmallMalloc(sizeof(msMSSQL2008LayerInfo)); layerinfo->sql = NULL; /* calc later */ layerinfo->row_num = 0; @@ -968,17 +989,17 @@ int msMSSQL2008LayerOpen(layerObj *layer) layerinfo->mssqlversion_major = 0; layerinfo->paging = MS_TRUE; - layerinfo->conn = (msODBCconn *) msConnPoolRequest(layer); + layerinfo->conn = (msODBCconn *)msConnPoolRequest(layer); - if(!layerinfo->conn) { - if(layer->debug) { + if (!layerinfo->conn) { + if (layer->debug) { msDebug("MSMSSQL2008LayerOpen -- shared connection not available.\n"); } /* Decrypt any encrypted token in connection and attempt to connect */ conn_decrypted = msDecryptStringTokens(layer->map, layer->connection); if (conn_decrypted == NULL) { - return(MS_FAILURE); /* An error should already have been produced */ + return (MS_FAILURE); /* An error should already have been produced */ } layerinfo->conn = mssql2008Connect(conn_decrypted); @@ -986,26 +1007,34 @@ int msMSSQL2008LayerOpen(layerObj *layer) msFree(conn_decrypted); conn_decrypted = NULL; - if(!layerinfo->conn || layerinfo->conn->errorMessage[0]) { + if (!layerinfo->conn || layerinfo->conn->errorMessage[0]) { char *errMess = "Out of memory"; if (layer->debug) - msDebug("MSMSSQL2008LayerOpen: Connection failure.\n"); + msDebug("MSMSSQL2008LayerOpen: Connection failure.\n"); if (layerinfo->conn) { errMess = layerinfo->conn->errorMessage; } - msDebug("Couldn't make connection to MS SQL Server with connect string '%s'.\n" - "Error reported was '%s'.\n\n" - "This error occured when trying to make a connection to the specified SQL server.\n" - "Most commonly this is caused by: \n" - "(1) incorrect connection string \n" - "(2) you didn't specify a 'user id=...' in your connection string \n" - "(3) SQL server isnt running \n" - "(4) TCPIP not enabled for SQL Client or server \n\n", - layer->connection, errMess); - msSetError(MS_QUERYERR, "Database connection failed. Check server logs for more details. Is SQL Server running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port?", "MSMSSQL2008LayerOpen()"); + msDebug( + "Couldn't make connection to MS SQL Server with connect string " + "'%s'.\n" + "Error reported was '%s'.\n\n" + "This error occured when trying to make a connection to the " + "specified SQL server.\n" + "Most commonly this is caused by: \n" + "(1) incorrect connection string \n" + "(2) you didn't specify a 'user id=...' in your connection string \n" + "(3) SQL server isnt running \n" + "(4) TCPIP not enabled for SQL Client or server \n\n", + layer->connection, errMess); + msSetError(MS_QUERYERR, + "Database connection failed. Check server logs for more " + "details. Is SQL Server running? Is it allowing connections? " + "Does the specified user exist? Is the password valid? Is the " + "database on the standard port?", + "MSMSSQL2008LayerOpen()"); msMSSQL2008CloseConnection(layerinfo->conn); msFree(layerinfo); @@ -1017,13 +1046,18 @@ int msMSSQL2008LayerOpen(layerObj *layer) setMSSQL2008LayerInfo(layer, layerinfo); - if (msMSSQL2008LayerParseData(layer, &layerinfo->geom_column, &layerinfo->geom_column_type, &layerinfo->geom_table, &layerinfo->urid_name, &layerinfo->user_srid, &layerinfo->index_name, &layerinfo->sort_spec, layer->debug) != MS_SUCCESS) { - msSetError( MS_QUERYERR, "Could not parse the layer data", "msMSSQL2008LayerOpen()"); + if (msMSSQL2008LayerParseData( + layer, &layerinfo->geom_column, &layerinfo->geom_column_type, + &layerinfo->geom_table, &layerinfo->urid_name, &layerinfo->user_srid, + &layerinfo->index_name, &layerinfo->sort_spec, + layer->debug) != MS_SUCCESS) { + msSetError(MS_QUERYERR, "Could not parse the layer data", + "msMSSQL2008LayerOpen()"); return MS_FAILURE; } /* identify the geometry transfer type */ - if (msLayerGetProcessingKey( layer, "MSSQL_READ_WKB" ) != NULL) + if (msLayerGetProcessingKey(layer, "MSSQL_READ_WKB") != NULL) layerinfo->geometry_format = MSSQLGEOMETRY_WKB; else { layerinfo->geometry_format = MSSQLGEOMETRY_NATIVE; @@ -1037,75 +1071,72 @@ int msMSSQL2008LayerOpen(layerObj *layer) } /* Return MS_TRUE if layer is open, MS_FALSE otherwise. */ -int msMSSQL2008LayerIsOpen(layerObj *layer) -{ +int msMSSQL2008LayerIsOpen(layerObj *layer) { return getMSSQL2008LayerInfo(layer) ? MS_TRUE : MS_FALSE; } - /* Free the itemindexes array in a layer. */ -void msMSSQL2008LayerFreeItemInfo(layerObj *layer) -{ - if(layer->debug) { +void msMSSQL2008LayerFreeItemInfo(layerObj *layer) { + if (layer->debug) { msDebug("msMSSQL2008LayerFreeItemInfo called\n"); } - if(layer->iteminfo) { + if (layer->iteminfo) { msFree(layer->iteminfo); } layer->iteminfo = NULL; } - /* allocate the iteminfo index array - same order as the item list */ -int msMSSQL2008LayerInitItemInfo(layerObj *layer) -{ - int i; - int *itemindexes ; +int msMSSQL2008LayerInitItemInfo(layerObj *layer) { + int i; + int *itemindexes; if (layer->debug) { msDebug("msMSSQL2008LayerInitItemInfo called\n"); } - if(layer->numitems == 0) { + if (layer->numitems == 0) { return MS_SUCCESS; } msFree(layer->iteminfo); - layer->iteminfo = (int *) msSmallMalloc(sizeof(int) * layer->numitems); + layer->iteminfo = (int *)msSmallMalloc(sizeof(int) * layer->numitems); - itemindexes = (int*)layer->iteminfo; + itemindexes = (int *)layer->iteminfo; - for(i = 0; i < layer->numitems; i++) { - itemindexes[i] = i; /* last one is always the geometry one - the rest are non-geom */ + for (i = 0; i < layer->numitems; i++) { + itemindexes[i] = + i; /* last one is always the geometry one - the rest are non-geom */ } return MS_SUCCESS; } -static int getMSSQLMajorVersion(layerObj* layer) -{ - msMSSQL2008LayerInfo *layerinfo = getMSSQL2008LayerInfo(layer); +static int getMSSQLMajorVersion(layerObj *layer) { + msMSSQL2008LayerInfo *layerinfo = getMSSQL2008LayerInfo(layer); if (layerinfo == NULL) return 0; if (layerinfo->mssqlversion_major == 0) { - const char* mssqlversion_major = msLayerGetProcessingKey(layer, "MSSQL_VERSION_MAJOR"); + const char *mssqlversion_major = + msLayerGetProcessingKey(layer, "MSSQL_VERSION_MAJOR"); if (mssqlversion_major != NULL) { layerinfo->mssqlversion_major = atoi(mssqlversion_major); - } - else { + } else { /* need to query from database */ - if (executeSQL(layerinfo->conn, "SELECT SERVERPROPERTY('ProductVersion')")) { + if (executeSQL(layerinfo->conn, + "SELECT SERVERPROPERTY('ProductVersion')")) { SQLRETURN rc = SQLFetch(layerinfo->conn->hstmt); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { /* process results */ char result_data[256]; SQLLEN retLen = 0; - rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); + rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); if (rc != SQL_ERROR) { result_data[retLen] = 0; @@ -1119,17 +1150,16 @@ static int getMSSQLMajorVersion(layerObj* layer) return layerinfo->mssqlversion_major; } -static int addFilter(layerObj *layer, char **query) -{ +static int addFilter(layerObj *layer, char **query) { if (layer->filter.native_string) { (*query) = msStringConcatenate(*query, " WHERE ("); (*query) = msStringConcatenate(*query, layer->filter.native_string); (*query) = msStringConcatenate(*query, ")"); return MS_TRUE; - } - else if (msLayerGetProcessingKey(layer, "NATIVE_FILTER") != NULL) { + } else if (msLayerGetProcessingKey(layer, "NATIVE_FILTER") != NULL) { (*query) = msStringConcatenate(*query, " WHERE ("); - (*query) = msStringConcatenate(*query, msLayerGetProcessingKey(layer, "NATIVE_FILTER")); + (*query) = msStringConcatenate( + *query, msLayerGetProcessingKey(layer, "NATIVE_FILTER")); (*query) = msStringConcatenate(*query, ")"); return MS_TRUE; } @@ -1139,195 +1169,214 @@ static int addFilter(layerObj *layer, char **query) /* Get the layer extent as specified in the mapfile or a largest area */ /* covering all features */ -int msMSSQL2008LayerGetExtent(layerObj *layer, rectObj *extent) -{ - msMSSQL2008LayerInfo *layerinfo; - char *query = 0; - char result_data[256]; - SQLLEN retLen; - SQLRETURN rc; - - if(layer->debug) { - msDebug("msMSSQL2008LayerGetExtent called\n"); - } - - if (!(layer->extent.minx == -1.0 && layer->extent.miny == -1.0 && - layer->extent.maxx == -1.0 && layer->extent.maxy == -1.0)) { - /* extent was already set */ - extent->minx = layer->extent.minx; - extent->miny = layer->extent.miny; - extent->maxx = layer->extent.maxx; - extent->maxy = layer->extent.maxy; - } +int msMSSQL2008LayerGetExtent(layerObj *layer, rectObj *extent) { + msMSSQL2008LayerInfo *layerinfo; + char *query = 0; + char result_data[256]; + SQLLEN retLen; + SQLRETURN rc; - layerinfo = getMSSQL2008LayerInfo(layer); + if (layer->debug) { + msDebug("msMSSQL2008LayerGetExtent called\n"); + } - if (!layerinfo) { - msSetError(MS_QUERYERR, "GetExtent called with layerinfo = NULL", "msMSSQL2008LayerGetExtent()"); - return MS_FAILURE; - } + if (!(layer->extent.minx == -1.0 && layer->extent.miny == -1.0 && + layer->extent.maxx == -1.0 && layer->extent.maxy == -1.0)) { + /* extent was already set */ + extent->minx = layer->extent.minx; + extent->miny = layer->extent.miny; + extent->maxx = layer->extent.maxx; + extent->maxy = layer->extent.maxy; + } - /* set up statement */ - if (getMSSQLMajorVersion(layer) >= 11) { - if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) { - query = msStringConcatenate(query, "WITH extent(extentcol) AS (SELECT geometry::EnvelopeAggregate(geometry::STGeomFromWKB("); - query = msStringConcatenate(query, layerinfo->geom_column); - query = msStringConcatenate(query, ".STAsBinary(), "); - query = msStringConcatenate(query, layerinfo->geom_column); - query = msStringConcatenate(query, ".STSrid)"); - } - else { - query = msStringConcatenate(query, "WITH extent(extentcol) AS (SELECT geometry::EnvelopeAggregate("); - query = msStringConcatenate(query, layerinfo->geom_column); - } - query = msStringConcatenate(query, ") AS extentcol FROM "); - query = msStringConcatenate(query, layerinfo->geom_table); + layerinfo = getMSSQL2008LayerInfo(layer); - /* adding attribute filter */ - addFilter(layer, &query); + if (!layerinfo) { + msSetError(MS_QUERYERR, "GetExtent called with layerinfo = NULL", + "msMSSQL2008LayerGetExtent()"); + return MS_FAILURE; + } - query = msStringConcatenate(query, ") SELECT extentcol.STPointN(1).STX, extentcol.STPointN(1).STY, extentcol.STPointN(3).STX, extentcol.STPointN(3).STY FROM extent"); + /* set up statement */ + if (getMSSQLMajorVersion(layer) >= 11) { + if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) { + query = msStringConcatenate( + query, "WITH extent(extentcol) AS (SELECT " + "geometry::EnvelopeAggregate(geometry::STGeomFromWKB("); + query = msStringConcatenate(query, layerinfo->geom_column); + query = msStringConcatenate(query, ".STAsBinary(), "); + query = msStringConcatenate(query, layerinfo->geom_column); + query = msStringConcatenate(query, ".STSrid)"); + } else { + query = msStringConcatenate( + query, + "WITH extent(extentcol) AS (SELECT geometry::EnvelopeAggregate("); + query = msStringConcatenate(query, layerinfo->geom_column); } - else { - if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) { - query = msStringConcatenate(query, "WITH ENVELOPE as (SELECT geometry::STGeomFromWKB("); - query = msStringConcatenate(query, layerinfo->geom_column); - query = msStringConcatenate(query, ".STAsBinary(), "); - query = msStringConcatenate(query, layerinfo->geom_column); - query = msStringConcatenate(query, ".STSrid)"); - } - else { - query = msStringConcatenate(query, "WITH ENVELOPE as (SELECT "); - query = msStringConcatenate(query, layerinfo->geom_column); - } - query = msStringConcatenate(query, ".STEnvelope() as envelope from "); - query = msStringConcatenate(query, layerinfo->geom_table); + query = msStringConcatenate(query, ") AS extentcol FROM "); + query = msStringConcatenate(query, layerinfo->geom_table); - /* adding attribute filter */ - addFilter(layer, &query); + /* adding attribute filter */ + addFilter(layer, &query); - query = msStringConcatenate(query, "), CORNERS as (SELECT envelope.STPointN(1) as point from ENVELOPE UNION ALL select envelope.STPointN(3) from ENVELOPE) SELECT MIN(point.STX), MIN(point.STY), MAX(point.STX), MAX(point.STY) FROM CORNERS"); + query = msStringConcatenate( + query, + ") SELECT extentcol.STPointN(1).STX, extentcol.STPointN(1).STY, " + "extentcol.STPointN(3).STX, extentcol.STPointN(3).STY FROM extent"); + } else { + if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) { + query = msStringConcatenate( + query, "WITH ENVELOPE as (SELECT geometry::STGeomFromWKB("); + query = msStringConcatenate(query, layerinfo->geom_column); + query = msStringConcatenate(query, ".STAsBinary(), "); + query = msStringConcatenate(query, layerinfo->geom_column); + query = msStringConcatenate(query, ".STSrid)"); + } else { + query = msStringConcatenate(query, "WITH ENVELOPE as (SELECT "); + query = msStringConcatenate(query, layerinfo->geom_column); } + query = msStringConcatenate(query, ".STEnvelope() as envelope from "); + query = msStringConcatenate(query, layerinfo->geom_table); - if (!executeSQL(layerinfo->conn, query)) { - msFree(query); - return MS_FAILURE; - } + /* adding attribute filter */ + addFilter(layer, &query); + + query = msStringConcatenate( + query, "), CORNERS as (SELECT envelope.STPointN(1) as point from " + "ENVELOPE UNION ALL select envelope.STPointN(3) from ENVELOPE) " + "SELECT MIN(point.STX), MIN(point.STY), MAX(point.STX), " + "MAX(point.STY) FROM CORNERS"); + } + if (!executeSQL(layerinfo->conn, query)) { msFree(query); + return MS_FAILURE; + } - /* process results */ - rc = SQLFetch(layerinfo->conn->hstmt); + msFree(query); - if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if (layer->debug) { - msDebug("msMSSQL2008LayerGetExtent: No results found.\n"); - } - return MS_FAILURE; - } + /* process results */ + rc = SQLFetch(layerinfo->conn->hstmt); - rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); - if (rc == SQL_ERROR || retLen < 0) { - msSetError(MS_QUERYERR, "Failed to get MinX value", "msMSSQL2008LayerGetExtent()"); - return MS_FAILURE; + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + if (layer->debug) { + msDebug("msMSSQL2008LayerGetExtent: No results found.\n"); } + return MS_FAILURE; + } - result_data[retLen] = 0; + rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); + if (rc == SQL_ERROR || retLen < 0) { + msSetError(MS_QUERYERR, "Failed to get MinX value", + "msMSSQL2008LayerGetExtent()"); + return MS_FAILURE; + } - extent->minx = atof(result_data); + result_data[retLen] = 0; - rc = SQLGetData(layerinfo->conn->hstmt, 2, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); - if (rc == SQL_ERROR || retLen < 0) { - msSetError(MS_QUERYERR, "Failed to get MinY value", "msMSSQL2008LayerGetExtent()"); - return MS_FAILURE; - } + extent->minx = atof(result_data); - result_data[retLen] = 0; + rc = SQLGetData(layerinfo->conn->hstmt, 2, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); + if (rc == SQL_ERROR || retLen < 0) { + msSetError(MS_QUERYERR, "Failed to get MinY value", + "msMSSQL2008LayerGetExtent()"); + return MS_FAILURE; + } - extent->miny = atof(result_data); + result_data[retLen] = 0; - rc = SQLGetData(layerinfo->conn->hstmt, 3, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); - if (rc == SQL_ERROR || retLen < 0) { - msSetError(MS_QUERYERR, "Failed to get MaxX value", "msMSSQL2008LayerGetExtent()"); - return MS_FAILURE; - } + extent->miny = atof(result_data); - result_data[retLen] = 0; + rc = SQLGetData(layerinfo->conn->hstmt, 3, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); + if (rc == SQL_ERROR || retLen < 0) { + msSetError(MS_QUERYERR, "Failed to get MaxX value", + "msMSSQL2008LayerGetExtent()"); + return MS_FAILURE; + } - extent->maxx = atof(result_data); + result_data[retLen] = 0; - rc = SQLGetData(layerinfo->conn->hstmt, 4, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); - if (rc == SQL_ERROR || retLen < 0) { - msSetError(MS_QUERYERR, "Failed to get MaxY value", "msMSSQL2008LayerGetExtent()"); - return MS_FAILURE; - } + extent->maxx = atof(result_data); - result_data[retLen] = 0; + rc = SQLGetData(layerinfo->conn->hstmt, 4, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); + if (rc == SQL_ERROR || retLen < 0) { + msSetError(MS_QUERYERR, "Failed to get MaxY value", + "msMSSQL2008LayerGetExtent()"); + return MS_FAILURE; + } - extent->maxy = atof(result_data); + result_data[retLen] = 0; - return MS_SUCCESS; + extent->maxy = atof(result_data); + + return MS_SUCCESS; } /* Get the layer feature count */ -int msMSSQL2008LayerGetNumFeatures(layerObj *layer) -{ - msMSSQL2008LayerInfo *layerinfo; - char *query = 0; - char result_data[256]; - SQLLEN retLen; - SQLRETURN rc; - - if (layer->debug) { - msDebug("msMSSQL2008LayerGetNumFeatures called\n"); - } +int msMSSQL2008LayerGetNumFeatures(layerObj *layer) { + msMSSQL2008LayerInfo *layerinfo; + char *query = 0; + char result_data[256]; + SQLLEN retLen; + SQLRETURN rc; - layerinfo = getMSSQL2008LayerInfo(layer); + if (layer->debug) { + msDebug("msMSSQL2008LayerGetNumFeatures called\n"); + } - if (!layerinfo) { - msSetError(MS_QUERYERR, "GetNumFeatures called with layerinfo = NULL", "msMSSQL2008LayerGetNumFeatures()"); - return -1; - } + layerinfo = getMSSQL2008LayerInfo(layer); - /* set up statement */ - query = msStringConcatenate(query, "SELECT count(*) FROM "); - query = msStringConcatenate(query, layerinfo->geom_table); + if (!layerinfo) { + msSetError(MS_QUERYERR, "GetNumFeatures called with layerinfo = NULL", + "msMSSQL2008LayerGetNumFeatures()"); + return -1; + } - /* adding attribute filter */ - addFilter(layer, &query); + /* set up statement */ + query = msStringConcatenate(query, "SELECT count(*) FROM "); + query = msStringConcatenate(query, layerinfo->geom_table); - if (!executeSQL(layerinfo->conn, query)) { - msFree(query); - return -1; - } + /* adding attribute filter */ + addFilter(layer, &query); + if (!executeSQL(layerinfo->conn, query)) { msFree(query); + return -1; + } - rc = SQLFetch(layerinfo->conn->hstmt); + msFree(query); - if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if (layer->debug) { - msDebug("msMSSQL2008LayerGetNumFeatures: No results found.\n"); - } + rc = SQLFetch(layerinfo->conn->hstmt); - return -1; + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + if (layer->debug) { + msDebug("msMSSQL2008LayerGetNumFeatures: No results found.\n"); } - rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); + return -1; + } - if (rc == SQL_ERROR) { - msSetError(MS_QUERYERR, "Failed to get feature count", "msMSSQL2008LayerGetNumFeatures()"); - return -1; - } + rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); + + if (rc == SQL_ERROR) { + msSetError(MS_QUERYERR, "Failed to get feature count", + "msMSSQL2008LayerGetNumFeatures()"); + return -1; + } - result_data[retLen] = 0; + result_data[retLen] = 0; - return atoi(result_data); + return atoi(result_data); } /* Prepare and execute the SQL statement for this layer */ -static int prepare_database(layerObj *layer, rectObj rect, char **query_string, int isQuery) -{ +static int prepare_database(layerObj *layer, rectObj rect, char **query_string, + int isQuery) { msMSSQL2008LayerInfo *layerinfo; char *query = 0; char *data_source = 0; @@ -1337,24 +1386,26 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, char *paging_query = 0; /* "Geometry::STGeomFromText('POLYGON(())',)" + terminator = 40 chars - Plus 10 formatted doubles (15 digits of precision, a decimal point, a space/comma delimiter each = 17 chars each) - Plus SRID + comma - if SRID is a long...we'll be safe with 10 chars + Plus 10 formatted doubles (15 digits of precision, a decimal point, a + space/comma delimiter each = 17 chars each) Plus SRID + comma - if SRID is a + long...we'll be safe with 10 chars + + or for geography columns - or for geography columns - "Geography::STGeomFromText('CURVEPOLYGON(())',)" + terminator = 46 chars - Plus 18 formatted doubles (15 digits of precision, a decimal point, a space/comma delimiter each = 17 chars each) - Plus SRID + comma - if SRID is a long...we'll be safe with 10 chars + Plus 18 formatted doubles (15 digits of precision, a decimal point, a + space/comma delimiter each = 17 chars each) Plus SRID + comma - if SRID is a + long...we'll be safe with 10 chars */ - char box3d[46 + 18 * 22 + 11]; - int t; + char box3d[46 + 18 * 22 + 11]; + int t; - char *pos_from, *pos_ftab, *pos_space, *pos_paren; + char *pos_from, *pos_ftab, *pos_space, *pos_paren; int hasFilter = MS_FALSE; const rectObj rectInvalid = MS_INIT_INVALID_RECT; const int bIsValidRect = memcmp(&rect, &rectInvalid, sizeof(rect)) != 0; - layerinfo = getMSSQL2008LayerInfo(layer); + layerinfo = getMSSQL2008LayerInfo(layer); /* Extract the proper f_table_name from the geom_table string. * We are expecting the geom_table to be either a single word @@ -1369,10 +1420,10 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, geom_table = msStrdup(layerinfo->geom_table); pos_from = strstrIgnoreCase(geom_table, " from "); - if(!pos_from) { - f_table_name = (char *) msSmallMalloc(strlen(geom_table) + 1); + if (!pos_from) { + f_table_name = (char *)msSmallMalloc(strlen(geom_table) + 1); strcpy(f_table_name, geom_table); - } else { /* geom_table is a sub-select clause */ + } else { /* geom_table is a sub-select clause */ pos_ftab = pos_from + 6; /* This should be the start of the ftab name */ pos_space = strstr(pos_ftab, " "); /* First space */ @@ -1383,82 +1434,83 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, pos_paren = rindex(pos_ftab, ')'); #endif - if(!pos_space || !pos_paren) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "prepare_database()", geom_table, "Error parsing MSSQL2008 data variable: Something is wrong with your subselect statement.

\n\nMore Help:

\n\n"); + if (!pos_space || !pos_paren) { + msSetError( + MS_QUERYERR, DATA_ERROR_MESSAGE, "prepare_database()", geom_table, + "Error parsing MSSQL2008 data variable: Something is wrong with your " + "subselect statement.

\n\nMore Help:

\n\n"); return MS_FAILURE; } if (pos_paren < pos_space) { /* closing parenthesis preceeds any space */ - f_table_name = (char *) msSmallMalloc(pos_paren - pos_ftab + 1); + f_table_name = (char *)msSmallMalloc(pos_paren - pos_ftab + 1); strlcpy(f_table_name, pos_ftab, pos_paren - pos_ftab + 1); } else { - f_table_name = (char *) msSmallMalloc(pos_space - pos_ftab + 1); + f_table_name = (char *)msSmallMalloc(pos_space - pos_ftab + 1); strlcpy(f_table_name, pos_ftab, pos_space - pos_ftab + 1); } } if (rect.minx == rect.maxx || rect.miny == rect.maxy) { - /* create point shape for rectangles with zero area */ - sprintf(box3d, "%s::STGeomFromText('POINT(%.15g %.15g)',%s)", /* %s.STSrid)", */ - layerinfo->geom_column_type, rect.minx, rect.miny, layerinfo->user_srid); + /* create point shape for rectangles with zero area */ + sprintf(box3d, + "%s::STGeomFromText('POINT(%.15g %.15g)',%s)", /* %s.STSrid)", */ + layerinfo->geom_column_type, rect.minx, rect.miny, + layerinfo->user_srid); } else if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) { - /* SQL Server has a problem when x is -180 or 180 */ - double minx = rect.minx <= -180? -179.999: rect.minx; - double maxx = rect.maxx >= 180? 179.999: rect.maxx; - double miny = rect.miny < -90? -90: rect.miny; - double maxy = rect.maxy > 90? 90: rect.maxy; - sprintf(box3d, "Geography::STGeomFromText('CURVEPOLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ - minx, miny, - minx + (maxx - minx) / 2, miny, - maxx, miny, - maxx, miny + (maxy - miny) / 2, - maxx, maxy, - minx + (maxx - minx) / 2, maxy, - minx, maxy, - minx, miny + (maxy - miny) / 2, - minx, miny, - layerinfo->user_srid); + /* SQL Server has a problem when x is -180 or 180 */ + double minx = rect.minx <= -180 ? -179.999 : rect.minx; + double maxx = rect.maxx >= 180 ? 179.999 : rect.maxx; + double miny = rect.miny < -90 ? -90 : rect.miny; + double maxy = rect.maxy > 90 ? 90 : rect.maxy; + sprintf(box3d, + "Geography::STGeomFromText('CURVEPOLYGON((%.15g %.15g,%.15g " + "%.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g " + "%.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ + minx, miny, minx + (maxx - minx) / 2, miny, maxx, miny, maxx, + miny + (maxy - miny) / 2, maxx, maxy, minx + (maxx - minx) / 2, + maxy, minx, maxy, minx, miny + (maxy - miny) / 2, minx, miny, + layerinfo->user_srid); } else { - sprintf(box3d, "Geometry::STGeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ - rect.minx, rect.miny, - rect.maxx, rect.miny, - rect.maxx, rect.maxy, - rect.minx, rect.maxy, - rect.minx, rect.miny, - layerinfo->user_srid - ); + sprintf(box3d, + "Geometry::STGeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g " + "%.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ + rect.minx, rect.miny, rect.maxx, rect.miny, rect.maxx, rect.maxy, + rect.minx, rect.maxy, rect.minx, rect.miny, layerinfo->user_srid); } - /* substitute token '!BOX!' in geom_table with the box3d - do an unlimited # of subs */ - /* to not undo the work here, we need to make sure that data_source is malloc'd here */ + /* substitute token '!BOX!' in geom_table with the box3d - do an unlimited # + * of subs */ + /* to not undo the work here, we need to make sure that data_source is + * malloc'd here */ if (!strstr(geom_table, "!BOX!")) { - data_source = (char *)msSmallMalloc(strlen(geom_table) + 1); - strcpy(data_source, geom_table); - } - else { - char* result = NULL; + data_source = (char *)msSmallMalloc(strlen(geom_table) + 1); + strcpy(data_source, geom_table); + } else { + char *result = NULL; - while (strstr(geom_table, "!BOX!")) { - /* need to do a substition */ - char *start, *end; - char *oldresult = result; - start = strstr(geom_table, "!BOX!"); - end = start + 5; + while (strstr(geom_table, "!BOX!")) { + /* need to do a substition */ + char *start, *end; + char *oldresult = result; + start = strstr(geom_table, "!BOX!"); + end = start + 5; - result = (char *)msSmallMalloc((start - geom_table) + strlen(box3d) + strlen(end) + 1); + result = (char *)msSmallMalloc((start - geom_table) + strlen(box3d) + + strlen(end) + 1); - strlcpy(result, geom_table, start - geom_table + 1); - strcpy(result + (start - geom_table), box3d); - strcat(result, end); + strlcpy(result, geom_table, start - geom_table + 1); + strcpy(result + (start - geom_table), box3d); + strcat(result, end); - geom_table = result; - msFree(oldresult); - } + geom_table = result; + msFree(oldresult); + } - /* if we're here, this will be a malloc'd string, so no need to copy it */ - data_source = (char *)geom_table; + /* if we're here, this will be a malloc'd string, so no need to copy it */ + data_source = (char *)geom_table; } /* start creating the query */ @@ -1470,64 +1522,61 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, /* adding items to the select list */ for (t = 0; t < layer->numitems; t++) { #ifdef USE_ICONV - query = msStringConcatenate(query, "convert(nvarchar(max), ["); + query = msStringConcatenate(query, "convert(nvarchar(max), ["); #else - query = msStringConcatenate(query, "convert(varchar(max), ["); + query = msStringConcatenate(query, "convert(varchar(max), ["); #endif - query = msStringConcatenate(query, layer->items[t]); - query = msStringConcatenate(query, "]) '"); - tmp = msIntToString(t); - query = msStringConcatenate(query, tmp); - if (paging_query) { - paging_query = msStringConcatenate(paging_query, "["); - paging_query = msStringConcatenate(paging_query, tmp); - paging_query = msStringConcatenate(paging_query, "], "); - } - msFree(tmp); - query = msStringConcatenate(query, "',"); + query = msStringConcatenate(query, layer->items[t]); + query = msStringConcatenate(query, "]) '"); + tmp = msIntToString(t); + query = msStringConcatenate(query, tmp); + if (paging_query) { + paging_query = msStringConcatenate(paging_query, "["); + paging_query = msStringConcatenate(paging_query, tmp); + paging_query = msStringConcatenate(paging_query, "], "); + } + msFree(tmp); + query = msStringConcatenate(query, "',"); } /* adding geometry column */ query = msStringConcatenate(query, "["); query = msStringConcatenate(query, layerinfo->geom_column); if (layerinfo->geometry_format == MSSQLGEOMETRY_NATIVE) - query = msStringConcatenate(query, "] 'geom',"); + query = msStringConcatenate(query, "] 'geom',"); else { - query = msStringConcatenate(query, "].STAsBinary() 'geom',"); + query = msStringConcatenate(query, "].STAsBinary() 'geom',"); } /* adding id column */ query = msStringConcatenate(query, "convert(varchar(36), ["); query = msStringConcatenate(query, layerinfo->urid_name); if (paging_query) { - paging_query = msStringConcatenate(paging_query, "[geom], [id] FROM ("); - query = msStringConcatenate(query, "]) 'id', row_number() over ("); - if (layerinfo->sort_spec) { - query = msStringConcatenate(query, layerinfo->sort_spec); - } + paging_query = msStringConcatenate(paging_query, "[geom], [id] FROM ("); + query = msStringConcatenate(query, "]) 'id', row_number() over ("); + if (layerinfo->sort_spec) { + query = msStringConcatenate(query, layerinfo->sort_spec); + } - if (layer->sortBy.nProperties > 0) { - tmp = msLayerBuildSQLOrderBy(layer); - if (layerinfo->sort_spec) { - query = msStringConcatenate(query, ", "); - } - else { - query = msStringConcatenate(query, " ORDER BY "); - } - query = msStringConcatenate(query, tmp); - msFree(tmp); + if (layer->sortBy.nProperties > 0) { + tmp = msLayerBuildSQLOrderBy(layer); + if (layerinfo->sort_spec) { + query = msStringConcatenate(query, ", "); + } else { + query = msStringConcatenate(query, " ORDER BY "); } - else { - if (!layerinfo->sort_spec) { - // use the unique Id as the default sort for paging - query = msStringConcatenate(query, "ORDER BY "); - query = msStringConcatenate(query, layerinfo->urid_name); - } + query = msStringConcatenate(query, tmp); + msFree(tmp); + } else { + if (!layerinfo->sort_spec) { + // use the unique Id as the default sort for paging + query = msStringConcatenate(query, "ORDER BY "); + query = msStringConcatenate(query, layerinfo->urid_name); } - query = msStringConcatenate(query, ") 'rownum' FROM "); - } - else { - query = msStringConcatenate(query, "]) 'id' FROM "); + } + query = msStringConcatenate(query, ") 'rownum' FROM "); + } else { + query = msStringConcatenate(query, "]) 'id' FROM "); } /* adding the source */ @@ -1537,20 +1586,20 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, /* use the index hint if provided */ if (layerinfo->index_name) { - query = msStringConcatenate(query, " WITH (INDEX("); - query = msStringConcatenate(query, layerinfo->index_name); - query = msStringConcatenate(query, "))"); + query = msStringConcatenate(query, " WITH (INDEX("); + query = msStringConcatenate(query, layerinfo->index_name); + query = msStringConcatenate(query, "))"); } /* adding attribute filter */ hasFilter = addFilter(layer, &query); - if( bIsValidRect ) { + if (bIsValidRect) { /* adding spatial filter */ if (hasFilter == MS_FALSE) - query = msStringConcatenate(query, " WHERE "); + query = msStringConcatenate(query, " WHERE "); else - query = msStringConcatenate(query, " AND "); + query = msStringConcatenate(query, " AND "); query = msStringConcatenate(query, layerinfo->geom_column); query = msStringConcatenate(query, ".STIntersects("); @@ -1559,117 +1608,123 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string, } if (paging_query) { - paging_query = msStringConcatenate(paging_query, query); - paging_query = msStringConcatenate(paging_query, ") tbl where [rownum] "); - if (layer->startindex > 0) { - tmp = msIntToString(layer->startindex); - paging_query = msStringConcatenate(paging_query, ">= "); - paging_query = msStringConcatenate(paging_query, tmp); - if (layer->maxfeatures >= 0) { - msFree(tmp); - tmp = msIntToString(layer->startindex + layer->maxfeatures); - paging_query = msStringConcatenate(paging_query, " and [rownum] < "); - paging_query = msStringConcatenate(paging_query, tmp); - } - } - else { - tmp = msIntToString(layer->maxfeatures); - paging_query = msStringConcatenate(paging_query, "< "); - paging_query = msStringConcatenate(paging_query, tmp); - } - msFree(tmp); - msFree(query); - query = paging_query; - } - else { - if (layerinfo->sort_spec) { - query = msStringConcatenate(query, layerinfo->sort_spec); + paging_query = msStringConcatenate(paging_query, query); + paging_query = msStringConcatenate(paging_query, ") tbl where [rownum] "); + if (layer->startindex > 0) { + tmp = msIntToString(layer->startindex); + paging_query = msStringConcatenate(paging_query, ">= "); + paging_query = msStringConcatenate(paging_query, tmp); + if (layer->maxfeatures >= 0) { + msFree(tmp); + tmp = msIntToString(layer->startindex + layer->maxfeatures); + paging_query = msStringConcatenate(paging_query, " and [rownum] < "); + paging_query = msStringConcatenate(paging_query, tmp); } + } else { + tmp = msIntToString(layer->maxfeatures); + paging_query = msStringConcatenate(paging_query, "< "); + paging_query = msStringConcatenate(paging_query, tmp); + } + msFree(tmp); + msFree(query); + query = paging_query; + } else { + if (layerinfo->sort_spec) { + query = msStringConcatenate(query, layerinfo->sort_spec); + } - /* Add extra sort by */ - if (layer->sortBy.nProperties > 0) { - char* pszTmp = msLayerBuildSQLOrderBy(layer); - if (layerinfo->sort_spec) - query = msStringConcatenate(query, ", "); - else - query = msStringConcatenate(query, " ORDER BY "); - query = msStringConcatenate(query, pszTmp); - msFree(pszTmp); - } - else if (isQuery && !layerinfo->sort_spec) { - /* Add orderby to make the result set order deterministic */ - query = msStringConcatenate(query, " ORDER BY ["); - query = msStringConcatenate(query, layerinfo->urid_name); - query = msStringConcatenate(query, "]"); - } + /* Add extra sort by */ + if (layer->sortBy.nProperties > 0) { + char *pszTmp = msLayerBuildSQLOrderBy(layer); + if (layerinfo->sort_spec) + query = msStringConcatenate(query, ", "); + else + query = msStringConcatenate(query, " ORDER BY "); + query = msStringConcatenate(query, pszTmp); + msFree(pszTmp); + } else if (isQuery && !layerinfo->sort_spec) { + /* Add orderby to make the result set order deterministic */ + query = msStringConcatenate(query, " ORDER BY ["); + query = msStringConcatenate(query, layerinfo->urid_name); + query = msStringConcatenate(query, "]"); + } } - if (layer->debug) { - msDebug("query:%s\n", query); + msDebug("query:%s\n", query); } if (executeSQL(layerinfo->conn, query)) { - char pass_field_def = 0; - int t; - const char *value; - *query_string = query; - /* collect result information */ - if ((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL - && strcasecmp(value, "auto") == 0) - pass_field_def = 1; - - msFree(layerinfo->itemtypes); - layerinfo->itemtypes = msSmallMalloc(sizeof(SQLSMALLINT) * (layer->numitems + 1)); - for (t = 0; t < layer->numitems; t++) { - char colBuff[256]; - SQLSMALLINT itemType = 0; - - columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff), layer, pass_field_def, &itemType); - layerinfo->itemtypes[t] = itemType; - } + char pass_field_def = 0; + int t; + const char *value; + *query_string = query; + /* collect result information */ + if ((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != + NULL && + strcasecmp(value, "auto") == 0) + pass_field_def = 1; + + msFree(layerinfo->itemtypes); + layerinfo->itemtypes = + msSmallMalloc(sizeof(SQLSMALLINT) * (layer->numitems + 1)); + for (t = 0; t < layer->numitems; t++) { + char colBuff[256]; + SQLSMALLINT itemType = 0; + + columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff), layer, + pass_field_def, &itemType); + layerinfo->itemtypes[t] = itemType; + } - return MS_SUCCESS; - } - else { - msSetError(MS_QUERYERR, "Error executing MSSQL2008 SQL statement: %s\n-%s\n", "msMSSQL2008LayerGetShape()", query, layerinfo->conn->errorMessage); + return MS_SUCCESS; + } else { + msSetError( + MS_QUERYERR, "Error executing MSSQL2008 SQL statement: %s\n-%s\n", + "msMSSQL2008LayerGetShape()", query, layerinfo->conn->errorMessage); - msFree(query); + msFree(query); - return MS_FAILURE; + return MS_FAILURE; } } /* Execute SQL query for this layer */ -int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)isQuery; - msMSSQL2008LayerInfo *layerinfo = 0; - char *query_str = 0; - int set_up_result; + msMSSQL2008LayerInfo *layerinfo = 0; + char *query_str = 0; + int set_up_result; - if(layer->debug) { + if (layer->debug) { msDebug("msMSSQL2008LayerWhichShapes called\n"); } layerinfo = getMSSQL2008LayerInfo(layer); - if(!layerinfo) { + if (!layerinfo) { /* layer not opened yet */ - msSetError(MS_QUERYERR, "msMSSQL2008LayerWhichShapes called on unopened layer (layerinfo = NULL)", "msMSSQL2008LayerWhichShapes()"); + msSetError(MS_QUERYERR, + "msMSSQL2008LayerWhichShapes called on unopened layer " + "(layerinfo = NULL)", + "msMSSQL2008LayerWhichShapes()"); return MS_FAILURE; } - if(!layer->data) { - msSetError(MS_QUERYERR, "Missing DATA clause in MSSQL2008 Layer definition. DATA statement must contain 'geometry_column from table_name' or 'geometry_column from (sub-query) as foo'.", "msMSSQL2008LayerWhichShapes()"); + if (!layer->data) { + msSetError(MS_QUERYERR, + "Missing DATA clause in MSSQL2008 Layer definition. DATA " + "statement must contain 'geometry_column from table_name' or " + "'geometry_column from (sub-query) as foo'.", + "msMSSQL2008LayerWhichShapes()"); return MS_FAILURE; } set_up_result = prepare_database(layer, rect, &query_str, isQuery); - if(set_up_result != MS_SUCCESS) { + if (set_up_result != MS_SUCCESS) { msFree(query_str); return set_up_result; /* relay error */ @@ -1683,13 +1738,12 @@ int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) } /* Close the MSSQL2008 record set and connection */ -int msMSSQL2008LayerClose(layerObj *layer) -{ - msMSSQL2008LayerInfo *layerinfo; +int msMSSQL2008LayerClose(layerObj *layer) { + msMSSQL2008LayerInfo *layerinfo; layerinfo = getMSSQL2008LayerInfo(layer); - if(layer->debug) { + if (layer->debug) { char *data = ""; if (layer->data) { @@ -1699,56 +1753,56 @@ int msMSSQL2008LayerClose(layerObj *layer) msDebug("msMSSQL2008LayerClose datastatement: %s\n", data); } - if(layer->debug && !layerinfo) { + if (layer->debug && !layerinfo) { msDebug("msMSSQL2008LayerClose -- layerinfo is NULL\n"); } - if(layerinfo) { + if (layerinfo) { msConnPoolRelease(layer, layerinfo->conn); layerinfo->conn = NULL; - if(layerinfo->user_srid) { + if (layerinfo->user_srid) { msFree(layerinfo->user_srid); layerinfo->user_srid = NULL; } - if(layerinfo->urid_name) { + if (layerinfo->urid_name) { msFree(layerinfo->urid_name); layerinfo->urid_name = NULL; } - if(layerinfo->index_name) { + if (layerinfo->index_name) { msFree(layerinfo->index_name); layerinfo->index_name = NULL; } - if(layerinfo->sort_spec) { + if (layerinfo->sort_spec) { msFree(layerinfo->sort_spec); layerinfo->sort_spec = NULL; } - if(layerinfo->sql) { + if (layerinfo->sql) { msFree(layerinfo->sql); layerinfo->sql = NULL; } - if(layerinfo->geom_column) { + if (layerinfo->geom_column) { msFree(layerinfo->geom_column); layerinfo->geom_column = NULL; } - if(layerinfo->geom_column_type) { + if (layerinfo->geom_column_type) { msFree(layerinfo->geom_column_type); layerinfo->geom_column_type = NULL; } - if(layerinfo->geom_table) { + if (layerinfo->geom_table) { msFree(layerinfo->geom_table); layerinfo->geom_table = NULL; } - if(layerinfo->itemtypes) { + if (layerinfo->itemtypes) { msFree(layerinfo->itemtypes); layerinfo->itemtypes = NULL; } @@ -1764,83 +1818,82 @@ int msMSSQL2008LayerClose(layerObj *layer) /* wkb is assumed to be 2d (force_2d) */ /* and wkb is a GEOMETRYCOLLECTION (force_collection) */ /* and wkb is in the endian of this computer (asbinary(...,'[XN]DR')) */ -/* each of the sub-geom inside the collection are point,linestring, or polygon */ +/* each of the sub-geom inside the collection are point,linestring, or polygon + */ /* */ /* also, int is 32bits long */ /* double is 64bits long */ /* ******************************************************* */ - /* convert the wkb into points */ /* points -> pass through */ /* lines-> constituent points */ /* polys-> treat ring like line and pull out the consituent points */ -static int force_to_points(char *wkb, shapeObj *shape) -{ - /* we're going to make a 'line' for each entity (point, line or ring) in the geom collection */ +static int force_to_points(char *wkb, shapeObj *shape) { + /* we're going to make a 'line' for each entity (point, line or ring) in the + * geom collection */ - int offset = 0; - int ngeoms; - int t, u, v; - int type, nrings, npoints; + int offset = 0; + int ngeoms; + int t, u, v; + int type, nrings, npoints; lineObj line = {0, NULL}; - shape->type = MS_SHAPE_NULL; /* nothing in it */ + shape->type = MS_SHAPE_NULL; /* nothing in it */ memcpy(&ngeoms, &wkb[5], 4); - offset = 9; /* were the first geometry is */ - for(t=0; t < ngeoms; t++) { - memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ + offset = 9; /* were the first geometry is */ + for (t = 0; t < ngeoms; t++) { + memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ - if(type == 1) { + if (type == 1) { /* Point */ shape->type = MS_SHAPE_POINT; line.numpoints = 1; - line.point = (pointObj *) msSmallMalloc(sizeof(pointObj)); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj)); memcpy(&line.point[0].x, &wkb[offset + 5], 8); memcpy(&line.point[0].y, &wkb[offset + 5 + 8], 8); offset += 5 + 16; msAddLine(shape, &line); msFree(line.point); - } else if(type == 2) { + } else if (type == 2) { /* Linestring */ shape->type = MS_SHAPE_POINT; - memcpy(&line.numpoints, &wkb[offset+5], 4); /* num points */ - line.point = (pointObj *) msSmallMalloc(sizeof(pointObj) * line.numpoints); - for(u = 0; u < line.numpoints; u++) { - memcpy( &line.point[u].x, &wkb[offset+9 + (16 * u)], 8); - memcpy( &line.point[u].y, &wkb[offset+9 + (16 * u)+8], 8); + memcpy(&line.numpoints, &wkb[offset + 5], 4); /* num points */ + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * line.numpoints); + for (u = 0; u < line.numpoints; u++) { + memcpy(&line.point[u].x, &wkb[offset + 9 + (16 * u)], 8); + memcpy(&line.point[u].y, &wkb[offset + 9 + (16 * u) + 8], 8); } - offset += 9 + 16 * line.numpoints; /* length of object */ + offset += 9 + 16 * line.numpoints; /* length of object */ msAddLine(shape, &line); msFree(line.point); - } else if(type == 3) { + } else if (type == 3) { /* Polygon */ shape->type = MS_SHAPE_POINT; - memcpy(&nrings, &wkb[offset+5],4); /* num rings */ + memcpy(&nrings, &wkb[offset + 5], 4); /* num rings */ /* add a line for each polygon ring */ offset += 9; /* now points at 1st linear ring */ - for(u = 0; u < nrings; u++) { + for (u = 0; u < nrings; u++) { /* for each ring, make a line */ memcpy(&npoints, &wkb[offset], 4); /* num points */ line.numpoints = npoints; - line.point = (pointObj *) msSmallMalloc(sizeof(pointObj)* npoints); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * npoints); /* point struct */ - for(v = 0; v < npoints; v++) { + for (v = 0; v < npoints; v++) { memcpy(&line.point[v].x, &wkb[offset + 4 + (16 * v)], 8); memcpy(&line.point[v].y, &wkb[offset + 4 + (16 * v) + 8], 8); } /* make offset point to next linear ring */ msAddLine(shape, &line); msFree(line.point); - offset += 4 + 16 *npoints; + offset += 4 + 16 * npoints; } } - } return MS_SUCCESS; @@ -1851,50 +1904,49 @@ static int force_to_points(char *wkb, shapeObj *shape) /* lines -> pass through */ /* polys -> treat rings as lines */ -static int force_to_lines(char *wkb, shapeObj *shape) -{ - int offset = 0; - int ngeoms; - int t, u, v; - int type, nrings, npoints; +static int force_to_lines(char *wkb, shapeObj *shape) { + int offset = 0; + int ngeoms; + int t, u, v; + int type, nrings, npoints; lineObj line = {0, NULL}; - shape->type = MS_SHAPE_NULL; /* nothing in it */ + shape->type = MS_SHAPE_NULL; /* nothing in it */ memcpy(&ngeoms, &wkb[5], 4); - offset = 9; /* were the first geometry is */ - for(t=0; t < ngeoms; t++) { - memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ + offset = 9; /* were the first geometry is */ + for (t = 0; t < ngeoms; t++) { + memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ /* cannot do anything with a point */ - if(type == 2) { + if (type == 2) { /* Linestring */ shape->type = MS_SHAPE_LINE; memcpy(&line.numpoints, &wkb[offset + 5], 4); - line.point = (pointObj*) msSmallMalloc(sizeof(pointObj) * line.numpoints ); - for(u=0; u < line.numpoints; u++) { + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * line.numpoints); + for (u = 0; u < line.numpoints; u++) { memcpy(&line.point[u].x, &wkb[offset + 9 + (16 * u)], 8); - memcpy(&line.point[u].y, &wkb[offset + 9 + (16 * u)+8], 8); + memcpy(&line.point[u].y, &wkb[offset + 9 + (16 * u) + 8], 8); } - offset += 9 + 16 * line.numpoints; /* length of object */ + offset += 9 + 16 * line.numpoints; /* length of object */ msAddLine(shape, &line); msFree(line.point); - } else if(type == 3) { + } else if (type == 3) { /* polygon */ shape->type = MS_SHAPE_LINE; memcpy(&nrings, &wkb[offset + 5], 4); /* num rings */ /* add a line for each polygon ring */ offset += 9; /* now points at 1st linear ring */ - for(u = 0; u < nrings; u++) { + for (u = 0; u < nrings; u++) { /* for each ring, make a line */ memcpy(&npoints, &wkb[offset], 4); line.numpoints = npoints; - line.point = (pointObj*) msSmallMalloc(sizeof(pointObj) * npoints); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * npoints); /* point struct */ - for(v = 0; v < npoints; v++) { + for (v = 0; v < npoints; v++) { memcpy(&line.point[v].x, &wkb[offset + 4 + (16 * v)], 8); memcpy(&line.point[v].y, &wkb[offset + 4 + (16 * v) + 8], 8); } @@ -1912,34 +1964,33 @@ static int force_to_lines(char *wkb, shapeObj *shape) /* point -> reject */ /* line -> reject */ /* polygon -> lines of linear rings */ -static int force_to_polygons(char *wkb, shapeObj *shape) -{ - int offset = 0; - int ngeoms; - int t, u, v; - int type, nrings, npoints; +static int force_to_polygons(char *wkb, shapeObj *shape) { + int offset = 0; + int ngeoms; + int t, u, v; + int type, nrings, npoints; lineObj line = {0, NULL}; - shape->type = MS_SHAPE_NULL; /* nothing in it */ + shape->type = MS_SHAPE_NULL; /* nothing in it */ memcpy(&ngeoms, &wkb[5], 4); - offset = 9; /* were the first geometry is */ - for(t = 0; t < ngeoms; t++) { - memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ + offset = 9; /* were the first geometry is */ + for (t = 0; t < ngeoms; t++) { + memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ - if(type == 3) { + if (type == 3) { /* polygon */ shape->type = MS_SHAPE_POLYGON; memcpy(&nrings, &wkb[offset + 5], 4); /* num rings */ /* add a line for each polygon ring */ offset += 9; /* now points at 1st linear ring */ - for(u=0; u < nrings; u++) { + for (u = 0; u < nrings; u++) { /* for each ring, make a line */ memcpy(&npoints, &wkb[offset], 4); /* num points */ line.numpoints = npoints; - line.point = (pointObj*) msSmallMalloc(sizeof(pointObj) * npoints); - for(v=0; v < npoints; v++) { + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * npoints); + for (v = 0; v < npoints; v++) { memcpy(&line.point[v].x, &wkb[offset + 4 + (16 * v)], 8); memcpy(&line.point[v].y, &wkb[offset + 4 + (16 * v) + 8], 8); } @@ -1958,36 +2009,35 @@ static int force_to_polygons(char *wkb, shapeObj *shape) /* if there is any line in wkb, return force_line */ /* otherwise return force_point */ -static int dont_force(char *wkb, shapeObj *shape) -{ - int offset =0; - int ngeoms; - int type, t; - int best_type; +static int dont_force(char *wkb, shapeObj *shape) { + int offset = 0; + int ngeoms; + int type, t; + int best_type; - best_type = MS_SHAPE_NULL; /* nothing in it */ + best_type = MS_SHAPE_NULL; /* nothing in it */ memcpy(&ngeoms, &wkb[5], 4); - offset = 9; /* were the first geometry is */ - for(t = 0; t < ngeoms; t++) { - memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ + offset = 9; /* were the first geometry is */ + for (t = 0; t < ngeoms; t++) { + memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ - if(type == 3) { + if (type == 3) { best_type = MS_SHAPE_POLYGON; - } else if(type ==2 && best_type != MS_SHAPE_POLYGON) { + } else if (type == 2 && best_type != MS_SHAPE_POLYGON) { best_type = MS_SHAPE_LINE; - } else if(type == 1 && best_type == MS_SHAPE_NULL) { + } else if (type == 1 && best_type == MS_SHAPE_NULL) { best_type = MS_SHAPE_POINT; } } - if(best_type == MS_SHAPE_POINT) { + if (best_type == MS_SHAPE_POINT) { return force_to_points(wkb, shape); } - if(best_type == MS_SHAPE_LINE) { + if (best_type == MS_SHAPE_LINE) { return force_to_lines(wkb, shape); } - if(best_type == MS_SHAPE_POLYGON) { + if (best_type == MS_SHAPE_POLYGON) { return force_to_polygons(wkb, shape); } @@ -2091,81 +2141,80 @@ static int force_to_shapeType(char *wkb, shapeObj *shape, int msShapeType) ///* if there is any polygon in wkb, return force_polygon */ ///* if there is any line in wkb, return force_line */ ///* otherwise return force_point */ -//static int dont_force(char *wkb, shapeObj *shape) +// static int dont_force(char *wkb, shapeObj *shape) //{ -// int offset =0; -// int ngeoms = 1; -// int type; -// int best_type; -// int u; -// int nrings, npoints; +// int offset =0; +// int ngeoms = 1; +// int type; +// int best_type; +// int u; +// int nrings, npoints; // -// best_type = MS_SHAPE_NULL; /* nothing in it */ +// best_type = MS_SHAPE_NULL; /* nothing in it */ // -// do -// { -// ngeoms--; +// do +// { +// ngeoms--; // -// memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ +// memcpy(&type, &wkb[offset + 1], 4); /* type of this geometry */ // -// if(type == 3) { -// best_type = MS_SHAPE_POLYGON; -// } else if(type ==2 && best_type != MS_SHAPE_POLYGON) { -// best_type = MS_SHAPE_LINE; -// } else if(type == 1 && best_type == MS_SHAPE_NULL) { -// best_type = MS_SHAPE_POINT; -// } +// if(type == 3) { +// best_type = MS_SHAPE_POLYGON; +// } else if(type ==2 && best_type != MS_SHAPE_POLYGON) { +// best_type = MS_SHAPE_LINE; +// } else if(type == 1 && best_type == MS_SHAPE_NULL) { +// best_type = MS_SHAPE_POINT; +// } // -// if (type == 1) -// { -// /* Point */ -// offset += 5 + 16; -// } -// else if(type == 2) -// { -// int numPoints; +// if (type == 1) +// { +// /* Point */ +// offset += 5 + 16; +// } +// else if(type == 2) +// { +// int numPoints; // -// memcpy(&numPoints, &wkb[offset+5], 4); /* num points */ -// /* Linestring */ -// offset += 9 + 16 * numPoints; /* length of object */ -// } -// else if(type == 3) -// { -// /* Polygon */ -// memcpy(&nrings, &wkb[offset+5],4); /* num rings */ -// offset += 9; /* now points at 1st linear ring */ -// for(u = 0; u < nrings; u++) { -// /* for each ring, make a line */ -// memcpy(&npoints, &wkb[offset], 4); /* num points */ -// offset += 4 + 16 *npoints; -// } -// } -// else if(type >= 4 && type <= 7) -// { -// int cnt = 0; +// memcpy(&numPoints, &wkb[offset+5], 4); /* num points */ +// /* Linestring */ +// offset += 9 + 16 * numPoints; /* length of object */ +// } +// else if(type == 3) +// { +// /* Polygon */ +// memcpy(&nrings, &wkb[offset+5],4); /* num rings */ +// offset += 9; /* now points at 1st linear ring */ +// for(u = 0; u < nrings; u++) { +// /* for each ring, make a line */ +// memcpy(&npoints, &wkb[offset], 4); /* num points */ +// offset += 4 + 16 *npoints; +// } +// } +// else if(type >= 4 && type <= 7) +// { +// int cnt = 0; // -// offset += 5; +// offset += 5; // -// memcpy(&cnt, &wkb[offset], 4); -// offset += 4; /* were the first geometry is */ +// memcpy(&cnt, &wkb[offset], 4); +// offset += 4; /* were the first geometry is */ // -// ngeoms += cnt; -// } -// } -// while (ngeoms > 0); +// ngeoms += cnt; +// } +// } +// while (ngeoms > 0); // -// return force_to_shapeType(wkb, shape, best_type); -//} +// return force_to_shapeType(wkb, shape, best_type); +// } // /* find the bounds of the shape */ -static void find_bounds(shapeObj *shape) -{ - int t, u; - int first_one = 1; +static void find_bounds(shapeObj *shape) { + int t, u; + int first_one = 1; - for(t = 0; t < shape->numlines; t++) { - for(u = 0; u < shape->line[t].numpoints; u++) { - if(first_one) { + for (t = 0; t < shape->numlines; t++) { + for (u = 0; u < shape->line[t].numpoints; u++) { + if (first_one) { shape->bounds.minx = shape->line[t].point[u].x; shape->bounds.maxx = shape->line[t].point[u].x; @@ -2173,17 +2222,17 @@ static void find_bounds(shapeObj *shape) shape->bounds.maxy = shape->line[t].point[u].y; first_one = 0; } else { - if(shape->line[t].point[u].x < shape->bounds.minx) { + if (shape->line[t].point[u].x < shape->bounds.minx) { shape->bounds.minx = shape->line[t].point[u].x; } - if(shape->line[t].point[u].x > shape->bounds.maxx) { + if (shape->line[t].point[u].x > shape->bounds.maxx) { shape->bounds.maxx = shape->line[t].point[u].x; } - if(shape->line[t].point[u].y < shape->bounds.miny) { + if (shape->line[t].point[u].y < shape->bounds.miny) { shape->bounds.miny = shape->line[t].point[u].y; } - if(shape->line[t].point[u].y > shape->bounds.maxy) { + if (shape->line[t].point[u].y > shape->bounds.maxy) { shape->bounds.maxy = shape->line[t].point[u].y; } } @@ -2192,15 +2241,16 @@ static void find_bounds(shapeObj *shape) } /* Used by NextShape() to access a shape in the query set */ -int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *record) -{ - msMSSQL2008LayerInfo *layerinfo; +int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, + long *record) { + msMSSQL2008LayerInfo *layerinfo; SQLLEN needLen = 0; SQLLEN retLen = 0; char dummyBuffer[1]; char *wkbBuffer; char *valueBuffer; - char oidBuffer[ 16 ]; /* assuming the OID will always be a long this should be enough */ + char oidBuffer[16]; /* assuming the OID will always be a long this should be + enough */ long record_oid; int t; @@ -2210,22 +2260,27 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor layerinfo = getMSSQL2008LayerInfo(layer); - if(!layerinfo) { - msSetError(MS_QUERYERR, "GetShape called with layerinfo = NULL", "msMSSQL2008LayerGetShape()"); + if (!layerinfo) { + msSetError(MS_QUERYERR, "GetShape called with layerinfo = NULL", + "msMSSQL2008LayerGetShape()"); return MS_FAILURE; } - if(!layerinfo->conn) { - msSetError(MS_QUERYERR, "NextShape called on MSSQL2008 layer with no connection to DB.", "msMSSQL2008LayerGetShape()"); + if (!layerinfo->conn) { + msSetError(MS_QUERYERR, + "NextShape called on MSSQL2008 layer with no connection to DB.", + "msMSSQL2008LayerGetShape()"); return MS_FAILURE; } shape->type = MS_SHAPE_NULL; - while(shape->type == MS_SHAPE_NULL) { - /* SQLRETURN rc = SQLFetchScroll(layerinfo->conn->hstmt, SQL_FETCH_ABSOLUTE, (SQLLEN) (*record) + 1); */ + while (shape->type == MS_SHAPE_NULL) { + /* SQLRETURN rc = SQLFetchScroll(layerinfo->conn->hstmt, SQL_FETCH_ABSOLUTE, + * (SQLLEN) (*record) + 1); */ - /* We only do forward fetches. the parameter 'record' is ignored, but is incremented */ + /* We only do forward fetches. the parameter 'record' is ignored, but is + * incremented */ SQLRETURN rc = SQLFetch(layerinfo->conn->hstmt); /* Any error assume out of recordset bounds */ @@ -2238,15 +2293,17 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor { /* have to retrieve shape attributes */ - shape->values = (char **) msSmallMalloc(sizeof(char *) * layer->numitems); + shape->values = (char **)msSmallMalloc(sizeof(char *) * layer->numitems); shape->numvalues = layer->numitems; - for(t=0; t < layer->numitems; t++) { - /* Startwith a 64 character long buffer. This may need to be increased after calling SQLGetData. */ + for (t = 0; t < layer->numitems; t++) { + /* Startwith a 64 character long buffer. This may need to be increased + * after calling SQLGetData. */ SQLLEN emptyLen = 64; - valueBuffer = (char*) msSmallMalloc(emptyLen); - if ( valueBuffer == NULL ) { - msSetError( MS_QUERYERR, "Could not allocate value buffer.", "msMSSQL2008LayerGetShapeRandom()" ); + valueBuffer = (char *)msSmallMalloc(emptyLen); + if (valueBuffer == NULL) { + msSetError(MS_QUERYERR, "Could not allocate value buffer.", + "msMSSQL2008LayerGetShapeRandom()"); return MS_FAILURE; } @@ -2259,27 +2316,36 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor char *bufferLocation = valueBuffer; int r = 0; while (r < 20) { - rc = SQLGetData(layerinfo->conn->hstmt, (SQLUSMALLINT)(t + 1), targetType, bufferLocation, emptyLen, &retLen); + rc = SQLGetData(layerinfo->conn->hstmt, (SQLUSMALLINT)(t + 1), + targetType, bufferLocation, emptyLen, &retLen); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) - totalLen += retLen > emptyLen || retLen == SQL_NO_TOTAL ? emptyLen : retLen; + totalLen += + retLen > emptyLen || retLen == SQL_NO_TOTAL ? emptyLen : retLen; if (rc == SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA) { - /* We must compensate for the last null termination that SQLGetData include */ - /* If we get SQL_NO_TOTAL we do not know how big buffer we need so we increase it with 512. */ + /* We must compensate for the last null termination that SQLGetData + * include */ + /* If we get SQL_NO_TOTAL we do not know how big buffer we need so + * we increase it with 512. */ #ifdef USE_ICONV totalLen -= sizeof(wchar_t); - emptyLen = retLen != SQL_NO_TOTAL? retLen - emptyLen + 2 * sizeof(wchar_t): 512; + emptyLen = retLen != SQL_NO_TOTAL + ? retLen - emptyLen + 2 * sizeof(wchar_t) + : 512; #else totalLen -= sizeof(char); - emptyLen = retLen != SQL_NO_TOTAL? retLen - emptyLen + 2 * sizeof(char): 512; + emptyLen = retLen != SQL_NO_TOTAL + ? retLen - emptyLen + 2 * sizeof(char) + : 512; #endif - valueBuffer = (char *)msSmallRealloc(valueBuffer, totalLen + emptyLen); + valueBuffer = + (char *)msSmallRealloc(valueBuffer, totalLen + emptyLen); bufferLocation = valueBuffer + totalLen; } else break; - + r++; } @@ -2289,7 +2355,8 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor if (totalLen > 0) { /* Pop the value into the shape's value array */ #ifdef USE_ICONV - shape->values[t] = msConvertWideStringToUTF8((wchar_t*)valueBuffer, "UCS-2LE"); + shape->values[t] = + msConvertWideStringToUTF8((wchar_t *)valueBuffer, "UCS-2LE"); msFree(valueBuffer); #else shape->values[t] = valueBuffer; @@ -2304,46 +2371,51 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor /* Get shape geometry */ { /* Set up to request the size of the buffer needed */ - rc = SQLGetData(layerinfo->conn->hstmt, (SQLUSMALLINT)(layer->numitems + 1), SQL_C_BINARY, dummyBuffer, 0, &needLen); + rc = SQLGetData(layerinfo->conn->hstmt, + (SQLUSMALLINT)(layer->numitems + 1), SQL_C_BINARY, + dummyBuffer, 0, &needLen); if (rc == SQL_ERROR) handleSQLError(layer); /* allow space for coercion to geometry collection if needed*/ - wkbTemp = (char*)msSmallMalloc(needLen+9); + wkbTemp = (char *)msSmallMalloc(needLen + 9); /* write data above space allocated for geometry collection coercion */ wkbBuffer = wkbTemp + 9; - if ( wkbBuffer == NULL ) { - msSetError( MS_QUERYERR, "Could not allocate value buffer.", "msMSSQL2008LayerGetShapeRandom()" ); + if (wkbBuffer == NULL) { + msSetError(MS_QUERYERR, "Could not allocate value buffer.", + "msMSSQL2008LayerGetShapeRandom()"); return MS_FAILURE; } /* Grab the WKB */ - rc = SQLGetData(layerinfo->conn->hstmt, (SQLUSMALLINT)(layer->numitems + 1), SQL_C_BINARY, wkbBuffer, needLen, &retLen); + rc = SQLGetData(layerinfo->conn->hstmt, + (SQLUSMALLINT)(layer->numitems + 1), SQL_C_BINARY, + wkbBuffer, needLen, &retLen); if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) handleSQLError(layer); if (layerinfo->geometry_format == MSSQLGEOMETRY_NATIVE) { - layerinfo->gpi.pszData = (unsigned char*)wkbBuffer; + layerinfo->gpi.pszData = (unsigned char *)wkbBuffer; layerinfo->gpi.nLen = (int)retLen; if (!ParseSqlGeometry(layerinfo, shape)) { - switch(layer->type) { - case MS_LAYER_POINT: - shape->type = MS_SHAPE_POINT; - break; + switch (layer->type) { + case MS_LAYER_POINT: + shape->type = MS_SHAPE_POINT; + break; - case MS_LAYER_LINE: - shape->type = MS_SHAPE_LINE; - break; + case MS_LAYER_LINE: + shape->type = MS_SHAPE_LINE; + break; - case MS_LAYER_POLYGON: - shape->type = MS_SHAPE_POLYGON; - break; + case MS_LAYER_POLYGON: + shape->type = MS_SHAPE_POLYGON; + break; - default: - break; + default: + break; } } } else { @@ -2355,7 +2427,8 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor wkbTemp[0] = wkbBuffer[0]; wkbBuffer = wkbTemp; - /* indicate type is geometry collection (although geomType + 3 would also work) */ + /* indicate type is geometry collection (although geomType + 3 would + * also work) */ wkbBuffer[1] = (char)7; wkbBuffer[2] = (char)0; wkbBuffer[3] = (char)0; @@ -2368,65 +2441,65 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor wkbBuffer[8] = (char)0; } - switch(layer->type) { - case MS_LAYER_POINT: - /*result =*/ force_to_points(wkbBuffer, shape); - break; + switch (layer->type) { + case MS_LAYER_POINT: + /*result =*/force_to_points(wkbBuffer, shape); + break; - case MS_LAYER_LINE: - /*result =*/ force_to_lines(wkbBuffer, shape); - break; + case MS_LAYER_LINE: + /*result =*/force_to_lines(wkbBuffer, shape); + break; - case MS_LAYER_POLYGON: - /*result =*/ force_to_polygons(wkbBuffer, shape); - break; + case MS_LAYER_POLYGON: + /*result =*/force_to_polygons(wkbBuffer, shape); + break; - case MS_LAYER_QUERY: - case MS_LAYER_CHART: - /*result =*/ dont_force(wkbBuffer, shape); - break; + case MS_LAYER_QUERY: + case MS_LAYER_CHART: + /*result =*/dont_force(wkbBuffer, shape); + break; - case MS_LAYER_RASTER: - msDebug( "Ignoring MS_LAYER_RASTER in mapMSSQL2008.c\n" ); - break; + case MS_LAYER_RASTER: + msDebug("Ignoring MS_LAYER_RASTER in mapMSSQL2008.c\n"); + break; - case MS_LAYER_CIRCLE: - msDebug( "Ignoring MS_LAYER_CIRCLE in mapMSSQL2008.c\n" ); - break; + case MS_LAYER_CIRCLE: + msDebug("Ignoring MS_LAYER_CIRCLE in mapMSSQL2008.c\n"); + break; - default: - msDebug( "Unsupported layer type in msMSSQL2008LayerNextShape()!" ); - break; + default: + msDebug("Unsupported layer type in msMSSQL2008LayerNextShape()!"); + break; } find_bounds(shape); } - //free(wkbBuffer); + // free(wkbBuffer); msFree(wkbTemp); } - /* Next get unique id for row - since the OID shouldn't be larger than a long we'll assume billions as a limit */ - rc = SQLGetData(layerinfo->conn->hstmt, (SQLUSMALLINT)(layer->numitems + 2), SQL_C_BINARY, oidBuffer, sizeof(oidBuffer) - 1, &retLen); + /* Next get unique id for row - since the OID shouldn't be larger than a + * long we'll assume billions as a limit */ + rc = SQLGetData(layerinfo->conn->hstmt, + (SQLUSMALLINT)(layer->numitems + 2), SQL_C_BINARY, + oidBuffer, sizeof(oidBuffer) - 1, &retLen); if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) handleSQLError(layer); - if (retLen < (int)sizeof(oidBuffer)) - { - oidBuffer[retLen] = 0; - record_oid = strtol(oidBuffer, NULL, 10); - shape->index = record_oid; - } - else - { - /* non integer fid column, use single pass */ - shape->index = -1; - } + if (retLen < (int)sizeof(oidBuffer)) { + oidBuffer[retLen] = 0; + record_oid = strtol(oidBuffer, NULL, 10); + shape->index = record_oid; + } else { + /* non integer fid column, use single pass */ + shape->index = -1; + } shape->resultindex = (*record); - (*record)++; /* move to next shape */ + (*record)++; /* move to next shape */ - if(shape->type != MS_SHAPE_NULL) { + if (shape->type != MS_SHAPE_NULL) { return MS_SUCCESS; } else { msDebug("msMSSQL2008LayerGetShapeRandom bad shape: %ld\n", *record); @@ -2440,19 +2513,20 @@ int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *recor return MS_FAILURE; } -/* find the next shape with the appropriate shape type (convert it if necessary) */ +/* find the next shape with the appropriate shape type (convert it if necessary) + */ /* also, load in the attribute data */ /* MS_DONE => no more data */ -int msMSSQL2008LayerNextShape(layerObj *layer, shapeObj *shape) -{ - int result; +int msMSSQL2008LayerNextShape(layerObj *layer, shapeObj *shape) { + int result; - msMSSQL2008LayerInfo *layerinfo; + msMSSQL2008LayerInfo *layerinfo; layerinfo = getMSSQL2008LayerInfo(layer); - if(!layerinfo) { - msSetError(MS_QUERYERR, "NextShape called with layerinfo = NULL", "msMSSQL2008LayerNextShape()"); + if (!layerinfo) { + msSetError(MS_QUERYERR, "NextShape called with layerinfo = NULL", + "msMSSQL2008LayerNextShape()"); return MS_FAILURE; } @@ -2464,44 +2538,53 @@ int msMSSQL2008LayerNextShape(layerObj *layer, shapeObj *shape) } /* Execute a query on the DB based on the query result. */ -int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - char *query_str; - char *columns_wanted = 0; +int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { + char *query_str; + char *columns_wanted = 0; - msMSSQL2008LayerInfo *layerinfo; - int t; + msMSSQL2008LayerInfo *layerinfo; + int t; char buffer[32000] = ""; long shapeindex = record->shapeindex; long resultindex = record->resultindex; - if(layer->debug) { - msDebug("msMSSQL2008LayerGetShape called for shapeindex = %ld\n", shapeindex); + if (layer->debug) { + msDebug("msMSSQL2008LayerGetShape called for shapeindex = %ld\n", + shapeindex); } layerinfo = getMSSQL2008LayerInfo(layer); - if(!layerinfo) { + if (!layerinfo) { /* Layer not open */ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetShape called on unopened layer (layerinfo = NULL)", "msMSSQL2008LayerGetShape()"); + msSetError( + MS_QUERYERR, + "msMSSQL2008LayerGetShape called on unopened layer (layerinfo = NULL)", + "msMSSQL2008LayerGetShape()"); return MS_FAILURE; } if (resultindex >= 0 && layerinfo->sql) { - /* trying to provide the result from the current resultset (single-pass query) */ - if( resultindex < layerinfo->row_num) { + /* trying to provide the result from the current resultset (single-pass + * query) */ + if (resultindex < layerinfo->row_num) { /* re-issue the query */ if (!executeSQL(layerinfo->conn, layerinfo->sql)) { - msSetError(MS_QUERYERR, "Error executing MSSQL2008 SQL statement: %s\n-%s\n", "msMSSQL2008LayerGetShape()", layerinfo->sql, layerinfo->conn->errorMessage); + msSetError(MS_QUERYERR, + "Error executing MSSQL2008 SQL statement: %s\n-%s\n", + "msMSSQL2008LayerGetShape()", layerinfo->sql, + layerinfo->conn->errorMessage); return MS_FAILURE; } layerinfo->row_num = 0; } - while( layerinfo->row_num < resultindex ) { + while (layerinfo->row_num < resultindex) { /* move forward until we reach the desired index */ - if (msMSSQL2008LayerGetShapeRandom(layer, shape, &(layerinfo->row_num)) != MS_SUCCESS) + if (msMSSQL2008LayerGetShapeRandom(layer, shape, &(layerinfo->row_num)) != + MS_SUCCESS) return MS_FAILURE; } @@ -2510,39 +2593,51 @@ int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record /* non single-pass case, fetch the record from the database */ - if(layer->numitems == 0) { + if (layer->numitems == 0) { if (layerinfo->geometry_format == MSSQLGEOMETRY_NATIVE) - snprintf(buffer, sizeof(buffer), "%s, convert(varchar(36), %s)", layerinfo->geom_column, layerinfo->urid_name); + snprintf(buffer, sizeof(buffer), "%s, convert(varchar(36), %s)", + layerinfo->geom_column, layerinfo->urid_name); else - snprintf(buffer, sizeof(buffer), "%s.STAsBinary(), convert(varchar(36), %s)", layerinfo->geom_column, layerinfo->urid_name); + snprintf(buffer, sizeof(buffer), + "%s.STAsBinary(), convert(varchar(36), %s)", + layerinfo->geom_column, layerinfo->urid_name); columns_wanted = msStrdup(buffer); } else { - for(t = 0; t < layer->numitems; t++) { - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "convert(varchar(max), %s),", layer->items[t]); + for (t = 0; t < layer->numitems; t++) { + snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), + "convert(varchar(max), %s),", layer->items[t]); } if (layerinfo->geometry_format == MSSQLGEOMETRY_NATIVE) - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%s, convert(varchar(36), %s)", layerinfo->geom_column, layerinfo->urid_name); + snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), + "%s, convert(varchar(36), %s)", layerinfo->geom_column, + layerinfo->urid_name); else - snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%s.STAsBinary(), convert(varchar(36), %s)", layerinfo->geom_column, layerinfo->urid_name); + snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), + "%s.STAsBinary(), convert(varchar(36), %s)", + layerinfo->geom_column, layerinfo->urid_name); columns_wanted = msStrdup(buffer); } - /* index_name is ignored here since the hint should be for the spatial index, not the PK index */ - snprintf(buffer, sizeof(buffer), "select %s from %s where %s = %ld", columns_wanted, layerinfo->geom_table, layerinfo->urid_name, shapeindex); + /* index_name is ignored here since the hint should be for the spatial index, + * not the PK index */ + snprintf(buffer, sizeof(buffer), "select %s from %s where %s = %ld", + columns_wanted, layerinfo->geom_table, layerinfo->urid_name, + shapeindex); query_str = msStrdup(buffer); - if(layer->debug) { + if (layer->debug) { msDebug("msMSSQL2008LayerGetShape: %s \n", query_str); } msFree(columns_wanted); if (!executeSQL(layerinfo->conn, query_str)) { - msSetError(MS_QUERYERR, "Error executing MSSQL2008 SQL statement: %s\n-%s\n", "msMSSQL2008LayerGetShape()", - query_str, layerinfo->conn->errorMessage); + msSetError( + MS_QUERYERR, "Error executing MSSQL2008 SQL statement: %s\n-%s\n", + "msMSSQL2008LayerGetShape()", query_str, layerinfo->conn->errorMessage); msFree(query_str); @@ -2558,167 +2653,180 @@ int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record /* ** Returns the number of shapes that match the potential filter and extent. - * rectProjection is the projection in which rect is expressed, or can be NULL if - * rect should be considered in the layer projection. - * This should be equivalent to calling msLayerWhichShapes() and counting the - * number of shapes returned by msLayerNextShape(), honouring layer->maxfeatures - * limitation if layer->maxfeatures>=0, and honouring layer->startindex if - * layer->startindex >= 1 and paging is enabled. - * Returns -1 in case of failure. - */ -int msMSSQL2008LayerGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProjection) -{ - msMSSQL2008LayerInfo *layerinfo; - char *query = 0; - char result_data[256]; - char box3d[40 + 10 * 22 + 11]; - SQLLEN retLen; - SQLRETURN rc; - int hasFilter = MS_FALSE; - const rectObj rectInvalid = MS_INIT_INVALID_RECT; - const int bIsValidRect = memcmp(&rect, &rectInvalid, sizeof(rect)) != 0; - - rectObj searchrectInLayerProj = rect; +* rectProjection is the projection in which rect is expressed, or can be NULL if +* rect should be considered in the layer projection. +* This should be equivalent to calling msLayerWhichShapes() and counting the +* number of shapes returned by msLayerNextShape(), honouring layer->maxfeatures +* limitation if layer->maxfeatures>=0, and honouring layer->startindex if +* layer->startindex >= 1 and paging is enabled. +* Returns -1 in case of failure. +*/ +int msMSSQL2008LayerGetShapeCount(layerObj *layer, rectObj rect, + projectionObj *rectProjection) { + msMSSQL2008LayerInfo *layerinfo; + char *query = 0; + char result_data[256]; + char box3d[40 + 10 * 22 + 11]; + SQLLEN retLen; + SQLRETURN rc; + int hasFilter = MS_FALSE; + const rectObj rectInvalid = MS_INIT_INVALID_RECT; + const int bIsValidRect = memcmp(&rect, &rectInvalid, sizeof(rect)) != 0; - if (layer->debug) { - msDebug("msMSSQL2008LayerGetShapeCount called.\n"); - } + rectObj searchrectInLayerProj = rect; - layerinfo = getMSSQL2008LayerInfo(layer); + if (layer->debug) { + msDebug("msMSSQL2008LayerGetShapeCount called.\n"); + } - if (!layerinfo) { - /* Layer not open */ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetShapeCount called on unopened layer (layerinfo = NULL)", "msMSSQL2008LayerGetShapeCount()"); + layerinfo = getMSSQL2008LayerInfo(layer); - return MS_FAILURE; - } + if (!layerinfo) { + /* Layer not open */ + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetShapeCount called on unopened layer " + "(layerinfo = NULL)", + "msMSSQL2008LayerGetShapeCount()"); - // Special processing if the specified projection for the rect is different from the layer projection - // We want to issue a WHERE that includes - // ((the_geom && rect_reprojected_in_layer_SRID) AND NOT ST_Disjoint(ST_Transform(the_geom, rect_SRID), rect)) - if (rectProjection != NULL && layer->project && - msProjectionsDiffer(&(layer->projection), rectProjection)) - { - // If we cannot guess the EPSG code of the rectProjection, fallback on slow implementation - if (rectProjection->numargs < 1 || - strncasecmp(rectProjection->args[0], "init=epsg:", (int)strlen("init=epsg:")) != 0) - { - if (layer->debug) { - msDebug("msMSSQL2008LayerGetShapeCount(): cannot find EPSG code of rectProjection. Falling back on client-side feature count.\n"); - } - return LayerDefaultGetShapeCount(layer, rect, rectProjection); - } + return MS_FAILURE; + } - // Reproject the passed rect into the layer projection and get - // the SRID from the rectProjection - msProjectRect(rectProjection, &(layer->projection), &searchrectInLayerProj); /* project the searchrect to source coords */ + // Special processing if the specified projection for the rect is different + // from the layer projection We want to issue a WHERE that includes + // ((the_geom && rect_reprojected_in_layer_SRID) AND NOT + // ST_Disjoint(ST_Transform(the_geom, rect_SRID), rect)) + if (rectProjection != NULL && layer->project && + msProjectionsDiffer(&(layer->projection), rectProjection)) { + // If we cannot guess the EPSG code of the rectProjection, fallback on slow + // implementation + if (rectProjection->numargs < 1 || + strncasecmp(rectProjection->args[0], + "init=epsg:", (int)strlen("init=epsg:")) != 0) { + if (layer->debug) { + msDebug("msMSSQL2008LayerGetShapeCount(): cannot find EPSG code of " + "rectProjection. Falling back on client-side feature count.\n"); + } + return LayerDefaultGetShapeCount(layer, rect, rectProjection); } - if (searchrectInLayerProj.minx == searchrectInLayerProj.maxx || - searchrectInLayerProj.miny == searchrectInLayerProj.maxy) { - /* create point shape for rectangles with zero area */ - snprintf(box3d, sizeof(box3d), "%s::STGeomFromText('POINT(%.15g %.15g)',%s)", /* %s.STSrid)", */ - layerinfo->geom_column_type, searchrectInLayerProj.minx, searchrectInLayerProj.miny, layerinfo->user_srid); - } - else { - snprintf(box3d, sizeof(box3d), "%s::STGeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ - layerinfo->geom_column_type, - searchrectInLayerProj.minx, searchrectInLayerProj.miny, - searchrectInLayerProj.maxx, searchrectInLayerProj.miny, - searchrectInLayerProj.maxx, searchrectInLayerProj.maxy, - searchrectInLayerProj.minx, searchrectInLayerProj.maxy, - searchrectInLayerProj.minx, searchrectInLayerProj.miny, - layerinfo->user_srid - ); - } + // Reproject the passed rect into the layer projection and get + // the SRID from the rectProjection + msProjectRect( + rectProjection, &(layer->projection), + &searchrectInLayerProj); /* project the searchrect to source coords */ + } - msLayerTranslateFilter(layer, &layer->filter, layer->filteritem); + if (searchrectInLayerProj.minx == searchrectInLayerProj.maxx || + searchrectInLayerProj.miny == searchrectInLayerProj.maxy) { + /* create point shape for rectangles with zero area */ + snprintf(box3d, sizeof(box3d), + "%s::STGeomFromText('POINT(%.15g %.15g)',%s)", /* %s.STSrid)", */ + layerinfo->geom_column_type, searchrectInLayerProj.minx, + searchrectInLayerProj.miny, layerinfo->user_srid); + } else { + snprintf(box3d, sizeof(box3d), + "%s::STGeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g " + "%.15g,%.15g %.15g,%.15g %.15g))',%s)", /* %s.STSrid)", */ + layerinfo->geom_column_type, searchrectInLayerProj.minx, + searchrectInLayerProj.miny, searchrectInLayerProj.maxx, + searchrectInLayerProj.miny, searchrectInLayerProj.maxx, + searchrectInLayerProj.maxy, searchrectInLayerProj.minx, + searchrectInLayerProj.maxy, searchrectInLayerProj.minx, + searchrectInLayerProj.miny, layerinfo->user_srid); + } - /* set up statement */ - query = msStringConcatenate(query, "SELECT count(*) FROM "); - query = msStringConcatenate(query, layerinfo->geom_table); + msLayerTranslateFilter(layer, &layer->filter, layer->filteritem); - /* adding attribute filter */ - hasFilter = addFilter(layer, &query); + /* set up statement */ + query = msStringConcatenate(query, "SELECT count(*) FROM "); + query = msStringConcatenate(query, layerinfo->geom_table); - if( bIsValidRect ) { - /* adding spatial filter */ - if (hasFilter == MS_FALSE) - query = msStringConcatenate(query, " WHERE "); - else - query = msStringConcatenate(query, " AND "); + /* adding attribute filter */ + hasFilter = addFilter(layer, &query); - query = msStringConcatenate(query, layerinfo->geom_column); - query = msStringConcatenate(query, ".STIntersects("); - query = msStringConcatenate(query, box3d); - query = msStringConcatenate(query, ") = 1 "); - } + if (bIsValidRect) { + /* adding spatial filter */ + if (hasFilter == MS_FALSE) + query = msStringConcatenate(query, " WHERE "); + else + query = msStringConcatenate(query, " AND "); - if (layer->debug) { - msDebug("query:%s\n", query); - } + query = msStringConcatenate(query, layerinfo->geom_column); + query = msStringConcatenate(query, ".STIntersects("); + query = msStringConcatenate(query, box3d); + query = msStringConcatenate(query, ") = 1 "); + } - if (!executeSQL(layerinfo->conn, query)) { - msFree(query); - return -1; - } + if (layer->debug) { + msDebug("query:%s\n", query); + } + if (!executeSQL(layerinfo->conn, query)) { msFree(query); + return -1; + } - rc = SQLFetch(layerinfo->conn->hstmt); + msFree(query); - if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if (layer->debug) { - msDebug("msMSSQL2008LayerGetShapeCount: No results found.\n"); - } + rc = SQLFetch(layerinfo->conn->hstmt); - return -1; + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + if (layer->debug) { + msDebug("msMSSQL2008LayerGetShapeCount: No results found.\n"); } - rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, sizeof(result_data), &retLen); + return -1; + } + + rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_CHAR, result_data, + sizeof(result_data), &retLen); - if (rc == SQL_ERROR) { - msSetError(MS_QUERYERR, "Failed to get feature count", "msMSSQL2008LayerGetShapeCount()"); - return -1; - } + if (rc == SQL_ERROR) { + msSetError(MS_QUERYERR, "Failed to get feature count", + "msMSSQL2008LayerGetShapeCount()"); + return -1; + } - result_data[retLen] = 0; + result_data[retLen] = 0; - return atoi(result_data); + return atoi(result_data); } /* Query the DB for info about the requested table */ -int msMSSQL2008LayerGetItems(layerObj *layer) -{ - msMSSQL2008LayerInfo *layerinfo; - char *sql = NULL; - size_t sqlSize; - char found_geom = 0; - int t, item_num; +int msMSSQL2008LayerGetItems(layerObj *layer) { + msMSSQL2008LayerInfo *layerinfo; + char *sql = NULL; + size_t sqlSize; + char found_geom = 0; + int t, item_num; SQLSMALLINT cols = 0; const char *value; /* - * Pass the field definitions through to the layer metadata in the - * "gml_[item]_{type,width,precision}" set of metadata items for - * defining fields. - */ - char pass_field_def = 0; + * Pass the field definitions through to the layer metadata in the + * "gml_[item]_{type,width,precision}" set of metadata items for + * defining fields. + */ + char pass_field_def = 0; - if(layer->debug) { + if (layer->debug) { msDebug("in msMSSQL2008LayerGetItems (find column names)\n"); } layerinfo = getMSSQL2008LayerInfo(layer); - if(!layerinfo) { + if (!layerinfo) { /* layer not opened yet */ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetItems called on unopened layer", "msMSSQL2008LayerGetItems()"); + msSetError(MS_QUERYERR, "msMSSQL2008LayerGetItems called on unopened layer", + "msMSSQL2008LayerGetItems()"); return MS_FAILURE; } - if(!layerinfo->conn) { - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetItems called on MSSQL2008 layer with no connection to DB.", "msMSSQL2008LayerGetItems()"); + if (!layerinfo->conn) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetItems called on MSSQL2008 layer with no " + "connection to DB.", + "msMSSQL2008LayerGetItems()"); return MS_FAILURE; } @@ -2735,12 +2843,16 @@ int msMSSQL2008LayerGetItems(layerObj *layer) msFree(sql); - SQLNumResultCols (layerinfo->conn->hstmt, &cols); + SQLNumResultCols(layerinfo->conn->hstmt, &cols); layer->numitems = cols - 1; /* dont include the geometry column */ - layer->items = msSmallMalloc(sizeof(char *) * (layer->numitems + 1)); /* +1 in case there is a problem finding goeometry column */ - layerinfo->itemtypes = msSmallMalloc(sizeof(SQLSMALLINT) * (layer->numitems + 1)); + layer->items = msSmallMalloc( + sizeof(char *) * + (layer->numitems + + 1)); /* +1 in case there is a problem finding goeometry column */ + layerinfo->itemtypes = + msSmallMalloc(sizeof(SQLSMALLINT) * (layer->numitems + 1)); /* it will return an error if there is no geometry column found, */ /* so this isnt a problem */ @@ -2748,19 +2860,20 @@ int msMSSQL2008LayerGetItems(layerObj *layer) item_num = 0; /* consider populating the field definitions in metadata */ - if((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL - && strcasecmp(value,"auto") == 0 ) + if ((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL && + strcasecmp(value, "auto") == 0) pass_field_def = 1; - for(t = 0; t < cols; t++) { + for (t = 0; t < cols; t++) { char colBuff[256]; SQLSMALLINT itemType = 0; - columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff), layer, pass_field_def, &itemType); + columnName(layerinfo->conn, t + 1, colBuff, sizeof(colBuff), layer, + pass_field_def, &itemType); - if(strcmp(colBuff, layerinfo->geom_column) != 0) { + if (strcmp(colBuff, layerinfo->geom_column) != 0) { /* this isnt the geometry column */ - layer->items[item_num] = (char *) msSmallMalloc(strlen(colBuff) + 1); + layer->items[item_num] = (char *)msSmallMalloc(strlen(colBuff) + 1); strcpy(layer->items[item_num], colBuff); layerinfo->itemtypes[item_num] = itemType; item_num++; @@ -2769,8 +2882,12 @@ int msMSSQL2008LayerGetItems(layerObj *layer) } } - if(!found_geom) { - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetItems: tried to find the geometry column in the results from the database, but couldnt find it. Is it miss-capitialized? '%s'", "msMSSQL2008LayerGetItems()", layerinfo->geom_column); + if (!found_geom) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetItems: tried to find the geometry column in " + "the results from the database, but couldnt find it. Is it " + "miss-capitialized? '%s'", + "msMSSQL2008LayerGetItems()", layerinfo->geom_column); return MS_FAILURE; } @@ -2778,55 +2895,64 @@ int msMSSQL2008LayerGetItems(layerObj *layer) } /* Get primary key column of table */ -int msMSSQL2008LayerRetrievePK(layerObj *layer, char **urid_name, char* table_name, int debug) -{ +int msMSSQL2008LayerRetrievePK(layerObj *layer, char **urid_name, + char *table_name, int debug) { - char sql[1024]; + char sql[1024]; msMSSQL2008LayerInfo *layerinfo = 0; SQLRETURN rc; snprintf(sql, sizeof(sql), - "SELECT convert(varchar(50), sys.columns.name) AS ColumnName, sys.indexes.name " + "SELECT convert(varchar(50), sys.columns.name) AS ColumnName, " + "sys.indexes.name " "FROM sys.columns INNER JOIN " " sys.indexes INNER JOIN " - " sys.tables ON sys.indexes.object_id = sys.tables.object_id INNER JOIN " - " sys.index_columns ON sys.indexes.object_id = sys.index_columns.object_id AND sys.indexes.index_id = sys.index_columns.index_id ON " - " sys.columns.object_id = sys.index_columns.object_id AND sys.columns.column_id = sys.index_columns.column_id " - "WHERE (sys.indexes.is_primary_key = 1) AND (sys.tables.name = N'%s') ", + " sys.tables ON sys.indexes.object_id = " + "sys.tables.object_id INNER JOIN " + " sys.index_columns ON sys.indexes.object_id = " + "sys.index_columns.object_id AND sys.indexes.index_id = " + "sys.index_columns.index_id ON " + " sys.columns.object_id = " + "sys.index_columns.object_id AND sys.columns.column_id = " + "sys.index_columns.column_id " + "WHERE (sys.indexes.is_primary_key = 1) AND (sys.tables.name = " + "N'%s') ", table_name); if (debug) { msDebug("msMSSQL2008LayerRetrievePK: query = %s\n", sql); } - layerinfo = (msMSSQL2008LayerInfo *) layer->layerinfo; + layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; - if(layerinfo->conn == NULL) { + if (layerinfo->conn == NULL) { - msSetError(MS_QUERYERR, "Layer does not have a MSSQL2008 connection.", "msMSSQL2008LayerRetrievePK()"); + msSetError(MS_QUERYERR, "Layer does not have a MSSQL2008 connection.", + "msMSSQL2008LayerRetrievePK()"); - return(MS_FAILURE); + return (MS_FAILURE); } /* error somewhere above here in this method */ - if(!executeSQL(layerinfo->conn, sql)) { + if (!executeSQL(layerinfo->conn, sql)) { char *tmp1; char *tmp2 = NULL; tmp1 = "Error executing MSSQL2008 statement (msMSSQL2008LayerRetrievePK():"; - tmp2 = (char *)msSmallMalloc(sizeof(char)*(strlen(tmp1) + strlen(sql) + 1)); + tmp2 = + (char *)msSmallMalloc(sizeof(char) * (strlen(tmp1) + strlen(sql) + 1)); strcpy(tmp2, tmp1); strcat(tmp2, sql); msSetError(MS_QUERYERR, "%s", "msMSSQL2008LayerRetrievePK()", tmp2); msFree(tmp2); - return(MS_FAILURE); + return (MS_FAILURE); } rc = SQLFetch(layerinfo->conn->hstmt); - if(rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if(debug) { + if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + if (debug) { msDebug("msMSSQL2008LayerRetrievePK: No results found.\n"); } @@ -2836,13 +2962,15 @@ int msMSSQL2008LayerRetrievePK(layerObj *layer, char **urid_name, char* table_na { char buff[100]; SQLLEN retLen; - rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_BINARY, buff, sizeof(buff), &retLen); + rc = SQLGetData(layerinfo->conn->hstmt, 1, SQL_C_BINARY, buff, sizeof(buff), + &retLen); rc = SQLFetch(layerinfo->conn->hstmt); - if(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { - if(debug) { - msDebug("msMSSQL2008LayerRetrievePK: Multiple primary key columns are not supported in MapServer\n"); + if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { + if (debug) { + msDebug("msMSSQL2008LayerRetrievePK: Multiple primary key columns are " + "not supported in MapServer\n"); } return MS_FAILURE; @@ -2860,10 +2988,14 @@ int msMSSQL2008LayerRetrievePK(layerObj *layer, char **urid_name, char* table_na * column name, table name and name of a column to serve as a * unique record id */ -static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, char **geom_column_type, char **table_name, char **urid_name, char **user_srid, char **index_name, char **sort_spec, int debug) -{ - char *pos_opt, *pos_scn, *tmp, *pos_srid, *pos_urid, *pos_geomtype, *pos_geomtype2, *pos_indexHint, *data, *pos_order; - size_t slength; +static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, + char **geom_column_type, char **table_name, + char **urid_name, char **user_srid, + char **index_name, char **sort_spec, + int debug) { + char *pos_opt, *pos_scn, *tmp, *pos_srid, *pos_urid, *pos_geomtype, + *pos_geomtype2, *pos_indexHint, *data, *pos_order; + size_t slength; data = msStrdup(layer->data); /* replace tabs with spaces */ @@ -2877,57 +3009,72 @@ static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, c /* First look for the optional ' using unique ID' string */ pos_urid = strstrIgnoreCase(data, " using unique "); - if(pos_urid) { - /* CHANGE - protect the trailing edge for thing like 'using unique ftab_id using srid=33' */ + if (pos_urid) { + /* CHANGE - protect the trailing edge for thing like 'using unique ftab_id + * using srid=33' */ tmp = strstr(pos_urid + 14, " "); - if(!tmp) { + if (!tmp) { tmp = pos_urid + strlen(pos_urid); } - *urid_name = (char *) msSmallMalloc((tmp - (pos_urid + 14)) + 1); + *urid_name = (char *)msSmallMalloc((tmp - (pos_urid + 14)) + 1); strlcpy(*urid_name, pos_urid + 14, (tmp - (pos_urid + 14)) + 1); } /* Find the srid */ pos_srid = strstrIgnoreCase(data, " using SRID="); - if(!pos_srid) { - *user_srid = (char *) msSmallMalloc(2); + if (!pos_srid) { + *user_srid = (char *)msSmallMalloc(2); (*user_srid)[0] = '0'; (*user_srid)[1] = 0; } else { slength = strspn(pos_srid + 12, "-0123456789"); - if(!slength) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable: You specified 'using SRID=#' but didn't have any numbers!

\n\nMore Help:

\n\n", data); + if (!slength) { + msSetError( + MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", + "Error parsing MSSQL2008 data variable: You specified 'using SRID=#' " + "but didn't have any numbers!

\n\nMore Help:

\n\n", + data); msFree(data); return MS_FAILURE; } else { - *user_srid = (char *) msSmallMalloc(slength + 1); - strlcpy(*user_srid, pos_srid + 12, slength+1); + *user_srid = (char *)msSmallMalloc(slength + 1); + strlcpy(*user_srid, pos_srid + 12, slength + 1); } } pos_indexHint = strstrIgnoreCase(data, " using index "); - if(pos_indexHint) { - /* CHANGE - protect the trailing edge for thing like 'using unique ftab_id using srid=33' */ + if (pos_indexHint) { + /* CHANGE - protect the trailing edge for thing like 'using unique ftab_id + * using srid=33' */ tmp = strstr(pos_indexHint + 13, " "); - if(!tmp) { + if (!tmp) { tmp = pos_indexHint + strlen(pos_indexHint); } - *index_name = (char *) msSmallMalloc((tmp - (pos_indexHint + 13)) + 1); - strlcpy(*index_name, pos_indexHint + 13, tmp - (pos_indexHint + 13)+1); + *index_name = (char *)msSmallMalloc((tmp - (pos_indexHint + 13)) + 1); + strlcpy(*index_name, pos_indexHint + 13, tmp - (pos_indexHint + 13) + 1); } - /* this is a little hack so the rest of the code works. If the ' using SRID=' comes before */ - /* the ' using unique ', then make sure pos_opt points to where the ' using SRID' starts! */ + /* this is a little hack so the rest of the code works. If the ' using SRID=' + * comes before */ + /* the ' using unique ', then make sure pos_opt points to where the ' using + * SRID' starts! */ pos_opt = pos_urid; - if ( !pos_opt || ( pos_srid && pos_srid < pos_opt ) ) pos_opt = pos_srid; - if ( !pos_opt || ( pos_indexHint && pos_indexHint < pos_opt ) ) pos_opt = pos_indexHint; - if ( !pos_opt ) pos_opt = data + strlen(data); + if (!pos_opt || (pos_srid && pos_srid < pos_opt)) + pos_opt = pos_srid; + if (!pos_opt || (pos_indexHint && pos_indexHint < pos_opt)) + pos_opt = pos_indexHint; + if (!pos_opt) + pos_opt = data + strlen(data); /* Scan for the table or sub-select clause */ pos_scn = strstrIgnoreCase(data, " from "); - if(!pos_scn) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable. Must contain 'geometry_column from table_name' or 'geom from (subselect) as foo' (couldn't find ' from '). More help:

\n\n", data); + if (!pos_scn) { + msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", + "Error parsing MSSQL2008 data variable. Must contain " + "'geometry_column from table_name' or 'geom from (subselect) as " + "foo' (couldn't find ' from '). More help:

\n\n", + data); msFree(data); return MS_FAILURE; @@ -2938,42 +3085,54 @@ static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, c while (pos_geomtype < pos_scn && *pos_geomtype != '(' && *pos_geomtype != 0) ++pos_geomtype; - if(*pos_geomtype == '(') { + if (*pos_geomtype == '(') { pos_geomtype2 = pos_geomtype; - while (pos_geomtype2 < pos_scn && *pos_geomtype2 != ')' && *pos_geomtype2 != 0) + while (pos_geomtype2 < pos_scn && *pos_geomtype2 != ')' && + *pos_geomtype2 != 0) ++pos_geomtype2; if (*pos_geomtype2 != ')' || pos_geomtype2 == pos_geomtype) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable. Invalid syntax near geometry column type.", data); + msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", + "Error parsing MSSQL2008 data variable. Invalid syntax near " + "geometry column type.", + data); msFree(data); return MS_FAILURE; } - *geom_column_name = (char *) msSmallMalloc((pos_geomtype - data) + 1); + *geom_column_name = (char *)msSmallMalloc((pos_geomtype - data) + 1); strlcpy(*geom_column_name, data, pos_geomtype - data + 1); - *geom_column_type = (char *) msSmallMalloc(pos_geomtype2 - pos_geomtype); + *geom_column_type = (char *)msSmallMalloc(pos_geomtype2 - pos_geomtype); strlcpy(*geom_column_type, pos_geomtype + 1, pos_geomtype2 - pos_geomtype); } else { /* Copy the geometry column name */ - *geom_column_name = (char *) msSmallMalloc((pos_scn - data) + 1); + *geom_column_name = (char *)msSmallMalloc((pos_scn - data) + 1); strlcpy(*geom_column_name, data, pos_scn - data + 1); *geom_column_type = msStrdup("geometry"); } /* Copy out the table name or sub-select clause */ - *table_name = (char *) msSmallMalloc((pos_opt - (pos_scn + 6)) + 1); + *table_name = (char *)msSmallMalloc((pos_opt - (pos_scn + 6)) + 1); strlcpy(*table_name, pos_scn + 6, pos_opt - (pos_scn + 6) + 1); - if(strlen(*table_name) < 1 || strlen(*geom_column_name) < 1) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "Error parsing MSSQL2008 data variable. Must contain 'geometry_column from table_name' or 'geom from (subselect) as foo' (couldnt find a geometry_column or table/subselect). More help:

\n\n", data); + if (strlen(*table_name) < 1 || strlen(*geom_column_name) < 1) { + msSetError( + MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", + "Error parsing MSSQL2008 data variable. Must contain 'geometry_column " + "from table_name' or 'geom from (subselect) as foo' (couldnt find a " + "geometry_column or table/subselect). More help:

\n\n", + data); msFree(data); return MS_FAILURE; } - if( !pos_urid ) { - if( msMSSQL2008LayerRetrievePK(layer, urid_name, *table_name, debug) != MS_SUCCESS ) { - msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", "No primary key defined for table, or primary key contains more that one column\n\n", + if (!pos_urid) { + if (msMSSQL2008LayerRetrievePK(layer, urid_name, *table_name, debug) != + MS_SUCCESS) { + msSetError(MS_QUERYERR, DATA_ERROR_MESSAGE, "msMSSQL2008LayerParseData()", + "No primary key defined for table, or primary key contains " + "more that one column\n\n", *table_name); msFree(data); @@ -2983,32 +3142,34 @@ static int msMSSQL2008LayerParseData(layerObj *layer, char **geom_column_name, c /* Find the order by */ pos_order = strstrIgnoreCase(pos_opt, " order by "); - + if (pos_order) { *sort_spec = msStrdup(pos_order); } - if(debug) { - msDebug("msMSSQL2008LayerParseData: unique column = %s, srid='%s', geom_column_name = %s, table_name=%s\n", *urid_name, *user_srid, *geom_column_name, *table_name); + if (debug) { + msDebug("msMSSQL2008LayerParseData: unique column = %s, srid='%s', " + "geom_column_name = %s, table_name=%s\n", + *urid_name, *user_srid, *geom_column_name, *table_name); } msFree(data); return MS_SUCCESS; } -char *msMSSQL2008LayerEscapePropertyName(layerObj *layer, const char* pszString) -{ +char *msMSSQL2008LayerEscapePropertyName(layerObj *layer, + const char *pszString) { (void)layer; - char* pszEscapedStr=NULL; + char *pszEscapedStr = NULL; int j = 0; if (pszString && strlen(pszString) > 0) { size_t nLength = strlen(pszString); - pszEscapedStr = (char*) msSmallMalloc( 1 + nLength + 1 + 1); + pszEscapedStr = (char *)msSmallMalloc(1 + nLength + 1 + 1); pszEscapedStr[j++] = '['; - for (size_t i=0; ilayerinfo != NULL); - layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; + assert(layer->layerinfo != NULL); + layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; - return layerinfo->paging; + return layerinfo->paging; } -void msMSSQL2008EnablePaging(layerObj *layer, int value) -{ - msMSSQL2008LayerInfo *layerinfo = NULL; +void msMSSQL2008EnablePaging(layerObj *layer, int value) { + msMSSQL2008LayerInfo *layerinfo = NULL; - if (!msMSSQL2008LayerIsOpen(layer)) - { - if(msMSSQL2008LayerOpen(layer) != MS_SUCCESS) - { - return; - } + if (!msMSSQL2008LayerIsOpen(layer)) { + if (msMSSQL2008LayerOpen(layer) != MS_SUCCESS) { + return; } + } - assert(layer->layerinfo != NULL); - layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; + assert(layer->layerinfo != NULL); + layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; - layerinfo->paging = value; + layerinfo->paging = value; } -int process_node(layerObj* layer, expressionObj *filter) -{ +int process_node(layerObj *layer, expressionObj *filter) { char *snippet = NULL; char *strtmpl = NULL; char *stresc = NULL; - msMSSQL2008LayerInfo *layerinfo = (msMSSQL2008LayerInfo *) layer->layerinfo; + msMSSQL2008LayerInfo *layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; - if (!layerinfo->current_node) - { - msSetError(MS_MISCERR, "Unecpected end of expression", "msMSSQL2008LayerTranslateFilter()"); + if (!layerinfo->current_node) { + msSetError(MS_MISCERR, "Unecpected end of expression", + "msMSSQL2008LayerTranslateFilter()"); return 0; } - switch(layerinfo->current_node->token) { - case '(': - filter->native_string = msStringConcatenate(filter->native_string, "("); - /* process subexpression */ - layerinfo->current_node = layerinfo->current_node->next; - while (layerinfo->current_node != NULL) { - if (!process_node(layer, filter)) - return 0; - if (!layerinfo->current_node) - break; - if (layerinfo->current_node->token == ')') - break; - layerinfo->current_node = layerinfo->current_node->next; - } - break; - case ')': - filter->native_string = msStringConcatenate(filter->native_string, ")"); - break; - /* argument separator */ - case ',': - break; - /* literal tokens */ - case MS_TOKEN_LITERAL_BOOLEAN: - if(layerinfo->current_node->tokenval.dblval == MS_TRUE) - filter->native_string = msStringConcatenate(filter->native_string, "1"); - else - filter->native_string = msStringConcatenate(filter->native_string, "0"); - break; - case MS_TOKEN_LITERAL_NUMBER: - { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.18g", layerinfo->current_node->tokenval.dblval); - filter->native_string = msStringConcatenate(filter->native_string, buffer); - break; + switch (layerinfo->current_node->token) { + case '(': + filter->native_string = msStringConcatenate(filter->native_string, "("); + /* process subexpression */ + layerinfo->current_node = layerinfo->current_node->next; + while (layerinfo->current_node != NULL) { + if (!process_node(layer, filter)) + return 0; + if (!layerinfo->current_node) + break; + if (layerinfo->current_node->token == ')') + break; + layerinfo->current_node = layerinfo->current_node->next; } - case MS_TOKEN_LITERAL_STRING: - strtmpl = "'%s'"; - stresc = msMSSQL2008LayerEscapeSQLParam(layer, layerinfo->current_node->tokenval.strval); - snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(stresc)); - sprintf(snippet, strtmpl, stresc); - filter->native_string = msStringConcatenate(filter->native_string, snippet); - msFree(snippet); - msFree(stresc); + break; + case ')': + filter->native_string = msStringConcatenate(filter->native_string, ")"); + break; + /* argument separator */ + case ',': + break; + /* literal tokens */ + case MS_TOKEN_LITERAL_BOOLEAN: + if (layerinfo->current_node->tokenval.dblval == MS_TRUE) + filter->native_string = msStringConcatenate(filter->native_string, "1"); + else + filter->native_string = msStringConcatenate(filter->native_string, "0"); + break; + case MS_TOKEN_LITERAL_NUMBER: { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%.18g", + layerinfo->current_node->tokenval.dblval); + filter->native_string = msStringConcatenate(filter->native_string, buffer); + break; + } + case MS_TOKEN_LITERAL_STRING: + strtmpl = "'%s'"; + stresc = msMSSQL2008LayerEscapeSQLParam( + layer, layerinfo->current_node->tokenval.strval); + snippet = (char *)msSmallMalloc(strlen(strtmpl) + strlen(stresc)); + sprintf(snippet, strtmpl, stresc); + filter->native_string = msStringConcatenate(filter->native_string, snippet); + msFree(snippet); + msFree(stresc); + break; + case MS_TOKEN_LITERAL_TIME: { + int resolution = msTimeGetResolution(layerinfo->current_node->tokensrc); + snippet = (char *)msSmallMalloc(128); + switch (resolution) { + case TIME_RESOLUTION_YEAR: + sprintf(snippet, "'%d'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900)); break; - case MS_TOKEN_LITERAL_TIME: - { - int resolution = msTimeGetResolution(layerinfo->current_node->tokensrc); - snippet = (char *) msSmallMalloc(128); - switch(resolution) { - case TIME_RESOLUTION_YEAR: - sprintf(snippet, "'%d'", (layerinfo->current_node->tokenval.tmval.tm_year+1900)); - break; - case TIME_RESOLUTION_MONTH: - sprintf(snippet, "'%d-%02d-01'", (layerinfo->current_node->tokenval.tmval.tm_year+1900), - (layerinfo->current_node->tokenval.tmval.tm_mon+1)); - break; - case TIME_RESOLUTION_DAY: - sprintf(snippet, "'%d-%02d-%02d'", (layerinfo->current_node->tokenval.tmval.tm_year+1900), - (layerinfo->current_node->tokenval.tmval.tm_mon+1), - layerinfo->current_node->tokenval.tmval.tm_mday); - break; - case TIME_RESOLUTION_HOUR: - sprintf(snippet, "'%d-%02d-%02d %02d:00'", (layerinfo->current_node->tokenval.tmval.tm_year+1900), - (layerinfo->current_node->tokenval.tmval.tm_mon+1), - layerinfo->current_node->tokenval.tmval.tm_mday, - layerinfo->current_node->tokenval.tmval.tm_hour); - break; - case TIME_RESOLUTION_MINUTE: - sprintf(snippet, "%d-%02d-%02d %02d:%02d'", (layerinfo->current_node->tokenval.tmval.tm_year+1900), - (layerinfo->current_node->tokenval.tmval.tm_mon+1), - layerinfo->current_node->tokenval.tmval.tm_mday, - layerinfo->current_node->tokenval.tmval.tm_hour, - layerinfo->current_node->tokenval.tmval.tm_min); - break; - case TIME_RESOLUTION_SECOND: - sprintf(snippet, "'%d-%02d-%02d %02d:%02d:%02d'", (layerinfo->current_node->tokenval.tmval.tm_year+1900), - (layerinfo->current_node->tokenval.tmval.tm_mon+1), - layerinfo->current_node->tokenval.tmval.tm_mday, - layerinfo->current_node->tokenval.tmval.tm_hour, - layerinfo->current_node->tokenval.tmval.tm_min, - layerinfo->current_node->tokenval.tmval.tm_sec); - break; - } - filter->native_string = msStringConcatenate(filter->native_string, snippet); - msFree(snippet); - } + case TIME_RESOLUTION_MONTH: + sprintf(snippet, "'%d-%02d-01'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900), + (layerinfo->current_node->tokenval.tmval.tm_mon + 1)); break; - case MS_TOKEN_LITERAL_SHAPE: - if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) - filter->native_string = msStringConcatenate(filter->native_string, "geography::STGeomFromText('"); - else - filter->native_string = msStringConcatenate(filter->native_string, "geometry::STGeomFromText('"); - filter->native_string = msStringConcatenate(filter->native_string, msShapeToWKT(layerinfo->current_node->tokenval.shpval)); - filter->native_string = msStringConcatenate(filter->native_string, "'"); - if(layerinfo->user_srid && strcmp(layerinfo->user_srid, "") != 0) { - filter->native_string = msStringConcatenate(filter->native_string, ", "); - filter->native_string = msStringConcatenate(filter->native_string, layerinfo->user_srid); - } - filter->native_string = msStringConcatenate(filter->native_string, ")"); + case TIME_RESOLUTION_DAY: + sprintf(snippet, "'%d-%02d-%02d'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900), + (layerinfo->current_node->tokenval.tmval.tm_mon + 1), + layerinfo->current_node->tokenval.tmval.tm_mday); break; - case MS_TOKEN_BINDING_TIME: - case MS_TOKEN_BINDING_DOUBLE: - case MS_TOKEN_BINDING_INTEGER: - case MS_TOKEN_BINDING_STRING: - if(layerinfo->current_node->next->token == MS_TOKEN_COMPARISON_IRE) - strtmpl = "LOWER(%s)"; - else - strtmpl = "%s"; - - stresc = msMSSQL2008LayerEscapePropertyName(layer, layerinfo->current_node->tokenval.bindval.item); - snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(stresc)); - sprintf(snippet, strtmpl, stresc); - filter->native_string = msStringConcatenate(filter->native_string, snippet); - msFree(snippet); - msFree(stresc); + case TIME_RESOLUTION_HOUR: + sprintf(snippet, "'%d-%02d-%02d %02d:00'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900), + (layerinfo->current_node->tokenval.tmval.tm_mon + 1), + layerinfo->current_node->tokenval.tmval.tm_mday, + layerinfo->current_node->tokenval.tmval.tm_hour); break; - case MS_TOKEN_BINDING_SHAPE: - filter->native_string = msStringConcatenate(filter->native_string, layerinfo->geom_column); + case TIME_RESOLUTION_MINUTE: + sprintf(snippet, "%d-%02d-%02d %02d:%02d'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900), + (layerinfo->current_node->tokenval.tmval.tm_mon + 1), + layerinfo->current_node->tokenval.tmval.tm_mday, + layerinfo->current_node->tokenval.tmval.tm_hour, + layerinfo->current_node->tokenval.tmval.tm_min); break; - case MS_TOKEN_BINDING_MAP_CELLSIZE: - { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.18g", layer->map->cellsize); - filter->native_string = msStringConcatenate(filter->native_string, buffer); + case TIME_RESOLUTION_SECOND: + sprintf(snippet, "'%d-%02d-%02d %02d:%02d:%02d'", + (layerinfo->current_node->tokenval.tmval.tm_year + 1900), + (layerinfo->current_node->tokenval.tmval.tm_mon + 1), + layerinfo->current_node->tokenval.tmval.tm_mday, + layerinfo->current_node->tokenval.tmval.tm_hour, + layerinfo->current_node->tokenval.tmval.tm_min, + layerinfo->current_node->tokenval.tmval.tm_sec); break; } + filter->native_string = msStringConcatenate(filter->native_string, snippet); + msFree(snippet); + } break; + case MS_TOKEN_LITERAL_SHAPE: + if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) + filter->native_string = msStringConcatenate( + filter->native_string, "geography::STGeomFromText('"); + else + filter->native_string = msStringConcatenate(filter->native_string, + "geometry::STGeomFromText('"); + filter->native_string = msStringConcatenate( + filter->native_string, + msShapeToWKT(layerinfo->current_node->tokenval.shpval)); + filter->native_string = msStringConcatenate(filter->native_string, "'"); + if (layerinfo->user_srid && strcmp(layerinfo->user_srid, "") != 0) { + filter->native_string = msStringConcatenate(filter->native_string, ", "); + filter->native_string = + msStringConcatenate(filter->native_string, layerinfo->user_srid); + } + filter->native_string = msStringConcatenate(filter->native_string, ")"); + break; + case MS_TOKEN_BINDING_TIME: + case MS_TOKEN_BINDING_DOUBLE: + case MS_TOKEN_BINDING_INTEGER: + case MS_TOKEN_BINDING_STRING: + if (layerinfo->current_node->next->token == MS_TOKEN_COMPARISON_IRE) + strtmpl = "LOWER(%s)"; + else + strtmpl = "%s"; - /* comparisons */ - case MS_TOKEN_COMPARISON_IN: - filter->native_string = msStringConcatenate(filter->native_string, " IN "); - break; - case MS_TOKEN_COMPARISON_RE: - case MS_TOKEN_COMPARISON_IRE: - case MS_TOKEN_COMPARISON_LIKE: { - /* process regexp */ - size_t i = 0, j = 0; - char c; - char c_next; - int bCaseInsensitive = (layerinfo->current_node->token == MS_TOKEN_COMPARISON_IRE); - int nEscapeLen = 0; - if (bCaseInsensitive) - filter->native_string = msStringConcatenate(filter->native_string, " LIKE LOWER("); - else - filter->native_string = msStringConcatenate(filter->native_string, " LIKE "); + stresc = msMSSQL2008LayerEscapePropertyName( + layer, layerinfo->current_node->tokenval.bindval.item); + snippet = (char *)msSmallMalloc(strlen(strtmpl) + strlen(stresc)); + sprintf(snippet, strtmpl, stresc); + filter->native_string = msStringConcatenate(filter->native_string, snippet); + msFree(snippet); + msFree(stresc); + break; + case MS_TOKEN_BINDING_SHAPE: + filter->native_string = + msStringConcatenate(filter->native_string, layerinfo->geom_column); + break; + case MS_TOKEN_BINDING_MAP_CELLSIZE: { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%.18g", layer->map->cellsize); + filter->native_string = msStringConcatenate(filter->native_string, buffer); + break; + } - layerinfo->current_node = layerinfo->current_node->next; - if (layerinfo->current_node->token != MS_TOKEN_LITERAL_STRING) return 0; + /* comparisons */ + case MS_TOKEN_COMPARISON_IN: + filter->native_string = msStringConcatenate(filter->native_string, " IN "); + break; + case MS_TOKEN_COMPARISON_RE: + case MS_TOKEN_COMPARISON_IRE: + case MS_TOKEN_COMPARISON_LIKE: { + /* process regexp */ + size_t i = 0, j = 0; + char c; + char c_next; + int bCaseInsensitive = + (layerinfo->current_node->token == MS_TOKEN_COMPARISON_IRE); + int nEscapeLen = 0; + if (bCaseInsensitive) + filter->native_string = + msStringConcatenate(filter->native_string, " LIKE LOWER("); + else + filter->native_string = + msStringConcatenate(filter->native_string, " LIKE "); - strtmpl = msStrdup(layerinfo->current_node->tokenval.strval); - if (strtmpl[0] == '/') { - stresc = strtmpl + 1; - strtmpl[strlen(strtmpl) - 1] = '\0'; - } - else if (strtmpl[0] == '^') - stresc = strtmpl + 1; - else - stresc = strtmpl; + layerinfo->current_node = layerinfo->current_node->next; + if (layerinfo->current_node->token != MS_TOKEN_LITERAL_STRING) + return 0; - while (*stresc) { - c = stresc[i]; - if (c == '%' || c == '_' || c == '[' || c == ']' || c == '^') { - nEscapeLen++; - } - stresc++; - } - snippet = (char *)msSmallMalloc(strlen(strtmpl) + nEscapeLen + 3); - snippet[j++] = '\''; - while (i < strlen(strtmpl)) { - c = strtmpl[i]; - c_next = strtmpl[i+1]; - - if (i == 0 && c == '^') { - i++; - continue; - } - if( c == '$' && c_next == 0 && strtmpl[0] == '^' ) - break; + strtmpl = msStrdup(layerinfo->current_node->tokenval.strval); + if (strtmpl[0] == '/') { + stresc = strtmpl + 1; + strtmpl[strlen(strtmpl) - 1] = '\0'; + } else if (strtmpl[0] == '^') + stresc = strtmpl + 1; + else + stresc = strtmpl; - if (c == '\\') { - i++; - c = c_next; - } - - if (c == '%' || c == '_' || c == '[' || c == ']' || c == '^') { - snippet[j++] = '\\'; - } - - if (c == '.' && c_next == '*') { - i++; - c = '%'; - } - else if (c == '.') - c = '_'; + while (*stresc) { + c = stresc[i]; + if (c == '%' || c == '_' || c == '[' || c == ']' || c == '^') { + nEscapeLen++; + } + stresc++; + } + snippet = (char *)msSmallMalloc(strlen(strtmpl) + nEscapeLen + 3); + snippet[j++] = '\''; + while (i < strlen(strtmpl)) { + c = strtmpl[i]; + c_next = strtmpl[i + 1]; + + if (i == 0 && c == '^') { + i++; + continue; + } + if (c == '$' && c_next == 0 && strtmpl[0] == '^') + break; - - snippet[j++] = c; - i++; + if (c == '\\') { + i++; + c = c_next; } - snippet[j++] = '\''; - snippet[j] = '\0'; - filter->native_string = msStringConcatenate(filter->native_string, snippet); - msFree(strtmpl); - msFree(snippet); + if (c == '%' || c == '_' || c == '[' || c == ']' || c == '^') { + snippet[j++] = '\\'; + } - if (bCaseInsensitive) - filter->native_string = msStringConcatenate(filter->native_string, ")"); + if (c == '.' && c_next == '*') { + i++; + c = '%'; + } else if (c == '.') + c = '_'; - if (nEscapeLen > 0) - filter->native_string = msStringConcatenate(filter->native_string, " ESCAPE '\\'"); + snippet[j++] = c; + i++; } - break; - case MS_TOKEN_COMPARISON_EQ: - filter->native_string = msStringConcatenate(filter->native_string, " = "); - break; - case MS_TOKEN_COMPARISON_NE: - filter->native_string = msStringConcatenate(filter->native_string, " != "); - break; - case MS_TOKEN_COMPARISON_GT: - filter->native_string = msStringConcatenate(filter->native_string, " > "); - break; - case MS_TOKEN_COMPARISON_GE: - filter->native_string = msStringConcatenate(filter->native_string, " >= "); - break; - case MS_TOKEN_COMPARISON_LT: - filter->native_string = msStringConcatenate(filter->native_string, " < "); - break; - case MS_TOKEN_COMPARISON_LE: - filter->native_string = msStringConcatenate(filter->native_string, " <= "); - break; - - /* logical ops */ - case MS_TOKEN_LOGICAL_AND: - filter->native_string = msStringConcatenate(filter->native_string, " AND "); - break; - case MS_TOKEN_LOGICAL_OR: - filter->native_string = msStringConcatenate(filter->native_string, " OR "); - break; - case MS_TOKEN_LOGICAL_NOT: - filter->native_string = msStringConcatenate(filter->native_string, " NOT "); - break; + snippet[j++] = '\''; + snippet[j] = '\0'; - /* spatial comparison tokens */ - case MS_TOKEN_COMPARISON_INTERSECTS: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STIntersects("); - if (!process_node(layer, filter)) - return 0; - break; + filter->native_string = msStringConcatenate(filter->native_string, snippet); + msFree(strtmpl); + msFree(snippet); - case MS_TOKEN_COMPARISON_DISJOINT: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STDisjoint("); - if (!process_node(layer, filter)) - return 0; - break; + if (bCaseInsensitive) + filter->native_string = msStringConcatenate(filter->native_string, ")"); - case MS_TOKEN_COMPARISON_TOUCHES: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STTouches("); - if (!process_node(layer, filter)) - return 0; - break; + if (nEscapeLen > 0) + filter->native_string = + msStringConcatenate(filter->native_string, " ESCAPE '\\'"); + } break; + case MS_TOKEN_COMPARISON_EQ: + filter->native_string = msStringConcatenate(filter->native_string, " = "); + break; + case MS_TOKEN_COMPARISON_NE: + filter->native_string = msStringConcatenate(filter->native_string, " != "); + break; + case MS_TOKEN_COMPARISON_GT: + filter->native_string = msStringConcatenate(filter->native_string, " > "); + break; + case MS_TOKEN_COMPARISON_GE: + filter->native_string = msStringConcatenate(filter->native_string, " >= "); + break; + case MS_TOKEN_COMPARISON_LT: + filter->native_string = msStringConcatenate(filter->native_string, " < "); + break; + case MS_TOKEN_COMPARISON_LE: + filter->native_string = msStringConcatenate(filter->native_string, " <= "); + break; - case MS_TOKEN_COMPARISON_OVERLAPS: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STOverlaps("); - if (!process_node(layer, filter)) - return 0; - break; + /* logical ops */ + case MS_TOKEN_LOGICAL_AND: + filter->native_string = msStringConcatenate(filter->native_string, " AND "); + break; + case MS_TOKEN_LOGICAL_OR: + filter->native_string = msStringConcatenate(filter->native_string, " OR "); + break; + case MS_TOKEN_LOGICAL_NOT: + filter->native_string = msStringConcatenate(filter->native_string, " NOT "); + break; - case MS_TOKEN_COMPARISON_CROSSES: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STCrosses("); - if (!process_node(layer, filter)) - return 0; - break; + /* spatial comparison tokens */ + case MS_TOKEN_COMPARISON_INTERSECTS: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STIntersects("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_COMPARISON_WITHIN: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STWithin("); - if (!process_node(layer, filter)) - return 0; - break; + case MS_TOKEN_COMPARISON_DISJOINT: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STDisjoint("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_COMPARISON_CONTAINS: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STContains("); - if (!process_node(layer, filter)) - return 0; - break; + case MS_TOKEN_COMPARISON_TOUCHES: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STTouches("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_COMPARISON_EQUALS: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STEquals("); - if (!process_node(layer, filter)) - return 0; - break; + case MS_TOKEN_COMPARISON_OVERLAPS: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STOverlaps("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_COMPARISON_BEYOND: - msSetError(MS_MISCERR, "Beyond operator is unsupported.", "msMSSQL2008LayerTranslateFilter()"); + case MS_TOKEN_COMPARISON_CROSSES: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STCrosses("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_COMPARISON_DWITHIN: - msSetError(MS_MISCERR, "DWithin operator is unsupported.", "msMSSQL2008LayerTranslateFilter()"); + case MS_TOKEN_COMPARISON_WITHIN: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STWithin("); + if (!process_node(layer, filter)) return 0; + break; - /* spatial functions */ - case MS_TOKEN_FUNCTION_AREA: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STArea()"); - break; + case MS_TOKEN_COMPARISON_CONTAINS: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STContains("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_FUNCTION_BUFFER: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STBuffer("); - if (!process_node(layer, filter)) - return 0; - filter->native_string = msStringConcatenate(filter->native_string, ")"); - break; + case MS_TOKEN_COMPARISON_EQUALS: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STEquals("); + if (!process_node(layer, filter)) + return 0; + break; - case MS_TOKEN_FUNCTION_DIFFERENCE: - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (!process_node(layer, filter)) - return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - if (layerinfo->current_node->next) layerinfo->current_node = layerinfo->current_node->next; - else return 0; - filter->native_string = msStringConcatenate(filter->native_string, ".STDifference("); - if (!process_node(layer, filter)) - return 0; - filter->native_string = msStringConcatenate(filter->native_string, ")"); - break; + case MS_TOKEN_COMPARISON_BEYOND: + msSetError(MS_MISCERR, "Beyond operator is unsupported.", + "msMSSQL2008LayerTranslateFilter()"); + return 0; - case MS_TOKEN_FUNCTION_FROMTEXT: - if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) - filter->native_string = msStringConcatenate(filter->native_string, "geography::STGeomFromText"); - else - filter->native_string = msStringConcatenate(filter->native_string, "geometry::STGeomFromText"); - break; + case MS_TOKEN_COMPARISON_DWITHIN: + msSetError(MS_MISCERR, "DWithin operator is unsupported.", + "msMSSQL2008LayerTranslateFilter()"); + return 0; - case MS_TOKEN_FUNCTION_LENGTH: - filter->native_string = msStringConcatenate(filter->native_string, "len"); - break; + /* spatial functions */ + case MS_TOKEN_FUNCTION_AREA: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STArea()"); + break; - case MS_TOKEN_FUNCTION_ROUND: - filter->native_string = msStringConcatenate(filter->native_string, "round"); - break; - - case MS_TOKEN_FUNCTION_TOSTRING: - break; + case MS_TOKEN_FUNCTION_BUFFER: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STBuffer("); + if (!process_node(layer, filter)) + return 0; + filter->native_string = msStringConcatenate(filter->native_string, ")"); + break; - case MS_TOKEN_FUNCTION_COMMIFY: - break; + case MS_TOKEN_FUNCTION_DIFFERENCE: + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (!process_node(layer, filter)) + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + if (layerinfo->current_node->next) + layerinfo->current_node = layerinfo->current_node->next; + else + return 0; + filter->native_string = + msStringConcatenate(filter->native_string, ".STDifference("); + if (!process_node(layer, filter)) + return 0; + filter->native_string = msStringConcatenate(filter->native_string, ")"); + break; - case MS_TOKEN_FUNCTION_SIMPLIFY: - filter->native_string = msStringConcatenate(filter->native_string, ".Reduce"); - break; - case MS_TOKEN_FUNCTION_SIMPLIFYPT: - break; - case MS_TOKEN_FUNCTION_GENERALIZE: - filter->native_string = msStringConcatenate(filter->native_string, ".Reduce"); - break; + case MS_TOKEN_FUNCTION_FROMTEXT: + if (strcasecmp(layerinfo->geom_column_type, "geography") == 0) + filter->native_string = msStringConcatenate(filter->native_string, + "geography::STGeomFromText"); + else + filter->native_string = msStringConcatenate(filter->native_string, + "geometry::STGeomFromText"); + break; - default: - msSetError(MS_MISCERR, "Translation to native SQL failed.","msMSSQL2008LayerTranslateFilter()"); - if (layer->debug) { - msDebug("Token not caught, exiting: Token is %i\n", layerinfo->current_node->token); - } - return 0; + case MS_TOKEN_FUNCTION_LENGTH: + filter->native_string = msStringConcatenate(filter->native_string, "len"); + break; + + case MS_TOKEN_FUNCTION_ROUND: + filter->native_string = msStringConcatenate(filter->native_string, "round"); + break; + + case MS_TOKEN_FUNCTION_TOSTRING: + break; + + case MS_TOKEN_FUNCTION_COMMIFY: + break; + + case MS_TOKEN_FUNCTION_SIMPLIFY: + filter->native_string = + msStringConcatenate(filter->native_string, ".Reduce"); + break; + case MS_TOKEN_FUNCTION_SIMPLIFYPT: + break; + case MS_TOKEN_FUNCTION_GENERALIZE: + filter->native_string = + msStringConcatenate(filter->native_string, ".Reduce"); + break; + + default: + msSetError(MS_MISCERR, "Translation to native SQL failed.", + "msMSSQL2008LayerTranslateFilter()"); + if (layer->debug) { + msDebug("Token not caught, exiting: Token is %i\n", + layerinfo->current_node->token); + } + return 0; } return 1; } /* Translate filter expression to native msssql filter */ -int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ +int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { char *snippet = NULL; char *strtmpl = NULL; char *stresc = NULL; - msMSSQL2008LayerInfo *layerinfo = (msMSSQL2008LayerInfo *) layer->layerinfo; + msMSSQL2008LayerInfo *layerinfo = (msMSSQL2008LayerInfo *)layer->layerinfo; - if(!filter->string) return MS_SUCCESS; + if (!filter->string) + return MS_SUCCESS; msFree(filter->native_string); filter->native_string = NULL; - if(filter->type == MS_STRING && filter->string && filteritem) { /* item/value pair */ + if (filter->type == MS_STRING && filter->string && + filteritem) { /* item/value pair */ stresc = msMSSQL2008LayerEscapePropertyName(layer, filteritem); - if(filter->flags & MS_EXP_INSENSITIVE) { - filter->native_string = msStringConcatenate(filter->native_string, "upper("); - filter->native_string = msStringConcatenate(filter->native_string, stresc); - filter->native_string = msStringConcatenate(filter->native_string, ") = upper("); + if (filter->flags & MS_EXP_INSENSITIVE) { + filter->native_string = + msStringConcatenate(filter->native_string, "upper("); + filter->native_string = + msStringConcatenate(filter->native_string, stresc); + filter->native_string = + msStringConcatenate(filter->native_string, ") = upper("); } else { - filter->native_string = msStringConcatenate(filter->native_string, stresc); + filter->native_string = + msStringConcatenate(filter->native_string, stresc); filter->native_string = msStringConcatenate(filter->native_string, " = "); } msFree(stresc); - strtmpl = "'%s'"; /* don't have a type for the righthand literal so assume it's a string and we quote */ - snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(filter->string)); - sprintf(snippet, strtmpl, filter->string); // TODO: escape filter->string + strtmpl = "'%s'"; /* don't have a type for the righthand literal so assume + it's a string and we quote */ + snippet = (char *)msSmallMalloc(strlen(strtmpl) + strlen(filter->string)); + sprintf(snippet, strtmpl, filter->string); // TODO: escape filter->string filter->native_string = msStringConcatenate(filter->native_string, snippet); free(snippet); - if(filter->flags & MS_EXP_INSENSITIVE) - filter->native_string = msStringConcatenate(filter->native_string, ")"); - - } else if(filter->type == MS_REGEX && filter->string && filteritem) { /* item/regex pair */ - /* NOTE: regex is not supported by MSSQL natively. We should install it in CLR UDF - according to https://msdn.microsoft.com/en-us/magazine/cc163473.aspx*/ - filter->native_string = msStringConcatenate(filter->native_string, "dbo.RegexMatch("); - if(filter->flags & MS_EXP_INSENSITIVE) { - filter->native_string = msStringConcatenate(filter->native_string, "'(?i)"); + if (filter->flags & MS_EXP_INSENSITIVE) + filter->native_string = msStringConcatenate(filter->native_string, ")"); + + } else if (filter->type == MS_REGEX && filter->string && + filteritem) { /* item/regex pair */ + /* NOTE: regex is not supported by MSSQL natively. We should install it in + CLR UDF according to + https://msdn.microsoft.com/en-us/magazine/cc163473.aspx*/ + filter->native_string = + msStringConcatenate(filter->native_string, "dbo.RegexMatch("); + if (filter->flags & MS_EXP_INSENSITIVE) { + filter->native_string = + msStringConcatenate(filter->native_string, "'(?i)"); } filter->native_string = msStrdup(filteritem); filter->native_string = msStringConcatenate(filter->native_string, ", "); strtmpl = "'%s'"; - snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(filter->string)); + snippet = (char *)msSmallMalloc(strlen(strtmpl) + strlen(filter->string)); sprintf(snippet, strtmpl, filter->string); // TODO: escape filter->string filter->native_string = msStringConcatenate(filter->native_string, snippet); filter->native_string = msStringConcatenate(filter->native_string, "')"); free(snippet); - } else if(filter->type == MS_EXPRESSION) { - - if(layer->debug >= 2) + } else if (filter->type == MS_EXPRESSION) { + + if (layer->debug >= 2) msDebug("msMSSQL2008LayerTranslateFilter. String: %s.\n", filter->string); - if(!filter->tokens) { - if(layer->debug >= 2) - msDebug("msMSSQL2008LayerTranslateFilter. There are tokens to process... \n"); + if (!filter->tokens) { + if (layer->debug >= 2) + msDebug("msMSSQL2008LayerTranslateFilter. There are tokens to " + "process... \n"); return MS_SUCCESS; } /* start processing nodes */ layerinfo->current_node = filter->tokens; while (layerinfo->current_node != NULL) { - if (!process_node(layer, filter)) - { + if (!process_node(layer, filter)) { msFree(filter->native_string); filter->native_string = 0; return MS_FAILURE; @@ -3623,7 +3904,7 @@ int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, char break; layerinfo->current_node = layerinfo->current_node->next; - } + } } return MS_SUCCESS; @@ -3633,110 +3914,150 @@ int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, char /* prototypes if MSSQL2008 isnt supposed to be compiled */ -int msMSSQL2008LayerOpen(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerOpen called but unimplemented! (mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerOpen()"); +int msMSSQL2008LayerOpen(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerOpen called but unimplemented! (mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008LayerOpen()"); return MS_FAILURE; } -int msMSSQL2008LayerIsOpen(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008IsLayerOpen called but unimplemented! (mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerIsOpen()"); +int msMSSQL2008LayerIsOpen(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008IsLayerOpen called but unimplemented! (mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008LayerIsOpen()"); return MS_FALSE; } -void msMSSQL2008LayerFreeItemInfo(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerFreeItemInfo called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerFreeItemInfo()"); +void msMSSQL2008LayerFreeItemInfo(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerFreeItemInfo called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerFreeItemInfo()"); } -int msMSSQL2008LayerInitItemInfo(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerInitItemInfo called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerInitItemInfo()"); +int msMSSQL2008LayerInitItemInfo(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerInitItemInfo called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerInitItemInfo()"); return MS_FAILURE; } -int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerWhichShapes called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerWhichShapes()"); +int msMSSQL2008LayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerWhichShapes called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerWhichShapes()"); return MS_FAILURE; } -int msMSSQL2008LayerClose(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerClose called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerClose()"); +int msMSSQL2008LayerClose(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerClose called but unimplemented!(mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008LayerClose()"); return MS_FAILURE; } -int msMSSQL2008LayerNextShape(layerObj *layer, shapeObj *shape) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerNextShape called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerNextShape()"); +int msMSSQL2008LayerNextShape(layerObj *layer, shapeObj *shape) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerNextShape called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerNextShape()"); return MS_FAILURE; } -int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, long record) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetShape called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetShape()"); +int msMSSQL2008LayerGetShape(layerObj *layer, shapeObj *shape, long record) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetShape called but unimplemented!(mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetShape()"); return MS_FAILURE; } -int msMSSQL2008LayerGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProjection) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetShapeCount called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetShapeCount()"); - return MS_FAILURE; +int msMSSQL2008LayerGetShapeCount(layerObj *layer, rectObj rect, + projectionObj *rectProjection) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetShapeCount called but " + "unimplemented!(mapserver not compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetShapeCount()"); + return MS_FAILURE; } -int msMSSQL2008LayerGetExtent(layerObj *layer, rectObj *extent) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetExtent called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetExtent()"); +int msMSSQL2008LayerGetExtent(layerObj *layer, rectObj *extent) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetExtent called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetExtent()"); return MS_FAILURE; } -int msMSSQL2008LayerGetNumFeatures(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetNumFeatures called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetNumFeatures()"); - return -1; +int msMSSQL2008LayerGetNumFeatures(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetNumFeatures called but " + "unimplemented!(mapserver not compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetNumFeatures()"); + return -1; } -int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, long *record) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetShapeRandom called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetShapeRandom()"); +int msMSSQL2008LayerGetShapeRandom(layerObj *layer, shapeObj *shape, + long *record) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetShapeRandom called but " + "unimplemented!(mapserver not compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetShapeRandom()"); return MS_FAILURE; } -int msMSSQL2008LayerGetItems(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerGetItems called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerGetItems()"); +int msMSSQL2008LayerGetItems(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerGetItems called but unimplemented!(mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008LayerGetItems()"); return MS_FAILURE; } -void msMSSQL2008EnablePaging(layerObj *layer, int value) -{ - msSetError(MS_QUERYERR, "msMSSQL2008EnablePaging called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008EnablePaging()"); - return; +void msMSSQL2008EnablePaging(layerObj *layer, int value) { + msSetError(MS_QUERYERR, + "msMSSQL2008EnablePaging called but unimplemented!(mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008EnablePaging()"); + return; } -int msMSSQL2008GetPaging(layerObj *layer) -{ - msSetError(MS_QUERYERR, "msMSSQL2008GetPaging called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008GetPaging()"); - return MS_FAILURE; +int msMSSQL2008GetPaging(layerObj *layer) { + msSetError(MS_QUERYERR, + "msMSSQL2008GetPaging called but unimplemented!(mapserver not " + "compiled with MSSQL2008 support)", + "msMSSQL2008GetPaging()"); + return MS_FAILURE; } -int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerTranslateFilter called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerTranslateFilter()"); +int msMSSQL2008LayerTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerTranslateFilter called but " + "unimplemented!(mapserver not compiled with MSSQL2008 support)", + "msMSSQL2008LayerTranslateFilter()"); return MS_FAILURE; } -char *msMSSQL2008LayerEscapeSQLParam(layerObj *layer, const char *pszString) -{ - msSetError(MS_QUERYERR, "msMSSQL2008EscapeSQLParam called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerEscapeSQLParam()"); +char *msMSSQL2008LayerEscapeSQLParam(layerObj *layer, const char *pszString) { + msSetError(MS_QUERYERR, + "msMSSQL2008EscapeSQLParam called but unimplemented!(mapserver " + "not compiled with MSSQL2008 support)", + "msMSSQL2008LayerEscapeSQLParam()"); return NULL; } -char *msMSSQL2008LayerEscapePropertyName(layerObj *layer, const char *pszString) -{ - msSetError(MS_QUERYERR, "msMSSQL2008LayerEscapePropertyName called but unimplemented!(mapserver not compiled with MSSQL2008 support)", "msMSSQL2008LayerEscapePropertyName()"); +char *msMSSQL2008LayerEscapePropertyName(layerObj *layer, + const char *pszString) { + msSetError(MS_QUERYERR, + "msMSSQL2008LayerEscapePropertyName called but " + "unimplemented!(mapserver not compiled with MSSQL2008 support)", + "msMSSQL2008LayerEscapePropertyName()"); return NULL; } @@ -3745,8 +4066,8 @@ char *msMSSQL2008LayerEscapePropertyName(layerObj *layer, const char *pszString) #ifdef USE_MSSQL2008_PLUGIN -MS_DLL_EXPORT int PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer) -{ +MS_DLL_EXPORT int PluginInitializeVirtualTable(layerVTableObj *vtable, + layerObj *layer) { assert(layer != NULL); assert(vtable != NULL); @@ -3785,9 +4106,7 @@ MS_DLL_EXPORT int PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj #endif -int -msMSSQL2008LayerInitializeVirtualTable(layerObj *layer) -{ +int msMSSQL2008LayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); @@ -3820,6 +4139,5 @@ msMSSQL2008LayerInitializeVirtualTable(layerObj *layer) /* layer->vtable->LayerCreateItems, use default */ layer->vtable->LayerGetNumFeatures = msMSSQL2008LayerGetNumFeatures; - return MS_SUCCESS; } diff --git a/mapmvt.c b/mapmvt.c index 280d899594..c733fb3a25 100644 --- a/mapmvt.c +++ b/mapmvt.c @@ -42,7 +42,11 @@ #define FEATURES_INCREMENT_SIZE 5 -enum MS_RING_DIRECTION { MS_DIRECTION_INVALID_RING, MS_DIRECTION_CLOCKWISE, MS_DIRECTION_COUNTERCLOCKWISE }; +enum MS_RING_DIRECTION { + MS_DIRECTION_INVALID_RING, + MS_DIRECTION_CLOCKWISE, + MS_DIRECTION_COUNTERCLOCKWISE +}; typedef struct { char *value; @@ -54,46 +58,54 @@ typedef struct { value_lookup *cache; } value_lookup_table; -#define COMMAND(id, count) (((id) & 0x7) | ((count) << 3)) +#define COMMAND(id, count) (((id)&0x7) | ((count) << 3)) #define PARAMETER(n) (((n) << 1) ^ ((n) >> 31)) -static double getTriangleHeight(lineObj *ring) -{ +static double getTriangleHeight(lineObj *ring) { int i; - double s=0, b=0; + double s = 0, b = 0; - if(ring->numpoints != 4) return -1; /* not a triangle */ + if (ring->numpoints != 4) + return -1; /* not a triangle */ - for(i=0; inumpoints-1; i++) { - s += (ring->point[i].x*ring->point[i+1].y - ring->point[i+1].x*ring->point[i].y); - b = MS_MAX(b, msDistancePointToPoint(&ring->point[i], &ring->point[i+1])); + for (i = 0; i < ring->numpoints - 1; i++) { + s += (ring->point[i].x * ring->point[i + 1].y - + ring->point[i + 1].x * ring->point[i].y); + b = MS_MAX(b, msDistancePointToPoint(&ring->point[i], &ring->point[i + 1])); } - return (MS_ABS(s/b)); + return (MS_ABS(s / b)); } static enum MS_RING_DIRECTION mvtGetRingDirection(lineObj *ring) { - int i, sum=0; + int i, sum = 0; - if(ring->numpoints < 4) return MS_DIRECTION_INVALID_RING; + if (ring->numpoints < 4) + return MS_DIRECTION_INVALID_RING; /* step throught the edges */ - for(i=0; inumpoints-1; i++) { - sum += ring->point[i].x * ring->point[i+1].y - ring->point[i+1].x * ring->point[i].y; + for (i = 0; i < ring->numpoints - 1; i++) { + sum += ring->point[i].x * ring->point[i + 1].y - + ring->point[i + 1].x * ring->point[i].y; } - return sum > 0 ? MS_DIRECTION_CLOCKWISE : - sum < 0 ? MS_DIRECTION_COUNTERCLOCKWISE : MS_DIRECTION_INVALID_RING; + return sum > 0 ? MS_DIRECTION_CLOCKWISE + : sum < 0 ? MS_DIRECTION_COUNTERCLOCKWISE + : MS_DIRECTION_INVALID_RING; } static void mvtReverseRingDirection(lineObj *ring) { pointObj temp; - int start=1, end=ring->numpoints-2; /* first and last points are the same so skip 'em */ + int start = 1, end = ring->numpoints - + 2; /* first and last points are the same so skip 'em */ while (start < end) { - temp.x = ring->point[start].x; temp.y = ring->point[start].y; - ring->point[start].x = ring->point[end].x; ring->point[start].y = ring->point[end].y; - ring->point[end].x = temp.x; ring->point[end].y = temp.y; + temp.x = ring->point[start].x; + temp.y = ring->point[start].y; + ring->point[start].x = ring->point[end].x; + ring->point[start].y = ring->point[end].y; + ring->point[end].x = temp.x; + ring->point[end].y = temp.y; start++; end--; } @@ -102,201 +114,228 @@ static void mvtReverseRingDirection(lineObj *ring) { static void mvtReorderRings(shapeObj *shape, int *outers) { int i, j; int t1; - lineObj t2; + lineObj t2; - for(i=0; i<(shape->numlines-1); i++) { - for(j=0; j<(shape->numlines-i-1); j++) { - if(outers[j] < outers[j+1]) { + for (i = 0; i < (shape->numlines - 1); i++) { + for (j = 0; j < (shape->numlines - i - 1); j++) { + if (outers[j] < outers[j + 1]) { /* swap */ - t1 = outers[j]; - outers[j] = outers[j+1]; - outers[j+1] = t1; + t1 = outers[j]; + outers[j] = outers[j + 1]; + outers[j + 1] = t1; - t2 = shape->line[j]; - shape->line[j] = shape->line[j+1]; - shape->line[j+1] = t2; + t2 = shape->line[j]; + shape->line[j] = shape->line[j + 1]; + shape->line[j + 1] = t2; } } } } -static int mvtTransformShape(shapeObj *shape, rectObj *extent, int layer_type, int mvt_layer_extent) { - double scale_x,scale_y; - int i,j,outj; +static int mvtTransformShape(shapeObj *shape, rectObj *extent, int layer_type, + int mvt_layer_extent) { + double scale_x, scale_y; + int i, j, outj; - int *outers=NULL, ring_direction; + int *outers = NULL, ring_direction; - scale_x = (double)mvt_layer_extent/(extent->maxx - extent->minx); - scale_y = (double)mvt_layer_extent/(extent->maxy - extent->miny); + scale_x = (double)mvt_layer_extent / (extent->maxx - extent->minx); + scale_y = (double)mvt_layer_extent / (extent->maxy - extent->miny); - if(layer_type == MS_LAYER_POLYGON) { + if (layer_type == MS_LAYER_POLYGON) { outers = msGetOuterList(shape); /* compute before we muck with the shape */ - if(outers[0] == 0) /* first ring must be an outer */ + if (outers[0] == 0) /* first ring must be an outer */ mvtReorderRings(shape, outers); } - for(i=0;inumlines;i++) { - for(j=0,outj=0;jline[i].numpoints;j++) { + for (i = 0; i < shape->numlines; i++) { + for (j = 0, outj = 0; j < shape->line[i].numpoints; j++) { - shape->line[i].point[outj].x = (int)((shape->line[i].point[j].x - extent->minx)*scale_x); - shape->line[i].point[outj].y = mvt_layer_extent - (int)((shape->line[i].point[j].y - extent->miny)*scale_y); + shape->line[i].point[outj].x = + (int)((shape->line[i].point[j].x - extent->minx) * scale_x); + shape->line[i].point[outj].y = + mvt_layer_extent - + (int)((shape->line[i].point[j].y - extent->miny) * scale_y); - if(!outj || shape->line[i].point[outj].x != shape->line[i].point[outj-1].x || shape->line[i].point[outj].y != shape->line[i].point[outj-1].y) - outj++; /* add the point to the shape only if it's the first one or if it's different than the previous one */ + if (!outj || + shape->line[i].point[outj].x != shape->line[i].point[outj - 1].x || + shape->line[i].point[outj].y != shape->line[i].point[outj - 1].y) + outj++; /* add the point to the shape only if it's the first one or if + it's different than the previous one */ } shape->line[i].numpoints = outj; - if(layer_type == MS_LAYER_POLYGON) { - if(shape->line[i].numpoints == 4 && getTriangleHeight(&shape->line[i]) < 1) { + if (layer_type == MS_LAYER_POLYGON) { + if (shape->line[i].numpoints == 4 && + getTriangleHeight(&shape->line[i]) < 1) { shape->line[i].numpoints = 0; /* so it's not considered anymore */ - continue; /* next ring */ + continue; /* next ring */ } ring_direction = mvtGetRingDirection(&shape->line[i]); - if(ring_direction == MS_DIRECTION_INVALID_RING) + if (ring_direction == MS_DIRECTION_INVALID_RING) shape->line[i].numpoints = 0; /* so it's not considered anymore */ - else if((outers[i] && ring_direction != MS_DIRECTION_CLOCKWISE) || (!outers[i] && ring_direction != MS_DIRECTION_COUNTERCLOCKWISE)) + else if ((outers[i] && ring_direction != MS_DIRECTION_CLOCKWISE) || + (!outers[i] && ring_direction != MS_DIRECTION_COUNTERCLOCKWISE)) mvtReverseRingDirection(&shape->line[i]); } } - msComputeBounds(shape); /* TODO: might need to limit this to just valid parts... */ + msComputeBounds( + shape); /* TODO: might need to limit this to just valid parts... */ msFree(outers); - return (shape->numlines == 0)?MS_FAILURE:MS_SUCCESS; /* sucess if at least one line */ + return (shape->numlines == 0) ? MS_FAILURE + : MS_SUCCESS; /* sucess if at least one line */ } -static int mvtClipShape(shapeObj *shape, int layer_type, int buffer, int mvt_layer_extent) { +static int mvtClipShape(shapeObj *shape, int layer_type, int buffer, + int mvt_layer_extent) { rectObj tile_rect; - tile_rect.minx = tile_rect.miny=-buffer*16; - tile_rect.maxx = tile_rect.maxy=mvt_layer_extent + buffer*16; + tile_rect.minx = tile_rect.miny = -buffer * 16; + tile_rect.maxx = tile_rect.maxy = mvt_layer_extent + buffer * 16; - if(layer_type == MS_LAYER_POLYGON) { + if (layer_type == MS_LAYER_POLYGON) { msClipPolygonRect(shape, tile_rect); - } else if(layer_type == MS_LAYER_LINE) { + } else if (layer_type == MS_LAYER_LINE) { msClipPolylineRect(shape, tile_rect); } /* success if at least one line and not a degenerate bounding box */ - if(shape->numlines > 0 && (layer_type == MS_LAYER_POINT || (shape->bounds.minx != shape->bounds.maxx || shape->bounds.miny != shape->bounds.maxy))) + if (shape->numlines > 0 && (layer_type == MS_LAYER_POINT || + (shape->bounds.minx != shape->bounds.maxx || + shape->bounds.miny != shape->bounds.maxy))) return MS_SUCCESS; else return MS_FAILURE; } -static void freeMvtFeature( VectorTile__Tile__Feature *mvt_feature ) { - if(mvt_feature->tags) +static void freeMvtFeature(VectorTile__Tile__Feature *mvt_feature) { + if (mvt_feature->tags) msFree(mvt_feature->tags); - if(mvt_feature->geometry) + if (mvt_feature->geometry) msFree(mvt_feature->geometry); } -static void freeMvtValue( VectorTile__Tile__Value *mvt_value ) { - if(mvt_value->string_value) +static void freeMvtValue(VectorTile__Tile__Value *mvt_value) { + if (mvt_value->string_value) msFree(mvt_value->string_value); } -static void freeMvtLayer( VectorTile__Tile__Layer *mvt_layer ) { - if(mvt_layer->keys) { - for(unsigned i=0;in_keys; i++) { +static void freeMvtLayer(VectorTile__Tile__Layer *mvt_layer) { + if (mvt_layer->keys) { + for (unsigned i = 0; i < mvt_layer->n_keys; i++) { msFree(mvt_layer->keys[i]); } msFree(mvt_layer->keys); } - if(mvt_layer->values) { - for(unsigned i=0;in_values; i++) { - freeMvtValue(mvt_layer->values[i]); - msFree(mvt_layer->values[i]); + if (mvt_layer->values) { + for (unsigned i = 0; i < mvt_layer->n_values; i++) { + freeMvtValue(mvt_layer->values[i]); + msFree(mvt_layer->values[i]); } msFree(mvt_layer->values); } - if(mvt_layer->features) { - for(unsigned i=0;in_features; i++) { - freeMvtFeature(mvt_layer->features[i]); - msFree(mvt_layer->features[i]); + if (mvt_layer->features) { + for (unsigned i = 0; i < mvt_layer->n_features; i++) { + freeMvtFeature(mvt_layer->features[i]); + msFree(mvt_layer->features[i]); } msFree(mvt_layer->features); } } -int mvtWriteShape( layerObj *layer, shapeObj *shape, VectorTile__Tile__Layer *mvt_layer, - gmlItemListObj *item_list, value_lookup_table *value_lookup_cache, - rectObj *unbuffered_bbox, int buffer) { +int mvtWriteShape(layerObj *layer, shapeObj *shape, + VectorTile__Tile__Layer *mvt_layer, gmlItemListObj *item_list, + value_lookup_table *value_lookup_cache, + rectObj *unbuffered_bbox, int buffer) { VectorTile__Tile__Feature *mvt_feature; - int i,j,iout; + int i, j, iout; value_lookup *value; long int n_geometry; /* could consider an intersection test here */ - if(mvtTransformShape(shape, unbuffered_bbox, layer->type, mvt_layer->extent) != MS_SUCCESS) { + if (mvtTransformShape(shape, unbuffered_bbox, layer->type, + mvt_layer->extent) != MS_SUCCESS) { return MS_SUCCESS; /* degenerate shape */ } - if(mvtClipShape(shape, layer->type, buffer, mvt_layer->extent) != MS_SUCCESS) { + if (mvtClipShape(shape, layer->type, buffer, mvt_layer->extent) != + MS_SUCCESS) { return MS_SUCCESS; /* no features left after clipping */ } n_geometry = 0; - if(layer->type == MS_LAYER_POINT) { - for(i=0;inumlines;i++) + if (layer->type == MS_LAYER_POINT) { + for (i = 0; i < shape->numlines; i++) n_geometry += shape->line[i].numpoints * 2; - if(n_geometry) + if (n_geometry) n_geometry++; /* one MOVETO */ - } else if(layer->type == MS_LAYER_LINE) { - for(i=0;inumlines;i++) - if(shape->line[i].numpoints >= 2) n_geometry += 2 + shape->line[i].numpoints * 2; /* one MOVETO, one LINETO */ - } else { /* MS_LAYER_POLYGON */ - for(i=0;inumlines;i++) - if(shape->line[i].numpoints >= 4) n_geometry += 3 + (shape->line[i].numpoints-1) * 2; /* one MOVETO, one LINETO, one CLOSEPATH (don't consider last duplicate point) */ + } else if (layer->type == MS_LAYER_LINE) { + for (i = 0; i < shape->numlines; i++) + if (shape->line[i].numpoints >= 2) + n_geometry += + 2 + shape->line[i].numpoints * 2; /* one MOVETO, one LINETO */ + } else { /* MS_LAYER_POLYGON */ + for (i = 0; i < shape->numlines; i++) + if (shape->line[i].numpoints >= 4) + n_geometry += 3 + (shape->line[i].numpoints - 1) * + 2; /* one MOVETO, one LINETO, one CLOSEPATH (don't + consider last duplicate point) */ } - if(n_geometry == 0) return MS_SUCCESS; + if (n_geometry == 0) + return MS_SUCCESS; - mvt_layer->features[mvt_layer->n_features++] = msSmallMalloc(sizeof(VectorTile__Tile__Feature)); - mvt_feature = mvt_layer->features[mvt_layer->n_features-1]; + mvt_layer->features[mvt_layer->n_features++] = + msSmallMalloc(sizeof(VectorTile__Tile__Feature)); + mvt_feature = mvt_layer->features[mvt_layer->n_features - 1]; vector_tile__tile__feature__init(mvt_feature); mvt_feature->n_tags = mvt_layer->n_keys * 2; mvt_feature->tags = msSmallMalloc(mvt_feature->n_tags * sizeof(uint32_t)); mvt_feature->id = shape->index; mvt_feature->has_id = 1; - if(layer->type == MS_LAYER_POLYGON) + if (layer->type == MS_LAYER_POLYGON) mvt_feature->type = VECTOR_TILE__TILE__GEOM_TYPE__POLYGON; - else if(layer->type == MS_LAYER_LINE) + else if (layer->type == MS_LAYER_LINE) mvt_feature->type = VECTOR_TILE__TILE__GEOM_TYPE__LINESTRING; else mvt_feature->type = VECTOR_TILE__TILE__GEOM_TYPE__POINT; mvt_feature->has_type = 1; /* output values */ - for( i = 0, iout = 0; i < item_list->numitems; i++ ) { + for (i = 0, iout = 0; i < item_list->numitems; i++) { gmlItemObj *item = item_list->items + i; - if( !item->visible ) + if (!item->visible) continue; UT_HASH_FIND_STR(value_lookup_cache->cache, shape->values[i], value); - if(!value) { + if (!value) { VectorTile__Tile__Value *mvt_value; value = msSmallMalloc(sizeof(value_lookup)); value->value = msStrdup(shape->values[i]); value->index = mvt_layer->n_values; - mvt_layer->values = msSmallRealloc(mvt_layer->values,(++mvt_layer->n_values)*sizeof(VectorTile__Tile__Value*)); - mvt_layer->values[mvt_layer->n_values-1] = msSmallMalloc(sizeof(VectorTile__Tile__Value)); - mvt_value = mvt_layer->values[mvt_layer->n_values-1]; + mvt_layer->values = msSmallRealloc(mvt_layer->values, + (++mvt_layer->n_values) * + sizeof(VectorTile__Tile__Value *)); + mvt_layer->values[mvt_layer->n_values - 1] = + msSmallMalloc(sizeof(VectorTile__Tile__Value)); + mvt_value = mvt_layer->values[mvt_layer->n_values - 1]; vector_tile__tile__value__init(mvt_value); - if( item->type && EQUAL(item->type,"Integer")) { + if (item->type && EQUAL(item->type, "Integer")) { mvt_value->int_value = atoi(value->value); mvt_value->has_int_value = 1; - } else if( item->type && EQUAL(item->type,"Long")) { /* signed */ - mvt_value->sint_value = atol(value->value); - mvt_value->has_sint_value = 1; - } else if( item->type && EQUAL(item->type,"Real")) { + } else if (item->type && EQUAL(item->type, "Long")) { /* signed */ + mvt_value->sint_value = atol(value->value); + mvt_value->has_sint_value = 1; + } else if (item->type && EQUAL(item->type, "Real")) { mvt_value->float_value = atof(value->value); mvt_value->has_float_value = 1; - } else if( item->type && EQUAL(item->type,"Boolean") ) { - if(EQUAL(value->value,"0") || EQUAL(value->value,"false")) + } else if (item->type && EQUAL(item->type, "Boolean")) { + if (EQUAL(value->value, "0") || EQUAL(value->value, "false")) mvt_value->bool_value = 0; else mvt_value->bool_value = 1; @@ -304,52 +343,63 @@ int mvtWriteShape( layerObj *layer, shapeObj *shape, VectorTile__Tile__Layer *mv } else { mvt_value->string_value = msStrdup(value->value); } - UT_HASH_ADD_KEYPTR(hh,value_lookup_cache->cache,value->value, strlen(value->value), value); + UT_HASH_ADD_KEYPTR(hh, value_lookup_cache->cache, value->value, + strlen(value->value), value); } - mvt_feature->tags[iout*2] = iout; - mvt_feature->tags[iout*2+1] = value->index; + mvt_feature->tags[iout * 2] = iout; + mvt_feature->tags[iout * 2 + 1] = value->index; iout++; } /* output geom */ mvt_feature->n_geometry = n_geometry; - mvt_feature->geometry = msSmallMalloc(mvt_feature->n_geometry * sizeof(uint32_t)); - - if(layer->type == MS_LAYER_POINT) { - int idx=0, lastx=0, lasty=0; - mvt_feature->geometry[idx++] = COMMAND(MOVETO, (mvt_feature->n_geometry-1) / 2); - for(i=0;inumlines;i++) { - for(j=0;jline[i].numpoints;j++) { - mvt_feature->geometry[idx++] = PARAMETER(MS_NINT(shape->line[i].point[j].x)-lastx); - mvt_feature->geometry[idx++] = PARAMETER(MS_NINT(shape->line[i].point[j].y)-lasty); + mvt_feature->geometry = + msSmallMalloc(mvt_feature->n_geometry * sizeof(uint32_t)); + + if (layer->type == MS_LAYER_POINT) { + int idx = 0, lastx = 0, lasty = 0; + mvt_feature->geometry[idx++] = + COMMAND(MOVETO, (mvt_feature->n_geometry - 1) / 2); + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + mvt_feature->geometry[idx++] = + PARAMETER(MS_NINT(shape->line[i].point[j].x) - lastx); + mvt_feature->geometry[idx++] = + PARAMETER(MS_NINT(shape->line[i].point[j].y) - lasty); lastx = MS_NINT(shape->line[i].point[j].x); lasty = MS_NINT(shape->line[i].point[j].y); } } } else { /* MS_LAYER_LINE or MS_LAYER_POLYGON */ int numpoints; - int idx=0, lastx=0, lasty=0; - for(i=0;inumlines;i++) { + int idx = 0, lastx = 0, lasty = 0; + for (i = 0; i < shape->numlines; i++) { - if((layer->type == MS_LAYER_LINE && !(shape->line[i].numpoints >= 2)) || - (layer->type == MS_LAYER_POLYGON && !(shape->line[i].numpoints >= 4))) { + if ((layer->type == MS_LAYER_LINE && !(shape->line[i].numpoints >= 2)) || + (layer->type == MS_LAYER_POLYGON && + !(shape->line[i].numpoints >= 4))) { continue; /* skip malformed parts */ } - numpoints = (layer->type == MS_LAYER_LINE)?shape->line[i].numpoints:(shape->line[i].numpoints-1); /* don't consider last point for polygons */ - for(j=0;jtype == MS_LAYER_LINE) + ? shape->line[i].numpoints + : (shape->line[i].numpoints - + 1); /* don't consider last point for polygons */ + for (j = 0; j < numpoints; j++) { + if (j == 0) { mvt_feature->geometry[idx++] = COMMAND(MOVETO, 1); - } else if(j==1) { - mvt_feature->geometry[idx++] = COMMAND(LINETO, numpoints-1); + } else if (j == 1) { + mvt_feature->geometry[idx++] = COMMAND(LINETO, numpoints - 1); } - mvt_feature->geometry[idx++] = PARAMETER(MS_NINT(shape->line[i].point[j].x)-lastx); - mvt_feature->geometry[idx++] = PARAMETER(MS_NINT(shape->line[i].point[j].y)-lasty); - lastx = MS_NINT(shape->line[i].point[j].x); - lasty = MS_NINT(shape->line[i].point[j].y); + mvt_feature->geometry[idx++] = + PARAMETER(MS_NINT(shape->line[i].point[j].x) - lastx); + mvt_feature->geometry[idx++] = + PARAMETER(MS_NINT(shape->line[i].point[j].y) - lasty); + lastx = MS_NINT(shape->line[i].point[j].x); + lasty = MS_NINT(shape->line[i].point[j].y); } - if(layer->type == MS_LAYER_POLYGON) { + if (layer->type == MS_LAYER_POLYGON) { mvt_feature->geometry[idx++] = COMMAND(CLOSEPATH, 1); } } @@ -358,36 +408,41 @@ int mvtWriteShape( layerObj *layer, shapeObj *shape, VectorTile__Tile__Layer *mv return MS_SUCCESS; } -static void freeMvtTile( VectorTile__Tile *mvt_tile ) { - for(unsigned iLayer=0;iLayern_layers;iLayer++) { +static void freeMvtTile(VectorTile__Tile *mvt_tile) { + for (unsigned iLayer = 0; iLayer < mvt_tile->n_layers; iLayer++) { freeMvtLayer(mvt_tile->layers[iLayer]); msFree(mvt_tile->layers[iLayer]); } msFree(mvt_tile->layers); } -int msMVTWriteTile( mapObj *map, int sendheaders ) { - int iLayer,retcode=MS_SUCCESS; +int msMVTWriteTile(mapObj *map, int sendheaders) { + int iLayer, retcode = MS_SUCCESS; unsigned len; void *buf; - const char *mvt_extent = msGetOutputFormatOption(map->outputformat, "EXTENT", "4096"); - const char *mvt_buffer = msGetOutputFormatOption(map->outputformat, "EDGE_BUFFER", "10"); + const char *mvt_extent = + msGetOutputFormatOption(map->outputformat, "EXTENT", "4096"); + const char *mvt_buffer = + msGetOutputFormatOption(map->outputformat, "EDGE_BUFFER", "10"); int buffer = MS_ABS(atoi(mvt_buffer)); VectorTile__Tile mvt_tile = VECTOR_TILE__TILE__INIT; - mvt_tile.layers = msSmallCalloc(map->numlayers, sizeof(VectorTile__Tile__Layer*)); + mvt_tile.layers = + msSmallCalloc(map->numlayers, sizeof(VectorTile__Tile__Layer *)); /* make sure we have a scale and cellsize computed */ map->cellsize = MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width); - msCalculateScale(map->extent, map->units, map->width, map->height, map->resolution, &map->scaledenom); + msCalculateScale(map->extent, map->units, map->width, map->height, + map->resolution, &map->scaledenom); - /* expand the map->extent so it goes from pixel center (MapServer) to pixel edge (OWS) */ + /* expand the map->extent so it goes from pixel center (MapServer) to pixel + * edge (OWS) */ map->extent.minx -= map->cellsize * 0.5; map->extent.maxx += map->cellsize * 0.5; map->extent.miny -= map->cellsize * 0.5; map->extent.maxy += map->cellsize * 0.5; - for( iLayer = 0; iLayer < map->numlayers; iLayer++ ) { - int status=MS_SUCCESS; + for (iLayer = 0; iLayer < map->numlayers; iLayer++) { + int status = MS_SUCCESS; layerObj *layer = GET_LAYER(map, iLayer); int i; shapeObj shape; @@ -399,19 +454,23 @@ int msMVTWriteTile( mapObj *map, int sendheaders ) { unsigned features_size = 0; - if(!msLayerIsVisible(map, layer)) continue; + if (!msLayerIsVisible(map, layer)) + continue; - if(layer->type != MS_LAYER_POINT && layer->type != MS_LAYER_POLYGON && layer->type != MS_LAYER_LINE) + if (layer->type != MS_LAYER_POINT && layer->type != MS_LAYER_POLYGON && + layer->type != MS_LAYER_LINE) continue; status = msLayerOpen(layer); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { retcode = status; goto layer_cleanup; } - status = msLayerWhichItems(layer, MS_TRUE, NULL); /* we want all items - behaves like a query in that sense */ - if(status != MS_SUCCESS) { + status = msLayerWhichItems( + layer, MS_TRUE, + NULL); /* we want all items - behaves like a query in that sense */ + if (status != MS_SUCCESS) { retcode = status; goto layer_cleanup; } @@ -419,22 +478,25 @@ int msMVTWriteTile( mapObj *map, int sendheaders ) { /* -------------------------------------------------------------------- */ /* Will we need to reproject? */ /* -------------------------------------------------------------------- */ - layer->project = msProjectionsDiffer(&(layer->projection), &(map->projection)); + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); rect = map->extent; - if(layer->project) msProjectRect(&(map->projection), &(layer->projection), &rect); + if (layer->project) + msProjectRect(&(map->projection), &(layer->projection), &rect); status = msLayerWhichShapes(layer, rect, MS_TRUE); - if(status == MS_DONE) { /* no overlap - that's ok */ + if (status == MS_DONE) { /* no overlap - that's ok */ retcode = MS_SUCCESS; goto layer_cleanup; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { retcode = status; goto layer_cleanup; } - mvt_tile.layers[mvt_tile.n_layers++] = msSmallMalloc(sizeof(VectorTile__Tile__Layer)); - mvt_layer = mvt_tile.layers[mvt_tile.n_layers-1]; + mvt_tile.layers[mvt_tile.n_layers++] = + msSmallMalloc(sizeof(VectorTile__Tile__Layer)); + mvt_layer = mvt_tile.layers[mvt_tile.n_layers - 1]; vector_tile__tile__layer__init(mvt_layer); mvt_layer->version = 2; mvt_layer->name = layer->name; @@ -445,18 +507,18 @@ int msMVTWriteTile( mapObj *map, int sendheaders ) { /* -------------------------------------------------------------------- */ /* Create appropriate attributes on this layer. */ /* -------------------------------------------------------------------- */ - item_list = msGMLGetItems( layer, "G" ); - assert( item_list->numitems == layer->numitems ); + item_list = msGMLGetItems(layer, "G"); + assert(item_list->numitems == layer->numitems); - mvt_layer->keys = msSmallMalloc(layer->numitems * sizeof(char*)); + mvt_layer->keys = msSmallMalloc(layer->numitems * sizeof(char *)); - for( i = 0; i < layer->numitems; i++ ) { + for (i = 0; i < layer->numitems; i++) { gmlItemObj *item = item_list->items + i; - if( !item->visible ) + if (!item->visible) continue; - if( item->alias ) + if (item->alias) mvt_layer->keys[mvt_layer->n_keys++] = msStrdup(item->alias); else mvt_layer->keys[mvt_layer->n_keys++] = msStrdup(item->name); @@ -465,109 +527,122 @@ int msMVTWriteTile( mapObj *map, int sendheaders ) { /* -------------------------------------------------------------------- */ /* Setup joins if needed. This is likely untested. */ /* -------------------------------------------------------------------- */ - if(layer->numjoins > 0) { + if (layer->numjoins > 0) { int j; - for(j=0; jnumjoins; j++) { + for (j = 0; j < layer->numjoins; j++) { status = msJoinConnect(layer, &(layer->joins[j])); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { retcode = status; goto layer_cleanup; } } } - mvt_layer->features = msSmallCalloc(FEATURES_INCREMENT_SIZE, sizeof(VectorTile__Tile__Feature*)); + mvt_layer->features = msSmallCalloc(FEATURES_INCREMENT_SIZE, + sizeof(VectorTile__Tile__Feature *)); features_size = FEATURES_INCREMENT_SIZE; msInitShape(&shape); - while((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { - - if(layer->numclasses > 0) { - shape.classindex = msShapeGetClass(layer, map, &shape, NULL, -1); /* Perform classification, and some annotation related magic. */ - if(shape.classindex < 0) + while ((status = msLayerNextShape(layer, &shape)) == MS_SUCCESS) { + + if (layer->numclasses > 0) { + shape.classindex = msShapeGetClass( + layer, map, &shape, NULL, -1); /* Perform classification, and some + annotation related magic. */ + if (shape.classindex < 0) goto feature_cleanup; /* no matching CLASS found, skip this feature */ } /* ** prepare any necessary JOINs here (one-to-one only) */ - if( layer->numjoins > 0) { + if (layer->numjoins > 0) { int j; - for(j=0; j < layer->numjoins; j++) { - if(layer->joins[j].type == MS_JOIN_ONE_TO_ONE) { + for (j = 0; j < layer->numjoins; j++) { + if (layer->joins[j].type == MS_JOIN_ONE_TO_ONE) { msJoinPrepare(&(layer->joins[j]), &shape); msJoinNext(&(layer->joins[j])); /* fetch the first row */ } } } - if(mvt_layer->n_features == features_size) { /* need to allocate more space */ + if (mvt_layer->n_features == + features_size) { /* need to allocate more space */ features_size += FEATURES_INCREMENT_SIZE; - mvt_layer->features = msSmallRealloc(mvt_layer->features, sizeof(VectorTile__Tile__Feature*)*(features_size)); + mvt_layer->features = msSmallRealloc( + mvt_layer->features, + sizeof(VectorTile__Tile__Feature *) * (features_size)); } - if( layer->project ) { - if( layer->reprojectorLayerToMap == NULL ) - { - layer->reprojectorLayerToMap = msProjectCreateReprojector( - &layer->projection, &map->projection); + if (layer->project) { + if (layer->reprojectorLayerToMap == NULL) { + layer->reprojectorLayerToMap = + msProjectCreateReprojector(&layer->projection, &map->projection); } - if( layer->reprojectorLayerToMap ) - status = msProjectShapeEx(layer->reprojectorLayerToMap, &shape); + if (layer->reprojectorLayerToMap) + status = msProjectShapeEx(layer->reprojectorLayerToMap, &shape); else - status = MS_FAILURE; + status = MS_FAILURE; } - if( status == MS_SUCCESS ) { - status = mvtWriteShape( layer, &shape, mvt_layer, item_list, &value_lookup_cache, &map->extent, buffer ); + if (status == MS_SUCCESS) { + status = mvtWriteShape(layer, &shape, mvt_layer, item_list, + &value_lookup_cache, &map->extent, buffer); } - feature_cleanup: + feature_cleanup: msFreeShape(&shape); - if(status != MS_SUCCESS) goto layer_cleanup; + if (status != MS_SUCCESS) + goto layer_cleanup; } /* next shape */ -layer_cleanup: + layer_cleanup: msLayerClose(layer); msGMLFreeItems(item_list); - UT_HASH_ITER(hh, value_lookup_cache.cache, cur_value_lookup, tmp_value_lookup) { + UT_HASH_ITER(hh, value_lookup_cache.cache, cur_value_lookup, + tmp_value_lookup) { msFree(cur_value_lookup->value); - UT_HASH_DEL(value_lookup_cache.cache,cur_value_lookup); + UT_HASH_DEL(value_lookup_cache.cache, cur_value_lookup); msFree(cur_value_lookup); } - if(retcode != MS_SUCCESS) goto cleanup; + if (retcode != MS_SUCCESS) + goto cleanup; } /* next layer */ - len = vector_tile__tile__get_packed_size(&mvt_tile); // This is the calculated packing length + len = vector_tile__tile__get_packed_size( + &mvt_tile); // This is the calculated packing length buf = msSmallMalloc(len); // Allocate memory vector_tile__tile__pack(&mvt_tile, buf); - if( sendheaders ) { - msIO_fprintf( stdout, - "Content-Length: %d\r\n" - "Content-Type: %s\r\n\r\n", - len, MS_IMAGE_MIME_TYPE(map->outputformat)); + if (sendheaders) { + msIO_fprintf(stdout, + "Content-Length: %d\r\n" + "Content-Type: %s\r\n\r\n", + len, MS_IMAGE_MIME_TYPE(map->outputformat)); } - msIO_fwrite(buf,len,1,stdout); + msIO_fwrite(buf, len, 1, stdout); msFree(buf); - cleanup: +cleanup: freeMvtTile(&mvt_tile); return retcode; } -int msPopulateRendererVTableMVT(rendererVTableObj * renderer) { +int msPopulateRendererVTableMVT(rendererVTableObj *renderer) { (void)renderer; return MS_SUCCESS; } #else -int msPopulateRendererVTableMVT(rendererVTableObj * renderer) { - msSetError(MS_MISCERR, "Vector Tile Driver requested but support is not compiled in", "msPopulateRendererVTableMVT()"); +int msPopulateRendererVTableMVT(rendererVTableObj *renderer) { + msSetError(MS_MISCERR, + "Vector Tile Driver requested but support is not compiled in", + "msPopulateRendererVTableMVT()"); return MS_FAILURE; } -int msMVTWriteTile( mapObj *map, int sendheaders ) { - msSetError(MS_MISCERR, "Vector Tile support is not available.", "msMVTWriteTile()"); +int msMVTWriteTile(mapObj *map, int sendheaders) { + msSetError(MS_MISCERR, "Vector Tile support is not available.", + "msMVTWriteTile()"); return MS_FAILURE; } #endif diff --git a/mapobject.c b/mapobject.c index 21fb1115e8..91baafe71b 100644 --- a/mapobject.c +++ b/mapobject.c @@ -45,24 +45,23 @@ void freeLegend(legendObj *legend); /* Create a new initialized map object. */ /************************************************************************/ -mapObj *msNewMapObj() -{ +mapObj *msNewMapObj() { mapObj *map = NULL; /* create an empty map, no layers etc... */ - map = (mapObj *)calloc(sizeof(mapObj),1); + map = (mapObj *)calloc(sizeof(mapObj), 1); - if(!map) { + if (!map) { msSetError(MS_MEMERR, NULL, "msCreateMap()"); return NULL; } - if( initMap( map ) == -1 ) { + if (initMap(map) == -1) { msFreeMap(map); return NULL; } - if( msPostMapParseOutputFormatSetup( map ) == MS_FAILURE ) { + if (msPostMapParseOutputFormatSetup(map) == MS_FAILURE) { msFreeMap(map); return NULL; } @@ -74,18 +73,19 @@ mapObj *msNewMapObj() /* msFreeMap() */ /************************************************************************/ -void msFreeMap(mapObj *map) -{ +void msFreeMap(mapObj *map) { int i; - if(!map) return; + if (!map) + return; - /* printf("msFreeMap(): maybe freeing map at %p count=%d.\n",map, map->refcount); */ - if(MS_REFCNT_DECR_IS_NOT_ZERO(map)) { + /* printf("msFreeMap(): maybe freeing map at %p count=%d.\n",map, + * map->refcount); */ + if (MS_REFCNT_DECR_IS_NOT_ZERO(map)) { return; } - if(map->debug >= MS_DEBUGLEVEL_VV) - msDebug("msFreeMap(): freeing map at %p.\n",map); + if (map->debug >= MS_DEBUGLEVEL_VV) + msDebug("msFreeMap(): freeing map at %p.\n", map); msCloseConnections(map); @@ -112,29 +112,31 @@ void msFreeMap(mapObj *map) freeReferenceMap(&(map->reference)); freeLegend(&(map->legend)); - for(i=0; imaxlayers; i++) { - if(GET_LAYER(map, i) != NULL) { + for (i = 0; i < map->maxlayers; i++) { + if (GET_LAYER(map, i) != NULL) { GET_LAYER(map, i)->map = NULL; - if(freeLayer((GET_LAYER(map, i))) == MS_SUCCESS) + if (freeLayer((GET_LAYER(map, i))) == MS_SUCCESS) free(GET_LAYER(map, i)); } } msFree(map->layers); - if(map->layerorder) + if (map->layerorder) free(map->layerorder); msFree(map->templatepattern); msFree(map->datapattern); msFreeHashItems(&(map->configoptions)); - if(map->outputformat && map->outputformat->refcount > 0 && --map->outputformat->refcount < 1) + if (map->outputformat && map->outputformat->refcount > 0 && + --map->outputformat->refcount < 1) msFreeOutputFormat(map->outputformat); - for(i=0; inumoutputformats; i++ ) { - if(map->outputformatlist[i]->refcount > 0 && --map->outputformatlist[i]->refcount < 1) + for (i = 0; i < map->numoutputformats; i++) { + if (map->outputformatlist[i]->refcount > 0 && + --map->outputformatlist[i]->refcount < 1) msFreeOutputFormat(map->outputformatlist[i]); } - if(map->outputformatlist != NULL) + if (map->outputformatlist != NULL) msFree(map->outputformatlist); msFreeQuery(&(map->query)); @@ -151,38 +153,38 @@ void msFreeMap(mapObj *map) /* msGetConfigOption() */ /************************************************************************/ -const char *msGetConfigOption( mapObj *map, const char *key) +const char *msGetConfigOption(mapObj *map, const char *key) { - return msLookupHashTable( &(map->configoptions), key ); + return msLookupHashTable(&(map->configoptions), key); } /************************************************************************/ /* msSetConfigOption() */ /************************************************************************/ -int msSetConfigOption( mapObj *map, const char *key, const char *value) +int msSetConfigOption(mapObj *map, const char *key, const char *value) { /* We have special "early" handling of this so that it will be */ /* in effect when the projection blocks are parsed and pj_init is called. */ - if( strcasecmp(key,"PROJ_DATA") == 0 || strcasecmp(key,"PROJ_LIB") == 0 ) { + if (strcasecmp(key, "PROJ_DATA") == 0 || strcasecmp(key, "PROJ_LIB") == 0) { /* value may be relative to map path */ - msSetPROJ_DATA( value, map->mappath ); + msSetPROJ_DATA(value, map->mappath); } /* Same for MS_ERRORFILE, we want it to kick in as early as possible * to catch parsing errors. * Value can be relative to mapfile, unless it's already absolute */ - if( strcasecmp(key,"MS_ERRORFILE") == 0 ) { - if (msSetErrorFile( value, map->mappath ) != MS_SUCCESS) + if (strcasecmp(key, "MS_ERRORFILE") == 0) { + if (msSetErrorFile(value, map->mappath) != MS_SUCCESS) return MS_FAILURE; } - if( msLookupHashTable( &(map->configoptions), key ) != NULL ) - msRemoveHashTable( &(map->configoptions), key ); - msInsertHashTable( &(map->configoptions), key, value ); + if (msLookupHashTable(&(map->configoptions), key) != NULL) + msRemoveHashTable(&(map->configoptions), key); + msInsertHashTable(&(map->configoptions), key, value); return MS_SUCCESS; } @@ -191,17 +193,16 @@ int msSetConfigOption( mapObj *map, const char *key, const char *value) /* msTestConfigOption() */ /************************************************************************/ -int msTestConfigOption( mapObj *map, const char *key, int default_result ) +int msTestConfigOption(mapObj *map, const char *key, int default_result) { - const char *result = msGetConfigOption( map, key ); + const char *result = msGetConfigOption(map, key); - if( result == NULL ) + if (result == NULL) return default_result; - if( strcasecmp(result,"YES") == 0 - || strcasecmp(result,"ON") == 0 - || strcasecmp(result,"TRUE") == 0 ) + if (strcasecmp(result, "YES") == 0 || strcasecmp(result, "ON") == 0 || + strcasecmp(result, "TRUE") == 0) return MS_TRUE; else return MS_FALSE; @@ -211,48 +212,45 @@ int msTestConfigOption( mapObj *map, const char *key, int default_result ) /* msApplyMapConfigOptions() */ /************************************************************************/ -void msApplyMapConfigOptions( mapObj *map ) +void msApplyMapConfigOptions(mapObj *map) { const char *key; - for( key = msFirstKeyFromHashTable( &(map->configoptions) ); - key != NULL; - key = msNextKeyFromHashTable( &(map->configoptions), key ) ) { - const char *value = msLookupHashTable( &(map->configoptions), key ); - if( strcasecmp(key,"PROJ_DATA") == 0 || - strcasecmp(key,"PROJ_LIB") == 0 ) { - msSetPROJ_DATA( value, map->mappath ); - } else if( strcasecmp(key,"MS_ERRORFILE") == 0 ) { - msSetErrorFile( value, map->mappath ); + for (key = msFirstKeyFromHashTable(&(map->configoptions)); key != NULL; + key = msNextKeyFromHashTable(&(map->configoptions), key)) { + const char *value = msLookupHashTable(&(map->configoptions), key); + if (strcasecmp(key, "PROJ_DATA") == 0 || strcasecmp(key, "PROJ_LIB") == 0) { + msSetPROJ_DATA(value, map->mappath); + } else if (strcasecmp(key, "MS_ERRORFILE") == 0) { + msSetErrorFile(value, map->mappath); } else { - CPLSetConfigOption( key, value ); + CPLSetConfigOption(key, value); } } } /************************************************************************/ -/* msMapIgnoreMissingData() */ +/* msMapIgnoreMissingData() */ /************************************************************************/ -int msMapIgnoreMissingData( mapObj *map ) -{ - const char *result = msGetConfigOption( map, "ON_MISSING_DATA" ); +int msMapIgnoreMissingData(mapObj *map) { + const char *result = msGetConfigOption(map, "ON_MISSING_DATA"); const int default_result = #ifndef IGNORE_MISSING_DATA - MS_MISSING_DATA_FAIL; + MS_MISSING_DATA_FAIL; #else - MS_MISSING_DATA_LOG; + MS_MISSING_DATA_LOG; #endif - if( result == NULL ) + if (result == NULL) return default_result; - if( strcasecmp(result,"FAIL") == 0 ) + if (strcasecmp(result, "FAIL") == 0) return MS_MISSING_DATA_FAIL; - else if( strcasecmp(result,"LOG") == 0 ) + else if (strcasecmp(result, "LOG") == 0) return MS_MISSING_DATA_LOG; - else if( strcasecmp(result,"IGNORE") == 0 ) + else if (strcasecmp(result, "IGNORE") == 0) return MS_MISSING_DATA_IGNORE; return default_result; @@ -262,9 +260,8 @@ int msMapIgnoreMissingData( mapObj *map ) /* msMapSetExtent() */ /************************************************************************/ -int msMapSetExtent( mapObj *map, - double minx, double miny, double maxx, double maxy) -{ +int msMapSetExtent(mapObj *map, double minx, double miny, double maxx, + double maxy) { map->extent.minx = minx; map->extent.miny = miny; @@ -272,44 +269,43 @@ int msMapSetExtent( mapObj *map, map->extent.maxy = maxy; if (!MS_VALID_EXTENT(map->extent)) { - msSetError(MS_MISCERR, "Given map extent is invalid. Check that it " \ - "is in the form: minx, miny, maxx, maxy", "setExtent()"); + msSetError(MS_MISCERR, + "Given map extent is invalid. Check that it " + "is in the form: minx, miny, maxx, maxy", + "setExtent()"); return MS_FAILURE; } - map->cellsize = msAdjustExtent(&(map->extent), map->width, - map->height); + map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); /* if the map size is also set, recompute scale, ignore errors? */ - if( map->width != -1 || map->height != -1 ) + if (map->width != -1 || map->height != -1) msCalculateScale(map->extent, map->units, map->width, map->height, map->resolution, &(map->scaledenom)); - return msMapComputeGeotransform( map ); + return msMapComputeGeotransform(map); } /************************************************************************/ /* msMapOffsetExtent() */ /************************************************************************/ -int msMapOffsetExtent( mapObj *map, double x, double y) -{ - return msMapSetExtent( map, - map->extent.minx + x, map->extent.miny + y, - map->extent.maxx + x, map->extent.maxy + y); +int msMapOffsetExtent(mapObj *map, double x, double y) { + return msMapSetExtent(map, map->extent.minx + x, map->extent.miny + y, + map->extent.maxx + x, map->extent.maxy + y); } /************************************************************************/ /* msMapScaleExtent() */ /************************************************************************/ -int msMapScaleExtent( mapObj *map, double zoomfactor, - double minscaledenom, double maxscaledenom) -{ +int msMapScaleExtent(mapObj *map, double zoomfactor, double minscaledenom, + double maxscaledenom) { double geo_width, geo_height, center_x, center_y, md; if (zoomfactor <= 0.0) { - msSetError(MS_MISCERR, "The given zoomfactor is invalid", "msMapScaleExtent()"); + msSetError(MS_MISCERR, "The given zoomfactor is invalid", + "msMapScaleExtent()"); } geo_width = map->extent.maxx - map->extent.minx; @@ -322,7 +318,8 @@ int msMapScaleExtent( mapObj *map, double zoomfactor, if (minscaledenom > 0 || maxscaledenom > 0) { /* ensure we are within the valid scale domain */ - md = (map->width-1)/(map->resolution * msInchesPerUnit(map->units, center_y)); + md = (map->width - 1) / + (map->resolution * msInchesPerUnit(map->units, center_y)); if (minscaledenom > 0 && geo_width < minscaledenom * md) geo_width = minscaledenom * md; if (maxscaledenom > 0 && geo_width > maxscaledenom * md) @@ -332,57 +329,57 @@ int msMapScaleExtent( mapObj *map, double zoomfactor, geo_width *= 0.5; geo_height = geo_width * map->height / map->width; - return msMapSetExtent( map, - center_x - geo_width, center_y - geo_height, - center_x + geo_width, center_y + geo_height); + return msMapSetExtent(map, center_x - geo_width, center_y - geo_height, + center_x + geo_width, center_y + geo_height); } /************************************************************************/ /* msMapSetCenter() */ /************************************************************************/ -int msMapSetCenter( mapObj *map, pointObj *center) -{ - return msMapOffsetExtent(map, center->x - (map->extent.minx + map->extent.maxx) * 0.5, - center->y - (map->extent.miny + map->extent.maxy) * 0.5); +int msMapSetCenter(mapObj *map, pointObj *center) { + return msMapOffsetExtent( + map, center->x - (map->extent.minx + map->extent.maxx) * 0.5, + center->y - (map->extent.miny + map->extent.maxy) * 0.5); } /************************************************************************/ /* msMapSetRotation() */ /************************************************************************/ -int msMapSetRotation( mapObj *map, double rotation_angle ) +int msMapSetRotation(mapObj *map, double rotation_angle) { map->gt.rotation_angle = rotation_angle; - if( map->gt.rotation_angle != 0.0 ) + if (map->gt.rotation_angle != 0.0) map->gt.need_geotransform = MS_TRUE; else map->gt.need_geotransform = MS_FALSE; - return msMapComputeGeotransform( map ); + return msMapComputeGeotransform(map); } /************************************************************************/ /* msMapSetSize() */ /************************************************************************/ -int msMapSetSize( mapObj *map, int width, int height ) +int msMapSetSize(mapObj *map, int width, int height) { map->width = width; map->height = height; - return msMapComputeGeotransform( map ); /* like SetRotation -- sean */ + return msMapComputeGeotransform(map); /* like SetRotation -- sean */ } /************************************************************************/ /* msMapComputeGeotransform() */ /************************************************************************/ -extern int InvGeoTransform( double *gt_in, double *gt_out ); +extern int InvGeoTransform(double *gt_in, double *gt_out); -int msMapComputeGeotransformEx( mapObj * map, double resolutionX, double resolutionY ) +int msMapComputeGeotransformEx(mapObj *map, double resolutionX, + double resolutionY) { double rot_angle; @@ -395,57 +392,51 @@ int msMapComputeGeotransformEx( mapObj * map, double resolutionX, double resolut geo_width = map->extent.maxx - map->extent.minx; geo_height = map->extent.maxy - map->extent.miny; - center_x = map->extent.minx + geo_width*0.5; - center_y = map->extent.miny + geo_height*0.5; + center_x = map->extent.minx + geo_width * 0.5; + center_y = map->extent.miny + geo_height * 0.5; /* ** Per bug 1916 we have to adjust for the fact that map extents ** are based on the center of the edge pixels, not the outer ** edges as is expected in a geotransform. */ - map->gt.geotransform[1] = - cos(rot_angle) * resolutionX; - map->gt.geotransform[2] = - sin(rot_angle) * resolutionY; - map->gt.geotransform[0] = center_x - - (map->width * 0.5) * map->gt.geotransform[1] - - (map->height * 0.5) * map->gt.geotransform[2]; - - map->gt.geotransform[4] = - sin(rot_angle) * resolutionX; - map->gt.geotransform[5] = - - cos(rot_angle) * resolutionY; - map->gt.geotransform[3] = center_y - - (map->width * 0.5) * map->gt.geotransform[4] - - (map->height * 0.5) * map->gt.geotransform[5]; - - if( InvGeoTransform( map->gt.geotransform, - map->gt.invgeotransform ) ) + map->gt.geotransform[1] = cos(rot_angle) * resolutionX; + map->gt.geotransform[2] = sin(rot_angle) * resolutionY; + map->gt.geotransform[0] = center_x - + (map->width * 0.5) * map->gt.geotransform[1] - + (map->height * 0.5) * map->gt.geotransform[2]; + + map->gt.geotransform[4] = sin(rot_angle) * resolutionX; + map->gt.geotransform[5] = -cos(rot_angle) * resolutionY; + map->gt.geotransform[3] = center_y - + (map->width * 0.5) * map->gt.geotransform[4] - + (map->height * 0.5) * map->gt.geotransform[5]; + + if (InvGeoTransform(map->gt.geotransform, map->gt.invgeotransform)) return MS_SUCCESS; else return MS_FAILURE; } -int msMapComputeGeotransform( mapObj * map ) +int msMapComputeGeotransform(mapObj *map) { /* Do we have all required parameters? */ - if( map->extent.minx == map->extent.maxx - || map->width <= 1 || map->height <= 1 ) + if (map->extent.minx == map->extent.maxx || map->width <= 1 || + map->height <= 1) return MS_FAILURE; const double geo_width = map->extent.maxx - map->extent.minx; const double geo_height = map->extent.maxy - map->extent.miny; - return msMapComputeGeotransformEx(map, - geo_width / (map->width-1), - geo_height / (map->height-1)); + return msMapComputeGeotransformEx(map, geo_width / (map->width - 1), + geo_height / (map->height - 1)); } /************************************************************************/ /* msMapPixelToGeoref() */ /************************************************************************/ -void msMapPixelToGeoref( mapObj *map, double *x, double *y ) +void msMapPixelToGeoref(mapObj *map, double *x, double *y) { (void)map; @@ -458,7 +449,7 @@ void msMapPixelToGeoref( mapObj *map, double *x, double *y ) /* msMapGeorefToPixel() */ /************************************************************************/ -void msMapGeorefToPixel( mapObj *map, double *x, double *y ) +void msMapGeorefToPixel(mapObj *map, double *x, double *y) { (void)map; @@ -471,7 +462,7 @@ void msMapGeorefToPixel( mapObj *map, double *x, double *y ) /* msMapSetFakedExtent() */ /************************************************************************/ -int msMapSetFakedExtent( mapObj *map ) +int msMapSetFakedExtent(mapObj *map) { int i; @@ -502,26 +493,24 @@ int msMapSetFakedExtent( mapObj *map ) /* -------------------------------------------------------------------- */ map->projection.gt = map->gt; - map->projection.gt.geotransform[0] - += map->height * map->gt.geotransform[2]; - map->projection.gt.geotransform[3] - += map->height * map->gt.geotransform[5]; + map->projection.gt.geotransform[0] += map->height * map->gt.geotransform[2]; + map->projection.gt.geotransform[3] += map->height * map->gt.geotransform[5]; map->projection.gt.geotransform[2] *= -1; map->projection.gt.geotransform[5] *= -1; - for(i=0; inumlayers; i++) + for (i = 0; i < map->numlayers; i++) GET_LAYER(map, i)->project = MS_TRUE; - return InvGeoTransform( map->projection.gt.geotransform, - map->projection.gt.invgeotransform ); + return InvGeoTransform(map->projection.gt.geotransform, + map->projection.gt.invgeotransform); } /************************************************************************/ /* msMapRestoreRealExtent() */ /************************************************************************/ -int msMapRestoreRealExtent( mapObj *map ) +int msMapRestoreRealExtent(mapObj *map) { map->projection.gt.need_geotransform = MS_FALSE; @@ -537,8 +526,7 @@ int msMapRestoreRealExtent( mapObj *map ) /* Returns the index at which the layer was inserted */ -int msInsertLayer(mapObj *map, layerObj *layer, int nIndex) -{ +int msInsertLayer(mapObj *map, layerObj *layer, int nIndex) { if (!layer) { msSetError(MS_CHILDERR, "Can't insert a NULL Layer", "msInsertLayer()"); return -1; @@ -550,16 +538,17 @@ int msInsertLayer(mapObj *map, layerObj *layer, int nIndex) return -1; } - /* msGrowMapLayers allocates the new layer which we don't need to do since we have 1 that we are inserting - not sure if it is possible for this to be non null otherwise, but better to check since this function - replaces the value */ - if (map->layers[map->numlayers]!=NULL) + /* msGrowMapLayers allocates the new layer which we don't need to do since we + have 1 that we are inserting not sure if it is possible for this to be non + null otherwise, but better to check since this function replaces the value + */ + if (map->layers[map->numlayers] != NULL) free(map->layers[map->numlayers]); /* Catch attempt to insert past end of layers array */ if (nIndex >= map->numlayers) { msSetError(MS_CHILDERR, "Cannot insert layer beyond index %d", - "msInsertLayer()", map->numlayers-1); + "msInsertLayer()", map->numlayers - 1); return -1; } else if (nIndex < 0) { /* Insert at the end by default */ map->layerorder[map->numlayers] = map->numlayers; @@ -568,28 +557,30 @@ int msInsertLayer(mapObj *map, layerObj *layer, int nIndex) GET_LAYER(map, map->numlayers)->map = map; MS_REFCNT_INCR(layer); map->numlayers++; - return map->numlayers-1; - } else { + return map->numlayers - 1; + } else { /* Move existing layers at the specified nIndex or greater */ /* to an index one higher */ int i; - for (i=map->numlayers; i>nIndex; i--) { - GET_LAYER(map, i)=GET_LAYER(map, i-1); + for (i = map->numlayers; i > nIndex; i--) { + GET_LAYER(map, i) = GET_LAYER(map, i - 1); GET_LAYER(map, i)->index = i; } /* assign new layer to specified index */ - GET_LAYER(map, nIndex)=layer; + GET_LAYER(map, nIndex) = layer; GET_LAYER(map, nIndex)->index = nIndex; GET_LAYER(map, nIndex)->map = map; /* adjust layers drawing order */ - for (i=map->numlayers; i>nIndex; i--) { - map->layerorder[i] = map->layerorder[i-1]; - if (map->layerorder[i] >= nIndex) map->layerorder[i]++; + for (i = map->numlayers; i > nIndex; i--) { + map->layerorder[i] = map->layerorder[i - 1]; + if (map->layerorder[i] >= nIndex) + map->layerorder[i]++; } - for (i=0; ilayerorder[i] >= nIndex) map->layerorder[i]++; + for (i = 0; i < nIndex; i++) { + if (map->layerorder[i] >= nIndex) + map->layerorder[i]++; } map->layerorder[nIndex] = nIndex; @@ -603,8 +594,7 @@ int msInsertLayer(mapObj *map, layerObj *layer, int nIndex) /************************************************************************/ /* msRemoveLayer() */ /************************************************************************/ -layerObj *msRemoveLayer(mapObj *map, int nIndex) -{ +layerObj *msRemoveLayer(mapObj *map, int nIndex) { int i; int order_index; layerObj *layer; @@ -614,38 +604,40 @@ layerObj *msRemoveLayer(mapObj *map, int nIndex) "msRemoveLayer()", nIndex); return NULL; } else { - layer=GET_LAYER(map, nIndex); + layer = GET_LAYER(map, nIndex); /* msCopyLayer(layer, (GET_LAYER(map, nIndex))); */ /* Iteratively copy the higher index layers down one index */ - for (i=nIndex; inumlayers-1; i++) { + for (i = nIndex; i < map->numlayers - 1; i++) { /* freeLayer((GET_LAYER(map, i))); */ /* initLayer((GET_LAYER(map, i)), map); */ /* msCopyLayer(GET_LAYER(map, i), GET_LAYER(map, i+1)); */ - GET_LAYER(map, i)=GET_LAYER(map, i+1); + GET_LAYER(map, i) = GET_LAYER(map, i + 1); GET_LAYER(map, i)->index = i; } /* Free the extra layer at the end */ /* freeLayer((GET_LAYER(map, map->numlayers-1))); */ - GET_LAYER(map, map->numlayers-1)=NULL; + GET_LAYER(map, map->numlayers - 1) = NULL; /* Adjust drawing order */ order_index = 0; - for (i=0; inumlayers; i++) { - if (map->layerorder[i] > nIndex) map->layerorder[i]--; + for (i = 0; i < map->numlayers; i++) { + if (map->layerorder[i] > nIndex) + map->layerorder[i]--; if (map->layerorder[i] == nIndex) { order_index = i; break; } } - for (i=order_index; inumlayers-1; i++) { - map->layerorder[i] = map->layerorder[i+1]; - if (map->layerorder[i] > nIndex) map->layerorder[i]--; + for (i = order_index; i < map->numlayers - 1; i++) { + map->layerorder[i] = map->layerorder[i + 1]; + if (map->layerorder[i] > nIndex) + map->layerorder[i]--; } /* decrement number of layers and return copy of removed layer */ map->numlayers--; - layer->map=NULL; + layer->map = NULL; MS_REFCNT_DECR(layer); return layer; } @@ -655,30 +647,27 @@ layerObj *msRemoveLayer(mapObj *map, int nIndex) ** Move the layer's order for drawing purpose. Moving it up here ** will have the effect of drawing the layer earlier. */ -int msMoveLayerUp(mapObj *map, int nLayerIndex) -{ +int msMoveLayerUp(mapObj *map, int nLayerIndex) { int iCurrentIndex = -1; - if (map && nLayerIndex < map->numlayers && nLayerIndex >=0) { - for (int i=0; inumlayers; i++) { - if ( map->layerorder[i] == nLayerIndex) { + if (map && nLayerIndex < map->numlayers && nLayerIndex >= 0) { + for (int i = 0; i < map->numlayers; i++) { + if (map->layerorder[i] == nLayerIndex) { iCurrentIndex = i; break; } } - if (iCurrentIndex >=0) { + if (iCurrentIndex >= 0) { /* we do not need to promote if it is the first one. */ if (iCurrentIndex == 0) return MS_FAILURE; - map->layerorder[iCurrentIndex] = - map->layerorder[iCurrentIndex-1]; - map->layerorder[iCurrentIndex-1] = nLayerIndex; + map->layerorder[iCurrentIndex] = map->layerorder[iCurrentIndex - 1]; + map->layerorder[iCurrentIndex - 1] = nLayerIndex; return MS_SUCCESS; } } - msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveLayerUp()", - nLayerIndex); + msSetError(MS_CHILDERR, "Invalid index: %d", "msMoveLayerUp()", nLayerIndex); return MS_FAILURE; } @@ -686,24 +675,22 @@ int msMoveLayerUp(mapObj *map, int nLayerIndex) ** Move the layer's order for drawing purpose. Moving it down here ** will have the effect of drawing the layer later. */ -int msMoveLayerDown(mapObj *map, int nLayerIndex) -{ +int msMoveLayerDown(mapObj *map, int nLayerIndex) { int iCurrentIndex = -1; - if (map && nLayerIndex < map->numlayers && nLayerIndex >=0) { - for (int i=0; inumlayers; i++) { - if ( map->layerorder[i] == nLayerIndex) { + if (map && nLayerIndex < map->numlayers && nLayerIndex >= 0) { + for (int i = 0; i < map->numlayers; i++) { + if (map->layerorder[i] == nLayerIndex) { iCurrentIndex = i; break; } } - if (iCurrentIndex >=0) { + if (iCurrentIndex >= 0) { /* we do not need to demote if it is the last one. */ - if (iCurrentIndex == map->numlayers-1) + if (iCurrentIndex == map->numlayers - 1) return MS_FAILURE; - map->layerorder[iCurrentIndex] = - map->layerorder[iCurrentIndex+1]; - map->layerorder[iCurrentIndex+1] = nLayerIndex; + map->layerorder[iCurrentIndex] = map->layerorder[iCurrentIndex + 1]; + map->layerorder[iCurrentIndex + 1] = nLayerIndex; return MS_SUCCESS; } @@ -713,7 +700,6 @@ int msMoveLayerDown(mapObj *map, int nLayerIndex) return MS_FAILURE; } - /* ** Set the array used for the drawing order. The array passed must contain ** all the layer's index ordered by the drawing priority. @@ -728,13 +714,12 @@ int msMoveLayerDown(mapObj *map, int nLayerIndex) ** of elements as the number of layers in the map. ** Return TRUE on success else FALSE. */ -int msSetLayersdrawingOrder(mapObj *self, int *panIndexes) -{ +int msSetLayersdrawingOrder(mapObj *self, int *panIndexes) { if (self && panIndexes) { const int nElements = self->numlayers; - for (int i=0; ilayerorder[i] = panIndexes[i]; } return 1; @@ -754,7 +739,6 @@ int msSetLayersdrawingOrder(mapObj *self, int *panIndexes) return 0; } - /* ========================================================================= msMapLoadOWSParameters @@ -762,32 +746,29 @@ int msSetLayersdrawingOrder(mapObj *self, int *panIndexes) ========================================================================= */ int msMapLoadOWSParameters(mapObj *map, cgiRequestObj *request, - const char *wmtver) -{ + const char *wmtver) { #ifdef USE_WMS_SVR int version; char *wms_exception_format = NULL; - const char *wms_request= NULL; + const char *wms_request = NULL; int result, i = 0; owsRequestObj ows_request; msOWSInitRequestObj(&ows_request); - version = msOWSParseVersionString(wmtver); - for(i=0; iNumParams; i++) { + for (i = 0; i < request->NumParams; i++) { if (strcasecmp(request->ParamNames[i], "EXCEPTIONS") == 0) wms_exception_format = request->ParamValues[i]; else if (strcasecmp(request->ParamNames[i], "REQUEST") == 0) wms_request = request->ParamValues[i]; - } msOWSRequestLayersEnabled(map, "M", wms_request, &ows_request); - result = msWMSLoadGetMapParams(map, version, request->ParamNames, - request->ParamValues, request->NumParams, wms_exception_format, - wms_request, &ows_request); + result = msWMSLoadGetMapParams( + map, version, request->ParamNames, request->ParamValues, + request->NumParams, wms_exception_format, wms_request, &ows_request); msOWSClearRequestObj(&ows_request); @@ -799,4 +780,3 @@ int msMapLoadOWSParameters(mapObj *map, cgiRequestObj *request, return MS_FAILURE; #endif } - diff --git a/mapogcapi.cpp b/mapogcapi.cpp index 28178f2812..e5ec09d167 100644 --- a/mapogcapi.cpp +++ b/mapogcapi.cpp @@ -6,7 +6,7 @@ * Author: Steve Lime and the MapServer team. * ********************************************************************** - * Copyright (c) 1996-2005 Regents of the University of Minnesota. + * Copyright (c) 1996-2005 Regents of the University of Minnesota. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -55,17 +55,12 @@ using json = nlohmann::json; #define OGCAPI_TEMPLATE_HTML_COLLECTION_ITEM "collection-item.html" #define OGCAPI_TEMPLATE_HTML_OPENAPI "openapi.html" -enum class OGCAPIFormat -{ - JSON, - GeoJSON, - OpenAPI_V3, - HTML -}; +enum class OGCAPIFormat { JSON, GeoJSON, OpenAPI_V3, HTML }; #define OGCAPI_MIMETYPE_JSON "application/json" #define OGCAPI_MIMETYPE_GEOJSON "application/geo+json" -#define OGCAPI_MIMETYPE_OPENAPI_V3 "application/vnd.oai.openapi+json;version=3.0" +#define OGCAPI_MIMETYPE_OPENAPI_V3 \ + "application/vnd.oai.openapi+json;version=3.0" #define OGCAPI_MIMETYPE_HTML "text/html" #define OGCAPI_DEFAULT_LIMIT 10 // by specification @@ -84,21 +79,16 @@ enum class OGCAPIFormat /* ** Returns a JSON object using and a description. */ -static void outputError(int code, const std::string& description) -{ - if(code < 0 || code >= OGCAPI_NUM_ERROR_CODES) code = 0; - - json error_codes = { - { {"text", "ServerError"}, {"status", "500"} }, - { {"text", "ConfigError"}, {"status", "500"} }, - { {"text", "InvalidParamterValue"}, {"status", "400"} }, - { {"text", "NotFound"}, {"status", "404"} } - }; +static void outputError(int code, const std::string &description) { + if (code < 0 || code >= OGCAPI_NUM_ERROR_CODES) + code = 0; - json j = { - { "code", error_codes[code]["text"] }, - { "description", description } - }; + json error_codes = {{{"text", "ServerError"}, {"status", "500"}}, + {{"text", "ConfigError"}, {"status", "500"}}, + {{"text", "InvalidParamterValue"}, {"status", "400"}}, + {{"text", "NotFound"}, {"status", "404"}}}; + + json j = {{"code", error_codes[code]["text"]}, {"description", description}}; std::string status = error_codes[code]["status"]; @@ -109,9 +99,8 @@ static void outputError(int code, const std::string& description) } static int includeLayer(mapObj *map, layerObj *layer) { - if(!msOWSRequestIsEnabled(map, layer, "AO", "OGCAPI", MS_FALSE) || - !msWFSIsLayerSupported(layer) || - !msIsLayerQueryable(layer)) { + if (!msOWSRequestIsEnabled(map, layer, "AO", "OGCAPI", MS_FALSE) || + !msWFSIsLayerSupported(layer) || !msIsLayerQueryable(layer)) { return MS_FALSE; } else { return MS_TRUE; @@ -123,58 +112,63 @@ static int includeLayer(mapObj *map, layerObj *layer) { */ /* -** Returns the value associated with an item from the request's query string and NULL if the item was not found. +** Returns the value associated with an item from the request's query string and +*NULL if the item was not found. */ -static const char *getRequestParameter(cgiRequestObj *request, const char *item) -{ +static const char *getRequestParameter(cgiRequestObj *request, + const char *item) { int i; - for(i=0; iNumParams; i++) { - if(strcmp(item, request->ParamNames[i]) == 0) + for (i = 0; i < request->NumParams; i++) { + if (strcmp(item, request->ParamNames[i]) == 0) return request->ParamValues[i]; } return NULL; } -static int getMaxLimit(mapObj *map, layerObj *layer) -{ +static int getMaxLimit(mapObj *map, layerObj *layer) { int max_limit = OGCAPI_MAX_LIMIT; - const char *value; + const char *value; // check metadata, layer then map value = msOWSLookupMetadata(&(layer->metadata), "A", "max_limit"); - if(value == NULL) value = msOWSLookupMetadata(&(map->web.metadata), "A", "max_limit"); + if (value == NULL) + value = msOWSLookupMetadata(&(map->web.metadata), "A", "max_limit"); - if(value != NULL) { + if (value != NULL) { int status = msStringToInt(value, &max_limit, 10); - if(status != MS_SUCCESS) max_limit = OGCAPI_MAX_LIMIT; // conversion failed + if (status != MS_SUCCESS) + max_limit = OGCAPI_MAX_LIMIT; // conversion failed } return max_limit; } -static int getDefaultLimit(mapObj *map, layerObj *layer) -{ +static int getDefaultLimit(mapObj *map, layerObj *layer) { int default_limit = OGCAPI_DEFAULT_LIMIT; // check metadata, layer then map - const char* value = msOWSLookupMetadata(&(layer->metadata), "A", "default_limit"); - if(value == NULL) value = msOWSLookupMetadata(&(map->web.metadata), "A", "default_limit"); + const char *value = + msOWSLookupMetadata(&(layer->metadata), "A", "default_limit"); + if (value == NULL) + value = msOWSLookupMetadata(&(map->web.metadata), "A", "default_limit"); - if(value != NULL) { + if (value != NULL) { int status = msStringToInt(value, &default_limit, 10); - if(status != MS_SUCCESS) default_limit = OGCAPI_DEFAULT_LIMIT; // conversion failed + if (status != MS_SUCCESS) + default_limit = OGCAPI_DEFAULT_LIMIT; // conversion failed } return default_limit; } /* -** Returns the limit as an int - between 1 and getMaxLimit(). We always return a valid value... +** Returns the limit as an int - between 1 and getMaxLimit(). We always return a +*valid value... */ -static int getLimit(mapObj *map, cgiRequestObj *request, layerObj *layer, int *limit) -{ +static int getLimit(mapObj *map, cgiRequestObj *request, layerObj *layer, + int *limit) { int status; const char *p; @@ -182,15 +176,17 @@ static int getLimit(mapObj *map, cgiRequestObj *request, layerObj *layer, int *l max_limit = getMaxLimit(map, layer); p = getRequestParameter(request, "limit"); - if(!p || (p && strlen(p) == 0)) { // missing or empty - *limit = MS_MIN(getDefaultLimit(map, layer), max_limit); // max could be smaller than the default + if (!p || (p && strlen(p) == 0)) { // missing or empty + *limit = MS_MIN(getDefaultLimit(map, layer), + max_limit); // max could be smaller than the default } else { status = msStringToInt(p, limit, 10); - if(status != MS_SUCCESS) + if (status != MS_SUCCESS) return MS_FAILURE; - if(*limit <= 0) { - *limit = MS_MIN(getDefaultLimit(map, layer), max_limit); // max could be smaller than the default + if (*limit <= 0) { + *limit = MS_MIN(getDefaultLimit(map, layer), + max_limit); // max could be smaller than the default } else { *limit = MS_MIN(*limit, max_limit); } @@ -202,27 +198,27 @@ static int getLimit(mapObj *map, cgiRequestObj *request, layerObj *layer, int *l /* ** Returns the bbox in SRS of the map. */ -static bool getBbox(mapObj *map, cgiRequestObj *request, rectObj *bbox) -{ +static bool getBbox(mapObj *map, cgiRequestObj *request, rectObj *bbox) { int status; const char *p; p = getRequestParameter(request, "bbox"); - if(!p || (p && strlen(p) == 0)) { // missing or empty - assign map->extent (no projection necessary) + if (!p || (p && strlen(p) == 0)) { // missing or empty - assign map->extent + // (no projection necessary) bbox->minx = map->extent.minx; bbox->miny = map->extent.miny; bbox->maxx = map->extent.maxx; bbox->maxy = map->extent.maxy; } else { const auto tokens = msStringSplit(p, ','); - if(tokens.size() != 4) { + if (tokens.size() != 4) { return false; } double values[4]; - for(int i=0; i<4; i++) { + for (int i = 0; i < 4; i++) { status = msStringToDouble(tokens[i].c_str(), &values[i]); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { return false; } } @@ -233,11 +229,13 @@ static bool getBbox(mapObj *map, cgiRequestObj *request, rectObj *bbox) bbox->maxy = values[3]; // validate bbox is well-formed (degenerate is ok) - if(MS_VALID_SEARCH_EXTENT(*bbox) != MS_TRUE) return false; + if (MS_VALID_SEARCH_EXTENT(*bbox) != MS_TRUE) + return false; // at the moment we are assuming the bbox is given in lat/lon status = msProjectRect(&map->latlon, &map->projection, bbox); - if(status != MS_SUCCESS) return false; + if (status != MS_SUCCESS) + return false; } return true; @@ -246,28 +244,30 @@ static bool getBbox(mapObj *map, cgiRequestObj *request, rectObj *bbox) /* ** Returns the template directory location or NULL if it isn't set. */ -static const char *getTemplateDirectory(mapObj *map, const char *key, const char *envvar) -{ +static const char *getTemplateDirectory(mapObj *map, const char *key, + const char *envvar) { const char *directory; - // TODO: if directory is provided then perhaps we need to check for a trailing slash + // TODO: if directory is provided then perhaps we need to check for a trailing + // slash - if((directory = msOWSLookupMetadata(&(map->web.metadata), "A", key)) != NULL) + if ((directory = msOWSLookupMetadata(&(map->web.metadata), "A", key)) != NULL) return directory; - else if((directory = CPLGetConfigOption(envvar, NULL)) != NULL) + else if ((directory = CPLGetConfigOption(envvar, NULL)) != NULL) return directory; else return NULL; } /* -** Returns the service title from oga_{key} and/or ows_{key} or a default value if not set. +** Returns the service title from oga_{key} and/or ows_{key} or a default value +*if not set. */ -static const char *getWebMetadata(mapObj *map, const char* domain, const char* key, const char* defaultVal) -{ +static const char *getWebMetadata(mapObj *map, const char *domain, + const char *key, const char *defaultVal) { const char *value; - if((value = msOWSLookupMetadata(&(map->web.metadata), domain, key)) != NULL) + if ((value = msOWSLookupMetadata(&(map->web.metadata), domain, key)) != NULL) return value; else return defaultVal; @@ -276,107 +276,94 @@ static const char *getWebMetadata(mapObj *map, const char* domain, const char* k /* ** Returns the service title from oga|ows_title or a default value if not set. */ -static const char *getTitle(mapObj *map) -{ +static const char *getTitle(mapObj *map) { return getWebMetadata(map, "OA", "title", OGCAPI_DEFAULT_TITLE); } /* -** Returns the API root URL from oga_onlineresource or builds a value if not set. +** Returns the API root URL from oga_onlineresource or builds a value if not +*set. */ -static std::string getApiRootUrl(mapObj *map) -{ +static std::string getApiRootUrl(mapObj *map) { const char *root; - if((root = msOWSLookupMetadata(&(map->web.metadata), "A", "onlineresource")) != NULL) + if ((root = msOWSLookupMetadata(&(map->web.metadata), "A", + "onlineresource")) != NULL) return std::string(root); else - return "http://" + std::string(getenv("SERVER_NAME")) + ":" + std::string(getenv("SERVER_PORT")) + std::string(getenv("SCRIPT_NAME")) + std::string(getenv("PATH_INFO")); + return "http://" + std::string(getenv("SERVER_NAME")) + ":" + + std::string(getenv("SERVER_PORT")) + + std::string(getenv("SCRIPT_NAME")) + + std::string(getenv("PATH_INFO")); } -static json getFeatureConstant(const gmlConstantObj *constant) -{ +static json getFeatureConstant(const gmlConstantObj *constant) { json j; // empty (null) - if(!constant) throw std::runtime_error("Null constant metadata."); - if(!constant->value) return j; - + if (!constant) + throw std::runtime_error("Null constant metadata."); + if (!constant->value) + return j; + // initialize - j = { { constant->name, constant->value } }; + j = {{constant->name, constant->value}}; return j; } -static json getFeatureItem(const gmlItemObj *item, const char *value) -{ +static json getFeatureItem(const gmlItemObj *item, const char *value) { json j; // empty (null) const char *key; - if(!item) throw std::runtime_error("Null item metadata."); - if(!item->visible) return j; + if (!item) + throw std::runtime_error("Null item metadata."); + if (!item->visible) + return j; - if(item->alias) + if (item->alias) key = item->alias; else key = item->name; // initialize - j = { { key, value } }; - - if( item->type && (EQUAL(item->type, "Date") || - EQUAL(item->type, "DateTime") || - EQUAL(item->type, "Time")) ) { - struct tm tm; - if( msParseTime(value, &tm) == MS_TRUE ) { - char tmpValue[64]; - if( EQUAL(item->type, "Date") ) - snprintf(tmpValue, sizeof(tmpValue), - "%04d-%02d-%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - else if( EQUAL(item->type, "Time") ) - snprintf(tmpValue, sizeof(tmpValue), - "%02d:%02d:%02dZ", - tm.tm_hour, tm.tm_min, tm.tm_sec); - else - snprintf(tmpValue, sizeof(tmpValue), - "%04d-%02d-%02dT%02d:%02d:%02dZ", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - - j = { { key, tmpValue } }; - } - } - else if( item->type && (EQUAL(item->type, "Integer") || - EQUAL(item->type, "Long")) ) - { - try - { - j = { { key, std::stoll(value) } }; - } - catch( const std::exception& ) - { - } - } - else if( item->type && EQUAL(item->type, "Real")) - { - try - { - j = { { key, std::stod(value) } }; - } - catch( const std::exception& ) - { - } - } - else if( item->type && EQUAL(item->type, "Boolean")) - { - if( EQUAL(value,"0") || EQUAL(value,"false") ) - { - j = { { key, false } }; - } + j = {{key, value}}; + + if (item->type && + (EQUAL(item->type, "Date") || EQUAL(item->type, "DateTime") || + EQUAL(item->type, "Time"))) { + struct tm tm; + if (msParseTime(value, &tm) == MS_TRUE) { + char tmpValue[64]; + if (EQUAL(item->type, "Date")) + snprintf(tmpValue, sizeof(tmpValue), "%04d-%02d-%02d", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + else if (EQUAL(item->type, "Time")) + snprintf(tmpValue, sizeof(tmpValue), "%02d:%02d:%02dZ", tm.tm_hour, + tm.tm_min, tm.tm_sec); else - { - j = { { key, true } }; - } + snprintf(tmpValue, sizeof(tmpValue), "%04d-%02d-%02dT%02d:%02d:%02dZ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec); + + j = {{key, tmpValue}}; + } + } else if (item->type && + (EQUAL(item->type, "Integer") || EQUAL(item->type, "Long"))) { + try { + j = {{key, std::stoll(value)}}; + } catch (const std::exception &) { + } + } else if (item->type && EQUAL(item->type, "Real")) { + try { + j = {{key, std::stod(value)}}; + } catch (const std::exception &) { + } + } else if (item->type && EQUAL(item->type, "Boolean")) { + if (EQUAL(value, "0") || EQUAL(value, "false")) { + j = {{key, false}}; + } else { + j = {{key, true}}; + } } return j; @@ -392,69 +379,82 @@ static double round_up(double value, int decimal_places) { return std::ceil(value * multiplier) / multiplier; } -static json getFeatureGeometry(shapeObj *shape, int precision) -{ +static json getFeatureGeometry(shapeObj *shape, int precision) { json geometry; // empty (null) - int *outerList=NULL, numOuterRings=0; + int *outerList = NULL, numOuterRings = 0; - if(!shape) throw std::runtime_error("Null shape."); + if (!shape) + throw std::runtime_error("Null shape."); - switch(shape->type) { - case(MS_SHAPE_POINT): - if(shape->numlines == 0 || shape->line[0].numpoints == 0) // not enough info for a point + switch (shape->type) { + case (MS_SHAPE_POINT): + if (shape->numlines == 0 || + shape->line[0].numpoints == 0) // not enough info for a point return geometry; - if(shape->line[0].numpoints == 1) { + if (shape->line[0].numpoints == 1) { geometry["type"] = "Point"; - geometry["coordinates"] = { round_up(shape->line[0].point[0].x, precision), round_up(shape->line[0].point[0].y, precision) }; + geometry["coordinates"] = { + round_up(shape->line[0].point[0].x, precision), + round_up(shape->line[0].point[0].y, precision)}; } else { geometry["type"] = "MultiPoint"; geometry["coordinates"] = json::array(); - for(int j=0; jline[0].numpoints; j++) { - geometry["coordinates"].push_back( { round_up(shape->line[0].point[j].x, precision), round_up(shape->line[0].point[j].y, precision) } ); + for (int j = 0; j < shape->line[0].numpoints; j++) { + geometry["coordinates"].push_back( + {round_up(shape->line[0].point[j].x, precision), + round_up(shape->line[0].point[j].y, precision)}); } } break; - case(MS_SHAPE_LINE): - if(shape->numlines == 0 || shape->line[0].numpoints < 2) // not enough info for a line + case (MS_SHAPE_LINE): + if (shape->numlines == 0 || + shape->line[0].numpoints < 2) // not enough info for a line return geometry; - if(shape->numlines == 1) { + if (shape->numlines == 1) { geometry["type"] = "LineString"; geometry["coordinates"] = json::array(); - for(int j=0; jline[0].numpoints; j++) { - geometry["coordinates"].push_back( { round_up(shape->line[0].point[j].x, precision), round_up(shape->line[0].point[j].y, precision) } ); + for (int j = 0; j < shape->line[0].numpoints; j++) { + geometry["coordinates"].push_back( + {round_up(shape->line[0].point[j].x, precision), + round_up(shape->line[0].point[j].y, precision)}); } } else { geometry["type"] = "MultiLineString"; geometry["coordinates"] = json::array(); - for(int i=0; inumlines; i++) { + for (int i = 0; i < shape->numlines; i++) { json part = json::array(); - for(int j=0; jline[i].numpoints; j++) { - part.push_back( { round_up(shape->line[i].point[j].x, precision), round_up(shape->line[i].point[j].y, precision) } ); + for (int j = 0; j < shape->line[i].numpoints; j++) { + part.push_back({round_up(shape->line[i].point[j].x, precision), + round_up(shape->line[i].point[j].y, precision)}); } geometry["coordinates"].push_back(part); } } break; - case(MS_SHAPE_POLYGON): - if(shape->numlines == 0 || shape->line[0].numpoints < 4) // not enough info for a polygon (first=last) + case (MS_SHAPE_POLYGON): + if (shape->numlines == 0 || + shape->line[0].numpoints < + 4) // not enough info for a polygon (first=last) return geometry; outerList = msGetOuterList(shape); - if(outerList == NULL) throw std::runtime_error("Unable to allocate list of outer rings."); - for(int k=0; knumlines; k++) { - if(outerList[k] == MS_TRUE) - numOuterRings++; + if (outerList == NULL) + throw std::runtime_error("Unable to allocate list of outer rings."); + for (int k = 0; k < shape->numlines; k++) { + if (outerList[k] == MS_TRUE) + numOuterRings++; } - if(numOuterRings == 1) { + if (numOuterRings == 1) { geometry["type"] = "Polygon"; geometry["coordinates"] = json::array(); - for(int i=0; inumlines; i++) { + for (int i = 0; i < shape->numlines; i++) { json part = json::array(); - for(int j=0; jline[i].numpoints; j++) { - part.push_back( { round_up(shape->line[i].point[j].x, precision), round_up(shape->line[i].point[j].y, precision) } ); + for (int j = 0; j < shape->line[i].numpoints; j++) { + part.push_back({round_up(shape->line[i].point[j].x, precision), + round_up(shape->line[i].point[j].y, precision)}); } geometry["coordinates"].push_back(part); } @@ -462,20 +462,25 @@ static json getFeatureGeometry(shapeObj *shape, int precision) geometry["type"] = "MultiPolygon"; geometry["coordinates"] = json::array(); - for(int k=0; knumlines; k++) { - if(outerList[k] == MS_TRUE) { // outer ring: generate polygon and add to coordinates + for (int k = 0; k < shape->numlines; k++) { + if (outerList[k] == + MS_TRUE) { // outer ring: generate polygon and add to coordinates int *innerList = msGetInnerList(shape, k, outerList); - if(innerList == NULL) { + if (innerList == NULL) { msFree(outerList); throw std::runtime_error("Unable to allocate list of inner rings."); } json polygon = json::array(); - for(int i=0; inumlines; i++) { - if(i == k || outerList[i] == MS_TRUE) { // add outer ring (k) and any inner rings + for (int i = 0; i < shape->numlines; i++) { + if (i == k || + outerList[i] == + MS_TRUE) { // add outer ring (k) and any inner rings json part = json::array(); - for(int j=0; jline[i].numpoints; j++) { - part.push_back( { round_up(shape->line[i].point[j].x, precision), round_up(shape->line[i].point[j].y, precision) } ); + for (int j = 0; j < shape->line[i].numpoints; j++) { + part.push_back( + {round_up(shape->line[i].point[j].x, precision), + round_up(shape->line[i].point[j].y, precision)}); } polygon.push_back(part); } @@ -499,55 +504,61 @@ static json getFeatureGeometry(shapeObj *shape, int precision) /* ** Return a GeoJSON representation of a shape. */ -static json getFeature(layerObj *layer, shapeObj *shape, gmlItemListObj *items, gmlConstantListObj *constants, int geometry_precision) -{ +static json getFeature(layerObj *layer, shapeObj *shape, gmlItemListObj *items, + gmlConstantListObj *constants, int geometry_precision) { int i; json feature; // empty (null) - if(!layer || !shape) throw std::runtime_error("Null arguments."); + if (!layer || !shape) + throw std::runtime_error("Null arguments."); // initialize - feature = { - { "type", "Feature" }, - { "properties", json::object() } - }; + feature = {{"type", "Feature"}, {"properties", json::object()}}; // id - const char *featureIdItem = msOWSLookupMetadata(&(layer->metadata), "AGFO", "featureid"); - if(featureIdItem == NULL) throw std::runtime_error("Missing required featureid metadata."); // should have been trapped earlier - for(i=0; inumitems; i++) { - if(strcasecmp(featureIdItem, items->items[i].name) == 0) { + const char *featureIdItem = + msOWSLookupMetadata(&(layer->metadata), "AGFO", "featureid"); + if (featureIdItem == NULL) + throw std::runtime_error( + "Missing required featureid metadata."); // should have been trapped + // earlier + for (i = 0; i < items->numitems; i++) { + if (strcasecmp(featureIdItem, items->items[i].name) == 0) { feature["id"] = shape->values[i]; break; } } - if(i == items->numitems) throw std::runtime_error("Feature id not found."); + if (i == items->numitems) + throw std::runtime_error("Feature id not found."); // properties - build from items and constants, no group support for now - for(int i=0; inumitems; i++) { + for (int i = 0; i < items->numitems; i++) { try { json item = getFeatureItem(&(items->items[i]), shape->values[i]); - if(!item.is_null()) feature["properties"].insert(item.begin(), item.end()); + if (!item.is_null()) + feature["properties"].insert(item.begin(), item.end()); } catch (const std::runtime_error &) { throw std::runtime_error("Error fetching item."); } } - for(int i=0; inumconstants; i++) { + for (int i = 0; i < constants->numconstants; i++) { try { json constant = getFeatureConstant(&(constants->constants[i])); - if(!constant.is_null()) feature["properties"].insert(constant.begin(), constant.end()); + if (!constant.is_null()) + feature["properties"].insert(constant.begin(), constant.end()); } catch (const std::runtime_error &) { - throw std::runtime_error("Error fetching constant."); + throw std::runtime_error("Error fetching constant."); } } // geometry try { json geometry = getFeatureGeometry(shape, geometry_precision); - if(!geometry.is_null()) feature["geometry"] = geometry; + if (!geometry.is_null()) + feature["geometry"] = geometry; } catch (const std::runtime_error &) { throw std::runtime_error("Error fetching geometry."); } @@ -555,72 +566,85 @@ static json getFeature(layerObj *layer, shapeObj *shape, gmlItemListObj *items, return feature; } -static json getLink(hashTableObj *metadata, const std::string& name) -{ +static json getLink(hashTableObj *metadata, const std::string &name) { json link; - const char *href = msOWSLookupMetadata(metadata, "A", (name + "_href").c_str()); - if(!href) throw std::runtime_error("Missing required link href property."); + const char *href = + msOWSLookupMetadata(metadata, "A", (name + "_href").c_str()); + if (!href) + throw std::runtime_error("Missing required link href property."); - const char *title = msOWSLookupMetadata(metadata, "A", (name + "_title").c_str()); - const char *type = msOWSLookupMetadata(metadata, "A", (name + "_type").c_str()); + const char *title = + msOWSLookupMetadata(metadata, "A", (name + "_title").c_str()); + const char *type = + msOWSLookupMetadata(metadata, "A", (name + "_type").c_str()); - link = { - { "href", href }, - { "title", title?title:href }, - { "type", type?type:"text/html" } - }; + link = {{"href", href}, + {"title", title ? title : href}, + {"type", type ? type : "text/html"}}; return link; } -static const char* getCollectionDescription(layerObj* layer) -{ - const char *description = msOWSLookupMetadata(&(layer->metadata), "A", "description"); - if(!description) description = msOWSLookupMetadata(&(layer->metadata), "OF", "abstract"); // fallback on abstract - if(!description) description = ""; // finally a warning... +static const char *getCollectionDescription(layerObj *layer) { + const char *description = + msOWSLookupMetadata(&(layer->metadata), "A", "description"); + if (!description) + description = msOWSLookupMetadata(&(layer->metadata), "OF", + "abstract"); // fallback on abstract + if (!description) + description = + ""; // finally + // a + // warning... return description; } -static const char* getCollectionTitle(layerObj* layer) -{ - const char* title = msOWSLookupMetadata(&(layer->metadata), "AOF", "title"); - if(!title) title = layer->name; // revert to layer name if no title found - return title; +static const char *getCollectionTitle(layerObj *layer) { + const char *title = msOWSLookupMetadata(&(layer->metadata), "AOF", "title"); + if (!title) + title = layer->name; // revert to layer name if no title found + return title; } -static int getGeometryPrecision(mapObj *map, layerObj *layer) -{ - int geometry_precision = OGCAPI_DEFAULT_GEOMETRY_PRECISION; - if(msOWSLookupMetadata(&(layer->metadata), "AF", "geometry_precision")) { - geometry_precision = atoi(msOWSLookupMetadata(&(layer->metadata), "AF", "geometry_precision")); - } else if(msOWSLookupMetadata(&map->web.metadata, "AF", "geometry_precision")) { - geometry_precision = atoi(msOWSLookupMetadata(&map->web.metadata, "AF", "geometry_precision")); - } - return geometry_precision; +static int getGeometryPrecision(mapObj *map, layerObj *layer) { + int geometry_precision = OGCAPI_DEFAULT_GEOMETRY_PRECISION; + if (msOWSLookupMetadata(&(layer->metadata), "AF", "geometry_precision")) { + geometry_precision = atoi( + msOWSLookupMetadata(&(layer->metadata), "AF", "geometry_precision")); + } else if (msOWSLookupMetadata(&map->web.metadata, "AF", + "geometry_precision")) { + geometry_precision = atoi( + msOWSLookupMetadata(&map->web.metadata, "AF", "geometry_precision")); + } + return geometry_precision; } -static json getCollection(mapObj *map, layerObj *layer, OGCAPIFormat format) -{ +static json getCollection(mapObj *map, layerObj *layer, OGCAPIFormat format) { json collection; // empty (null) rectObj bbox; - if(!map || !layer) return collection; + if (!map || !layer) + return collection; - if(!includeLayer(map, layer)) return collection; + if (!includeLayer(map, layer)) + return collection; // initialize some things std::string api_root = getApiRootUrl(map); - if(msOWSGetLayerExtent(map, layer, "AOF", &bbox) == MS_SUCCESS) { + if (msOWSGetLayerExtent(map, layer, "AOF", &bbox) == MS_SUCCESS) { if (layer->projection.numargs > 0) msOWSProjectToWGS84(&layer->projection, &bbox); else if (map->projection.numargs > 0) msOWSProjectToWGS84(&map->projection, &bbox); else - throw std::runtime_error("Unable to transform bounding box, no projection defined."); + throw std::runtime_error( + "Unable to transform bounding box, no projection defined."); } else { - throw std::runtime_error("Unable to get collection bounding box."); // might be too harsh since extent is optional + throw std::runtime_error( + "Unable to get collection bounding box."); // might be too harsh since + // extent is optional } const char *description = getCollectionDescription(layer); @@ -632,69 +656,64 @@ static json getCollection(mapObj *map, layerObj *layer, OGCAPIFormat format) const int geometry_precision = getGeometryPrecision(map, layer); // build collection object - collection = { - { "id", id }, - { "description", description }, - { "title", title }, - { "extent", { - { "spatial", { - { "bbox", {{ round_down(bbox.minx, geometry_precision), - round_down(bbox.miny, geometry_precision), - round_up(bbox.maxx, geometry_precision), - round_up(bbox.maxy, geometry_precision) }}}, - { "crs", "http://www.opengis.net/def/crs/OGC/1.3/CRS84" } - } - } - } - }, - { "links", { - { - { "rel", format==OGCAPIFormat::JSON?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "This collection as JSON" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "?f=json" } - },{ - { "rel", format==OGCAPIFormat::HTML?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "This collection as HTML" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "?f=html" } - },{ - { "rel", "items" }, - { "type", OGCAPI_MIMETYPE_GEOJSON }, - { "title", "Items for this collection as GeoJSON" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "/items?f=json" } - },{ - { "rel", "items" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "Items for this collection as HTML" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "/items?f=html" } - } - - } - }, - { "itemType", "feature" } - }; + collection = {{"id", id}, + {"description", description}, + {"title", title}, + {"extent", + {{"spatial", + {{"bbox", + {{round_down(bbox.minx, geometry_precision), + round_down(bbox.miny, geometry_precision), + round_up(bbox.maxx, geometry_precision), + round_up(bbox.maxy, geometry_precision)}}}, + {"crs", "http://www.opengis.net/def/crs/OGC/1.3/CRS84"}}}}}, + {"links", + {{{"rel", format == OGCAPIFormat::JSON ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", "This collection as JSON"}, + {"href", api_root + "/collections/" + + std::string(id_encoded) + "?f=json"}}, + {{"rel", format == OGCAPIFormat::HTML ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "This collection as HTML"}, + {"href", api_root + "/collections/" + + std::string(id_encoded) + "?f=html"}}, + {{"rel", "items"}, + {"type", OGCAPI_MIMETYPE_GEOJSON}, + {"title", "Items for this collection as GeoJSON"}, + {"href", api_root + "/collections/" + + std::string(id_encoded) + "/items?f=json"}}, + {{"rel", "items"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "Items for this collection as HTML"}, + {"href", api_root + "/collections/" + + std::string(id_encoded) + "/items?f=html"}} + + }}, + {"itemType", "feature"}}; msFree(id_encoded); // done // handle optional configuration (keywords and links) const char *value = msOWSLookupMetadata(&(layer->metadata), "A", "keywords"); - if(!value) value = msOWSLookupMetadata(&(layer->metadata), "OF", "keywordlist"); // fallback on keywordlist - if(value) { + if (!value) + value = msOWSLookupMetadata(&(layer->metadata), "OF", + "keywordlist"); // fallback on keywordlist + if (value) { std::vector keywords = msStringSplit(value, ','); - for(std::string keyword : keywords) { + for (std::string keyword : keywords) { collection["keywords"].push_back(keyword); } } value = msOWSLookupMetadata(&(layer->metadata), "A", "links"); - if(value) { + if (value) { std::vector names = msStringSplit(value, ','); - for(std::string name : names) { + for (std::string name : names) { try { json link = getLink(&(layer->metadata), name); collection["links"].push_back(link); - } catch(const std::runtime_error &e) { + } catch (const std::runtime_error &e) { throw e; } } @@ -707,8 +726,7 @@ static json getCollection(mapObj *map, layerObj *layer, OGCAPIFormat format) ** Output stuff... */ -static void outputJson(const json& j, const char *mimetype) -{ +static void outputJson(const json &j, const char *mimetype) { std::string js; try { @@ -723,11 +741,11 @@ static void outputJson(const json& j, const char *mimetype) msIO_printf("%s\n", js.c_str()); } -static void outputTemplate(const char *directory, const char *filename, const json& j, const char *mimetype) -{ +static void outputTemplate(const char *directory, const char *filename, + const json &j, const char *mimetype) { std::string _directory(directory); std::string _filename(filename); - Environment env {_directory}; // catch + Environment env{_directory}; // catch // ERB-style instead of Mustache (we'll see) // env.set_expression("<%=", "%>"); @@ -751,16 +769,19 @@ static void outputTemplate(const char *directory, const char *filename, const js msIO_setHeader("Content-Type", "%s", mimetype); msIO_sendHeaders(); - msIO_printf("%s\n", result.c_str()); - } catch(const inja::RenderError &e) { - outputError(OGCAPI_CONFIG_ERROR, "Template rendering error. " + std::string(e.what()) + " (" + std::string(filename) + ")."); + msIO_printf("%s\n", result.c_str()); + } catch (const inja::RenderError &e) { + outputError(OGCAPI_CONFIG_ERROR, "Template rendering error. " + + std::string(e.what()) + " (" + + std::string(filename) + ")."); return; - } - catch (const inja::InjaError& e) { - outputError(OGCAPI_CONFIG_ERROR, "InjaError error. " + std::string(e.what()) + " (" + std::string(filename) + ")." - + " (" + std::string(directory) + ")."); - return; - } catch(...) { + } catch (const inja::InjaError &e) { + outputError(OGCAPI_CONFIG_ERROR, "InjaError error. " + + std::string(e.what()) + " (" + + std::string(filename) + ")." + " (" + + std::string(directory) + ")."); + return; + } catch (...) { outputError(OGCAPI_SERVER_ERROR, "General template handling error."); return; } @@ -769,19 +790,22 @@ static void outputTemplate(const char *directory, const char *filename, const js /* ** Generic response outputr. */ -static void outputResponse(mapObj *map, cgiRequestObj *request, OGCAPIFormat format, const char *filename, const json& response) -{ +static void outputResponse(mapObj *map, cgiRequestObj *request, + OGCAPIFormat format, const char *filename, + const json &response) { const char *path = NULL; char fullpath[MS_MAXPATHLEN]; - if(format == OGCAPIFormat::JSON) { + if (format == OGCAPIFormat::JSON) { outputJson(response, OGCAPI_MIMETYPE_JSON); - } else if(format == OGCAPIFormat::GeoJSON) { + } else if (format == OGCAPIFormat::GeoJSON) { outputJson(response, OGCAPI_MIMETYPE_GEOJSON); - } else if(format == OGCAPIFormat::OpenAPI_V3) { + } else if (format == OGCAPIFormat::OpenAPI_V3) { outputJson(response, OGCAPI_MIMETYPE_OPENAPI_V3); - } else if(format == OGCAPIFormat::HTML) { - if((path = getTemplateDirectory(map, "html_template_directory", "OGCAPI_HTML_TEMPLATE_DIRECTORY")) == NULL) { + } else if (format == OGCAPIFormat::HTML) { + if ((path = getTemplateDirectory(map, "html_template_directory", + "OGCAPI_HTML_TEMPLATE_DIRECTORY")) == + NULL) { outputError(OGCAPI_CONFIG_ERROR, "Template directory not set."); return; // bail } @@ -789,36 +813,39 @@ static void outputResponse(mapObj *map, cgiRequestObj *request, OGCAPIFormat for json j; - j["response"] = response; // nest the response so we could write the whole object in the template + j["response"] = response; // nest the response so we could write the whole + // object in the template // extend the JSON with a few things that we need for templating - j["template"] = { - { "path", json::array() }, - { "params", json::object() }, - { "api_root", getApiRootUrl(map) }, - { "title", getTitle(map) }, - { "tags", json::object() } - }; + j["template"] = {{"path", json::array()}, + {"params", json::object()}, + {"api_root", getApiRootUrl(map)}, + {"title", getTitle(map)}, + {"tags", json::object()}}; // api path - for( int i=0; iapi_path_length; i++ ) + for (int i = 0; i < request->api_path_length; i++) j["template"]["path"].push_back(request->api_path[i]); // parameters (optional) - for( int i=0; iNumParams; i++) { - if(request->ParamValues[i] && strlen(request->ParamValues[i]) > 0) { // skip empty params - j["template"]["params"].update({{ request->ParamNames[i], request->ParamValues[i] }}); + for (int i = 0; i < request->NumParams; i++) { + if (request->ParamValues[i] && + strlen(request->ParamValues[i]) > 0) { // skip empty params + j["template"]["params"].update( + {{request->ParamNames[i], request->ParamValues[i]}}); } } // add custom tags (optional) - const char *tags = msOWSLookupMetadata(&(map->web.metadata), "A", "html_tags"); - if(tags) { + const char *tags = + msOWSLookupMetadata(&(map->web.metadata), "A", "html_tags"); + if (tags) { std::vector names = msStringSplit(tags, ','); - for(std::string name : names) { - const char *value = msOWSLookupMetadata(&(map->web.metadata), "A", ("tag_" + name).c_str()); - if(value) { - j["template"]["tags"].update({{ name, value }}); // add object + for (std::string name : names) { + const char *value = msOWSLookupMetadata(&(map->web.metadata), "A", + ("tag_" + name).c_str()); + if (value) { + j["template"]["tags"].update({{name, value}}); // add object } } } @@ -832,77 +859,72 @@ static void outputResponse(mapObj *map, cgiRequestObj *request, OGCAPIFormat for /* ** Process stuff... */ -static int processLandingRequest(mapObj *map, cgiRequestObj *request, OGCAPIFormat format) -{ +static int processLandingRequest(mapObj *map, cgiRequestObj *request, + OGCAPIFormat format) { json response; // define ambiguous elements - const char *description = msOWSLookupMetadata(&(map->web.metadata), "A", "description"); - if(!description) description = msOWSLookupMetadata(&(map->web.metadata), "OF", "abstract"); // fallback on abstract if necessary + const char *description = + msOWSLookupMetadata(&(map->web.metadata), "A", "description"); + if (!description) + description = + msOWSLookupMetadata(&(map->web.metadata), "OF", + "abstract"); // fallback on abstract if necessary // define api root url std::string api_root = getApiRootUrl(map); // build response object // - consider conditionally excluding links for HTML format - response = { - { "title", getTitle(map) }, - { "description", description?description:"" }, - { "links", { - { - { "rel", format==OGCAPIFormat::JSON?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "This document as JSON" }, - { "href", api_root + "?f=json" } - },{ - { "rel", format==OGCAPIFormat::HTML?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "This document as HTML" }, - { "href", api_root + "?f=html" } - },{ - { "rel", "conformance" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "OCG API conformance classes implemented by this server (JSON)" }, - { "href", api_root + "/conformance?f=json" } - },{ - { "rel", "conformance" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "OCG API conformance classes implemented by this server" }, - { "href", api_root + "/conformance?f=html" } - },{ - { "rel", "data" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "Information about feature collections available from this server (JSON)" }, - { "href", api_root + "/collections?f=json" } - },{ - { "rel", "data" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "Information about feature collections available from this server" }, - { "href", api_root + "/collections?f=html" } - },{ - { "rel", "service-desc" }, - { "type", OGCAPI_MIMETYPE_OPENAPI_V3 }, - { "title", "OpenAPI document" }, - { "href", api_root + "/api?f=json" } - },{ - { "rel", "service-doc" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "API documentation" }, - { "href", api_root + "/api?f=html" } - } - } - } - }; + response = { + {"title", getTitle(map)}, + {"description", description ? description : ""}, + {"links", + {{{"rel", format == OGCAPIFormat::JSON ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", "This document as JSON"}, + {"href", api_root + "?f=json"}}, + {{"rel", format == OGCAPIFormat::HTML ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "This document as HTML"}, + {"href", api_root + "?f=html"}}, + {{"rel", "conformance"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", + "OCG API conformance classes implemented by this server (JSON)"}, + {"href", api_root + "/conformance?f=json"}}, + {{"rel", "conformance"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "OCG API conformance classes implemented by this server"}, + {"href", api_root + "/conformance?f=html"}}, + {{"rel", "data"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", "Information about feature collections available from this " + "server (JSON)"}, + {"href", api_root + "/collections?f=json"}}, + {{"rel", "data"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", + "Information about feature collections available from this server"}, + {"href", api_root + "/collections?f=html"}}, + {{"rel", "service-desc"}, + {"type", OGCAPI_MIMETYPE_OPENAPI_V3}, + {"title", "OpenAPI document"}, + {"href", api_root + "/api?f=json"}}, + {{"rel", "service-doc"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "API documentation"}, + {"href", api_root + "/api?f=html"}}}}}; // handle custom links (optional) const char *links = msOWSLookupMetadata(&(map->web.metadata), "A", "links"); - if(links) { + if (links) { std::vector names = msStringSplit(links, ','); - for(std::string name : names) { + for (std::string name : names) { try { json link = getLink(&(map->web.metadata), name); response["links"].push_back(link); - } catch(const std::runtime_error &e) { + } catch (const std::runtime_error &e) { outputError(OGCAPI_CONFIG_ERROR, std::string(e.what())); return MS_SUCCESS; } @@ -913,29 +935,31 @@ static int processLandingRequest(mapObj *map, cgiRequestObj *request, OGCAPIForm return MS_SUCCESS; } -static int processConformanceRequest(mapObj *map, cgiRequestObj *request, OGCAPIFormat format) -{ +static int processConformanceRequest(mapObj *map, cgiRequestObj *request, + OGCAPIFormat format) { json response; - + // build response object response = { - { "conformsTo", { - "http://www.opengis.net/spec/ogcapi-common-1/1.0/conf/core", - "http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections", - "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core", - "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30", - "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html", - "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson", - } - } - }; - - outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_CONFORMANCE, response); + {"conformsTo", + { + "http://www.opengis.net/spec/ogcapi-common-1/1.0/conf/core", + "http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections", + "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core", + "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30", + "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html", + "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson", + }}}; + + outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_CONFORMANCE, + response); return MS_SUCCESS; } -static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, const char *collectionId, const char *featureId, OGCAPIFormat format) -{ +static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, + const char *collectionId, + const char *featureId, + OGCAPIFormat format) { json response; int i; layerObj *layer; @@ -946,19 +970,20 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co int numberMatched = 0; // find the right layer - for(i=0; inumlayers; i++) { - if(strcmp(map->layers[i]->name, collectionId) == 0) break; // match + for (i = 0; i < map->numlayers; i++) { + if (strcmp(map->layers[i]->name, collectionId) == 0) + break; // match } - if(i == map->numlayers) { // invalid collectionId + if (i == map->numlayers) { // invalid collectionId outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid collection."); return MS_SUCCESS; } layer = map->layers[i]; // for convenience - layer->status = MS_ON; // force on (do we need to save and reset?) + layer->status = MS_ON; // force on (do we need to save and reset?) - if(!includeLayer(map, layer)) { + if (!includeLayer(map, layer)) { outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid collection."); return MS_SUCCESS; } @@ -966,20 +991,21 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co // // handle parameters specific to this endpoint // - if(getLimit(map, request, layer, &limit) != MS_SUCCESS) { + if (getLimit(map, request, layer, &limit) != MS_SUCCESS) { outputError(OGCAPI_PARAM_ERROR, "Bad value for limit."); return MS_SUCCESS; } - if(!getBbox(map, request, &bbox)) { + if (!getBbox(map, request, &bbox)) { outputError(OGCAPI_PARAM_ERROR, "Bad value for bbox."); return MS_SUCCESS; } int offset = 0; - if(featureId) { - const char *featureIdItem = msOWSLookupMetadata(&(layer->metadata), "AGFO", "featureid"); - if(featureIdItem == NULL) { + if (featureId) { + const char *featureIdItem = + msOWSLookupMetadata(&(layer->metadata), "AGFO", "featureid"); + if (featureIdItem == NULL) { outputError(OGCAPI_CONFIG_ERROR, "Missing required featureid metadata."); return MS_SUCCESS; } @@ -987,8 +1013,11 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co // TODO: does featureIdItem exist in the data? // optional validation - const char *featureIdValidation = msLookupHashTable(&(layer->validation), featureIdItem); - if(featureIdValidation && msValidateParameter(featureId, featureIdValidation, NULL, NULL, NULL) != MS_SUCCESS) { + const char *featureIdValidation = + msLookupHashTable(&(layer->validation), featureIdItem); + if (featureIdValidation && + msValidateParameter(featureId, featureIdValidation, NULL, NULL, NULL) != + MS_SUCCESS) { outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid feature id."); return MS_SUCCESS; } @@ -1003,32 +1032,30 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co map->query.filter.type = MS_STRING; map->query.filter.string = strdup(featureId); - if(msExecuteQuery(map) != MS_SUCCESS) { + if (msExecuteQuery(map) != MS_SUCCESS) { outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items id query failed."); return MS_SUCCESS; } - if(!layer->resultcache || layer->resultcache->numresults != 1) { + if (!layer->resultcache || layer->resultcache->numresults != 1) { outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items id query failed."); return MS_SUCCESS; } } else { // bbox query - const char *compliance_mode = msOWSLookupMetadata(&(map->web.metadata), "A", "compliance_mode"); - if(compliance_mode != NULL && strcasecmp(compliance_mode, "true") == 0) { - for(int j=0; jNumParams; j++) { - const char* paramName = request->ParamNames[j]; - if (strcmp(paramName, "f") == 0 || - strcmp(paramName, "bbox") == 0 || + const char *compliance_mode = + msOWSLookupMetadata(&(map->web.metadata), "A", "compliance_mode"); + if (compliance_mode != NULL && strcasecmp(compliance_mode, "true") == 0) { + for (int j = 0; j < request->NumParams; j++) { + const char *paramName = request->ParamNames[j]; + if (strcmp(paramName, "f") == 0 || strcmp(paramName, "bbox") == 0 || strcmp(paramName, "datetime") == 0 || strcmp(paramName, "limit") == 0 || - strcmp(paramName, "offset") == 0) - { + strcmp(paramName, "offset") == 0) { // ok - } - else - { - outputError(OGCAPI_PARAM_ERROR, + } else { + outputError( + OGCAPI_PARAM_ERROR, (std::string("Unknown query parameter: ") + paramName).c_str()); return MS_SUCCESS; } @@ -1042,51 +1069,49 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co map->query.only_cache_result_count = MS_TRUE; // get number matched - if(msExecuteQuery(map) != MS_SUCCESS) { + if (msExecuteQuery(map) != MS_SUCCESS) { outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items query failed."); return MS_SUCCESS; } - if(!layer->resultcache) { + if (!layer->resultcache) { outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items query failed."); return MS_SUCCESS; } numberMatched = layer->resultcache->numresults; - if( numberMatched > 0 ) { - map->query.only_cache_result_count = MS_FALSE; - map->query.maxfeatures = limit; - - const char* offsetStr = getRequestParameter(request, "offset"); - if( offsetStr ) - { - if( msStringToInt(offsetStr, &offset, 10) != MS_SUCCESS ) - { - outputError(OGCAPI_PARAM_ERROR, "Bad value for offset."); - return MS_SUCCESS; - } + if (numberMatched > 0) { + map->query.only_cache_result_count = MS_FALSE; + map->query.maxfeatures = limit; - if(offset < 0 || offset >= numberMatched) { - outputError(OGCAPI_PARAM_ERROR, "Offset out of range."); - return MS_SUCCESS; - } - - // msExecuteQuery() use a 1-based offset convention, whereas the API - // uses a 0-based offset convention. - map->query.startindex = 1 + offset; - layer->startindex = 1 + offset; + const char *offsetStr = getRequestParameter(request, "offset"); + if (offsetStr) { + if (msStringToInt(offsetStr, &offset, 10) != MS_SUCCESS) { + outputError(OGCAPI_PARAM_ERROR, "Bad value for offset."); + return MS_SUCCESS; } - if(msExecuteQuery(map) != MS_SUCCESS) { - outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items query failed."); + if (offset < 0 || offset >= numberMatched) { + outputError(OGCAPI_PARAM_ERROR, "Offset out of range."); return MS_SUCCESS; } + + // msExecuteQuery() use a 1-based offset convention, whereas the API + // uses a 0-based offset convention. + map->query.startindex = 1 + offset; + layer->startindex = 1 + offset; + } + + if (msExecuteQuery(map) != MS_SUCCESS) { + outputError(OGCAPI_NOT_FOUND_ERROR, "Collection items query failed."); + return MS_SUCCESS; + } } } // build response object - if(!featureId) { + if (!featureId) { std::string api_root = getApiRootUrl(map); const char *id = layer->name; char *id_encoded = msEncodeUrl(id); // free after use @@ -1095,49 +1120,46 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co extra_kvp += "&offset=" + std::to_string(offset); response = { - { "type", "FeatureCollection" }, - { "numberMatched", numberMatched }, - { "numberReturned", layer->resultcache->numresults }, - { "features", json::array() }, - { "links", { - { - { "rel", format==OGCAPIFormat::JSON?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_GEOJSON }, - { "title", "Items for this collection as GeoJSON" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "/items?f=json" + extra_kvp } - },{ - { "rel", format==OGCAPIFormat::HTML?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "Items for this collection as HTML" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "/items?f=html" + extra_kvp } - } - }} - }; - - if( offset + layer->resultcache->numresults < numberMatched ) - { - response["links"].push_back({ - { "rel", "next" }, - { "type", format==OGCAPIFormat::JSON? OGCAPI_MIMETYPE_GEOJSON : OGCAPI_MIMETYPE_HTML }, - { "title", "next page" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + - "/items?f=" + (format==OGCAPIFormat::JSON? "json" : "html") + - "&limit=" + std::to_string(limit) + - "&offset=" + std::to_string(offset + limit) } - }); + {"type", "FeatureCollection"}, + {"numberMatched", numberMatched}, + {"numberReturned", layer->resultcache->numresults}, + {"features", json::array()}, + {"links", + {{{"rel", format == OGCAPIFormat::JSON ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_GEOJSON}, + {"title", "Items for this collection as GeoJSON"}, + {"href", api_root + "/collections/" + std::string(id_encoded) + + "/items?f=json" + extra_kvp}}, + {{"rel", format == OGCAPIFormat::HTML ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "Items for this collection as HTML"}, + {"href", api_root + "/collections/" + std::string(id_encoded) + + "/items?f=html" + extra_kvp}}}}}; + + if (offset + layer->resultcache->numresults < numberMatched) { + response["links"].push_back( + {{"rel", "next"}, + {"type", format == OGCAPIFormat::JSON ? OGCAPI_MIMETYPE_GEOJSON + : OGCAPI_MIMETYPE_HTML}, + {"title", "next page"}, + {"href", + api_root + "/collections/" + std::string(id_encoded) + + "/items?f=" + (format == OGCAPIFormat::JSON ? "json" : "html") + + "&limit=" + std::to_string(limit) + + "&offset=" + std::to_string(offset + limit)}}); } - if( offset > 0 ) - { - response["links"].push_back({ - { "rel", "prev" }, - { "type", format==OGCAPIFormat::JSON? OGCAPI_MIMETYPE_GEOJSON : OGCAPI_MIMETYPE_HTML }, - { "title", "previous page" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + - "/items?f=" + (format==OGCAPIFormat::JSON? "json" : "html") + - "&limit=" + std::to_string(limit) + - "&offset=" + std::to_string(MS_MAX(0, (offset - limit))) } - }); + if (offset > 0) { + response["links"].push_back( + {{"rel", "prev"}, + {"type", format == OGCAPIFormat::JSON ? OGCAPI_MIMETYPE_GEOJSON + : OGCAPI_MIMETYPE_HTML}, + {"title", "previous page"}, + {"href", + api_root + "/collections/" + std::string(id_encoded) + + "/items?f=" + (format == OGCAPIFormat::JSON ? "json" : "html") + + "&limit=" + std::to_string(limit) + + "&offset=" + std::to_string(MS_MAX(0, (offset - limit)))}}); } msFree(id_encoded); // done @@ -1152,10 +1174,11 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co gmlItemListObj *items = msGMLGetItems(layer, "AG"); gmlConstantListObj *constants = msGMLGetConstants(layer, "AG"); - if(!items || !constants) { + if (!items || !constants) { msGMLFreeItems(items); msGMLFreeConstants(constants); - outputError(OGCAPI_SERVER_ERROR, "Error fetching layer attribute metadata."); + outputError(OGCAPI_SERVER_ERROR, + "Error fetching layer attribute metadata."); return MS_SUCCESS; } @@ -1163,34 +1186,38 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co // reprojection to EPSG:4326 (if necessary) reprojectionObj *reprojector = NULL; - if(layer->projection.numargs > 0) { - if(msProjectionsDiffer(&(layer->projection), &(map->latlon))) { - reprojector = msProjectCreateReprojector(&(layer->projection), &(map->latlon)); - if(reprojector == NULL) { + if (layer->projection.numargs > 0) { + if (msProjectionsDiffer(&(layer->projection), &(map->latlon))) { + reprojector = + msProjectCreateReprojector(&(layer->projection), &(map->latlon)); + if (reprojector == NULL) { msGMLFreeItems(items); msGMLFreeConstants(constants); outputError(OGCAPI_SERVER_ERROR, "Error creating re-projector."); return MS_SUCCESS; } } - } else if(map->projection.numargs > 0) { - if(msProjectionsDiffer(&(map->projection), &(map->latlon))) { - reprojector = msProjectCreateReprojector(&(map->projection), &(map->latlon)); - if(reprojector == NULL) { - msGMLFreeItems(items); + } else if (map->projection.numargs > 0) { + if (msProjectionsDiffer(&(map->projection), &(map->latlon))) { + reprojector = + msProjectCreateReprojector(&(map->projection), &(map->latlon)); + if (reprojector == NULL) { + msGMLFreeItems(items); msGMLFreeConstants(constants); - outputError(OGCAPI_SERVER_ERROR, "Error creating re-projector."); + outputError(OGCAPI_SERVER_ERROR, "Error creating re-projector."); return MS_SUCCESS; } } } else { - outputError(OGCAPI_CONFIG_ERROR, "Unable to transform geometries, no projection defined."); + outputError(OGCAPI_CONFIG_ERROR, + "Unable to transform geometries, no projection defined."); return MS_SUCCESS; } - for(i=0; iresultcache->numresults; i++) { - int status = msLayerGetShape(layer, &shape, &(layer->resultcache->results[i])); - if(status != MS_SUCCESS) { + for (i = 0; i < layer->resultcache->numresults; i++) { + int status = + msLayerGetShape(layer, &shape, &(layer->resultcache->results[i])); + if (status != MS_SUCCESS) { msGMLFreeItems(items); msGMLFreeConstants(constants); msProjectDestroyReprojector(reprojector); @@ -1198,9 +1225,9 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co return MS_SUCCESS; } - if(reprojector) { + if (reprojector) { status = msProjectShapeEx(reprojector, &shape); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msGMLFreeItems(items); msGMLFreeConstants(constants); msProjectDestroyReprojector(reprojector); @@ -1211,8 +1238,9 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co } try { - json feature = getFeature(layer, &shape, items, constants, geometry_precision); - if(featureId) { + json feature = + getFeature(layer, &shape, items, constants, geometry_precision); + if (featureId) { response = feature; } else { response["features"].push_back(feature); @@ -1222,7 +1250,8 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co msGMLFreeConstants(constants); msProjectDestroyReprojector(reprojector); msFreeShape(&shape); - outputError(OGCAPI_SERVER_ERROR, "Error getting feature. " + std::string(e.what())); + outputError(OGCAPI_SERVER_ERROR, + "Error getting feature. " + std::string(e.what())); return MS_SUCCESS; } @@ -1235,87 +1264,84 @@ static int processCollectionItemsRequest(mapObj *map, cgiRequestObj *request, co } // extend the response a bit for templating (HERE) - if(format == OGCAPIFormat::HTML) { + if (format == OGCAPIFormat::HTML) { const char *title = getCollectionTitle(layer); const char *id = layer->name; - response["collection"] = { - { "id", id }, - { "title", title?title:"" } - }; + response["collection"] = {{"id", id}, {"title", title ? title : ""}}; } - if(featureId) - { + if (featureId) { std::string api_root = getApiRootUrl(map); const char *id = layer->name; char *id_encoded = msEncodeUrl(id); // free after use response["links"] = { - { - { "rel", format==OGCAPIFormat::JSON?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_GEOJSON }, - { "title", "This document as GeoJSON" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + - "/items/" + featureId + "?f=json" } - },{ - { "rel", format==OGCAPIFormat::HTML?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "This document as HTML" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + - "/items/" + featureId + "?f=html" } - },{ - { "rel", "collection" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "This collection as JSON" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "?f=json" } - },{ - { "rel", "collection" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "This collection as HTML" }, - { "href", api_root + "/collections/" + std::string(id_encoded) + "?f=html" } - } - }; + {{"rel", format == OGCAPIFormat::JSON ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_GEOJSON}, + {"title", "This document as GeoJSON"}, + {"href", api_root + "/collections/" + std::string(id_encoded) + + "/items/" + featureId + "?f=json"}}, + {{"rel", format == OGCAPIFormat::HTML ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "This document as HTML"}, + {"href", api_root + "/collections/" + std::string(id_encoded) + + "/items/" + featureId + "?f=html"}}, + {{"rel", "collection"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", "This collection as JSON"}, + {"href", + api_root + "/collections/" + std::string(id_encoded) + "?f=json"}}, + {{"rel", "collection"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "This collection as HTML"}, + {"href", + api_root + "/collections/" + std::string(id_encoded) + "?f=html"}}}; msFree(id_encoded); - outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION_ITEM, response); - } - else - outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION_ITEMS, response); + outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION_ITEM, + response); + } else + outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION_ITEMS, + response); return MS_SUCCESS; } -static int processCollectionRequest(mapObj *map, cgiRequestObj *request, const char *collectionId, OGCAPIFormat format) -{ +static int processCollectionRequest(mapObj *map, cgiRequestObj *request, + const char *collectionId, + OGCAPIFormat format) { json response; int l; - for(l=0; lnumlayers; l++) { - if(strcmp(map->layers[l]->name, collectionId) == 0) break; // match + for (l = 0; l < map->numlayers; l++) { + if (strcmp(map->layers[l]->name, collectionId) == 0) + break; // match } - if(l == map->numlayers) { // invalid collectionId + if (l == map->numlayers) { // invalid collectionId outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid collection."); return MS_SUCCESS; } try { response = getCollection(map, map->layers[l], format); - if(response.is_null()) { // same as not found + if (response.is_null()) { // same as not found outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid collection."); return MS_SUCCESS; } } catch (const std::runtime_error &e) { - outputError(OGCAPI_CONFIG_ERROR, "Error getting collection. " + std::string(e.what())); + outputError(OGCAPI_CONFIG_ERROR, + "Error getting collection. " + std::string(e.what())); return MS_SUCCESS; } - outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION, response); + outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTION, + response); return MS_SUCCESS; } -static int processCollectionsRequest(mapObj *map, cgiRequestObj *request, OGCAPIFormat format) -{ +static int processCollectionsRequest(mapObj *map, cgiRequestObj *request, + OGCAPIFormat format) { json response; int i; @@ -1323,297 +1349,326 @@ static int processCollectionsRequest(mapObj *map, cgiRequestObj *request, OGCAPI std::string api_root = getApiRootUrl(map); // build response object - response = { - { "links", { - { - { "rel", format==OGCAPIFormat::JSON?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_JSON }, - { "title", "This document as JSON" }, - { "href", api_root + "/collections?f=json" } - },{ - { "rel", format==OGCAPIFormat::HTML?"self":"alternate" }, - { "type", OGCAPI_MIMETYPE_HTML }, - { "title", "This document as HTML" }, - { "href", api_root + "/collections?f=html" } - } - } - },{ - "collections", json::array() - } - }; - - for(i=0; inumlayers; i++) { + response = {{"links", + {{{"rel", format == OGCAPIFormat::JSON ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_JSON}, + {"title", "This document as JSON"}, + {"href", api_root + "/collections?f=json"}}, + {{"rel", format == OGCAPIFormat::HTML ? "self" : "alternate"}, + {"type", OGCAPI_MIMETYPE_HTML}, + {"title", "This document as HTML"}, + {"href", api_root + "/collections?f=html"}}}}, + {"collections", json::array()}}; + + for (i = 0; i < map->numlayers; i++) { try { json collection = getCollection(map, map->layers[i], format); - if(!collection.is_null()) response["collections"].push_back(collection); + if (!collection.is_null()) + response["collections"].push_back(collection); } catch (const std::runtime_error &e) { - outputError(OGCAPI_CONFIG_ERROR, "Error getting collection." + std::string(e.what())); + outputError(OGCAPI_CONFIG_ERROR, + "Error getting collection." + std::string(e.what())); return MS_SUCCESS; } } - outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTIONS, response); + outputResponse(map, request, format, OGCAPI_TEMPLATE_HTML_COLLECTIONS, + response); return MS_SUCCESS; } -static int processApiRequest(mapObj *map, cgiRequestObj *request, OGCAPIFormat format) -{ - // Strongly inspired from https://github.com/geopython/pygeoapi/blob/master/pygeoapi/openapi.py +static int processApiRequest(mapObj *map, cgiRequestObj *request, + OGCAPIFormat format) { + // Strongly inspired from + // https://github.com/geopython/pygeoapi/blob/master/pygeoapi/openapi.py json response; response = { - { "openapi", "3.0.2" }, - { "tags", json::array() }, + {"openapi", "3.0.2"}, + {"tags", json::array()}, }; response["info"] = { - { "title", getTitle(map) }, - { "version", getWebMetadata(map, "A", "version", "1.0.0") }, + {"title", getTitle(map)}, + {"version", getWebMetadata(map, "A", "version", "1.0.0")}, }; - for( const char* item: { "description", "termsOfService" }) { - const char* value = getWebMetadata(map, "AO", item, nullptr); - if( value ) { - response["info"][item] = value; - } + for (const char *item : {"description", "termsOfService"}) { + const char *value = getWebMetadata(map, "AO", item, nullptr); + if (value) { + response["info"][item] = value; + } } - for( const auto& pair: { - std::make_pair("name", "contactperson"), - std::make_pair("url", "contacturl"), - std::make_pair("email", "contactelectronicmailaddress"), - }) { - const char* value = getWebMetadata(map, "AO", pair.second, nullptr); - if( value ) { - response["info"]["contact"][pair.first] = value; - } + for (const auto &pair : { + std::make_pair("name", "contactperson"), + std::make_pair("url", "contacturl"), + std::make_pair("email", "contactelectronicmailaddress"), + }) { + const char *value = getWebMetadata(map, "AO", pair.second, nullptr); + if (value) { + response["info"]["contact"][pair.first] = value; + } } - for( const auto& pair: { - std::make_pair("name", "licensename"), - std::make_pair("url", "licenseurl"), - }) { - const char* value = getWebMetadata(map, "AO", pair.second, nullptr); - if( value ) { - response["info"]["license"][pair.first] = value; - } + for (const auto &pair : { + std::make_pair("name", "licensename"), + std::make_pair("url", "licenseurl"), + }) { + const char *value = getWebMetadata(map, "AO", pair.second, nullptr); + if (value) { + response["info"]["license"][pair.first] = value; + } } { - const char* value = getWebMetadata(map, "AO", "keywords", nullptr); - if( value ) { - response["info"]["x-keywords"] = value; - } + const char *value = getWebMetadata(map, "AO", "keywords", nullptr); + if (value) { + response["info"]["x-keywords"] = value; + } } json server; server["url"] = getApiRootUrl(map); { - const char* value = getWebMetadata(map, "AO", "server_description", nullptr); - if( value ) { - server["description"] = value; - } + const char *value = + getWebMetadata(map, "AO", "server_description", nullptr); + if (value) { + server["description"] = value; + } } response["servers"].push_back(server); - const std::string oapif_yaml_url = "http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml"; + const std::string oapif_yaml_url = + "http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/" + "ogcapi-features-1.yaml"; json paths; paths["/"]["get"] = { - { "summary", "Landing page" }, - { "description", "Landing page" }, - { "tags", { "server" } }, - { "operationId", "getLandingPage" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/LandingPage"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; + {"summary", "Landing page"}, + {"description", "Landing page"}, + {"tags", {"server"}}, + {"operationId", "getLandingPage"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + }}, + {"responses", + {{"200", + {{"$ref", oapif_yaml_url + "#/components/responses/LandingPage"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"500", + {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; paths["/api"]["get"] = { - { "summary", "API documentation" }, - { "description", "API documentation" }, - { "tags", { "server" } }, - { "operationId", "getOpenapi" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - }}, - { "responses", { - { "200", {{"$ref", "#/components/responses/200"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "default", {{"$ref", "#/components/responses/default"}} } - }} - }; + {"summary", "API documentation"}, + {"description", "API documentation"}, + {"tags", {"server"}}, + {"operationId", "getOpenapi"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + }}, + {"responses", + {{"200", {{"$ref", "#/components/responses/200"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"default", {{"$ref", "#/components/responses/default"}}}}}}; paths["/conformance"]["get"] = { - { "summary", "API conformance definition" }, - { "description", "API conformance definition" }, - { "tags", { "server" } }, - { "operationId", "getConformanceDeclaration" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/ConformanceDeclaration"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; + {"summary", "API conformance definition"}, + {"description", "API conformance definition"}, + {"tags", {"server"}}, + {"operationId", "getConformanceDeclaration"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + }}, + {"responses", + {{"200", + {{"$ref", + oapif_yaml_url + "#/components/responses/ConformanceDeclaration"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"500", + {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; paths["/collections"]["get"] = { - { "summary", "Collections" }, - { "description", "Collections" }, - { "tags", { "server" } }, - { "operationId", "getCollections" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/Collections"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; - - for(int i=0; inumlayers; i++) { - layerObj* layer = map->layers[i]; - if(!includeLayer(map, layer)) { - continue; - } + {"summary", "Collections"}, + {"description", "Collections"}, + {"tags", {"server"}}, + {"operationId", "getCollections"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + }}, + {"responses", + {{"200", + {{"$ref", oapif_yaml_url + "#/components/responses/Collections"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"500", + {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; + + for (int i = 0; i < map->numlayers; i++) { + layerObj *layer = map->layers[i]; + if (!includeLayer(map, layer)) { + continue; + } - json collection_get = { - { "summary", std::string("Get ") + getCollectionTitle(layer) + " metadata" }, - { "description", getCollectionDescription(layer) }, - { "tags", { layer->name } }, - { "operationId", "describe" + std::string(layer->name) + "Collection" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/Collection"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; - - std::string collectionNamePath("/collections/"); - collectionNamePath += layer->name; - paths[collectionNamePath]["get"] = collection_get; - - // check metadata, layer then map - const char* max_limit_str = msOWSLookupMetadata(&(layer->metadata), "A", "max_limit"); - if(max_limit_str == nullptr) - max_limit_str = msOWSLookupMetadata(&(map->web.metadata), "A", "max_limit"); - const int max_limit = max_limit_str ? atoi(max_limit_str) : OGCAPI_MAX_LIMIT; - const int default_limit = getDefaultLimit(map, layer); - - json items_get = { - { "summary", std::string("Get ") + getCollectionTitle(layer) + " items" }, - { "description", getCollectionDescription(layer) }, - { "tags", { layer->name } }, - { "operationId", "get" + std::string(layer->name) + "Features" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - {{ "$ref", oapif_yaml_url + "#/components/parameters/bbox"}}, - {{ "$ref", oapif_yaml_url + "#/components/parameters/datetime"}}, - {{ "$ref", "#/components/parameters/offset"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/Features"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; - - json param_limit = { - { "name", "limit"}, - { "in", "query"}, - { "description", "The optional limit parameter limits the number of items that are presented in the response document."}, - { "required", false}, - { "schema", { - { "type", "integer"}, - { "minimum", 1}, - { "maximum", max_limit}, - { "default", default_limit}, - }}, - { "style", "form" }, - { "explode", false }, - }; - items_get["parameters"].emplace_back(param_limit); - - std::string itemsPath(collectionNamePath + "/items"); - paths[itemsPath]["get"] = items_get; - - json feature_id_get = { - { "summary", std::string("Get ") + getCollectionTitle(layer) + " item by id" }, - { "description", getCollectionDescription(layer) }, - { "tags", { layer->name } }, - { "operationId", "get" + std::string(layer->name) + "Feature" }, - { "parameters", { - {{ "$ref", "#/components/parameters/f"}}, - {{ "$ref", oapif_yaml_url + "#/components/parameters/featureId"}}, - }}, - { "responses", { - { "200", {{"$ref", oapif_yaml_url + "#/components/responses/Feature"}} }, - { "400", {{"$ref", oapif_yaml_url + "#/components/responses/InvalidParameter"}} }, - { "404", {{"$ref", oapif_yaml_url + "#/components/responses/NotFound"}} }, - { "500", {{"$ref", oapif_yaml_url + "#/components/responses/ServerError"}} } - }} - }; - std::string itemsFeatureIdPath(collectionNamePath + "/items/{featureId}"); - paths[itemsFeatureIdPath]["get"] = feature_id_get; + json collection_get = { + {"summary", + std::string("Get ") + getCollectionTitle(layer) + " metadata"}, + {"description", getCollectionDescription(layer)}, + {"tags", {layer->name}}, + {"operationId", "describe" + std::string(layer->name) + "Collection"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + }}, + {"responses", + {{"200", + {{"$ref", oapif_yaml_url + "#/components/responses/Collection"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"500", + {{"$ref", + oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; + + std::string collectionNamePath("/collections/"); + collectionNamePath += layer->name; + paths[collectionNamePath]["get"] = collection_get; + + // check metadata, layer then map + const char *max_limit_str = + msOWSLookupMetadata(&(layer->metadata), "A", "max_limit"); + if (max_limit_str == nullptr) + max_limit_str = + msOWSLookupMetadata(&(map->web.metadata), "A", "max_limit"); + const int max_limit = + max_limit_str ? atoi(max_limit_str) : OGCAPI_MAX_LIMIT; + const int default_limit = getDefaultLimit(map, layer); + + json items_get = { + {"summary", std::string("Get ") + getCollectionTitle(layer) + " items"}, + {"description", getCollectionDescription(layer)}, + {"tags", {layer->name}}, + {"operationId", "get" + std::string(layer->name) + "Features"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + {{"$ref", oapif_yaml_url + "#/components/parameters/bbox"}}, + {{"$ref", oapif_yaml_url + "#/components/parameters/datetime"}}, + {{"$ref", "#/components/parameters/offset"}}, + }}, + {"responses", + {{"200", + {{"$ref", oapif_yaml_url + "#/components/responses/Features"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"500", + {{"$ref", + oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; + + json param_limit = { + {"name", "limit"}, + {"in", "query"}, + {"description", "The optional limit parameter limits the number of " + "items that are presented in the response document."}, + {"required", false}, + {"schema", + { + {"type", "integer"}, + {"minimum", 1}, + {"maximum", max_limit}, + {"default", default_limit}, + }}, + {"style", "form"}, + {"explode", false}, + }; + items_get["parameters"].emplace_back(param_limit); + + std::string itemsPath(collectionNamePath + "/items"); + paths[itemsPath]["get"] = items_get; + + json feature_id_get = { + {"summary", + std::string("Get ") + getCollectionTitle(layer) + " item by id"}, + {"description", getCollectionDescription(layer)}, + {"tags", {layer->name}}, + {"operationId", "get" + std::string(layer->name) + "Feature"}, + {"parameters", + { + {{"$ref", "#/components/parameters/f"}}, + {{"$ref", oapif_yaml_url + "#/components/parameters/featureId"}}, + }}, + {"responses", + {{"200", + {{"$ref", oapif_yaml_url + "#/components/responses/Feature"}}}, + {"400", + {{"$ref", + oapif_yaml_url + "#/components/responses/InvalidParameter"}}}, + {"404", + {{"$ref", oapif_yaml_url + "#/components/responses/NotFound"}}}, + {"500", + {{"$ref", + oapif_yaml_url + "#/components/responses/ServerError"}}}}}}; + std::string itemsFeatureIdPath(collectionNamePath + "/items/{featureId}"); + paths[itemsFeatureIdPath]["get"] = feature_id_get; } response["paths"] = paths; json components; - components["responses"]["200"] = { - { "description", "successful operation" } - }; + components["responses"]["200"] = {{"description", "successful operation"}}; components["responses"]["default"] = { - { "description", "unexpected error" }, - { "content", { - { "application/json", { - { "schema", { - { "$ref", "https://raw.githubusercontent.com/opengeospatial/ogcapi-processes/master/core/openapi/schemas/exception.yaml" } - }} - }} - }} - }; + {"description", "unexpected error"}, + {"content", + {{"application/json", + {{"schema", + {{"$ref", "https://raw.githubusercontent.com/opengeospatial/" + "ogcapi-processes/master/core/openapi/schemas/" + "exception.yaml"}}}}}}}}; json parameters; parameters["f"] = { - { "name", "f"}, - { "in", "query"}, - { "description", "The optional f parameter indicates the output format which the server shall provide as part of the response document. The default format is GeoJSON."}, - { "required", false}, - { "schema", { - { "type", "string"}, - {"enum", {"json", "html"}}, - {"default", "json"} - }}, - { "style", "form" }, - { "explode", false }, + {"name", "f"}, + {"in", "query"}, + {"description", "The optional f parameter indicates the output format " + "which the server shall provide as part of the response " + "document. The default format is GeoJSON."}, + {"required", false}, + {"schema", + {{"type", "string"}, {"enum", {"json", "html"}}, {"default", "json"}}}, + {"style", "form"}, + {"explode", false}, }; parameters["offset"] = { - { "name", "offset"}, - { "in", "query"}, - { "description", "The optional offset parameter indicates the index within the result set from which the server shall begin presenting results in the response document. The first element has an index of 0 (default)."}, - { "required", false}, - { "schema", { - { "type", "integer"}, - { "minimum", 0}, - { "default", 0}, - }}, - { "style", "form" }, - { "explode", false }, + {"name", "offset"}, + {"in", "query"}, + {"description", + "The optional offset parameter indicates the index within the result " + "set from which the server shall begin presenting results in the " + "response document. The first element has an index of 0 (default)."}, + {"required", false}, + {"schema", + { + {"type", "integer"}, + {"minimum", 0}, + {"default", 0}, + }}, + {"style", "form"}, + {"explode", false}, }; components["parameters"] = parameters; @@ -1623,21 +1678,22 @@ static int processApiRequest(mapObj *map, cgiRequestObj *request, OGCAPIFormat f // TODO: "tags" array ? outputResponse(map, request, - format == OGCAPIFormat::JSON ? OGCAPIFormat::OpenAPI_V3 : format, + format == OGCAPIFormat::JSON ? OGCAPIFormat::OpenAPI_V3 + : format, OGCAPI_TEMPLATE_HTML_OPENAPI, response); return MS_SUCCESS; } #endif -int msOGCAPIDispatchRequest(mapObj *map, cgiRequestObj *request) -{ +int msOGCAPIDispatchRequest(mapObj *map, cgiRequestObj *request) { #ifdef USE_OGCAPI_SVR // make sure ogcapi requests are enabled for this map int status = msOWSRequestIsEnabled(map, NULL, "AO", "OGCAPI", MS_FALSE); - if(status != MS_TRUE) { - msSetError(MS_OGCAPIERR, "OGC API requests are not enabled.", "msCGIDispatchAPIRequest()"); + if (status != MS_TRUE) { + msSetError(MS_OGCAPIERR, "OGC API requests are not enabled.", + "msCGIDispatchAPIRequest()"); return MS_FAILURE; // let normal error handling take over } @@ -1645,27 +1701,25 @@ int msOGCAPIDispatchRequest(mapObj *map, cgiRequestObj *request) const char *p = getRequestParameter(request, "f"); // if f= query parameter is not specified, use HTTP Accept header if available - if( p == nullptr ) - { - const char* accept = getenv("HTTP_ACCEPT"); - if( accept ) - { - if( strcmp(accept, "*/*") == 0 ) - p = OGCAPI_MIMETYPE_JSON; - else - p = accept; - } + if (p == nullptr) { + const char *accept = getenv("HTTP_ACCEPT"); + if (accept) { + if (strcmp(accept, "*/*") == 0) + p = OGCAPI_MIMETYPE_JSON; + else + p = accept; + } } - if(p && (strcmp(p, "json") == 0 || - strstr(p, OGCAPI_MIMETYPE_JSON) != nullptr || - strstr(p, OGCAPI_MIMETYPE_GEOJSON) != nullptr || - strstr(p, OGCAPI_MIMETYPE_OPENAPI_V3) != nullptr)) { + if (p && + (strcmp(p, "json") == 0 || strstr(p, OGCAPI_MIMETYPE_JSON) != nullptr || + strstr(p, OGCAPI_MIMETYPE_GEOJSON) != nullptr || + strstr(p, OGCAPI_MIMETYPE_OPENAPI_V3) != nullptr)) { format = OGCAPIFormat::JSON; - } else if(p && (strcmp(p, "html") == 0 || - strstr(p, OGCAPI_MIMETYPE_HTML) != nullptr)) { + } else if (p && (strcmp(p, "html") == 0 || + strstr(p, OGCAPI_MIMETYPE_HTML) != nullptr)) { format = OGCAPIFormat::HTML; - } else if(p) { + } else if (p) { std::string errorMsg("Unsupported format requested: "); errorMsg += p; outputError(OGCAPI_PARAM_ERROR, errorMsg.c_str()); @@ -1674,47 +1728,57 @@ int msOGCAPIDispatchRequest(mapObj *map, cgiRequestObj *request) format = OGCAPIFormat::HTML; // default for now } - if(request->api_path_length == 2) { + if (request->api_path_length == 2) { return processLandingRequest(map, request, format); - } else if(request->api_path_length == 3) { + } else if (request->api_path_length == 3) { - if(strcmp(request->api_path[2], "conformance") == 0) { + if (strcmp(request->api_path[2], "conformance") == 0) { return processConformanceRequest(map, request, format); - } else if(strcmp(request->api_path[2], "conformance.html") == 0) { + } else if (strcmp(request->api_path[2], "conformance.html") == 0) { return processConformanceRequest(map, request, OGCAPIFormat::HTML); - } else if(strcmp(request->api_path[2], "collections") == 0) { + } else if (strcmp(request->api_path[2], "collections") == 0) { return processCollectionsRequest(map, request, format); - } else if(strcmp(request->api_path[2], "collections.html") == 0) { + } else if (strcmp(request->api_path[2], "collections.html") == 0) { return processCollectionsRequest(map, request, OGCAPIFormat::HTML); - } else if(strcmp(request->api_path[2], "api") == 0) { + } else if (strcmp(request->api_path[2], "api") == 0) { return processApiRequest(map, request, format); } - } else if(request->api_path_length == 4) { + } else if (request->api_path_length == 4) { - if(strcmp(request->api_path[2], "collections") == 0) { // next argument (3) is collectionId - return processCollectionRequest(map, request, request->api_path[3], format); + if (strcmp(request->api_path[2], "collections") == + 0) { // next argument (3) is collectionId + return processCollectionRequest(map, request, request->api_path[3], + format); } - } else if(request->api_path_length == 5) { + } else if (request->api_path_length == 5) { - if(strcmp(request->api_path[2], "collections") == 0 && strcmp(request->api_path[4], "items") == 0) { // middle argument (3) is the collectionId - return processCollectionItemsRequest(map, request, request->api_path[3], NULL, format); + if (strcmp(request->api_path[2], "collections") == 0 && + strcmp(request->api_path[4], "items") == + 0) { // middle argument (3) is the collectionId + return processCollectionItemsRequest(map, request, request->api_path[3], + NULL, format); } - } else if(request->api_path_length == 6) { + } else if (request->api_path_length == 6) { - if(strcmp(request->api_path[2], "collections") == 0 && strcmp(request->api_path[4], "items") == 0) { // middle argument (3) is the collectionId, last argument (5) is featureId - return processCollectionItemsRequest(map, request, request->api_path[3], request->api_path[5], format); + if (strcmp(request->api_path[2], "collections") == 0 && + strcmp(request->api_path[4], "items") == + 0) { // middle argument (3) is the collectionId, last argument (5) + // is featureId + return processCollectionItemsRequest(map, request, request->api_path[3], + request->api_path[5], format); } } outputError(OGCAPI_NOT_FOUND_ERROR, "Invalid API path."); return MS_SUCCESS; // avoid any downstream MapServer processing #else - msSetError(MS_OGCAPIERR, "OGC API server support is not enabled.", "msOGCAPIDispatchRequest()"); + msSetError(MS_OGCAPIERR, "OGC API server support is not enabled.", + "msOGCAPIDispatchRequest()"); return MS_FAILURE; #endif } diff --git a/mapogcapi.h b/mapogcapi.h index a9f22d44c1..e2ce43b26e 100644 --- a/mapogcapi.h +++ b/mapogcapi.h @@ -6,7 +6,7 @@ * Author: Steve Lime and the MapServer team. * ********************************************************************** - * Copyright (c) 1996-2005 Regents of the University of Minnesota. + * Copyright (c) 1996-2005 Regents of the University of Minnesota. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,13 +29,13 @@ #ifndef MAPOGCAPI_H #define MAPOGCAPI_H -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif int msOGCAPIDispatchRequest(mapObj *map, cgiRequestObj *request); -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/mapogcfilter.cpp b/mapogcfilter.cpp index 829bb932c3..c3c0f65ee4 100644 --- a/mapogcfilter.cpp +++ b/mapogcfilter.cpp @@ -43,25 +43,26 @@ static int FLTHasUniqueTopLevelDuringFilter(FilterEncodingNode *psFilterNode); #endif #if !(defined(_WIN32) && !defined(__CYGWIN__)) -static inline void IGUR_double(double ignored) { (void)ignored; } /* Ignore GCC Unused Result */ +static inline void IGUR_double(double ignored) { + (void)ignored; +} /* Ignore GCC Unused Result */ #endif -int FLTIsNumeric(const char *pszValue) -{ +int FLTIsNumeric(const char *pszValue) { if (pszValue != NULL && *pszValue != '\0' && !isspace(*pszValue)) { /*the regex seems to have a problem on windows when mapserver is built using PHP regex*/ #if defined(_WIN32) && !defined(__CYGWIN__) - int i = 0, nLength=0, bString=0; + int i = 0, nLength = 0, bString = 0; nLength = strlen(pszValue); - for (i=0; iconnectiontype == MS_POSTGIS || lp->connectiontype == MS_ORACLESPATIAL || + if (lp->connectiontype == MS_POSTGIS || + lp->connectiontype == MS_ORACLESPATIAL || lp->connectiontype == MS_PLUGIN) { pszFinalExpression = msStrdup("("); - pszFinalExpression = msStringConcatenate(pszFinalExpression, pszExpression); + pszFinalExpression = + msStringConcatenate(pszFinalExpression, pszExpression); pszFinalExpression = msStringConcatenate(pszFinalExpression, ")"); } else if (lp->connectiontype == MS_OGR) { pszFinalExpression = msStrdup(pszExpression); if (lp->filter.type != MS_EXPRESSION) { bConcatWhere = 1; } else { - if (lp->filter.string && EQUALN(lp->filter.string,"WHERE ",6)) { + if (lp->filter.string && EQUALN(lp->filter.string, "WHERE ", 6)) { bHasAWhere = 1; - bConcatWhere =1; + bConcatWhere = 1; } } @@ -115,7 +118,7 @@ int FLTApplyExpressionToLayer(layerObj *lp, const char *pszExpression) if (lp->filter.string && lp->filter.type == MS_EXPRESSION) { pszBuffer = msStringConcatenate(pszBuffer, "(("); if (bHasAWhere) - pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string+6); + pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string + 6); else pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); pszBuffer = msStringConcatenate(pszBuffer, ") and "); @@ -124,7 +127,7 @@ int FLTApplyExpressionToLayer(layerObj *lp, const char *pszExpression) pszBuffer = msStringConcatenate(pszBuffer, pszFinalExpression); - if(lp->filter.string && lp->filter.type == MS_EXPRESSION) + if (lp->filter.string && lp->filter.type == MS_EXPRESSION) pszBuffer = msStringConcatenate(pszBuffer, ")"); /*assuming that expression was properly escaped @@ -135,7 +138,6 @@ int FLTApplyExpressionToLayer(layerObj *lp, const char *pszExpression) */ msLoadExpressionString(&lp->filter, pszBuffer); - msFree(pszFinalExpression); if (pszBuffer) @@ -147,26 +149,26 @@ int FLTApplyExpressionToLayer(layerObj *lp, const char *pszExpression) return MS_FALSE; } -char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char *value, int forcecharcter) -{ +char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, + const char *value, int forcecharcter) { int bIscharacter; - char *pszExpression = NULL, *pszEscapedStr=NULL, *pszTmpExpression=NULL; - char **paszElements = NULL, **papszRangeElements=NULL; - int numelements,i,nrangeelements; + char *pszExpression = NULL, *pszEscapedStr = NULL, *pszTmpExpression = NULL; + char **paszElements = NULL, **papszRangeElements = NULL; + int numelements, i, nrangeelements; /* double minval, maxval; */ if (lp && item && value) { if (strstr(value, "/") == NULL) { /*value(s)*/ - paszElements = msStringSplit (value, ',', &numelements); + paszElements = msStringSplit(value, ',', &numelements); if (paszElements && numelements > 0) { if (forcecharcter) bIscharacter = MS_TRUE; else - bIscharacter= !FLTIsNumeric(paszElements[0]); + bIscharacter = !FLTIsNumeric(paszElements[0]); pszTmpExpression = msStringConcatenate(pszTmpExpression, "("); - for (i=0; i 0) { pszTmpExpression = msStringConcatenate(pszTmpExpression, "("); - for (i=0; i 0) { pszTmpExpression = msStringConcatenate(pszTmpExpression, "("); if (nrangeelements == 2 || nrangeelements == 3) { @@ -227,9 +231,10 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char pszTmpExpression = msStringConcatenate(pszTmpExpression, " >= "); pszEscapedStr = msLayerEscapeSQLParam(lp, papszRangeElements[0]); - pszTmpExpression = msStringConcatenate(pszTmpExpression, pszEscapedStr); + pszTmpExpression = + msStringConcatenate(pszTmpExpression, pszEscapedStr); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; pszTmpExpression = msStringConcatenate(pszTmpExpression, " AND "); @@ -242,9 +247,10 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char pszTmpExpression = msStringConcatenate(pszTmpExpression, " <= "); pszEscapedStr = msLayerEscapeSQLParam(lp, papszRangeElements[1]); - pszTmpExpression = msStringConcatenate(pszTmpExpression, pszEscapedStr); + pszTmpExpression = + msStringConcatenate(pszTmpExpression, pszEscapedStr); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; pszTmpExpression = msStringConcatenate(pszTmpExpression, ")"); } else if (nrangeelements == 1) { @@ -258,9 +264,10 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char pszTmpExpression = msStringConcatenate(pszTmpExpression, " = "); pszEscapedStr = msLayerEscapeSQLParam(lp, papszRangeElements[0]); - pszTmpExpression = msStringConcatenate(pszTmpExpression, pszEscapedStr); + pszTmpExpression = + msStringConcatenate(pszTmpExpression, pszEscapedStr); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; pszTmpExpression = msStringConcatenate(pszTmpExpression, ")"); } @@ -268,10 +275,10 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char if (pszExpression != NULL) pszExpression = msStringConcatenate(pszExpression, " OR "); - pszExpression = msStringConcatenate(pszExpression, pszTmpExpression); + pszExpression = + msStringConcatenate(pszExpression, pszTmpExpression); msFree(pszTmpExpression); pszTmpExpression = NULL; - } msFreeCharArray(papszRangeElements, nrangeelements); } @@ -285,21 +292,19 @@ char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char } int FLTogrConvertGeometry(OGRGeometryH hGeometry, shapeObj *psShape, - OGRwkbGeometryType nType) -{ + OGRwkbGeometryType nType) { return msOGRGeometryToShape(hGeometry, psShape, nType); } -static -int FLTShapeFromGMLTree(CPLXMLNode *psTree, shapeObj *psShape , char **ppszSRS) -{ +static int FLTShapeFromGMLTree(CPLXMLNode *psTree, shapeObj *psShape, + char **ppszSRS) { const char *pszSRS = NULL; if (psTree && psShape) { CPLXMLNode *psNext = psTree->psNext; OGRGeometryH hGeometry = NULL; psTree->psNext = NULL; - hGeometry = OGR_G_CreateFromGMLTree(psTree ); + hGeometry = OGR_G_CreateFromGMLTree(psTree); psTree->psNext = psNext; if (hGeometry) { @@ -309,7 +314,7 @@ int FLTShapeFromGMLTree(CPLXMLNode *psTree, shapeObj *psShape , char **ppszSRS) nType = wkbPolygon; else if (nType == wkbLineString25D || nType == wkbMultiLineString25D) nType = wkbLineString; - else if (nType == wkbPoint25D || nType == wkbMultiPoint25D) + else if (nType == wkbPoint25D || nType == wkbMultiPoint25D) nType = wkbPoint; FLTogrConvertGeometry(hGeometry, psShape, nType); @@ -326,8 +331,7 @@ int FLTShapeFromGMLTree(CPLXMLNode *psTree, shapeObj *psShape , char **ppszSRS) return MS_FALSE; } -int FLTGetGeosOperator(char *pszValue) -{ +int FLTGetGeosOperator(char *pszValue) { if (!pszValue) return -1; @@ -356,8 +360,7 @@ int FLTGetGeosOperator(char *pszValue) return -1; } -int FLTIsGeosNode(char *pszValue) -{ +int FLTIsGeosNode(char *pszValue) { if (FLTGetGeosOperator(pszValue) == -1) return MS_FALSE; @@ -369,8 +372,7 @@ int FLTIsGeosNode(char *pszValue) /* */ /* Filter encoding with only attribute queries */ /************************************************************************/ -int FLTIsSimpleFilterNoSpatial(FilterEncodingNode *psNode) -{ +int FLTIsSimpleFilterNoSpatial(FilterEncodingNode *psNode) { if (FLTIsSimpleFilter(psNode) && FLTNumberOfFilterType(psNode, "BBOX") == 0) return MS_TRUE; @@ -381,8 +383,8 @@ int FLTIsSimpleFilterNoSpatial(FilterEncodingNode *psNode) /* FLTApplySimpleSQLFilter() */ /************************************************************************/ -int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex) -{ +int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex) { layerObj *lp = NULL; char *szExpression = NULL; rectObj sQueryRect = map->extent; @@ -390,34 +392,37 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI projectionObj sProjTmp; char *pszBuffer = NULL; int bConcatWhere = 0; - int bHasAWhere =0; + int bHasAWhere = 0; char *pszTmp = NULL, *pszTmp2 = NULL; char *tmpfilename = NULL; - const char* pszTimeField = NULL; - const char* pszTimeValue = NULL; + const char *pszTimeField = NULL; + const char *pszTimeValue = NULL; lp = (GET_LAYER(map, iLayerIndex)); /* if there is a bbox use it */ szEPSG = FLTGetBBOX(psNode, &sQueryRect); - if(szEPSG && map->projection.numargs > 0) { + if (szEPSG && map->projection.numargs > 0) { msInitProjection(&sProjTmp); msProjectionInheritContextFrom(&sProjTmp, &map->projection); - /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */ + /* Use the non EPSG variant since axis swapping is done in + * FLTDoAxisSwappingIfNecessary */ if (msLoadProjectionString(&sProjTmp, szEPSG) == 0) { msProjectRect(&sProjTmp, &map->projection, &sQueryRect); } msFreeProjection(&sProjTmp); } - - if( lp->connectiontype == MS_OGR ) { + + if (lp->connectiontype == MS_OGR) { pszTimeValue = FLTGetDuring(psNode, &pszTimeField); } /* make sure that the layer can be queried*/ - if (!lp->_template) lp->_template = msStrdup("ttt.html"); + if (!lp->_template) + lp->_template = msStrdup("ttt.html"); - /* if there is no class, create at least one, so that query by rect would work */ + /* if there is no class, create at least one, so that query by rect would work + */ if (lp->numclasses == 0) { if (msGrowLayerClasses(lp) == NULL) return MS_FAILURE; @@ -426,7 +431,8 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI bConcatWhere = 0; bHasAWhere = 0; - if (lp->connectiontype == MS_POSTGIS || lp->connectiontype == MS_ORACLESPATIAL || + if (lp->connectiontype == MS_POSTGIS || + lp->connectiontype == MS_ORACLESPATIAL || lp->connectiontype == MS_PLUGIN) { szExpression = FLTGetSQLExpression(psNode, lp); if (szExpression) { @@ -440,24 +446,23 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI /* concatenates the WHERE clause for OGR layers. This only applies if the expression was empty or not of an expression string. If there is an sql type expression, it is assumed to have the WHERE clause. - If it is an expression and does not have a WHERE it is assumed to be a mapserver - type expression*/ + If it is an expression and does not have a WHERE it is assumed to be a + mapserver type expression*/ else if (lp->connectiontype == MS_OGR) { if (lp->filter.type != MS_EXPRESSION) { szExpression = FLTGetSQLExpression(psNode, lp); bConcatWhere = 1; } else { - if (lp->filter.string && EQUALN(lp->filter.string,"WHERE ",6)) { + if (lp->filter.string && EQUALN(lp->filter.string, "WHERE ", 6)) { szExpression = FLTGetSQLExpression(psNode, lp); bHasAWhere = 1; - bConcatWhere =1; + bConcatWhere = 1; } else { szExpression = FLTGetCommonExpression(psNode, lp); } } } else { szExpression = FLTGetCommonExpression(psNode, lp); - } if (szExpression) { @@ -469,7 +474,7 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI if (lp->filter.string && lp->filter.type == MS_EXPRESSION) { pszBuffer = msStringConcatenate(pszBuffer, "(("); if (bHasAWhere) - pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string+6); + pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string + 6); else pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); pszBuffer = msStringConcatenate(pszBuffer, ") and "); @@ -478,15 +483,15 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI pszBuffer = msStringConcatenate(pszBuffer, szExpression); - if(lp->filter.string && lp->filter.type == MS_EXPRESSION) + if (lp->filter.string && lp->filter.type == MS_EXPRESSION) pszBuffer = msStringConcatenate(pszBuffer, ")"); msLoadExpressionString(&lp->filter, pszBuffer); free(szExpression); } - + if (pszTimeField && pszTimeValue) - msLayerSetTimeFilter(lp, pszTimeValue, pszTimeField); + msLayerSetTimeFilter(lp, pszTimeValue, pszTimeField); if (pszBuffer) free(pszBuffer); @@ -496,23 +501,27 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI map->query.layer = lp->index; map->query.rect = sQueryRect; - if(map->debug == MS_DEBUGLEVEL_VVV) { + if (map->debug == MS_DEBUGLEVEL_VVV) { tmpfilename = msTmpFile(map, map->mappath, NULL, "_filter.map"); if (tmpfilename == NULL) { - tmpfilename = msTmpFile(map, NULL, NULL, "_filter.map" ); + tmpfilename = msTmpFile(map, NULL, NULL, "_filter.map"); } if (tmpfilename) { - msSaveMap(map,tmpfilename); - msDebug("FLTApplySimpleSQLFilter(): Map file after Filter was applied %s\n", tmpfilename); + msSaveMap(map, tmpfilename); + msDebug( + "FLTApplySimpleSQLFilter(): Map file after Filter was applied %s\n", + tmpfilename); msFree(tmpfilename); } } - /*for oracle connection, if we have a simple filter with no spatial constraints - we should set the connection function to NONE to have a better performance + /*for oracle connection, if we have a simple filter with no spatial + constraints we should set the connection function to NONE to have a better + performance (#2725)*/ - if (lp->connectiontype == MS_ORACLESPATIAL && FLTIsSimpleFilterNoSpatial(psNode)) { + if (lp->connectiontype == MS_ORACLESPATIAL && + FLTIsSimpleFilterNoSpatial(psNode)) { if (strcasestr(lp->data, "USING") == 0) lp->data = msStringConcatenate(lp->data, " USING NONE"); else if (strcasestr(lp->data, "NONE") == 0) { @@ -552,74 +561,66 @@ int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, int iLayerI /* */ /* Split filters separated by parentheses into an array of strings. */ /************************************************************************/ -char** FLTSplitFilters(const char* pszStr, int* pnTokens) -{ - const char* pszTokenBegin; - char** papszRet = NULL; - int nTokens = 0; - char chStringQuote = '\0'; - int nXMLIndent = 0; - int bInBracket = FALSE; +char **FLTSplitFilters(const char *pszStr, int *pnTokens) { + const char *pszTokenBegin; + char **papszRet = NULL; + int nTokens = 0; + char chStringQuote = '\0'; + int nXMLIndent = 0; + int bInBracket = FALSE; - if( *pszStr != '(' ) - { - *pnTokens = 0; - return NULL; + if (*pszStr != '(') { + *pnTokens = 0; + return NULL; + } + pszStr++; + pszTokenBegin = pszStr; + while (*pszStr != '\0') { + /* Ignore any character until end of quoted string */ + if (chStringQuote != '\0') { + if (*pszStr == chStringQuote) + chStringQuote = 0; } - pszStr ++; - pszTokenBegin = pszStr; - while( *pszStr != '\0' ) - { - /* Ignore any character until end of quoted string */ - if( chStringQuote != '\0' ) - { - if( *pszStr == chStringQuote ) - chStringQuote = 0; - } - /* Detect begin of quoted string only for an XML attribute, i.e. between < and > */ - else if( bInBracket && (*pszStr == '\'' || *pszStr == '"') ) - { - chStringQuote = *pszStr; - } - /* Begin of XML element */ - else if( *pszStr == '<' ) - { - bInBracket = TRUE; - if( pszStr[1] == '/' ) - nXMLIndent --; - else if( pszStr[1] != '!' ) - nXMLIndent ++; - } - /* case */ - else if (*pszStr == '/' && pszStr[1] == '>' ) - { - bInBracket = FALSE; - nXMLIndent --; - pszStr ++; - } - /* End of XML element */ - else if( *pszStr == '>' ) - { - bInBracket = FALSE; - } - /* Only detect and of filter when XML indentation goes back to zero */ - else if( nXMLIndent == 0 && *pszStr == ')' ) - { - papszRet = (char**) msSmallRealloc(papszRet, sizeof(char*) * (nTokens + 1)); - papszRet[nTokens] = msStrdup(pszTokenBegin); - papszRet[nTokens][pszStr - pszTokenBegin] = '\0'; - nTokens ++; - if( pszStr[1] != '(' ) - { - break; - } - pszStr ++; - pszTokenBegin = pszStr + 1; - } - pszStr ++; + /* Detect begin of quoted string only for an XML attribute, i.e. between < + and > */ + else if (bInBracket && (*pszStr == '\'' || *pszStr == '"')) { + chStringQuote = *pszStr; + } + /* Begin of XML element */ + else if (*pszStr == '<') { + bInBracket = TRUE; + if (pszStr[1] == '/') + nXMLIndent--; + else if (pszStr[1] != '!') + nXMLIndent++; } - *pnTokens = nTokens; - return papszRet; + /* case */ + else if (*pszStr == '/' && pszStr[1] == '>') { + bInBracket = FALSE; + nXMLIndent--; + pszStr++; + } + /* End of XML element */ + else if (*pszStr == '>') { + bInBracket = FALSE; + } + /* Only detect and of filter when XML indentation goes back to zero */ + else if (nXMLIndent == 0 && *pszStr == ')') { + papszRet = + (char **)msSmallRealloc(papszRet, sizeof(char *) * (nTokens + 1)); + papszRet[nTokens] = msStrdup(pszTokenBegin); + papszRet[nTokens][pszStr - pszTokenBegin] = '\0'; + nTokens++; + if (pszStr[1] != '(') { + break; + } + pszStr++; + pszTokenBegin = pszStr + 1; + } + pszStr++; + } + *pnTokens = nTokens; + return papszRet; } /************************************************************************/ @@ -627,8 +628,7 @@ char** FLTSplitFilters(const char* pszStr, int* pnTokens) /* */ /* Filter encoding with only attribute queries and only one bbox. */ /************************************************************************/ -int FLTIsSimpleFilter(FilterEncodingNode *psNode) -{ +int FLTIsSimpleFilter(FilterEncodingNode *psNode) { if (FLTValidForBBoxFilter(psNode)) { if (FLTNumberOfFilterType(psNode, "DWithin") == 0 && FLTNumberOfFilterType(psNode, "Intersect") == 0 && @@ -653,18 +653,18 @@ int FLTIsSimpleFilter(FilterEncodingNode *psNode) /* Use the filter encoding node to create mapserver expressions */ /* and apply it to the layer. */ /************************************************************************/ -int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex) -{ +int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex) { layerObj *layer = GET_LAYER(map, iLayerIndex); - if ( ! layer->vtable) { - int rv = msInitializeVirtualTable(layer); + if (!layer->vtable) { + int rv = msInitializeVirtualTable(layer); if (rv != MS_SUCCESS) return rv; } - if( !layer->vtable ) - return MS_FAILURE; - return layer->vtable->LayerApplyFilterToLayer(psNode, map, iLayerIndex); + if (!layer->vtable) + return MS_FAILURE; + return layer->vtable->LayerApplyFilterToLayer(psNode, map, iLayerIndex); } /************************************************************************/ @@ -672,43 +672,38 @@ int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerInd /* */ /* Helper function for layer virtual table architecture */ /************************************************************************/ -int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex) -{ +int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, + int iLayerIndex) { return FLTLayerApplyPlainFilterToLayer(psNode, map, iLayerIndex); } - /************************************************************************/ /* FLTGetTopBBOX */ /* */ /* Return the "top" BBOX if there's a unique one. */ /************************************************************************/ -static int FLTGetTopBBOXInternal(FilterEncodingNode *psNode, FilterEncodingNode** ppsTopBBOX, int *pnCount) -{ +static int FLTGetTopBBOXInternal(FilterEncodingNode *psNode, + FilterEncodingNode **ppsTopBBOX, + int *pnCount) { if (psNode->pszValue && strcasecmp(psNode->pszValue, "BBOX") == 0) { - (*pnCount) ++; - if( *pnCount == 1 ) - { + (*pnCount)++; + if (*pnCount == 1) { *ppsTopBBOX = psNode; return TRUE; } *ppsTopBBOX = NULL; return FALSE; - } - else if (psNode->pszValue && strcasecmp(psNode->pszValue, "AND") == 0) { + } else if (psNode->pszValue && strcasecmp(psNode->pszValue, "AND") == 0) { return FLTGetTopBBOXInternal(psNode->psLeftNode, ppsTopBBOX, pnCount) && FLTGetTopBBOXInternal(psNode->psRightNode, ppsTopBBOX, pnCount); - } - else - { + } else { return TRUE; } } -static FilterEncodingNode* FLTGetTopBBOX(FilterEncodingNode *psNode) -{ +static FilterEncodingNode *FLTGetTopBBOX(FilterEncodingNode *psNode) { int nCount = 0; - FilterEncodingNode* psTopBBOX = NULL; + FilterEncodingNode *psTopBBOX = NULL; FLTGetTopBBOXInternal(psNode, &psTopBBOX, &nCount); return psTopBBOX; } @@ -722,20 +717,18 @@ static FilterEncodingNode* FLTGetTopBBOX(FilterEncodingNode *psNode) /* they should not issue a spatial filter. */ /************************************************************************/ -int FLTLayerSetInvalidRectIfSupported(layerObj* lp, - rectObj* rect) -{ - const char* pszUseDefaultExtent = msOWSLookupMetadata(&(lp->metadata), "F", - "use_default_extent_for_getfeature"); - if( pszUseDefaultExtent && !CSLTestBoolean(pszUseDefaultExtent) && - (lp->connectiontype == MS_OGR || - ((lp->connectiontype == MS_PLUGIN) && (strstr(lp->plugin_library,"msplugin_mssql2008") != NULL))) ) - { - const rectObj rectInvalid = MS_INIT_INVALID_RECT; - *rect = rectInvalid; - return MS_TRUE; - } - return MS_FALSE; +int FLTLayerSetInvalidRectIfSupported(layerObj *lp, rectObj *rect) { + const char *pszUseDefaultExtent = msOWSLookupMetadata( + &(lp->metadata), "F", "use_default_extent_for_getfeature"); + if (pszUseDefaultExtent && !CSLTestBoolean(pszUseDefaultExtent) && + (lp->connectiontype == MS_OGR || + ((lp->connectiontype == MS_PLUGIN) && + (strstr(lp->plugin_library, "msplugin_mssql2008") != NULL)))) { + const rectObj rectInvalid = MS_INIT_INVALID_RECT; + *rect = rectInvalid; + return MS_TRUE; + } + return MS_FALSE; } /************************************************************************/ @@ -744,38 +737,34 @@ int FLTLayerSetInvalidRectIfSupported(layerObj* lp, /* Helper function for layer virtual table architecture */ /************************************************************************/ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, - int iLayerIndex) -{ - char *pszExpression =NULL; - int status =MS_FALSE; - layerObj* lp = GET_LAYER(map, iLayerIndex); + int iLayerIndex) { + char *pszExpression = NULL; + int status = MS_FALSE; + layerObj *lp = GET_LAYER(map, iLayerIndex); - pszExpression = FLTGetCommonExpression(psNode, lp); + pszExpression = FLTGetCommonExpression(psNode, lp); if (pszExpression) { - FilterEncodingNode* psTopBBOX; + FilterEncodingNode *psTopBBOX; rectObj rect = map->extent; FLTLayerSetInvalidRectIfSupported(lp, &rect); psTopBBOX = FLTGetTopBBOX(psNode); - if( psTopBBOX ) - { + if (psTopBBOX) { int can_remove_expression = MS_TRUE; - const char* pszEPSG = FLTGetBBOX(psNode, &rect); - if(pszEPSG && map->projection.numargs > 0) { + const char *pszEPSG = FLTGetBBOX(psNode, &rect); + if (pszEPSG && map->projection.numargs > 0) { projectionObj sProjTmp; msInitProjection(&sProjTmp); msProjectionInheritContextFrom(&sProjTmp, &map->projection); - /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */ + /* Use the non EPSG variant since axis swapping is done in + * FLTDoAxisSwappingIfNecessary */ if (msLoadProjectionString(&sProjTmp, pszEPSG) == 0) { rectObj oldRect = rect; msProjectRect(&sProjTmp, &map->projection, &rect); /* If reprojection is involved, do not remove the expression */ - if( rect.minx != oldRect.minx || - rect.miny != oldRect.miny || - rect.maxx != oldRect.maxx || - rect.maxy != oldRect.maxy ) - { + if (rect.minx != oldRect.minx || rect.miny != oldRect.miny || + rect.maxx != oldRect.maxx || rect.maxy != oldRect.maxy) { can_remove_expression = MS_FALSE; } } @@ -784,19 +773,21 @@ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, /* Small optimization: if the query is just a BBOX, then do a */ /* msQueryByRect() */ - if( psTopBBOX == psNode && can_remove_expression ) - { + if (psTopBBOX == psNode && can_remove_expression) { msFree(pszExpression); pszExpression = NULL; } } - if(map->debug == MS_DEBUGLEVEL_VVV) - { - if( pszExpression ) - msDebug("FLTLayerApplyPlainFilterToLayer(): %s, rect=%.15g,%.15g,%.15g,%.15g\n", pszExpression, rect.minx, rect.miny, rect.maxx, rect.maxy); + if (map->debug == MS_DEBUGLEVEL_VVV) { + if (pszExpression) + msDebug("FLTLayerApplyPlainFilterToLayer(): %s, " + "rect=%.15g,%.15g,%.15g,%.15g\n", + pszExpression, rect.minx, rect.miny, rect.maxx, rect.maxy); else - msDebug("FLTLayerApplyPlainFilterToLayer(): rect=%.15g,%.15g,%.15g,%.15g\n", rect.minx, rect.miny, rect.maxx, rect.maxy); + msDebug( + "FLTLayerApplyPlainFilterToLayer(): rect=%.15g,%.15g,%.15g,%.15g\n", + rect.minx, rect.miny, rect.maxx, rect.maxy); } status = FLTApplyFilterToLayerCommonExpressionWithRect(map, iLayerIndex, @@ -807,8 +798,6 @@ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, return status; } - - /************************************************************************/ /* FilterNode *FLTPaserFilterEncoding(char *szXMLString) */ /* */ @@ -819,9 +808,8 @@ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, /* Calling function should use FreeFilterEncodingNode function */ /* to free memeory. */ /************************************************************************/ -FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) -{ - CPLXMLNode *psRoot = NULL, *psChild=NULL, *psFilter=NULL; +FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) { + CPLXMLNode *psRoot = NULL, *psChild = NULL, *psFilter = NULL; FilterEncodingNode *psFilterNode = NULL; if (szXMLString == NULL || strlen(szXMLString) == 0 || @@ -830,7 +818,7 @@ FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) psRoot = CPLParseXMLString(szXMLString); - if( psRoot == NULL) + if (psRoot == NULL) return NULL; /* strip namespaces. We srtip all name spaces (#1350)*/ @@ -840,9 +828,8 @@ FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) /* get the root element (Filter). */ /* -------------------------------------------------------------------- */ psFilter = CPLGetXMLNode(psRoot, "=Filter"); - if (!psFilter) - { - CPLDestroyXMLNode( psRoot ); + if (!psFilter) { + CPLDestroyXMLNode(psRoot); return NULL; } @@ -856,7 +843,7 @@ FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) psChild = psChild->psNext; } - CPLDestroyXMLNode( psRoot ); + CPLDestroyXMLNode(psRoot); /* -------------------------------------------------------------------- */ /* validate the node tree to make sure that all the nodes are valid.*/ @@ -866,11 +853,9 @@ FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) return NULL; } - return psFilterNode; } - /************************************************************************/ /* int FLTValidFilterNode(FilterEncodingNode *psFilterNode) */ /* */ @@ -879,8 +864,7 @@ FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString) /* could be incorrect if the filter string sent is corrupted */ /* (eg missing a value :) */ /************************************************************************/ -int FLTValidFilterNode(FilterEncodingNode *psFilterNode) -{ +int FLTValidFilterNode(FilterEncodingNode *psFilterNode) { if (!psFilterNode) return 0; @@ -902,11 +886,10 @@ int FLTValidFilterNode(FilterEncodingNode *psFilterNode) /* FLTIsGeometryFilterNodeType */ /************************************************************************/ -static int FLTIsGeometryFilterNodeType(int eType) -{ - return (eType == FILTER_NODE_TYPE_GEOMETRY_POINT || - eType == FILTER_NODE_TYPE_GEOMETRY_LINE || - eType == FILTER_NODE_TYPE_GEOMETRY_POLYGON); +static int FLTIsGeometryFilterNodeType(int eType) { + return (eType == FILTER_NODE_TYPE_GEOMETRY_POINT || + eType == FILTER_NODE_TYPE_GEOMETRY_LINE || + eType == FILTER_NODE_TYPE_GEOMETRY_POLYGON); } /************************************************************************/ @@ -914,8 +897,7 @@ static int FLTIsGeometryFilterNodeType(int eType) /* */ /* recursive freeing of Filter Encoding nodes. */ /************************************************************************/ -void FLTFreeFilterEncodingNode(FilterEncodingNode *psFilterNode) -{ +void FLTFreeFilterEncodingNode(FilterEncodingNode *psFilterNode) { if (psFilterNode) { if (psFilterNode->psLeftNode) { FLTFreeFilterEncodingNode(psFilterNode->psLeftNode); @@ -927,46 +909,43 @@ void FLTFreeFilterEncodingNode(FilterEncodingNode *psFilterNode) } if (psFilterNode->pszSRS) - free( psFilterNode->pszSRS); + free(psFilterNode->pszSRS); - if( psFilterNode->pOther ) { + if (psFilterNode->pOther) { if (psFilterNode->pszValue != NULL && strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) { - FEPropertyIsLike* propIsLike = (FEPropertyIsLike *)psFilterNode->pOther; - if( propIsLike->pszWildCard ) - free( propIsLike->pszWildCard ); - if( propIsLike->pszSingleChar ) - free( propIsLike->pszSingleChar ); - if( propIsLike->pszEscapeChar ) - free( propIsLike->pszEscapeChar ); + FEPropertyIsLike *propIsLike = (FEPropertyIsLike *)psFilterNode->pOther; + if (propIsLike->pszWildCard) + free(propIsLike->pszWildCard); + if (propIsLike->pszSingleChar) + free(propIsLike->pszSingleChar); + if (propIsLike->pszEscapeChar) + free(propIsLike->pszEscapeChar); } else if (FLTIsGeometryFilterNodeType(psFilterNode->eType)) { msFreeShape((shapeObj *)(psFilterNode->pOther)); } /* else */ /* TODO free pOther special fields */ - free( psFilterNode->pOther ); + free(psFilterNode->pOther); } /* Cannot free pszValue before, 'cause we are testing it above */ - if( psFilterNode->pszValue ) - free( psFilterNode->pszValue ); + if (psFilterNode->pszValue) + free(psFilterNode->pszValue); free(psFilterNode); } } - /************************************************************************/ /* FLTCreateFilterEncodingNode */ /* */ /* return a FilterEncoding node. */ /************************************************************************/ -FilterEncodingNode *FLTCreateFilterEncodingNode(void) -{ +FilterEncodingNode *FLTCreateFilterEncodingNode(void) { FilterEncodingNode *psFilterNode = NULL; - psFilterNode = - (FilterEncodingNode *)malloc(sizeof (FilterEncodingNode)); + psFilterNode = (FilterEncodingNode *)malloc(sizeof(FilterEncodingNode)); psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; psFilterNode->pszValue = NULL; psFilterNode->pOther = NULL; @@ -977,8 +956,7 @@ FilterEncodingNode *FLTCreateFilterEncodingNode(void) return psFilterNode; } -FilterEncodingNode *FLTCreateBinaryCompFilterEncodingNode(void) -{ +FilterEncodingNode *FLTCreateBinaryCompFilterEncodingNode(void) { FilterEncodingNode *psFilterNode = NULL; psFilterNode = FLTCreateFilterEncodingNode(); @@ -990,97 +968,88 @@ FilterEncodingNode *FLTCreateBinaryCompFilterEncodingNode(void) return psFilterNode; } - /************************************************************************/ /* FLTFindGeometryNode */ /* */ /************************************************************************/ -static CPLXMLNode* FLTFindGeometryNode(CPLXMLNode* psXMLNode, - int* pbPoint, - int* pbLine, - int* pbPolygon) -{ - CPLXMLNode *psGMLElement = NULL; +static CPLXMLNode *FLTFindGeometryNode(CPLXMLNode *psXMLNode, int *pbPoint, + int *pbLine, int *pbPolygon) { + CPLXMLNode *psGMLElement = NULL; - psGMLElement = CPLGetXMLNode(psXMLNode, "Point"); - if (!psGMLElement) - psGMLElement = CPLGetXMLNode(psXMLNode, "PointType"); + psGMLElement = CPLGetXMLNode(psXMLNode, "Point"); + if (!psGMLElement) + psGMLElement = CPLGetXMLNode(psXMLNode, "PointType"); + if (psGMLElement) + *pbPoint = 1; + else { + psGMLElement = CPLGetXMLNode(psXMLNode, "Polygon"); if (psGMLElement) - *pbPoint =1; - else { - psGMLElement= CPLGetXMLNode(psXMLNode, "Polygon"); - if (psGMLElement) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPolygon"))) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Surface"))) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiSurface"))) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Box"))) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Envelope"))) - *pbPolygon = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "LineString"))) - *pbLine = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiLineString"))) - *pbLine = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "Curve"))) - *pbLine = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiCurve"))) - *pbLine = 1; - else if ((psGMLElement= CPLGetXMLNode(psXMLNode, "MultiPoint"))) - *pbPoint = 1; - } - return psGMLElement; + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "MultiPolygon"))) + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "Surface"))) + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "MultiSurface"))) + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "Box"))) + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "Envelope"))) + *pbPolygon = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "LineString"))) + *pbLine = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "MultiLineString"))) + *pbLine = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "Curve"))) + *pbLine = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "MultiCurve"))) + *pbLine = 1; + else if ((psGMLElement = CPLGetXMLNode(psXMLNode, "MultiPoint"))) + *pbPoint = 1; + } + return psGMLElement; } /************************************************************************/ /* FLTGetPropertyName */ /************************************************************************/ -static const char* FLTGetPropertyName(CPLXMLNode* psXMLNode) -{ - const char* pszPropertyName; +static const char *FLTGetPropertyName(CPLXMLNode *psXMLNode) { + const char *pszPropertyName; - pszPropertyName = CPLGetXMLValue(psXMLNode, "PropertyName", NULL); - if( pszPropertyName == NULL ) /* FE 2.0 ? */ - pszPropertyName = CPLGetXMLValue(psXMLNode, "ValueReference", NULL); - return pszPropertyName; + pszPropertyName = CPLGetXMLValue(psXMLNode, "PropertyName", NULL); + if (pszPropertyName == NULL) /* FE 2.0 ? */ + pszPropertyName = CPLGetXMLValue(psXMLNode, "ValueReference", NULL); + return pszPropertyName; } /************************************************************************/ /* FLTGetFirstChildNode */ /************************************************************************/ -static CPLXMLNode* FLTGetFirstChildNode(CPLXMLNode* psXMLNode) -{ - if( psXMLNode == NULL ) - return NULL; - psXMLNode = psXMLNode->psChild; - while( psXMLNode != NULL ) - { - if( psXMLNode->eType == CXT_Element ) - return psXMLNode; - psXMLNode = psXMLNode->psNext; - } +static CPLXMLNode *FLTGetFirstChildNode(CPLXMLNode *psXMLNode) { + if (psXMLNode == NULL) return NULL; + psXMLNode = psXMLNode->psChild; + while (psXMLNode != NULL) { + if (psXMLNode->eType == CXT_Element) + return psXMLNode; + psXMLNode = psXMLNode->psNext; + } + return NULL; } /************************************************************************/ /* FLTGetNextSibblingNode */ /************************************************************************/ -static CPLXMLNode* FLTGetNextSibblingNode(CPLXMLNode* psXMLNode) -{ - if( psXMLNode == NULL ) - return NULL; - psXMLNode = psXMLNode->psNext; - while( psXMLNode != NULL ) - { - if( psXMLNode->eType == CXT_Element ) - return psXMLNode; - psXMLNode = psXMLNode->psNext; - } +static CPLXMLNode *FLTGetNextSibblingNode(CPLXMLNode *psXMLNode) { + if (psXMLNode == NULL) return NULL; + psXMLNode = psXMLNode->psNext; + while (psXMLNode != NULL) { + if (psXMLNode->eType == CXT_Element) + return psXMLNode; + psXMLNode = psXMLNode->psNext; + } + return NULL; } /************************************************************************/ @@ -1090,15 +1059,14 @@ static CPLXMLNode* FLTGetNextSibblingNode(CPLXMLNode* psXMLNode) /* contents into the Filter Encoding node structure. */ /************************************************************************/ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, - CPLXMLNode *psXMLNode) -{ + CPLXMLNode *psXMLNode) { char *pszTmp = NULL; - FilterEncodingNode *psCurFilNode= NULL; + FilterEncodingNode *psCurFilNode = NULL; CPLXMLNode *psCurXMLNode = NULL; CPLXMLNode *psTmpNode = NULL; CPLXMLNode *psFeatureIdNode = NULL; - const char *pszFeatureId=NULL; - char *pszFeatureIdList=NULL; + const char *pszFeatureId = NULL; + char *pszFeatureIdList = NULL; if (psFilterNode && psXMLNode && psXMLNode->pszValue) { psFilterNode->pszValue = msStrdup(psXMLNode->pszValue); @@ -1125,11 +1093,11 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->eType = FILTER_NODE_TYPE_LOGICAL; if (strcasecmp(psFilterNode->pszValue, "AND") == 0 || strcasecmp(psFilterNode->pszValue, "OR") == 0) { - CPLXMLNode* psFirstNode = FLTGetFirstChildNode(psXMLNode); - CPLXMLNode* psSecondNode = FLTGetNextSibblingNode(psFirstNode); + CPLXMLNode *psFirstNode = FLTGetFirstChildNode(psXMLNode); + CPLXMLNode *psSecondNode = FLTGetNextSibblingNode(psFirstNode); if (psFirstNode && psSecondNode) { /*2 operators */ - CPLXMLNode* psNextNode = FLTGetNextSibblingNode(psSecondNode); + CPLXMLNode *psNextNode = FLTGetNextSibblingNode(psSecondNode); if (psNextNode == NULL) { psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); FLTInsertElementInNode(psFilterNode->psLeftNode, psFirstNode); @@ -1138,14 +1106,15 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, } else { psCurXMLNode = psFirstNode; psCurFilNode = psFilterNode; - while(psCurXMLNode) { + while (psCurXMLNode) { psNextNode = FLTGetNextSibblingNode(psCurXMLNode); if (FLTGetNextSibblingNode(psNextNode)) { psCurFilNode->psLeftNode = FLTCreateFilterEncodingNode(); FLTInsertElementInNode(psCurFilNode->psLeftNode, psCurXMLNode); psCurFilNode->psRightNode = FLTCreateFilterEncodingNode(); psCurFilNode->psRightNode->eType = FILTER_NODE_TYPE_LOGICAL; - psCurFilNode->psRightNode->pszValue = msStrdup(psFilterNode->pszValue); + psCurFilNode->psRightNode->pszValue = + msStrdup(psFilterNode->pszValue); psCurFilNode = psCurFilNode->psRightNode; psCurXMLNode = psNextNode; @@ -1159,21 +1128,18 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, } } } - } - else + } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } else if (strcasecmp(psFilterNode->pszValue, "NOT") == 0) { - CPLXMLNode* psFirstNode = FLTGetFirstChildNode(psXMLNode); + CPLXMLNode *psFirstNode = FLTGetFirstChildNode(psXMLNode); if (psFirstNode) { psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); - FLTInsertElementInNode(psFilterNode->psLeftNode, - psFirstNode); - } - else + FLTInsertElementInNode(psFilterNode->psLeftNode, psFirstNode); + } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; - }/* end if is logical */ + } /* end if is logical */ /* -------------------------------------------------------------------- */ /* Spatial Filter. */ /* BBOX : */ @@ -1217,7 +1183,8 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, /* */ /* Intersect */ /* */ - /* type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>*/ + /* type="ogc:BinarySpatialOpType" + substitutionGroup="ogc:spatialOps"/>*/ /* */ @@ -1240,9 +1207,9 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, if (strcasecmp(psXMLNode->pszValue, "BBOX") == 0) { char *pszSRS = NULL; - const char* pszPropertyName = NULL; - CPLXMLNode *psBox = NULL, *psEnvelope=NULL; - rectObj sBox = {0,0,0,0}; + const char *pszPropertyName = NULL; + CPLXMLNode *psBox = NULL, *psEnvelope = NULL; + rectObj sBox = {0, 0, 0, 0}; int bCoordinatesValid = 0; @@ -1263,12 +1230,12 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->pszSRS = pszSRS; psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); - psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; + psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; /* PropertyName is optional since FE 1.1.0, in which case */ /* the BBOX must apply to all geometry fields. As we support */ /* currently only one geometry field, this doesn't make much */ /* difference to further processing. */ - if( pszPropertyName != NULL ) { + if (pszPropertyName != NULL) { psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); } @@ -1276,11 +1243,11 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->psRightNode = FLTCreateFilterEncodingNode(); psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_BBOX; psFilterNode->psRightNode->pOther = - (rectObj *)msSmallMalloc(sizeof(rectObj)); + (rectObj *)msSmallMalloc(sizeof(rectObj)); ((rectObj *)psFilterNode->psRightNode->pOther)->minx = sBox.minx; ((rectObj *)psFilterNode->psRightNode->pOther)->miny = sBox.miny; ((rectObj *)psFilterNode->psRightNode->pOther)->maxx = sBox.maxx; - ((rectObj *)psFilterNode->psRightNode->pOther)->maxy = sBox.maxy; + ((rectObj *)psFilterNode->psRightNode->pOther)->maxy = sBox.maxy; } else { msFree(pszSRS); psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; @@ -1292,27 +1259,27 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, shapeObj *psShape = NULL; int bPoint = 0, bLine = 0, bPolygon = 0; const char *pszUnits = NULL; - const char* pszDistance = NULL; - const char* pszPropertyName; + const char *pszDistance = NULL; + const char *pszPropertyName; char *pszSRS = NULL; - CPLXMLNode *psGMLElement = NULL, *psDistance=NULL; + CPLXMLNode *psGMLElement = NULL, *psDistance = NULL; pszPropertyName = FLTGetPropertyName(psXMLNode); - psGMLElement = FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon); + psGMLElement = + FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon); psDistance = CPLGetXMLNode(psXMLNode, "Distance"); - if( psDistance != NULL ) - pszDistance = CPLGetXMLValue(psDistance, NULL, NULL ); - if (pszPropertyName != NULL && psGMLElement && psDistance != NULL ) { + if (psDistance != NULL) + pszDistance = CPLGetXMLValue(psDistance, NULL, NULL); + if (pszPropertyName != NULL && psGMLElement && psDistance != NULL) { pszUnits = CPLGetXMLValue(psDistance, "units", NULL); - if( pszUnits == NULL ) /* FE 2.0 */ - pszUnits = CPLGetXMLValue(psDistance, "uom", NULL); + if (pszUnits == NULL) /* FE 2.0 */ + pszUnits = CPLGetXMLValue(psDistance, "uom", NULL); psShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(psShape); - if (FLTShapeFromGMLTree(psGMLElement, psShape, &pszSRS)) - { + if (FLTShapeFromGMLTree(psGMLElement, psShape, &pszSRS)) { /*set the srs if available*/ if (pszSRS) psFilterNode->pszSRS = pszSRS; @@ -1323,24 +1290,26 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->psRightNode = FLTCreateFilterEncodingNode(); if (bPoint) - psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_POINT; + psFilterNode->psRightNode->eType = + FILTER_NODE_TYPE_GEOMETRY_POINT; else if (bLine) psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_LINE; else if (bPolygon) - psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_POLYGON; + psFilterNode->psRightNode->eType = + FILTER_NODE_TYPE_GEOMETRY_POLYGON; psFilterNode->psRightNode->pOther = (shapeObj *)psShape; /*the value will be distance;units*/ psFilterNode->psRightNode->pszValue = msStrdup(pszDistance); if (pszUnits) { - psFilterNode->psRightNode->pszValue= msStringConcatenate(psFilterNode->psRightNode->pszValue, ";"); - psFilterNode->psRightNode->pszValue= msStringConcatenate(psFilterNode->psRightNode->pszValue, pszUnits); + psFilterNode->psRightNode->pszValue = + msStringConcatenate(psFilterNode->psRightNode->pszValue, ";"); + psFilterNode->psRightNode->pszValue = msStringConcatenate( + psFilterNode->psRightNode->pszValue, pszUnits); } - } - else - { - free(psShape); - msFree(pszSRS); - psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; + } else { + free(psShape); + msFree(pszSRS); + psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; @@ -1354,21 +1323,21 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, strcasecmp(psXMLNode->pszValue, "Contains") == 0 || strcasecmp(psXMLNode->pszValue, "Overlaps") == 0) { shapeObj *psShape = NULL; - int bLine = 0, bPolygon = 0, bPoint=0; + int bLine = 0, bPolygon = 0, bPoint = 0; char *pszSRS = NULL; - const char* pszPropertyName; + const char *pszPropertyName; CPLXMLNode *psGMLElement = NULL; pszPropertyName = FLTGetPropertyName(psXMLNode); - psGMLElement = FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon); + psGMLElement = + FLTFindGeometryNode(psXMLNode, &bPoint, &bLine, &bPolygon); if (pszPropertyName != NULL && psGMLElement) { psShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(psShape); - if (FLTShapeFromGMLTree(psGMLElement, psShape, &pszSRS)) - { + if (FLTShapeFromGMLTree(psGMLElement, psShape, &pszSRS)) { /*set the srs if available*/ if (pszSRS) psFilterNode->pszSRS = pszSRS; @@ -1379,27 +1348,25 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->psRightNode = FLTCreateFilterEncodingNode(); if (bPoint) - psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_POINT; + psFilterNode->psRightNode->eType = + FILTER_NODE_TYPE_GEOMETRY_POINT; else if (bLine) psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_LINE; else if (bPolygon) - psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_GEOMETRY_POLYGON; + psFilterNode->psRightNode->eType = + FILTER_NODE_TYPE_GEOMETRY_POLYGON; psFilterNode->psRightNode->pOther = (shapeObj *)psShape; - } - else - { - free(psShape); - msFree(pszSRS); - psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; + } else { + free(psShape); + msFree(pszSRS); + psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } - - }/* end of is spatial */ - + } /* end of is spatial */ /* -------------------------------------------------------------------- */ /* Comparison Filter */ @@ -1417,29 +1384,30 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, /* */ /* -------------------------------------------------------------------- */ if (FLTIsBinaryComparisonFilterType(psXMLNode->pszValue)) { - const char* pszPropertyName = FLTGetPropertyName(psXMLNode); - if (pszPropertyName != NULL ) { + const char *pszPropertyName = FLTGetPropertyName(psXMLNode); + if (pszPropertyName != NULL) { psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); - psTmpNode = CPLSearchXMLNode(psXMLNode, "Literal"); + psTmpNode = CPLSearchXMLNode(psXMLNode, "Literal"); if (psTmpNode) { - const char* pszLiteral = CPLGetXMLValue(psTmpNode, NULL, NULL); + const char *pszLiteral = CPLGetXMLValue(psTmpNode, NULL, NULL); psFilterNode->psRightNode = FLTCreateBinaryCompFilterEncodingNode(); psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_LITERAL; if (pszLiteral != NULL) { - const char* pszMatchCase; + const char *pszMatchCase; psFilterNode->psRightNode->pszValue = msStrdup(pszLiteral); - + pszMatchCase = CPLGetXMLValue(psXMLNode, "matchCase", NULL); /*check if the matchCase attribute is set*/ - if( pszMatchCase != NULL && strcasecmp( pszMatchCase, "false") == 0) { + if (pszMatchCase != NULL && + strcasecmp(pszMatchCase, "false") == 0) { (*(int *)psFilterNode->psRightNode->pOther) = 1; } @@ -1451,7 +1419,8 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->psRightNode->pszValue = NULL; } } - if (psFilterNode->psLeftNode == NULL || psFilterNode->psRightNode == NULL) + if (psFilterNode->psLeftNode == NULL || + psFilterNode->psRightNode == NULL) psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } @@ -1474,27 +1443,26 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, /* */ /* -------------------------------------------------------------------- */ else if (strcasecmp(psXMLNode->pszValue, "PropertyIsBetween") == 0) { - const char* pszPropertyName = FLTGetPropertyName(psXMLNode); - CPLXMLNode* psLowerBoundary = CPLGetXMLNode(psXMLNode, "LowerBoundary"); - CPLXMLNode* psUpperBoundary = CPLGetXMLNode(psXMLNode, "UpperBoundary"); - const char* pszLowerNode = NULL; - const char* pszUpperNode = NULL; - if( psLowerBoundary != NULL ) - { + const char *pszPropertyName = FLTGetPropertyName(psXMLNode); + CPLXMLNode *psLowerBoundary = CPLGetXMLNode(psXMLNode, "LowerBoundary"); + CPLXMLNode *psUpperBoundary = CPLGetXMLNode(psXMLNode, "UpperBoundary"); + const char *pszLowerNode = NULL; + const char *pszUpperNode = NULL; + if (psLowerBoundary != NULL) { /* check if the is there */ if (CPLGetXMLNode(psLowerBoundary, "Literal") != NULL) pszLowerNode = CPLGetXMLValue(psLowerBoundary, "Literal", NULL); else pszLowerNode = CPLGetXMLValue(psLowerBoundary, NULL, NULL); } - if( psUpperBoundary != NULL ) - { - if (CPLGetXMLNode(psUpperBoundary, "Literal") != NULL) + if (psUpperBoundary != NULL) { + if (CPLGetXMLNode(psUpperBoundary, "Literal") != NULL) pszUpperNode = CPLGetXMLValue(psUpperBoundary, "Literal", NULL); else pszUpperNode = CPLGetXMLValue(psUpperBoundary, NULL, NULL); } - if (pszPropertyName != NULL && pszLowerNode != NULL && pszUpperNode != NULL) { + if (pszPropertyName != NULL && pszLowerNode != NULL && + pszUpperNode != NULL) { psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; @@ -1504,19 +1472,20 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_BOUNDARY; /* adding a ; between bounary values */ - const int nStrLength = strlen(pszLowerNode) + strlen(pszUpperNode) + 2; + const int nStrLength = + strlen(pszLowerNode) + strlen(pszUpperNode) + 2; psFilterNode->psRightNode->pszValue = - (char *)malloc(sizeof(char)*(nStrLength)); - strcpy( psFilterNode->psRightNode->pszValue, pszLowerNode); + (char *)malloc(sizeof(char) * (nStrLength)); + strcpy(psFilterNode->psRightNode->pszValue, pszLowerNode); strlcat(psFilterNode->psRightNode->pszValue, ";", nStrLength); - strlcat(psFilterNode->psRightNode->pszValue, pszUpperNode, nStrLength); - + strlcat(psFilterNode->psRightNode->pszValue, pszUpperNode, + nStrLength); } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; - }/* end of PropertyIsBetween */ + } /* end of PropertyIsBetween */ /* -------------------------------------------------------------------- */ /* PropertyIsLike */ /* */ @@ -1528,17 +1497,18 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, /* */ /* -------------------------------------------------------------------- */ else if (strcasecmp(psXMLNode->pszValue, "PropertyIsLike") == 0) { - const char* pszPropertyName = FLTGetPropertyName(psXMLNode); - const char* pszLiteral = CPLGetXMLValue(psXMLNode, "Literal", NULL); - const char* pszWildCard = CPLGetXMLValue(psXMLNode, "wildCard", NULL); - const char* pszSingleChar = CPLGetXMLValue(psXMLNode, "singleChar", NULL); - const char* pszEscapeChar = CPLGetXMLValue(psXMLNode, "escape", NULL); - if( pszEscapeChar == NULL ) - pszEscapeChar = CPLGetXMLValue(psXMLNode, "escapeChar", NULL); + const char *pszPropertyName = FLTGetPropertyName(psXMLNode); + const char *pszLiteral = CPLGetXMLValue(psXMLNode, "Literal", NULL); + const char *pszWildCard = CPLGetXMLValue(psXMLNode, "wildCard", NULL); + const char *pszSingleChar = + CPLGetXMLValue(psXMLNode, "singleChar", NULL); + const char *pszEscapeChar = CPLGetXMLValue(psXMLNode, "escape", NULL); + if (pszEscapeChar == NULL) + pszEscapeChar = CPLGetXMLValue(psXMLNode, "escapeChar", NULL); if (pszPropertyName != NULL && pszLiteral != NULL && - pszWildCard != NULL && pszSingleChar != NULL && pszEscapeChar != NULL) - { - FEPropertyIsLike* propIsLike; + pszWildCard != NULL && pszSingleChar != NULL && + pszEscapeChar != NULL) { + FEPropertyIsLike *propIsLike; propIsLike = (FEPropertyIsLike *)malloc(sizeof(FEPropertyIsLike)); @@ -1550,11 +1520,13 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, pszTmp = (char *)CPLGetXMLValue(psXMLNode, "matchCase", NULL); if (pszTmp && strcasecmp(pszTmp, "false") == 0) { - propIsLike->bCaseInsensitive =1; + propIsLike->bCaseInsensitive = 1; } - /* -------------------------------------------------------------------- */ - /* Create left and right node for the attribute and the value. */ - /* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- + */ + /* Create left and right node for the attribute and the value. */ + /* -------------------------------------------------------------------- + */ psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); @@ -1571,24 +1543,22 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, } else if (strcasecmp(psXMLNode->pszValue, "PropertyIsNull") == 0) { - const char* pszPropertyName = FLTGetPropertyName(psXMLNode); - if( pszPropertyName != NULL ) - { - psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); - psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); - psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; - } else + const char *pszPropertyName = FLTGetPropertyName(psXMLNode); + if (pszPropertyName != NULL) { + psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); + psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); + psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; + } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } else if (strcasecmp(psXMLNode->pszValue, "PropertyIsNil") == 0) { - const char* pszPropertyName = FLTGetPropertyName(psXMLNode); - if( pszPropertyName != NULL ) - { - psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); - psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); - psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; - } else + const char *pszPropertyName = FLTGetPropertyName(psXMLNode); + if (pszPropertyName != NULL) { + psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); + psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); + psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; + } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } } @@ -1627,19 +1597,20 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, if (pszFeatureIdList) pszFeatureIdList = msStringConcatenate(pszFeatureIdList, ","); - pszFeatureIdList = msStringConcatenate(pszFeatureIdList, pszFeatureId); + pszFeatureIdList = + msStringConcatenate(pszFeatureIdList, pszFeatureId); } psFeatureIdNode = psFeatureIdNode->psNext; } if (pszFeatureIdList) { msFree(psFilterNode->pszValue); - psFilterNode->pszValue = msStrdup(pszFeatureIdList); + psFilterNode->pszValue = msStrdup(pszFeatureIdList); msFree(pszFeatureIdList); } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } - + /* -------------------------------------------------------------------- */ /* Temporal Filter. */ /* @@ -1664,58 +1635,59 @@ void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, psFilterNode->eType = FILTER_NODE_TYPE_TEMPORAL; if (strcasecmp(psXMLNode->pszValue, "During") == 0) { - const char* pszPropertyName = NULL; - const char* pszBeginTime; - const char* pszEndTime; + const char *pszPropertyName = NULL; + const char *pszBeginTime; + const char *pszEndTime; pszPropertyName = FLTGetPropertyName(psXMLNode); - pszBeginTime = CPLGetXMLValue(psXMLNode, "TimePeriod.begin.TimeInstant.timePosition", NULL); - if( pszBeginTime == NULL ) - pszBeginTime = CPLGetXMLValue(psXMLNode, "TimePeriod.beginPosition", NULL); - pszEndTime = CPLGetXMLValue(psXMLNode, "TimePeriod.end.TimeInstant.timePosition", NULL); - if( pszEndTime == NULL ) - pszEndTime = CPLGetXMLValue(psXMLNode, "TimePeriod.endPosition", NULL); + pszBeginTime = CPLGetXMLValue( + psXMLNode, "TimePeriod.begin.TimeInstant.timePosition", NULL); + if (pszBeginTime == NULL) + pszBeginTime = + CPLGetXMLValue(psXMLNode, "TimePeriod.beginPosition", NULL); + pszEndTime = CPLGetXMLValue( + psXMLNode, "TimePeriod.end.TimeInstant.timePosition", NULL); + if (pszEndTime == NULL) + pszEndTime = + CPLGetXMLValue(psXMLNode, "TimePeriod.endPosition", NULL); if (pszPropertyName && pszBeginTime && pszEndTime && - strchr(pszBeginTime, '\'') == NULL && strchr(pszBeginTime, '\\') == NULL && - strchr(pszEndTime, '\'') == NULL && strchr(pszEndTime, '\\') == NULL && + strchr(pszBeginTime, '\'') == NULL && + strchr(pszBeginTime, '\\') == NULL && + strchr(pszEndTime, '\'') == NULL && + strchr(pszEndTime, '\\') == NULL && msTimeGetResolution(pszBeginTime) >= 0 && msTimeGetResolution(pszEndTime) >= 0) { psFilterNode->psLeftNode = FLTCreateFilterEncodingNode(); - psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; + psFilterNode->psLeftNode->eType = FILTER_NODE_TYPE_PROPERTYNAME; psFilterNode->psLeftNode->pszValue = msStrdup(pszPropertyName); psFilterNode->psRightNode = FLTCreateFilterEncodingNode(); psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_TIME_PERIOD; - psFilterNode->psRightNode->pszValue = static_cast(msSmallMalloc( strlen(pszBeginTime) + strlen(pszEndTime) + 2 )); - sprintf(psFilterNode->psRightNode->pszValue, "%s/%s", pszBeginTime, pszEndTime); - } - else + psFilterNode->psRightNode->pszValue = static_cast( + msSmallMalloc(strlen(pszBeginTime) + strlen(pszEndTime) + 2)); + sprintf(psFilterNode->psRightNode->pszValue, "%s/%s", pszBeginTime, + pszEndTime); + } else psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } else { psFilterNode->eType = FILTER_NODE_TYPE_UNDEFINED; } - }/* end of is temporal */ - - - + } /* end of is temporal */ } } - /************************************************************************/ /* int FLTIsLogicalFilterType((char *pszValue) */ /* */ /* return TRUE if the value of the node is of logical filter */ /* encoding type. */ /************************************************************************/ -int FLTIsLogicalFilterType(const char *pszValue) -{ +int FLTIsLogicalFilterType(const char *pszValue) { if (pszValue) { - if (strcasecmp(pszValue, "AND") == 0 || - strcasecmp(pszValue, "OR") == 0 || + if (strcasecmp(pszValue, "AND") == 0 || strcasecmp(pszValue, "OR") == 0 || strcasecmp(pszValue, "NOT") == 0) return MS_TRUE; } @@ -1728,8 +1700,7 @@ int FLTIsLogicalFilterType(const char *pszValue) /* */ /* Binary comparison filter type. */ /************************************************************************/ -int FLTIsBinaryComparisonFilterType(const char *pszValue) -{ +int FLTIsBinaryComparisonFilterType(const char *pszValue) { if (pszValue) { if (strcasecmp(pszValue, "PropertyIsEqualTo") == 0 || strcasecmp(pszValue, "PropertyIsNotEqualTo") == 0 || @@ -1749,8 +1720,7 @@ int FLTIsBinaryComparisonFilterType(const char *pszValue) /* return TRUE if the value of the node is of comparison filter */ /* encoding type. */ /************************************************************************/ -int FLTIsComparisonFilterType(const char *pszValue) -{ +int FLTIsComparisonFilterType(const char *pszValue) { if (pszValue) { if (FLTIsBinaryComparisonFilterType(pszValue) || strcasecmp(pszValue, "PropertyIsLike") == 0 || @@ -1769,8 +1739,7 @@ int FLTIsComparisonFilterType(const char *pszValue) /* return TRUE if the value of the node is of featureid filter */ /* encoding type. */ /************************************************************************/ -int FLTIsFeatureIdFilterType(const char *pszValue) -{ +int FLTIsFeatureIdFilterType(const char *pszValue) { if (pszValue && (strcasecmp(pszValue, "FeatureId") == 0 || strcasecmp(pszValue, "GmlObjectId") == 0 || strcasecmp(pszValue, "ResourceId") == 0)) @@ -1786,21 +1755,20 @@ int FLTIsFeatureIdFilterType(const char *pszValue) /* return TRUE if the value of the node is of spatial filter */ /* encoding type. */ /************************************************************************/ -int FLTIsSpatialFilterType(const char *pszValue) -{ +int FLTIsSpatialFilterType(const char *pszValue) { if (pszValue) { - if ( strcasecmp(pszValue, "BBOX") == 0 || - strcasecmp(pszValue, "DWithin") == 0 || - strcasecmp(pszValue, "Intersect") == 0 || - strcasecmp(pszValue, "Intersects") == 0 || - strcasecmp(pszValue, "Equals") == 0 || - strcasecmp(pszValue, "Disjoint") == 0 || - strcasecmp(pszValue, "Touches") == 0 || - strcasecmp(pszValue, "Crosses") == 0 || - strcasecmp(pszValue, "Within") == 0 || - strcasecmp(pszValue, "Contains") == 0 || - strcasecmp(pszValue, "Overlaps") == 0 || - strcasecmp(pszValue, "Beyond") == 0) + if (strcasecmp(pszValue, "BBOX") == 0 || + strcasecmp(pszValue, "DWithin") == 0 || + strcasecmp(pszValue, "Intersect") == 0 || + strcasecmp(pszValue, "Intersects") == 0 || + strcasecmp(pszValue, "Equals") == 0 || + strcasecmp(pszValue, "Disjoint") == 0 || + strcasecmp(pszValue, "Touches") == 0 || + strcasecmp(pszValue, "Crosses") == 0 || + strcasecmp(pszValue, "Within") == 0 || + strcasecmp(pszValue, "Contains") == 0 || + strcasecmp(pszValue, "Overlaps") == 0 || + strcasecmp(pszValue, "Beyond") == 0) return MS_TRUE; } @@ -1813,10 +1781,9 @@ int FLTIsSpatialFilterType(const char *pszValue) /* return TRUE if the value of the node is of temporal filter */ /* encoding type. */ /************************************************************************/ -int FLTIsTemporalFilterType(const char *pszValue) -{ +int FLTIsTemporalFilterType(const char *pszValue) { if (pszValue) { - if ( strcasecmp(pszValue, "During") == 0 ) + if (strcasecmp(pszValue, "During") == 0) return MS_TRUE; } @@ -1829,8 +1796,7 @@ int FLTIsTemporalFilterType(const char *pszValue) /* Verfify if the value of the node is one of the supported */ /* filter type. */ /************************************************************************/ -int FLTIsSupportedFilterType(CPLXMLNode *psXMLNode) -{ +int FLTIsSupportedFilterType(CPLXMLNode *psXMLNode) { if (psXMLNode) { if (FLTIsLogicalFilterType(psXMLNode->pszValue) || FLTIsSpatialFilterType(psXMLNode->pszValue) || @@ -1849,15 +1815,15 @@ int FLTIsSupportedFilterType(CPLXMLNode *psXMLNode) /* Loop trhough the nodes and return the number of nodes of */ /* specified value. */ /************************************************************************/ -int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, const char *szType) -{ +int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, + const char *szType) { int nCount = 0; - int nLeftNode=0 , nRightNode = 0; + int nLeftNode = 0, nRightNode = 0; if (!psFilterNode || !szType || !psFilterNode->pszValue) return 0; - if (strcasecmp(psFilterNode->pszValue, (char*)szType) == 0) + if (strcasecmp(psFilterNode->pszValue, (char *)szType) == 0) nCount++; if (psFilterNode->psLeftNode) @@ -1872,9 +1838,6 @@ int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, const char *szType) return nCount; } - - - /************************************************************************/ /* FLTValidForBBoxFilter */ /* */ @@ -1886,7 +1849,8 @@ int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, const char *szType) /* eg 1: */ /* */ /* Geometry */ -/* */ +/* */ /* 13.0983,31.5899 35.5472,42.8143*/ /* */ /* */ @@ -1896,7 +1860,8 @@ int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, const char *szType) /* */ /* */ /* Geometry */ -/* */ +/* */ /* 13.0983,31.5899 35.5472,42.8143*/ /* */ /* */ @@ -1908,8 +1873,7 @@ int FLTNumberOfFilterType(FilterEncodingNode *psFilterNode, const char *szType) /* */ /* */ /************************************************************************/ -int FLTValidForBBoxFilter(FilterEncodingNode *psFilterNode) -{ +int FLTValidForBBoxFilter(FilterEncodingNode *psFilterNode) { int nCount = 0; if (!psFilterNode || !psFilterNode->pszValue) @@ -1962,8 +1926,7 @@ static int FLTHasUniqueTopLevelDuringFilter(FilterEncodingNode *psFilterNode) } #endif -int FLTIsLineFilter(FilterEncodingNode *psFilterNode) -{ +int FLTIsLineFilter(FilterEncodingNode *psFilterNode) { if (!psFilterNode || !psFilterNode->pszValue) return 0; @@ -1975,8 +1938,7 @@ int FLTIsLineFilter(FilterEncodingNode *psFilterNode) return 0; } -int FLTIsPolygonFilter(FilterEncodingNode *psFilterNode) -{ +int FLTIsPolygonFilter(FilterEncodingNode *psFilterNode) { if (!psFilterNode || !psFilterNode->pszValue) return 0; @@ -1988,8 +1950,7 @@ int FLTIsPolygonFilter(FilterEncodingNode *psFilterNode) return 0; } -int FLTIsPointFilter(FilterEncodingNode *psFilterNode) -{ +int FLTIsPointFilter(FilterEncodingNode *psFilterNode) { if (!psFilterNode || !psFilterNode->pszValue) return 0; @@ -2001,8 +1962,7 @@ int FLTIsPointFilter(FilterEncodingNode *psFilterNode) return 0; } -int FLTIsBBoxFilter(FilterEncodingNode *psFilterNode) -{ +int FLTIsBBoxFilter(FilterEncodingNode *psFilterNode) { if (!psFilterNode || !psFilterNode->pszValue) return 0; @@ -2013,8 +1973,7 @@ int FLTIsBBoxFilter(FilterEncodingNode *psFilterNode) } shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, double *pdfDistance, - int *pnUnit) -{ + int *pnUnit) { char **tokens = NULL; int nTokens = 0; FilterEncodingNode *psNode = psFilterNode; @@ -2033,7 +1992,7 @@ shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, double *pdfDistance, if unit is there syntax is "URI#unit" (eg http://..../#m) or just "unit" */ - tokens = msStringSplit(psNode->pszValue,';', &nTokens); + tokens = msStringSplit(psNode->pszValue, ';', &nTokens); if (tokens && nTokens >= 1) { *pdfDistance = atof(tokens[0]); @@ -2041,41 +2000,40 @@ shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, double *pdfDistance, szUnitStr = msStrdup(tokens[1]); msFreeCharArray(tokens, nTokens); nTokens = 0; - tokens = msStringSplit(szUnitStr,'#', &nTokens); + tokens = msStringSplit(szUnitStr, '#', &nTokens); msFree(szUnitStr); if (tokens && nTokens >= 1) { - if (nTokens ==1) + if (nTokens == 1) szUnit = tokens[0]; else szUnit = tokens[1]; - if (strcasecmp(szUnit,"m") == 0 || - strcasecmp(szUnit,"meters") == 0 ) + if (strcasecmp(szUnit, "m") == 0 || + strcasecmp(szUnit, "meters") == 0) *pnUnit = MS_METERS; - else if (strcasecmp(szUnit,"km") == 0 || - strcasecmp(szUnit,"kilometers") == 0) + else if (strcasecmp(szUnit, "km") == 0 || + strcasecmp(szUnit, "kilometers") == 0) *pnUnit = MS_KILOMETERS; - else if (strcasecmp(szUnit,"NM") == 0 || - strcasecmp(szUnit,"nauticalmiles") == 0) + else if (strcasecmp(szUnit, "NM") == 0 || + strcasecmp(szUnit, "nauticalmiles") == 0) *pnUnit = MS_NAUTICALMILES; - else if (strcasecmp(szUnit,"mi") == 0 || - strcasecmp(szUnit,"miles") == 0) + else if (strcasecmp(szUnit, "mi") == 0 || + strcasecmp(szUnit, "miles") == 0) *pnUnit = MS_MILES; - else if (strcasecmp(szUnit,"in") == 0 || - strcasecmp(szUnit,"inches") == 0) + else if (strcasecmp(szUnit, "in") == 0 || + strcasecmp(szUnit, "inches") == 0) *pnUnit = MS_INCHES; - else if (strcasecmp(szUnit,"ft") == 0 || - strcasecmp(szUnit,"feet") == 0) + else if (strcasecmp(szUnit, "ft") == 0 || + strcasecmp(szUnit, "feet") == 0) *pnUnit = MS_FEET; - else if (strcasecmp(szUnit,"deg") == 0 || - strcasecmp(szUnit,"dd") == 0) + else if (strcasecmp(szUnit, "deg") == 0 || + strcasecmp(szUnit, "dd") == 0) *pnUnit = MS_DD; - else if (strcasecmp(szUnit,"px") == 0) + else if (strcasecmp(szUnit, "px") == 0) *pnUnit = MS_PIXELS; - } } - } + } msFreeCharArray(tokens, nTokens); } @@ -2092,43 +2050,43 @@ shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, double *pdfDistance, /* first bbox node found. The retrun value is the epsg code of */ /* the bbox. */ /************************************************************************/ -const char *FLTGetBBOX(FilterEncodingNode *psFilterNode, rectObj *psRect) -{ +const char *FLTGetBBOX(FilterEncodingNode *psFilterNode, rectObj *psRect) { const char *pszReturn = NULL; if (!psFilterNode || !psRect) return NULL; - if (psFilterNode->pszValue && strcasecmp(psFilterNode->pszValue, "BBOX") == 0) { + if (psFilterNode->pszValue && + strcasecmp(psFilterNode->pszValue, "BBOX") == 0) { if (psFilterNode->psRightNode && psFilterNode->psRightNode->pOther) { - rectObj* pRect= (rectObj *)psFilterNode->psRightNode->pOther; + rectObj *pRect = (rectObj *)psFilterNode->psRightNode->pOther; psRect->minx = pRect->minx; psRect->miny = pRect->miny; psRect->maxx = pRect->maxx; psRect->maxy = pRect->maxy; return psFilterNode->pszSRS; - } } else { pszReturn = FLTGetBBOX(psFilterNode->psLeftNode, psRect); if (pszReturn) return pszReturn; else - return FLTGetBBOX(psFilterNode->psRightNode, psRect); + return FLTGetBBOX(psFilterNode->psRightNode, psRect); } return pszReturn; } -const char* FLTGetDuring(FilterEncodingNode *psFilterNode, const char** ppszTimeField) -{ +const char *FLTGetDuring(FilterEncodingNode *psFilterNode, + const char **ppszTimeField) { const char *pszReturn = NULL; if (!psFilterNode || !ppszTimeField) return NULL; - if (psFilterNode->pszValue && strcasecmp(psFilterNode->pszValue, "During") == 0) { + if (psFilterNode->pszValue && + strcasecmp(psFilterNode->pszValue, "During") == 0) { *ppszTimeField = psFilterNode->psLeftNode->pszValue; return psFilterNode->psRightNode->pszValue; } else { @@ -2136,7 +2094,7 @@ const char* FLTGetDuring(FilterEncodingNode *psFilterNode, const char** ppszTime if (pszReturn) return pszReturn; else - return FLTGetDuring(psFilterNode->psRightNode, ppszTimeField); + return FLTGetDuring(psFilterNode->psRightNode, ppszTimeField); } return pszReturn; @@ -2147,59 +2105,52 @@ const char* FLTGetDuring(FilterEncodingNode *psFilterNode, const char** ppszTime /* */ /* Build SQL expressions from the mapserver nodes. */ /************************************************************************/ -char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp) { char *pszExpression = NULL; if (psFilterNode == NULL || lp == NULL) return NULL; if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON) { - if ( psFilterNode->psLeftNode && psFilterNode->psRightNode) { + if (psFilterNode->psLeftNode && psFilterNode->psRightNode) { if (FLTIsBinaryComparisonFilterType(psFilterNode->pszValue)) { + pszExpression = FLTGetBinaryComparisonSQLExpresssion(psFilterNode, lp); + } else if (strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0) { pszExpression = - FLTGetBinaryComparisonSQLExpresssion(psFilterNode, lp); - } else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsBetween") == 0) { - pszExpression = - FLTGetIsBetweenComparisonSQLExpresssion(psFilterNode, lp); - } else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsLike") == 0) { - pszExpression = - FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp); - + FLTGetIsBetweenComparisonSQLExpresssion(psFilterNode, lp); + } else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) { + pszExpression = FLTGetIsLikeComparisonSQLExpression(psFilterNode, lp); } } } else if (psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL) { if (strcasecmp(psFilterNode->pszValue, "AND") == 0 || strcasecmp(psFilterNode->pszValue, "OR") == 0) { - pszExpression = - FLTGetLogicalComparisonSQLExpresssion(psFilterNode, lp); + pszExpression = FLTGetLogicalComparisonSQLExpresssion(psFilterNode, lp); } else if (strcasecmp(psFilterNode->pszValue, "NOT") == 0) { - pszExpression = - FLTGetLogicalComparisonSQLExpresssion(psFilterNode, lp); - + pszExpression = FLTGetLogicalComparisonSQLExpresssion(psFilterNode, lp); } } else if (psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL) { /* TODO */ } else if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID) { -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) if (psFilterNode->pszValue) { - const char *pszAttribute = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); + const char *pszAttribute = + msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); if (pszAttribute) { int nTokens = 0; - char **tokens = msStringSplit(psFilterNode->pszValue,',', &nTokens); + char **tokens = msStringSplit(psFilterNode->pszValue, ',', &nTokens); int bString = 0; if (tokens && nTokens > 0) { - for (int i=0; iconnectiontype == MS_OGR || lp->connectiontype == MS_POSTGIS ) - snprintf(szTmp, sizeof(szTmp), "(CAST(%s AS CHARACTER(255)) = '%s')" , pszAttribute, pszEscapedStr); + if (bString) { + if (lp->connectiontype == MS_OGR || + lp->connectiontype == MS_POSTGIS) + snprintf(szTmp, sizeof(szTmp), + "(CAST(%s AS CHARACTER(255)) = '%s')", pszAttribute, + pszEscapedStr); else - snprintf(szTmp, sizeof(szTmp), "(%s = '%s')" , pszAttribute, pszEscapedStr); - } - else - snprintf(szTmp, sizeof(szTmp), "(%s = %s)" , pszAttribute, pszEscapedStr); + snprintf(szTmp, sizeof(szTmp), "(%s = '%s')", pszAttribute, + pszEscapedStr); + } else + snprintf(szTmp, sizeof(szTmp), "(%s = %s)", pszAttribute, + pszEscapedStr); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; if (pszExpression != NULL) pszExpression = msStringConcatenate(pszExpression, " OR "); @@ -2243,9 +2197,8 @@ char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp) return NULL; #endif - } - else if ( lp->connectiontype != MS_OGR && - psFilterNode->eType == FILTER_NODE_TYPE_TEMPORAL ) + } else if (lp->connectiontype != MS_OGR && + psFilterNode->eType == FILTER_NODE_TYPE_TEMPORAL) pszExpression = msStrdup(FLTGetTimeExpression(psFilterNode, lp).c_str()); return pszExpression; @@ -2257,8 +2210,7 @@ char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp) /* Return the expression for logical comparison expression. */ /************************************************************************/ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, - layerObj *lp) -{ + layerObj *lp) { char *pszBuffer = NULL; char *pszTmp = NULL; @@ -2286,10 +2238,10 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* ==================================================================== */ /* special case for temporal filter node (OGR layer only) */ /* ==================================================================== */ - else if (lp->connectiontype == MS_OGR && - psFilterNode->psLeftNode && psFilterNode->psRightNode && - (psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_TEMPORAL || - psFilterNode->psRightNode->eType == FILTER_NODE_TYPE_TEMPORAL) ) { + else if (lp->connectiontype == MS_OGR && psFilterNode->psLeftNode && + psFilterNode->psRightNode && + (psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_TEMPORAL || + psFilterNode->psRightNode->eType == FILTER_NODE_TYPE_TEMPORAL)) { if (psFilterNode->psLeftNode->eType != FILTER_NODE_TYPE_TEMPORAL) pszTmp = FLTGetSQLExpression(psFilterNode->psLeftNode, lp); else @@ -2301,7 +2253,7 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, pszBuffer = (char *)malloc(sizeof(char) * (strlen(pszTmp) + 1)); sprintf(pszBuffer, "%s", pszTmp); } - + /* -------------------------------------------------------------------- */ /* OR and AND */ /* -------------------------------------------------------------------- */ @@ -2310,9 +2262,8 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, if (!pszTmp) return NULL; - pszBuffer = (char *)malloc(sizeof(char) * - (strlen(pszTmp) + - strlen(psFilterNode->pszValue) + 5)); + pszBuffer = (char *)malloc( + sizeof(char) * (strlen(pszTmp) + strlen(psFilterNode->pszValue) + 5)); pszBuffer[0] = '\0'; strcat(pszBuffer, " ("); strcat(pszBuffer, pszTmp); @@ -2320,7 +2271,7 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, strcat(pszBuffer, psFilterNode->pszValue); strcat(pszBuffer, " "); - free( pszTmp ); + free(pszTmp); const size_t nTmp = strlen(pszBuffer); pszTmp = FLTGetSQLExpression(psFilterNode->psRightNode, lp); @@ -2329,8 +2280,8 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, return NULL; } - pszBuffer = (char *)msSmallRealloc(pszBuffer, - sizeof(char) * (strlen(pszTmp) + nTmp +3)); + pszBuffer = (char *)msSmallRealloc( + pszBuffer, sizeof(char) * (strlen(pszTmp) + nTmp + 3)); strcat(pszBuffer, pszTmp); strcat(pszBuffer, ") "); } @@ -2343,7 +2294,7 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, if (!pszTmp) return NULL; - pszBuffer = (char *)malloc(sizeof(char) * (strlen(pszTmp) + 9)); + pszBuffer = (char *)malloc(sizeof(char) * (strlen(pszTmp) + 9)); pszBuffer[0] = '\0'; strcat(pszBuffer, " (NOT "); @@ -2355,30 +2306,26 @@ char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ - if( pszTmp != NULL ) - free( pszTmp ); + if (pszTmp != NULL) + free(pszTmp); return pszBuffer; - } - /************************************************************************/ /* FLTGetBinaryComparisonSQLExpresssion */ /* */ /* Return the expression for a binary comparison filter node. */ /************************************************************************/ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, - layerObj *lp) -{ + layerObj *lp) { const size_t bufferSize = 1024; char szBuffer[1024]; - int bString=0; + int bString = 0; char szTmp[256]; - char* pszEscapedStr = NULL; + char *pszEscapedStr = NULL; szBuffer[0] = '\0'; - if (!psFilterNode || ! - FLTIsBinaryComparisonFilterType(psFilterNode->pszValue)) + if (!psFilterNode || !FLTIsBinaryComparisonFilterType(psFilterNode->pszValue)) return NULL; /* -------------------------------------------------------------------- */ @@ -2387,10 +2334,11 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* -------------------------------------------------------------------- */ bString = 0; if (psFilterNode->psRightNode->pszValue) { - const char* pszOFGType; - snprintf(szTmp, sizeof(szTmp), "%s_type", psFilterNode->psLeftNode->pszValue); + const char *pszOFGType; + snprintf(szTmp, sizeof(szTmp), "%s_type", + psFilterNode->psLeftNode->pszValue); pszOFGType = msOWSLookupMetadata(&(lp->metadata), "OFG", szTmp); - if (pszOFGType!= NULL && strcasecmp(pszOFGType, "Character") == 0) + if (pszOFGType != NULL && strcasecmp(pszOFGType, "Character") == 0) bString = 1; else if (FLTIsNumeric(psFilterNode->psRightNode->pszValue) == MS_FALSE) @@ -2401,21 +2349,18 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, if (psFilterNode->psRightNode->pszValue == NULL) bString = 1; - /*opening bracket*/ strlcat(szBuffer, " (", bufferSize); - pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); - + pszEscapedStr = + msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); /* attribute */ /*case insensitive set ? */ - if (bString && - strcasecmp(psFilterNode->pszValue, - "PropertyIsEqualTo") == 0 && + if (bString && strcasecmp(psFilterNode->pszValue, "PropertyIsEqualTo") == 0 && psFilterNode->psRightNode->pOther && (*(int *)psFilterNode->psRightNode->pOther) == 1) { - snprintf(szTmp, sizeof(szTmp), "lower(%s) ", pszEscapedStr); + snprintf(szTmp, sizeof(szTmp), "lower(%s) ", pszEscapedStr); strlcat(szBuffer, szTmp, bufferSize); } else strlcat(szBuffer, pszEscapedStr, bufferSize); @@ -2423,22 +2368,17 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, msFree(pszEscapedStr); pszEscapedStr = NULL; - /* logical operator */ - if (strcasecmp(psFilterNode->pszValue, - "PropertyIsEqualTo") == 0) + if (strcasecmp(psFilterNode->pszValue, "PropertyIsEqualTo") == 0) strlcat(szBuffer, "=", bufferSize); - else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsNotEqualTo") == 0) + else if (strcasecmp(psFilterNode->pszValue, "PropertyIsNotEqualTo") == 0) strlcat(szBuffer, "<>", bufferSize); - else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsLessThan") == 0) + else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLessThan") == 0) strlcat(szBuffer, "<", bufferSize); - else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsGreaterThan") == 0) + else if (strcasecmp(psFilterNode->pszValue, "PropertyIsGreaterThan") == 0) strlcat(szBuffer, ">", bufferSize); - else if (strcasecmp(psFilterNode->pszValue, - "PropertyIsLessThanOrEqualTo") == 0) + else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLessThanOrEqualTo") == + 0) strlcat(szBuffer, "<=", bufferSize); else if (strcasecmp(psFilterNode->pszValue, "PropertyIsGreaterThanOrEqualTo") == 0) @@ -2448,14 +2388,13 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* value */ - if (bString && - psFilterNode->psRightNode->pszValue && - strcasecmp(psFilterNode->pszValue, - "PropertyIsEqualTo") == 0 && + if (bString && psFilterNode->psRightNode->pszValue && + strcasecmp(psFilterNode->pszValue, "PropertyIsEqualTo") == 0 && psFilterNode->psRightNode->pOther && (*(int *)psFilterNode->psRightNode->pOther) == 1) { - char* pszEscapedStr; - pszEscapedStr = msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue); + char *pszEscapedStr; + pszEscapedStr = + msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue); snprintf(szTmp, sizeof(szTmp), "lower('%s') ", pszEscapedStr); msFree(pszEscapedStr); strlcat(szBuffer, szTmp, bufferSize); @@ -2465,18 +2404,18 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, if (psFilterNode->psRightNode->pszValue) { if (bString) { - char* pszEscapedStr; - pszEscapedStr = msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue); + char *pszEscapedStr; + pszEscapedStr = + msLayerEscapeSQLParam(lp, psFilterNode->psRightNode->pszValue); strlcat(szBuffer, pszEscapedStr, bufferSize); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; } else strlcat(szBuffer, psFilterNode->psRightNode->pszValue, bufferSize); } if (bString) strlcat(szBuffer, "'", bufferSize); - } /*closing bracket*/ strlcat(szBuffer, ") ", bufferSize); @@ -2484,29 +2423,27 @@ char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, return msStrdup(szBuffer); } - /************************************************************************/ /* FLTGetIsBetweenComparisonSQLExpresssion */ /* */ /* Build an SQL expresssion for IsBteween Filter. */ /************************************************************************/ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, - layerObj *lp) -{ + layerObj *lp) { const size_t bufferSize = 1024; char szBuffer[1024]; char **aszBounds = NULL; int nBounds = 0; - int bString=0; + int bString = 0; char szTmp[256]; - char* pszEscapedStr; + char *pszEscapedStr; szBuffer[0] = '\0'; if (!psFilterNode || !(strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0)) return NULL; - if (!psFilterNode->psLeftNode || !psFilterNode->psRightNode ) + if (!psFilterNode->psLeftNode || !psFilterNode->psRightNode) return NULL; /* -------------------------------------------------------------------- */ @@ -2523,10 +2460,11 @@ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* -------------------------------------------------------------------- */ bString = 0; if (aszBounds[0]) { - const char* pszOFGType; - snprintf(szTmp, sizeof(szTmp), "%s_type", psFilterNode->psLeftNode->pszValue); + const char *pszOFGType; + snprintf(szTmp, sizeof(szTmp), "%s_type", + psFilterNode->psLeftNode->pszValue); pszOFGType = msOWSLookupMetadata(&(lp->metadata), "OFG", szTmp); - if (pszOFGType!= NULL && strcasecmp(pszOFGType, "Character") == 0) + if (pszOFGType != NULL && strcasecmp(pszOFGType, "Character") == 0) bString = 1; else if (FLTIsNumeric(aszBounds[0]) == MS_FALSE) bString = 1; @@ -2538,7 +2476,6 @@ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, } } - /* -------------------------------------------------------------------- */ /* build expresssion. */ /* -------------------------------------------------------------------- */ @@ -2546,7 +2483,8 @@ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, strlcat(szBuffer, " (", bufferSize); /* attribute */ - pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); + pszEscapedStr = + msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); strlcat(szBuffer, pszEscapedStr, bufferSize); msFree(pszEscapedStr); @@ -2557,27 +2495,27 @@ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /*bound 1*/ if (bString) - strlcat(szBuffer,"'", bufferSize); - pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[0]); + strlcat(szBuffer, "'", bufferSize); + pszEscapedStr = msLayerEscapeSQLParam(lp, aszBounds[0]); strlcat(szBuffer, pszEscapedStr, bufferSize); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; if (bString) - strlcat(szBuffer,"'", bufferSize); + strlcat(szBuffer, "'", bufferSize); strlcat(szBuffer, " AND ", bufferSize); /*bound 2*/ if (bString) strlcat(szBuffer, "'", bufferSize); - pszEscapedStr = msLayerEscapeSQLParam( lp, aszBounds[1]); + pszEscapedStr = msLayerEscapeSQLParam(lp, aszBounds[1]); strlcat(szBuffer, pszEscapedStr, bufferSize); msFree(pszEscapedStr); - pszEscapedStr=NULL; + pszEscapedStr = NULL; if (bString) - strlcat(szBuffer,"'", bufferSize); + strlcat(szBuffer, "'", bufferSize); /*closing paranthesis*/ strlcat(szBuffer, ")", bufferSize); @@ -2593,8 +2531,7 @@ char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, /* Build an sql expression for IsLike filter. */ /************************************************************************/ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, - layerObj *lp) -{ + layerObj *lp) { const size_t bufferSize = 1024; char szBuffer[1024]; char *pszValue = NULL; @@ -2604,11 +2541,11 @@ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, const char *pszEscape = NULL; char szTmp[4]; - int nLength=0, i=0, j=0; - int bCaseInsensitive = 0; + int nLength = 0, i = 0, j = 0; + int bCaseInsensitive = 0; char *pszEscapedStr = NULL; - FEPropertyIsLike* propIsLike; + FEPropertyIsLike *propIsLike; if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode || !psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue) @@ -2620,27 +2557,28 @@ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, pszEscape = propIsLike->pszEscapeChar; bCaseInsensitive = propIsLike->bCaseInsensitive; - if (!pszWild || strlen(pszWild) == 0 || - !pszSingle || strlen(pszSingle) == 0 || - !pszEscape || strlen(pszEscape) == 0) + if (!pszWild || strlen(pszWild) == 0 || !pszSingle || + strlen(pszSingle) == 0 || !pszEscape || strlen(pszEscape) == 0) return NULL; if (pszEscape[0] == '\'') { /* This might be valid, but the risk of SQL injection is too high */ /* and the below code is not ready for that */ /* Someone who does this has clearly suspect intentions ! */ - msSetError(MS_MISCERR, "Single quote character is not allowed as an escaping character.", - "FLTGetIsLikeComparisonSQLExpression()"); + msSetError( + MS_MISCERR, + "Single quote character is not allowed as an escaping character.", + "FLTGetIsLikeComparisonSQLExpression()"); return NULL; } - szBuffer[0] = '\0'; /*opening bracket*/ strlcat(szBuffer, " (", bufferSize); /* attribute name */ - pszEscapedStr = msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); + pszEscapedStr = + msLayerEscapePropertyName(lp, psFilterNode->psLeftNode->pszValue); strlcat(szBuffer, pszEscapedStr, bufferSize); msFree(pszEscapedStr); @@ -2657,13 +2595,11 @@ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, pszValue = psFilterNode->psRightNode->pszValue; nLength = strlen(pszValue); - pszEscapedStr = (char*) msSmallMalloc( 3 * nLength + 1); + pszEscapedStr = (char *)msSmallMalloc(3 * nLength + 1); - for (i=0, j=0; iconnectiontype != MS_OGR) { if (lp->connectiontype == MS_POSTGIS && pszEscape[0] == '\\') - strlcat(szBuffer, " escape E'", bufferSize); + strlcat(szBuffer, " escape E'", bufferSize); else - strlcat(szBuffer, " escape '", bufferSize); + strlcat(szBuffer, " escape '", bufferSize); szTmp[0] = pszEscape[0]; if (pszEscape[0] == '\\') { szTmp[1] = '\\'; @@ -2709,9 +2645,9 @@ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, szTmp[2] = '\0'; } - strlcat(szBuffer, szTmp, bufferSize); + strlcat(szBuffer, szTmp, bufferSize); } - strlcat(szBuffer, ") ", bufferSize); + strlcat(szBuffer, ") ", bufferSize); return msStrdup(szBuffer); } @@ -2722,8 +2658,7 @@ char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, /* Utility function to see if a spatial filter is included in */ /* the node. */ /************************************************************************/ -int FLTHasSpatialFilter(FilterEncodingNode *psNode) -{ +int FLTHasSpatialFilter(FilterEncodingNode *psNode) { int bResult = MS_FALSE; if (!psNode) @@ -2745,41 +2680,36 @@ int FLTHasSpatialFilter(FilterEncodingNode *psNode) FLTIsLineFilter(psNode) || FLTIsPolygonFilter(psNode)) return MS_TRUE; - return MS_FALSE; } - /************************************************************************/ /* FLTCreateFeatureIdFilterEncoding */ /* */ /* Utility function to create a filter node of FeatureId type. */ /************************************************************************/ -FilterEncodingNode *FLTCreateFeatureIdFilterEncoding(const char *pszString) -{ +FilterEncodingNode *FLTCreateFeatureIdFilterEncoding(const char *pszString) { FilterEncodingNode *psFilterNode = NULL; if (pszString) { psFilterNode = FLTCreateFilterEncodingNode(); psFilterNode->eType = FILTER_NODE_TYPE_FEATUREID; - psFilterNode->pszValue = msStrdup(pszString); + psFilterNode->pszValue = msStrdup(pszString); return psFilterNode; } return NULL; } - /************************************************************************/ /* FLTParseGMLBox */ /* */ /* Parse gml box. Used for FE 1.0 */ /************************************************************************/ -int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) -{ +int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) { int bCoordinatesValid = 0; CPLXMLNode *psCoordinates = NULL; CPLXMLNode *psCoord1 = NULL, *psCoord2 = NULL; - char **papszCoords=NULL, **papszMin=NULL, **papszMax = NULL; + char **papszCoords = NULL, **papszMin = NULL, **papszMax = NULL; int nCoords = 0, nCoordsMin = 0, nCoordsMax = 0; const char *pszTmpCoord = NULL; const char *pszSRS = NULL; @@ -2794,11 +2724,11 @@ int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) psCoordinates = CPLGetXMLNode(psBox, "coordinates"); pszTS = CPLGetXMLValue(psCoordinates, "ts", NULL); - if( pszTS == NULL ) - pszTS = " "; + if (pszTS == NULL) + pszTS = " "; pszCS = CPLGetXMLValue(psCoordinates, "cs", NULL); - if( pszCS == NULL ) - pszCS = ","; + if (pszCS == NULL) + pszCS = ","; pszTmpCoord = CPLGetXMLValue(psCoordinates, NULL, NULL); if (pszTmpCoord) { @@ -2809,11 +2739,11 @@ int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) papszMax = msStringSplit(papszCoords[1], pszCS[0], &nCoordsMax); } if (papszMax && nCoordsMax == 2) { - bCoordinatesValid =1; - minx = atof(papszMin[0]); - miny = atof(papszMin[1]); - maxx = atof(papszMax[0]); - maxy = atof(papszMax[1]); + bCoordinatesValid = 1; + minx = atof(papszMin[0]); + miny = atof(papszMin[1]); + maxx = atof(papszMax[0]); + maxy = atof(papszMax[1]); } msFreeCharArray(papszMin, nCoordsMin); @@ -2825,8 +2755,8 @@ int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) psCoord1 = CPLGetXMLNode(psBox, "coord"); psCoord2 = FLTGetNextSibblingNode(psCoord1); if (psCoord1 && psCoord2 && strcmp(psCoord2->pszValue, "coord") == 0) { - const char* pszX = CPLGetXMLValue(psCoord1, "X", NULL); - const char* pszY = CPLGetXMLValue(psCoord1, "Y", NULL); + const char *pszX = CPLGetXMLValue(psCoord1, "X", NULL); + const char *pszY = CPLGetXMLValue(psCoord1, "Y", NULL); if (pszX && pszY) { minx = atof(pszX); miny = atof(pszY); @@ -2840,16 +2770,15 @@ int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) } } } - } } if (bCoordinatesValid) { - psBbox->minx = minx; - psBbox->miny = miny; + psBbox->minx = minx; + psBbox->miny = miny; - psBbox->maxx = maxx; - psBbox->maxy = maxy; + psBbox->maxx = maxx; + psBbox->maxy = maxy; } return bCoordinatesValid; @@ -2859,21 +2788,20 @@ int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS) /* */ /* Utility function to parse a gml:Envelope (used for SOS and FE1.1)*/ /************************************************************************/ -int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, char **ppszSRS) -{ - CPLXMLNode *psUpperCorner=NULL, *psLowerCorner=NULL; - const char *pszLowerCorner=NULL, *pszUpperCorner=NULL; +int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, char **ppszSRS) { + CPLXMLNode *psUpperCorner = NULL, *psLowerCorner = NULL; + const char *pszLowerCorner = NULL, *pszUpperCorner = NULL; int bValid = 0; char **tokens; int n; if (psRoot && psBbox && psRoot->eType == CXT_Element && - EQUAL(psRoot->pszValue,"Envelope")) { + EQUAL(psRoot->pszValue, "Envelope")) { /*Get the srs if available*/ if (ppszSRS) { - const char* pszSRS = CPLGetXMLValue(psRoot, "srsName", NULL); - if( pszSRS != NULL ) - *ppszSRS = msStrdup(pszSRS); + const char *pszSRS = CPLGetXMLValue(psRoot, "srsName", NULL); + if (pszSRS != NULL) + *ppszSRS = msStrdup(pszSRS); } psLowerCorner = CPLSearchXMLNode(psRoot, "lowerCorner"); psUpperCorner = CPLSearchXMLNode(psRoot, "upperCorner"); @@ -2909,20 +2837,18 @@ int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, char **ppszSRS) /* FLTNeedSRSSwapping */ /************************************************************************/ -static int FLTNeedSRSSwapping( mapObj *map, const char* pszSRS ) -{ - int bNeedSwapping = MS_FALSE; - projectionObj sProjTmp; - msInitProjection(&sProjTmp); - if( map ) - { - msProjectionInheritContextFrom(&sProjTmp, &map->projection); - } - if (msLoadProjectionStringEPSG(&sProjTmp, pszSRS) == 0) { - bNeedSwapping = msIsAxisInvertedProj(&sProjTmp); - } - msFreeProjection(&sProjTmp); - return bNeedSwapping; +static int FLTNeedSRSSwapping(mapObj *map, const char *pszSRS) { + int bNeedSwapping = MS_FALSE; + projectionObj sProjTmp; + msInitProjection(&sProjTmp); + if (map) { + msProjectionInheritContextFrom(&sProjTmp, &map->projection); + } + if (msLoadProjectionStringEPSG(&sProjTmp, pszSRS) == 0) { + bNeedSwapping = msIsAxisInvertedProj(&sProjTmp); + } + msFreeProjection(&sProjTmp); + return bNeedSwapping; } /************************************************************************/ @@ -2934,55 +2860,46 @@ static int FLTNeedSRSSwapping( mapObj *map, const char* pszSRS ) /* caller will have to determine its value from a more general */ /* context. */ /************************************************************************/ -void FLTDoAxisSwappingIfNecessary(mapObj *map, - FilterEncodingNode *psFilterNode, - int bDefaultSRSNeedsAxisSwapping) -{ - if( psFilterNode == NULL ) - return; - - if( psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL && - psFilterNode->psRightNode->eType == FILTER_NODE_TYPE_BBOX ) - { - rectObj* rect = (rectObj *)psFilterNode->psRightNode->pOther; - const char* pszSRS = psFilterNode->pszSRS; - if( (pszSRS != NULL && FLTNeedSRSSwapping(map, pszSRS)) || - (pszSRS == NULL && bDefaultSRSNeedsAxisSwapping) ) - { - double tmp; - - tmp = rect->minx; - rect->minx = rect->miny; - rect->miny = tmp; - - tmp = rect->maxx; - rect->maxx = rect->maxy; - rect->maxy = tmp; - } - } - else if( psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL && - FLTIsGeometryFilterNodeType(psFilterNode->psRightNode->eType) ) - { - shapeObj* shape = (shapeObj *)(psFilterNode->psRightNode->pOther); - const char* pszSRS = psFilterNode->pszSRS; - if( (pszSRS != NULL && FLTNeedSRSSwapping(map, pszSRS)) || - (pszSRS == NULL && bDefaultSRSNeedsAxisSwapping) ) - { - msAxisSwapShape(shape); - } +void FLTDoAxisSwappingIfNecessary(mapObj *map, FilterEncodingNode *psFilterNode, + int bDefaultSRSNeedsAxisSwapping) { + if (psFilterNode == NULL) + return; + + if (psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL && + psFilterNode->psRightNode->eType == FILTER_NODE_TYPE_BBOX) { + rectObj *rect = (rectObj *)psFilterNode->psRightNode->pOther; + const char *pszSRS = psFilterNode->pszSRS; + if ((pszSRS != NULL && FLTNeedSRSSwapping(map, pszSRS)) || + (pszSRS == NULL && bDefaultSRSNeedsAxisSwapping)) { + double tmp; + + tmp = rect->minx; + rect->minx = rect->miny; + rect->miny = tmp; + + tmp = rect->maxx; + rect->maxx = rect->maxy; + rect->maxy = tmp; } - else - { - FLTDoAxisSwappingIfNecessary(map, psFilterNode->psLeftNode, bDefaultSRSNeedsAxisSwapping); - FLTDoAxisSwappingIfNecessary(map, psFilterNode->psRightNode, bDefaultSRSNeedsAxisSwapping); + } else if (psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL && + FLTIsGeometryFilterNodeType(psFilterNode->psRightNode->eType)) { + shapeObj *shape = (shapeObj *)(psFilterNode->psRightNode->pOther); + const char *pszSRS = psFilterNode->pszSRS; + if ((pszSRS != NULL && FLTNeedSRSSwapping(map, pszSRS)) || + (pszSRS == NULL && bDefaultSRSNeedsAxisSwapping)) { + msAxisSwapShape(shape); } + } else { + FLTDoAxisSwappingIfNecessary(map, psFilterNode->psLeftNode, + bDefaultSRSNeedsAxisSwapping); + FLTDoAxisSwappingIfNecessary(map, psFilterNode->psRightNode, + bDefaultSRSNeedsAxisSwapping); + } } - static void FLTReplacePropertyName(FilterEncodingNode *psFilterNode, const char *pszOldName, - const char *pszNewName) -{ + const char *pszNewName) { if (psFilterNode && pszOldName && pszNewName) { if (psFilterNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { if (psFilterNode->pszValue && @@ -2992,45 +2909,39 @@ static void FLTReplacePropertyName(FilterEncodingNode *psFilterNode, } } if (psFilterNode->psLeftNode) - FLTReplacePropertyName(psFilterNode->psLeftNode, pszOldName, - pszNewName); + FLTReplacePropertyName(psFilterNode->psLeftNode, pszOldName, pszNewName); if (psFilterNode->psRightNode) - FLTReplacePropertyName(psFilterNode->psRightNode, pszOldName, - pszNewName); + FLTReplacePropertyName(psFilterNode->psRightNode, pszOldName, pszNewName); } } - -static int FLTIsGMLDefaultProperty(const char* pszName) -{ - return (strcmp(pszName, "gml:name") == 0 || - strcmp(pszName, "gml:description") == 0 || - strcmp(pszName, "gml:descriptionReference") == 0 || - strcmp(pszName, "gml:identifier") == 0 || - strcmp(pszName, "gml:boundedBy") == 0 || - strcmp(pszName, "@gml:id") == 0); +static int FLTIsGMLDefaultProperty(const char *pszName) { + return (strcmp(pszName, "gml:name") == 0 || + strcmp(pszName, "gml:description") == 0 || + strcmp(pszName, "gml:descriptionReference") == 0 || + strcmp(pszName, "gml:identifier") == 0 || + strcmp(pszName, "gml:boundedBy") == 0 || + strcmp(pszName, "@gml:id") == 0); } -static void FLTStripNameSpacesFromPropertyName(FilterEncodingNode *psFilterNode) -{ - char **tokens=NULL; - int n=0; +static void +FLTStripNameSpacesFromPropertyName(FilterEncodingNode *psFilterNode) { + char **tokens = NULL; + int n = 0; if (psFilterNode) { if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && psFilterNode->psLeftNode != NULL && psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME && - FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue) ) - { - return; + FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue)) { + return; } if (psFilterNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { - if (psFilterNode->pszValue && - strstr(psFilterNode->pszValue, ":")) { + if (psFilterNode->pszValue && strstr(psFilterNode->pszValue, ":")) { tokens = msStringSplit(psFilterNode->pszValue, ':', &n); - if (tokens && n==2) { + if (tokens && n == 2) { msFree(psFilterNode->pszValue); psFilterNode->pszValue = msStrdup(tokens[1]); } @@ -3042,34 +2953,32 @@ static void FLTStripNameSpacesFromPropertyName(FilterEncodingNode *psFilterNode) if (psFilterNode->psRightNode) FLTStripNameSpacesFromPropertyName(psFilterNode->psRightNode); } - } static void FLTRemoveGroupName(FilterEncodingNode *psFilterNode, - gmlGroupListObj* groupList) -{ + gmlGroupListObj *groupList) { int i; if (psFilterNode) { if (psFilterNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { - if( psFilterNode->pszValue != NULL ) - { - const char* pszPropertyName = psFilterNode->pszValue; - const char* pszSlash = strchr(pszPropertyName, '/'); - if( pszSlash != NULL ) { - const char* pszColon = strchr(pszPropertyName, ':'); - if( pszColon != NULL && pszColon < pszSlash ) - pszPropertyName = pszColon + 1; - for(i=0;inumgroups;i++) { - const char* pszGroupName = groupList->groups[i].name; + if (psFilterNode->pszValue != NULL) { + const char *pszPropertyName = psFilterNode->pszValue; + const char *pszSlash = strchr(pszPropertyName, '/'); + if (pszSlash != NULL) { + const char *pszColon = strchr(pszPropertyName, ':'); + if (pszColon != NULL && pszColon < pszSlash) + pszPropertyName = pszColon + 1; + for (i = 0; i < groupList->numgroups; i++) { + const char *pszGroupName = groupList->groups[i].name; size_t nGroupNameLen = strlen(pszGroupName); - if(strncasecmp(pszPropertyName, pszGroupName, nGroupNameLen) == 0 && - pszPropertyName[nGroupNameLen] == '/') { - char* pszTmp; + if (strncasecmp(pszPropertyName, pszGroupName, nGroupNameLen) == + 0 && + pszPropertyName[nGroupNameLen] == '/') { + char *pszTmp; pszPropertyName = pszPropertyName + nGroupNameLen + 1; pszColon = strchr(pszPropertyName, ':'); - if( pszColon != NULL ) + if (pszColon != NULL) pszPropertyName = pszColon + 1; pszTmp = msStrdup(pszPropertyName); msFree(psFilterNode->pszValue); @@ -3086,7 +2995,6 @@ static void FLTRemoveGroupName(FilterEncodingNode *psFilterNode, if (psFilterNode->psRightNode) FLTRemoveGroupName(psFilterNode->psRightNode, groupList); } - } /************************************************************************/ @@ -3096,10 +3004,11 @@ static void FLTRemoveGroupName(FilterEncodingNode *psFilterNode, /* with their internal name. */ /************************************************************************/ void FLTPreParseFilterForAliasAndGroup(FilterEncodingNode *psFilterNode, - mapObj *map, int i, const char *namespaces) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) - if (psFilterNode && map && i>=0 && inumlayers) { + mapObj *map, int i, + const char *namespaces) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) + if (psFilterNode && map && i >= 0 && i < map->numlayers) { /*strip name spaces before hand*/ FLTStripNameSpacesFromPropertyName(psFilterNode); @@ -3107,24 +3016,26 @@ void FLTPreParseFilterForAliasAndGroup(FilterEncodingNode *psFilterNode, int layerWasOpened = msLayerIsOpen(lp); if (msLayerOpen(lp) == MS_SUCCESS && msLayerGetItems(lp) == MS_SUCCESS) { - /* Remove group names from property names if using groupname/itemname syntax */ - gmlGroupListObj* groupList = msGMLGetGroups(lp, namespaces); - if( groupList && groupList->numgroups > 0 ) + /* Remove group names from property names if using groupname/itemname + * syntax */ + gmlGroupListObj *groupList = msGMLGetGroups(lp, namespaces); + if (groupList && groupList->numgroups > 0) FLTRemoveGroupName(psFilterNode, groupList); msGMLFreeGroups(groupList); - for(i=0; inumitems; i++) { + for (i = 0; i < lp->numitems; i++) { if (!lp->items[i] || strlen(lp->items[i]) <= 0) continue; char szTmp[256]; snprintf(szTmp, sizeof(szTmp), "%s_alias", lp->items[i]); - const char *pszFullName = msOWSLookupMetadata(&(lp->metadata), namespaces, szTmp); + const char *pszFullName = + msOWSLookupMetadata(&(lp->metadata), namespaces, szTmp); if (pszFullName) { - FLTReplacePropertyName(psFilterNode, pszFullName, - lp->items[i]); + FLTReplacePropertyName(psFilterNode, pszFullName, lp->items[i]); } } - if (!layerWasOpened) /* do not close the layer if it has been opened somewhere else (paging?) */ + if (!layerWasOpened) /* do not close the layer if it has been opened + somewhere else (paging?) */ msLayerClose(lp); } } @@ -3141,48 +3052,43 @@ void FLTPreParseFilterForAliasAndGroup(FilterEncodingNode *psFilterNode, /* Check that FeatureId filters match features in the active */ /* layer. */ /************************************************************************/ -int FLTCheckFeatureIdFilters(FilterEncodingNode *psFilterNode, - mapObj *map, int i) -{ - int status = MS_SUCCESS; - - if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID) - { - char** tokens; - int nTokens = 0; - layerObj* lp; - int j; - - lp = GET_LAYER(map, i); - tokens = msStringSplit(psFilterNode->pszValue,',', &nTokens); - for (j=0; j(pszDot - pszId) != strlen(lp->name) || - strncasecmp(pszId, lp->name, strlen(lp->name)) != 0 ) - { - msSetError(MS_MISCERR, "Feature id %s not consistent with feature type name %s.", - "FLTPreParseFilterForAlias()", pszId, lp->name); - status = MS_FAILURE; - break; - } - } +int FLTCheckFeatureIdFilters(FilterEncodingNode *psFilterNode, mapObj *map, + int i) { + int status = MS_SUCCESS; + + if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID) { + char **tokens; + int nTokens = 0; + layerObj *lp; + int j; + + lp = GET_LAYER(map, i); + tokens = msStringSplit(psFilterNode->pszValue, ',', &nTokens); + for (j = 0; j < nTokens; j++) { + const char *pszId = tokens[j]; + const char *pszDot = strrchr(pszId, '.'); + if (pszDot) { + if (static_cast(pszDot - pszId) != strlen(lp->name) || + strncasecmp(pszId, lp->name, strlen(lp->name)) != 0) { + msSetError(MS_MISCERR, + "Feature id %s not consistent with feature type name %s.", + "FLTPreParseFilterForAlias()", pszId, lp->name); + status = MS_FAILURE; + break; } - msFreeCharArray(tokens, nTokens); + } } + msFreeCharArray(tokens, nTokens); + } - if (psFilterNode->psLeftNode) - { - status = FLTCheckFeatureIdFilters(psFilterNode->psLeftNode, map, i); - if( status == MS_SUCCESS ) - { - if (psFilterNode->psRightNode) - status = FLTCheckFeatureIdFilters(psFilterNode->psRightNode, map, i); - } + if (psFilterNode->psLeftNode) { + status = FLTCheckFeatureIdFilters(psFilterNode->psLeftNode, map, i); + if (status == MS_SUCCESS) { + if (psFilterNode->psRightNode) + status = FLTCheckFeatureIdFilters(psFilterNode->psRightNode, map, i); } - return status; + } + return status; } /************************************************************************/ @@ -3191,33 +3097,29 @@ int FLTCheckFeatureIdFilters(FilterEncodingNode *psFilterNode, /* Check that the operand of a comparison operator is valid */ /* Currently only detects use of boundedBy in a binary comparison */ /************************************************************************/ -int FLTCheckInvalidOperand(FilterEncodingNode *psFilterNode) -{ - int status = MS_SUCCESS; - - if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && - psFilterNode->psLeftNode != NULL && - psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) - { - if( strcmp(psFilterNode->psLeftNode->pszValue, "gml:boundedBy") == 0 && - strcmp(psFilterNode->pszValue, "PropertyIsNull") != 0 && - strcmp(psFilterNode->pszValue, "PropertyIsNil") != 0 ) - { - msSetError(MS_MISCERR, "Operand '%s' is invalid in comparison.", - "FLTCheckInvalidOperand()", psFilterNode->psLeftNode->pszValue); - return MS_FAILURE; - } +int FLTCheckInvalidOperand(FilterEncodingNode *psFilterNode) { + int status = MS_SUCCESS; + + if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && + psFilterNode->psLeftNode != NULL && + psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { + if (strcmp(psFilterNode->psLeftNode->pszValue, "gml:boundedBy") == 0 && + strcmp(psFilterNode->pszValue, "PropertyIsNull") != 0 && + strcmp(psFilterNode->pszValue, "PropertyIsNil") != 0) { + msSetError(MS_MISCERR, "Operand '%s' is invalid in comparison.", + "FLTCheckInvalidOperand()", + psFilterNode->psLeftNode->pszValue); + return MS_FAILURE; } - if (psFilterNode->psLeftNode) - { - status = FLTCheckInvalidOperand(psFilterNode->psLeftNode); - if( status == MS_SUCCESS ) - { - if (psFilterNode->psRightNode) - status = FLTCheckInvalidOperand(psFilterNode->psRightNode); - } + } + if (psFilterNode->psLeftNode) { + status = FLTCheckInvalidOperand(psFilterNode->psLeftNode); + if (status == MS_SUCCESS) { + if (psFilterNode->psRightNode) + status = FLTCheckInvalidOperand(psFilterNode->psRightNode); } - return status; + } + return status; } /************************************************************************/ @@ -3226,49 +3128,45 @@ int FLTCheckInvalidOperand(FilterEncodingNode *psFilterNode) /* HACK for PropertyIsNull processing. PostGIS & Spatialite only */ /* for now. */ /************************************************************************/ -int FLTProcessPropertyIsNull(FilterEncodingNode *psFilterNode, - mapObj *map, int i) -{ - int status = MS_SUCCESS; - - if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && - psFilterNode->psLeftNode != NULL && - psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME && - strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 && - !FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue) ) - { - layerObj* lp; - int layerWasOpened; - - lp = GET_LAYER(map, i); - layerWasOpened = msLayerIsOpen(lp); - - /* Horrible HACK to compensate for the lack of null testing in MapServer */ - if( (lp->connectiontype == MS_POSTGIS || - (lp->connectiontype == MS_OGR && msOGRSupportsIsNull(lp))) && - strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 ) - { - msFree(psFilterNode->pszValue); - psFilterNode->pszValue = msStrdup("PropertyIsEqualTo"); - psFilterNode->psRightNode = FLTCreateBinaryCompFilterEncodingNode(); - psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_LITERAL; - psFilterNode->psRightNode->pszValue = msStrdup("_MAPSERVER_NULL_"); - } - - if (!layerWasOpened) /* do not close the layer if it has been opened somewhere else (paging?) */ - msLayerClose(lp); +int FLTProcessPropertyIsNull(FilterEncodingNode *psFilterNode, mapObj *map, + int i) { + int status = MS_SUCCESS; + + if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && + psFilterNode->psLeftNode != NULL && + psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME && + strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 && + !FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue)) { + layerObj *lp; + int layerWasOpened; + + lp = GET_LAYER(map, i); + layerWasOpened = msLayerIsOpen(lp); + + /* Horrible HACK to compensate for the lack of null testing in MapServer */ + if ((lp->connectiontype == MS_POSTGIS || + (lp->connectiontype == MS_OGR && msOGRSupportsIsNull(lp))) && + strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0) { + msFree(psFilterNode->pszValue); + psFilterNode->pszValue = msStrdup("PropertyIsEqualTo"); + psFilterNode->psRightNode = FLTCreateBinaryCompFilterEncodingNode(); + psFilterNode->psRightNode->eType = FILTER_NODE_TYPE_LITERAL; + psFilterNode->psRightNode->pszValue = msStrdup("_MAPSERVER_NULL_"); } - if (psFilterNode->psLeftNode) - { - status = FLTProcessPropertyIsNull(psFilterNode->psLeftNode, map, i); - if( status == MS_SUCCESS ) - { - if (psFilterNode->psRightNode) - status = FLTProcessPropertyIsNull(psFilterNode->psRightNode, map, i); - } + if (!layerWasOpened) /* do not close the layer if it has been opened + somewhere else (paging?) */ + msLayerClose(lp); + } + + if (psFilterNode->psLeftNode) { + status = FLTProcessPropertyIsNull(psFilterNode->psLeftNode, map, i); + if (status == MS_SUCCESS) { + if (psFilterNode->psRightNode) + status = FLTProcessPropertyIsNull(psFilterNode->psRightNode, map, i); } - return status; + } + return status; } /************************************************************************/ @@ -3276,65 +3174,62 @@ int FLTProcessPropertyIsNull(FilterEncodingNode *psFilterNode, /* */ /* Check that property names are known */ /************************************************************************/ -int FLTCheckInvalidProperty(FilterEncodingNode *psFilterNode, - mapObj *map, int i) -{ - int status = MS_SUCCESS; - - if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && - psFilterNode->psLeftNode != NULL && - psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) - { - layerObj* lp; - int layerWasOpened; - int bFound = MS_FALSE; - - if ((strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 || - strcmp(psFilterNode->pszValue, "PropertyIsNil") == 0) && - FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue) ) - { - return MS_SUCCESS; - } +int FLTCheckInvalidProperty(FilterEncodingNode *psFilterNode, mapObj *map, + int i) { + int status = MS_SUCCESS; + + if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && + psFilterNode->psLeftNode != NULL && + psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { + layerObj *lp; + int layerWasOpened; + int bFound = MS_FALSE; + + if ((strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 || + strcmp(psFilterNode->pszValue, "PropertyIsNil") == 0) && + FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue)) { + return MS_SUCCESS; + } - lp = GET_LAYER(map, i); - layerWasOpened = msLayerIsOpen(lp); - if ((layerWasOpened || msLayerOpen(lp) == MS_SUCCESS) - && msLayerGetItems(lp) == MS_SUCCESS) { - int i; - gmlItemListObj* items = msGMLGetItems(lp, "G"); - for(i=0; inumitems; i++) { - if (!items->items[i].name || strlen(items->items[i].name) == 0 || - !items->items[i].visible) - continue; - if (strcasecmp(items->items[i].name, psFilterNode->psLeftNode->pszValue) == 0) { - bFound = MS_TRUE; - break; - } - } - msGMLFreeItems(items); + lp = GET_LAYER(map, i); + layerWasOpened = msLayerIsOpen(lp); + if ((layerWasOpened || msLayerOpen(lp) == MS_SUCCESS) && + msLayerGetItems(lp) == MS_SUCCESS) { + int i; + gmlItemListObj *items = msGMLGetItems(lp, "G"); + for (i = 0; i < items->numitems; i++) { + if (!items->items[i].name || strlen(items->items[i].name) == 0 || + !items->items[i].visible) + continue; + if (strcasecmp(items->items[i].name, + psFilterNode->psLeftNode->pszValue) == 0) { + bFound = MS_TRUE; + break; } + } + msGMLFreeItems(items); + } - if (!layerWasOpened) /* do not close the layer if it has been opened somewhere else (paging?) */ - msLayerClose(lp); + if (!layerWasOpened) /* do not close the layer if it has been opened + somewhere else (paging?) */ + msLayerClose(lp); - if( !bFound ) - { - msSetError(MS_MISCERR, "Property '%s' is unknown.", - "FLTCheckInvalidProperty()", psFilterNode->psLeftNode->pszValue); - return MS_FAILURE; - } + if (!bFound) { + msSetError(MS_MISCERR, "Property '%s' is unknown.", + "FLTCheckInvalidProperty()", + psFilterNode->psLeftNode->pszValue); + return MS_FAILURE; } + } - if (psFilterNode->psLeftNode) - { - status = FLTCheckInvalidProperty(psFilterNode->psLeftNode, map, i); - if( status == MS_SUCCESS ) - { - if (psFilterNode->psRightNode) - status = FLTCheckInvalidProperty(psFilterNode->psRightNode, map, i); - } + if (psFilterNode->psLeftNode) { + status = FLTCheckInvalidProperty(psFilterNode->psLeftNode, map, i); + if (status == MS_SUCCESS) { + if (psFilterNode->psRightNode) + status = FLTCheckInvalidProperty(psFilterNode->psRightNode, map, i); } - return status; + } + return status; } /************************************************************************/ @@ -3348,160 +3243,179 @@ int FLTCheckInvalidProperty(FilterEncodingNode *psFilterNode, /* that the filter evaluates to FALSE, or MS_TRUE that it */ /* evaluates to TRUE */ /************************************************************************/ -FilterEncodingNode* FLTSimplify(FilterEncodingNode *psFilterNode, - int* pnEvaluation) -{ - *pnEvaluation = -1; +FilterEncodingNode *FLTSimplify(FilterEncodingNode *psFilterNode, + int *pnEvaluation) { + *pnEvaluation = -1; + + /* There are no nullable or nillable property in WFS currently */ + /* except gml:name or gml:description that are null */ + if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && + (strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 || + strcmp(psFilterNode->pszValue, "PropertyIsNil") == 0) && + psFilterNode->psLeftNode != NULL && + psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME) { + if (strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 && + FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue) && + strcmp(psFilterNode->psLeftNode->pszValue, "@gml:id") != 0 && + strcmp(psFilterNode->psLeftNode->pszValue, "gml:boundedBy") != 0) + *pnEvaluation = MS_TRUE; + else + *pnEvaluation = MS_FALSE; + FLTFreeFilterEncodingNode(psFilterNode); + return NULL; + } - /* There are no nullable or nillable property in WFS currently */ - /* except gml:name or gml:description that are null */ - if( psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON && - (strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 || - strcmp(psFilterNode->pszValue, "PropertyIsNil") == 0 ) && - psFilterNode->psLeftNode != NULL && - psFilterNode->psLeftNode->eType == FILTER_NODE_TYPE_PROPERTYNAME ) - { - if( strcmp(psFilterNode->pszValue, "PropertyIsNull") == 0 && - FLTIsGMLDefaultProperty(psFilterNode->psLeftNode->pszValue) && - strcmp(psFilterNode->psLeftNode->pszValue, "@gml:id") != 0 && - strcmp(psFilterNode->psLeftNode->pszValue, "gml:boundedBy") != 0) - *pnEvaluation = MS_TRUE; - else - *pnEvaluation = MS_FALSE; - FLTFreeFilterEncodingNode(psFilterNode); - return NULL; + if (psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL && + strcasecmp(psFilterNode->pszValue, "NOT") == 0 && + psFilterNode->psLeftNode != NULL) { + int nEvaluation; + psFilterNode->psLeftNode = + FLTSimplify(psFilterNode->psLeftNode, &nEvaluation); + if (psFilterNode->psLeftNode == NULL) { + *pnEvaluation = 1 - nEvaluation; + FLTFreeFilterEncodingNode(psFilterNode); + return NULL; } + } - if( psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL && - strcasecmp(psFilterNode->pszValue, "NOT") == 0 && - psFilterNode->psLeftNode != NULL ) - { - int nEvaluation; - psFilterNode->psLeftNode = FLTSimplify(psFilterNode->psLeftNode, - &nEvaluation); - if( psFilterNode->psLeftNode == NULL ) - { - *pnEvaluation = 1 - nEvaluation; - FLTFreeFilterEncodingNode(psFilterNode); - return NULL; - } + if (psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL && + (strcasecmp(psFilterNode->pszValue, "AND") == 0 || + strcasecmp(psFilterNode->pszValue, "OR") == 0) && + psFilterNode->psLeftNode != NULL && psFilterNode->psRightNode != NULL) { + FilterEncodingNode *psOtherNode; + int nEvaluation; + int nExpectedValForFastExit; + psFilterNode->psLeftNode = + FLTSimplify(psFilterNode->psLeftNode, &nEvaluation); + + if (strcasecmp(psFilterNode->pszValue, "AND") == 0) + nExpectedValForFastExit = MS_FALSE; + else + nExpectedValForFastExit = MS_TRUE; + + if (psFilterNode->psLeftNode == NULL) { + if (nEvaluation == nExpectedValForFastExit) { + *pnEvaluation = nEvaluation; + FLTFreeFilterEncodingNode(psFilterNode); + return NULL; + } + psOtherNode = psFilterNode->psRightNode; + psFilterNode->psRightNode = NULL; + FLTFreeFilterEncodingNode(psFilterNode); + return FLTSimplify(psOtherNode, pnEvaluation); } - if( psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL && - (strcasecmp(psFilterNode->pszValue, "AND") == 0 || - strcasecmp(psFilterNode->pszValue, "OR") == 0) && - psFilterNode->psLeftNode != NULL && - psFilterNode->psRightNode != NULL ) - { - FilterEncodingNode* psOtherNode; - int nEvaluation; - int nExpectedValForFastExit; - psFilterNode->psLeftNode = FLTSimplify(psFilterNode->psLeftNode, - &nEvaluation); - - if( strcasecmp(psFilterNode->pszValue, "AND") == 0 ) - nExpectedValForFastExit = MS_FALSE; - else - nExpectedValForFastExit = MS_TRUE; - - if( psFilterNode->psLeftNode == NULL ) - { - if( nEvaluation == nExpectedValForFastExit ) - { - *pnEvaluation = nEvaluation; - FLTFreeFilterEncodingNode(psFilterNode); - return NULL; - } - psOtherNode = psFilterNode->psRightNode; - psFilterNode->psRightNode = NULL; - FLTFreeFilterEncodingNode(psFilterNode); - return FLTSimplify(psOtherNode, pnEvaluation); - } - - psFilterNode->psRightNode = FLTSimplify(psFilterNode->psRightNode, - &nEvaluation); - if( psFilterNode->psRightNode == NULL ) - { - if( nEvaluation == nExpectedValForFastExit ) - { - *pnEvaluation = nEvaluation; - FLTFreeFilterEncodingNode(psFilterNode); - return NULL; - } - psOtherNode = psFilterNode->psLeftNode; - psFilterNode->psLeftNode = NULL; - FLTFreeFilterEncodingNode(psFilterNode); - return FLTSimplify(psOtherNode, pnEvaluation); - } + psFilterNode->psRightNode = + FLTSimplify(psFilterNode->psRightNode, &nEvaluation); + if (psFilterNode->psRightNode == NULL) { + if (nEvaluation == nExpectedValForFastExit) { + *pnEvaluation = nEvaluation; + FLTFreeFilterEncodingNode(psFilterNode); + return NULL; + } + psOtherNode = psFilterNode->psLeftNode; + psFilterNode->psLeftNode = NULL; + FLTFreeFilterEncodingNode(psFilterNode); + return FLTSimplify(psOtherNode, pnEvaluation); } + } - return psFilterNode; + return psFilterNode; } - #ifdef USE_LIBXML2 -xmlNodePtr FLTGetCapabilities(xmlNsPtr psNsParent, xmlNsPtr psNsOgc, int bTemporal) -{ - xmlNodePtr psRootNode = NULL, psNode = NULL, psSubNode = NULL, psSubSubNode = NULL; +xmlNodePtr FLTGetCapabilities(xmlNsPtr psNsParent, xmlNsPtr psNsOgc, + int bTemporal) { + xmlNodePtr psRootNode = NULL, psNode = NULL, psSubNode = NULL, + psSubSubNode = NULL; psRootNode = xmlNewNode(psNsParent, BAD_CAST "Filter_Capabilities"); - psNode = xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Spatial_Capabilities", NULL); + psNode = + xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Spatial_Capabilities", NULL); psSubNode = xmlNewChild(psNode, psNsOgc, BAD_CAST "GeometryOperands", NULL); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", BAD_CAST "gml:Point"); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", BAD_CAST "gml:LineString"); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", BAD_CAST "gml:Polygon"); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", BAD_CAST "gml:Envelope"); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", + BAD_CAST "gml:Point"); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", + BAD_CAST "gml:LineString"); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", + BAD_CAST "gml:Polygon"); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "GeometryOperand", + BAD_CAST "gml:Envelope"); psSubNode = xmlNewChild(psNode, psNsOgc, BAD_CAST "SpatialOperators", NULL); #ifdef USE_GEOS - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Equals"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Disjoint"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Touches"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Within"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Overlaps"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Crosses"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Intersects"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Contains"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "DWithin"); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "Beyond"); #endif - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "SpatialOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "BBOX"); if (bTemporal) { - psNode = xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Temporal_Capabilities", NULL); + psNode = xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Temporal_Capabilities", + NULL); psSubNode = xmlNewChild(psNode, psNsOgc, BAD_CAST "TemporalOperands", NULL); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperand", BAD_CAST "gml:TimePeriod"); - xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperand", BAD_CAST "gml:TimeInstant"); - - psSubNode = xmlNewChild(psNode, psNsOgc, BAD_CAST "TemporalOperators", NULL); - psSubSubNode = xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperator", NULL); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperand", + BAD_CAST "gml:TimePeriod"); + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperand", + BAD_CAST "gml:TimeInstant"); + + psSubNode = + xmlNewChild(psNode, psNsOgc, BAD_CAST "TemporalOperators", NULL); + psSubSubNode = + xmlNewChild(psSubNode, psNsOgc, BAD_CAST "TemporalOperator", NULL); xmlNewProp(psSubSubNode, BAD_CAST "name", BAD_CAST "TM_Equals"); } - psNode = xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Scalar_Capabilities", NULL); + psNode = + xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Scalar_Capabilities", NULL); xmlNewChild(psNode, psNsOgc, BAD_CAST "LogicalOperators", NULL); psNode = xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperators", NULL); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "LessThan"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "GreaterThan"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "LessThanEqualTo"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "GreaterThanEqualTo"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "EqualTo"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "NotEqualTo"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "LessThan"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "GreaterThan"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "LessThanEqualTo"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "GreaterThanEqualTo"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "EqualTo"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "NotEqualTo"); xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "Like"); - xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", BAD_CAST "Between"); + xmlNewChild(psNode, psNsOgc, BAD_CAST "ComparisonOperator", + BAD_CAST "Between"); psNode = xmlNewChild(psRootNode, psNsOgc, BAD_CAST "Id_Capabilities", NULL); xmlNewChild(psNode, psNsOgc, BAD_CAST "EID", NULL); diff --git a/mapogcfilter.h b/mapogcfilter.h index 75a16b4053..ba08b3ac5c 100644 --- a/mapogcfilter.h +++ b/mapogcfilter.h @@ -36,8 +36,8 @@ #ifdef USE_LIBXML2 -#include -#include +#include +#include #endif #ifdef __cplusplus @@ -48,26 +48,32 @@ typedef struct { char *pszWildCard; char *pszSingleChar; char *pszEscapeChar; - int bCaseInsensitive; + int bCaseInsensitive; } FEPropertyIsLike; /* -------------------------------------------------------------------- */ /* prototypes. */ /* -------------------------------------------------------------------- */ MS_DLL_EXPORT int FLTIsNumeric(const char *pszValue); -MS_DLL_EXPORT int FLTApplyExpressionToLayer(layerObj *lp, const char *pszExpression); -MS_DLL_EXPORT char *FLTGetExpressionForValuesRanges(layerObj *lp, const char *item, const char *value, int forcecharcter); - -MS_DLL_EXPORT FilterEncodingNode *FLTParseFilterEncoding(const char *szXMLString); +MS_DLL_EXPORT int FLTApplyExpressionToLayer(layerObj *lp, + const char *pszExpression); +MS_DLL_EXPORT char *FLTGetExpressionForValuesRanges(layerObj *lp, + const char *item, + const char *value, + int forcecharcter); + +MS_DLL_EXPORT FilterEncodingNode * +FLTParseFilterEncoding(const char *szXMLString); MS_DLL_EXPORT FilterEncodingNode *FLTCreateFilterEncodingNode(void); -MS_DLL_EXPORT char** FLTSplitFilters(const char* pszStr, int* pnTokens); +MS_DLL_EXPORT char **FLTSplitFilters(const char *pszStr, int *pnTokens); MS_DLL_EXPORT int FLTApplyFilterToLayer(FilterEncodingNode *psNode, mapObj *map, int iLayerIndex); -MS_DLL_EXPORT int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map, - int iLayerIndex); -MS_DLL_EXPORT int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map, - int iLayerIndex); +MS_DLL_EXPORT int FLTLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, + mapObj *map, + int iLayerIndex); +MS_DLL_EXPORT int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, + mapObj *map, int iLayerIndex); MS_DLL_EXPORT void FLTFreeFilterEncodingNode(FilterEncodingNode *psFilterNode); @@ -80,11 +86,12 @@ MS_DLL_EXPORT int FLTIsPointFilter(FilterEncodingNode *psFilterNode); MS_DLL_EXPORT int FLTIsLineFilter(FilterEncodingNode *psFilterNode); MS_DLL_EXPORT int FLTIsPolygonFilter(FilterEncodingNode *psFilterNode); -MS_DLL_EXPORT int FLTValidForPropertyIsLikeFilter(FilterEncodingNode *psFilterNode); +MS_DLL_EXPORT int +FLTValidForPropertyIsLikeFilter(FilterEncodingNode *psFilterNode); MS_DLL_EXPORT int FLTIsOnlyPropertyIsLike(FilterEncodingNode *psFilterNode); MS_DLL_EXPORT void FLTInsertElementInNode(FilterEncodingNode *psFilterNode, - CPLXMLNode *psXMLNode); + CPLXMLNode *psXMLNode); MS_DLL_EXPORT int FLTIsLogicalFilterType(const char *pszValue); MS_DLL_EXPORT int FLTIsBinaryComparisonFilterType(const char *pszValue); MS_DLL_EXPORT int FLTIsComparisonFilterType(const char *pszValue); @@ -93,60 +100,81 @@ MS_DLL_EXPORT int FLTIsSpatialFilterType(const char *pszValue); MS_DLL_EXPORT int FLTIsTemporalFilterType(const char *pszValue); MS_DLL_EXPORT int FLTIsSupportedFilterType(CPLXMLNode *psXMLNode); -MS_DLL_EXPORT const char *FLTGetBBOX(FilterEncodingNode *psFilterNode, rectObj *psRect); -const char* FLTGetDuring(FilterEncodingNode *psFilterNode, const char** ppszTimeField); +MS_DLL_EXPORT const char *FLTGetBBOX(FilterEncodingNode *psFilterNode, + rectObj *psRect); +const char *FLTGetDuring(FilterEncodingNode *psFilterNode, + const char **ppszTimeField); -MS_DLL_EXPORT shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, double *pdfDistance, - int *pnUnit); +MS_DLL_EXPORT shapeObj *FLTGetShape(FilterEncodingNode *psFilterNode, + double *pdfDistance, int *pnUnit); MS_DLL_EXPORT int FLTHasSpatialFilter(FilterEncodingNode *psFilterNode); - /*SQL expressions related functions.*/ -MS_DLL_EXPORT int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, mapObj *map, - int iLayerIndex); - -MS_DLL_EXPORT char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode,layerObj *lp); -MS_DLL_EXPORT char *FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp); -MS_DLL_EXPORT char *FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, layerObj *lp); -MS_DLL_EXPORT char *FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, layerObj *lp); - -MS_DLL_EXPORT char *FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, - layerObj *lp); +MS_DLL_EXPORT int FLTApplySimpleSQLFilter(FilterEncodingNode *psNode, + mapObj *map, int iLayerIndex); + +MS_DLL_EXPORT char *FLTGetSQLExpression(FilterEncodingNode *psFilterNode, + layerObj *lp); +MS_DLL_EXPORT char * +FLTGetBinaryComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp); +MS_DLL_EXPORT char * +FLTGetIsBetweenComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp); +MS_DLL_EXPORT char * +FLTGetIsLikeComparisonSQLExpression(FilterEncodingNode *psFilterNode, + layerObj *lp); + +MS_DLL_EXPORT char * +FLTGetLogicalComparisonSQLExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp); MS_DLL_EXPORT int FLTIsSimpleFilter(FilterEncodingNode *psFilterNode); -MS_DLL_EXPORT FilterEncodingNode *FLTCreateFeatureIdFilterEncoding(const char *pszString); +MS_DLL_EXPORT FilterEncodingNode * +FLTCreateFeatureIdFilterEncoding(const char *pszString); -MS_DLL_EXPORT int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, char **ppszSRS); -MS_DLL_EXPORT int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, char **ppszSRS); +MS_DLL_EXPORT int FLTParseGMLEnvelope(CPLXMLNode *psRoot, rectObj *psBbox, + char **ppszSRS); +MS_DLL_EXPORT int FLTParseGMLBox(CPLXMLNode *psBox, rectObj *psBbox, + char **ppszSRS); /*common-expressions*/ -MS_DLL_EXPORT char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp); -MS_DLL_EXPORT int FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, const char *pszExpression); +MS_DLL_EXPORT char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, + layerObj *lp); +MS_DLL_EXPORT int +FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, + const char *pszExpression); #ifdef USE_LIBXML2 -MS_DLL_EXPORT xmlNodePtr FLTGetCapabilities(xmlNsPtr psNsParent, xmlNsPtr psNsOgc, int bTemporal); +MS_DLL_EXPORT xmlNodePtr FLTGetCapabilities(xmlNsPtr psNsParent, + xmlNsPtr psNsOgc, int bTemporal); #endif -void FLTDoAxisSwappingIfNecessary(mapObj *map, FilterEncodingNode *psFilterNode, int bDefaultSRSNeedsAxisSwapping); +void FLTDoAxisSwappingIfNecessary(mapObj *map, FilterEncodingNode *psFilterNode, + int bDefaultSRSNeedsAxisSwapping); void FLTPreParseFilterForAliasAndGroup(FilterEncodingNode *psFilterNode, - mapObj *map, int i, const char *namespaces); -int FLTCheckFeatureIdFilters(FilterEncodingNode *psFilterNode, - mapObj *map, int i); + mapObj *map, int i, + const char *namespaces); +int FLTCheckFeatureIdFilters(FilterEncodingNode *psFilterNode, mapObj *map, + int i); int FLTCheckInvalidOperand(FilterEncodingNode *psFilterNode); -int FLTCheckInvalidProperty(FilterEncodingNode *psFilterNode, - mapObj *map, int i); -FilterEncodingNode* FLTSimplify(FilterEncodingNode *psFilterNode, - int* pnEvaluation); -int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, const char *pszExpression, rectObj rect); -int FLTProcessPropertyIsNull(FilterEncodingNode *psFilterNode, - mapObj *map, int i); -int FLTLayerSetInvalidRectIfSupported(layerObj* lp, rectObj* rect); +int FLTCheckInvalidProperty(FilterEncodingNode *psFilterNode, mapObj *map, + int i); +FilterEncodingNode *FLTSimplify(FilterEncodingNode *psFilterNode, + int *pnEvaluation); +int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, + const char *pszExpression, + rectObj rect); +int FLTProcessPropertyIsNull(FilterEncodingNode *psFilterNode, mapObj *map, + int i); +int FLTLayerSetInvalidRectIfSupported(layerObj *lp, rectObj *rect); #ifdef __cplusplus } -std::string FLTGetTimeExpression(FilterEncodingNode *psFilterNode, layerObj *lp); +std::string FLTGetTimeExpression(FilterEncodingNode *psFilterNode, + layerObj *lp); #endif diff --git a/mapogcfiltercommon.cpp b/mapogcfiltercommon.cpp index f73d47b0db..bc06a1f3f2 100644 --- a/mapogcfiltercommon.cpp +++ b/mapogcfiltercommon.cpp @@ -34,22 +34,27 @@ #include -static std::string FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *psFilterNode) -{ - /* From http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04 */ +static std::string +FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *psFilterNode) { + /* From + * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04 + */ /* also add double quote because we are within a string */ - const char* pszRegexSpecialCharsAndDoubleQuote = "\\^${[().*+?|\""; + const char *pszRegexSpecialCharsAndDoubleQuote = "\\^${[().*+?|\""; - if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode || !psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue) + if (!psFilterNode || !psFilterNode->pOther || !psFilterNode->psLeftNode || + !psFilterNode->psRightNode || !psFilterNode->psRightNode->pszValue) return std::string(); - const FEPropertyIsLike* propIsLike = (const FEPropertyIsLike *)psFilterNode->pOther; - const char* pszWild = propIsLike->pszWildCard; - const char* pszSingle = propIsLike->pszSingleChar; - const char* pszEscape = propIsLike->pszEscapeChar; + const FEPropertyIsLike *propIsLike = + (const FEPropertyIsLike *)psFilterNode->pOther; + const char *pszWild = propIsLike->pszWildCard; + const char *pszSingle = propIsLike->pszSingleChar; + const char *pszEscape = propIsLike->pszEscapeChar; const bool bCaseInsensitive = propIsLike->bCaseInsensitive != 0; - if (!pszWild || strlen(pszWild) == 0 || !pszSingle || strlen(pszSingle) == 0 || !pszEscape || strlen(pszEscape) == 0) + if (!pszWild || strlen(pszWild) == 0 || !pszSingle || + strlen(pszSingle) == 0 || !pszEscape || strlen(pszEscape) == 0) return std::string(); /* -------------------------------------------------------------------- */ @@ -61,62 +66,61 @@ static std::string FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *ps expr += psFilterNode->psLeftNode->pszValue; /* #3521 */ - if (bCaseInsensitive ) + if (bCaseInsensitive) expr += "]\" ~* \""; else expr += "]\" ~ \""; - const char* pszValue = psFilterNode->psRightNode->pszValue; + const char *pszValue = psFilterNode->psRightNode->pszValue; const size_t nLength = strlen(pszValue); if (nLength > 0) { expr += '^'; } - for (size_t i=0; ipsLeftNode == NULL || psFilterNode->psRightNode == NULL ) +static std::string +FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode *psFilterNode, + layerObj *lp) { + if (psFilterNode->psLeftNode == NULL || psFilterNode->psRightNode == NULL) return std::string(); /* -------------------------------------------------------------------- */ @@ -147,8 +152,9 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode bool bString = false; bool bDateTime = false; - const char* pszType = msOWSLookupMetadata(&(lp->metadata), "OFG", - (std::string(psFilterNode->psLeftNode->pszValue)+ "_type").c_str()); + const char *pszType = msOWSLookupMetadata( + &(lp->metadata), "OFG", + (std::string(psFilterNode->psLeftNode->pszValue) + "_type").c_str()); if (pszType != NULL && (strcasecmp(pszType, "Character") == 0)) bString = true; else if (pszType != NULL && (strcasecmp(pszType, "Date") == 0)) @@ -157,8 +163,8 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode bString = true; if (!bString && !bDateTime) { - if (FLTIsNumeric(bounds[1].c_str()) == MS_FALSE) - bString = true; + if (FLTIsNumeric(bounds[1].c_str()) == MS_FALSE) + bString = true; } std::string expr; @@ -182,8 +188,7 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode if (bString) { expr += '\"'; - } - else if (bDateTime) { + } else if (bDateTime) { expr += '`'; } @@ -191,8 +196,7 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode if (bString) { expr += '\"'; - } - else if (bDateTime) { + } else if (bDateTime) { expr += '`'; } @@ -215,8 +219,7 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode if (bString) { expr += '\"'; - } - else if (bDateTime) { + } else if (bDateTime) { expr += '`'; } @@ -224,8 +227,7 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode if (bString) { expr += '\"'; - } - else if (bDateTime) { + } else if (bDateTime) { expr += '`'; } expr += ')'; @@ -233,9 +235,9 @@ static std::string FLTGetIsBetweenComparisonCommonExpresssion(FilterEncodingNode return expr; } -static -std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +static std::string +FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterNode, + layerObj *lp) { /* -------------------------------------------------------------------- */ /* check if the value is a numeric value or alphanumeric. If it */ /* is alphanumeric, add quotes around attribute and values. */ @@ -243,11 +245,12 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN bool bString = false; bool bDateTime = false; if (psFilterNode->psRightNode->pszValue) { - const char* pszType = msOWSLookupMetadata(&(lp->metadata), "OFG", + const char *pszType = msOWSLookupMetadata( + &(lp->metadata), "OFG", (std::string(psFilterNode->psLeftNode->pszValue) + "_type").c_str()); - if (pszType!= NULL && (strcasecmp(pszType, "Character") == 0)) + if (pszType != NULL && (strcasecmp(pszType, "Character") == 0)) bString = true; - else if (pszType!= NULL && (strcasecmp(pszType, "Date") == 0)) + else if (pszType != NULL && (strcasecmp(pszType, "Date") == 0)) bDateTime = true; else if (FLTIsNumeric(psFilterNode->psRightNode->pszValue) == MS_FALSE) bString = true; @@ -255,7 +258,8 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN /* specical case to be able to have empty strings in the expression. */ /* propertyislike is always treated as string */ - if (psFilterNode->psRightNode->pszValue == NULL || strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) + if (psFilterNode->psRightNode->pszValue == NULL || + strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) bString = true; /* attribute */ @@ -265,7 +269,7 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN else expr = "(["; expr += psFilterNode->psLeftNode->pszValue; - + if (bString) expr += "]\" "; else @@ -273,7 +277,8 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN if (strcasecmp(psFilterNode->pszValue, "PropertyIsEqualTo") == 0) { /* case insensitive set ? */ - if (psFilterNode->psRightNode->pOther && (*(int *)psFilterNode->psRightNode->pOther) == 1) + if (psFilterNode->psRightNode->pOther && + (*(int *)psFilterNode->psRightNode->pOther) == 1) expr += "=*"; else expr += "="; @@ -283,9 +288,11 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN expr += "<"; else if (strcasecmp(psFilterNode->pszValue, "PropertyIsGreaterThan") == 0) expr += ">"; - else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLessThanOrEqualTo") == 0) + else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLessThanOrEqualTo") == + 0) expr += "<="; - else if (strcasecmp(psFilterNode->pszValue, "PropertyIsGreaterThanOrEqualTo") == 0) + else if (strcasecmp(psFilterNode->pszValue, + "PropertyIsGreaterThanOrEqualTo") == 0) expr += ">="; else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) expr += "~"; @@ -294,8 +301,7 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN /* value */ if (bString) { expr += "\""; - } - else if (bDateTime) { + } else if (bDateTime) { expr += "`"; } @@ -305,8 +311,7 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN if (bString) { expr += "\""; - } - else if (bDateTime) { + } else if (bDateTime) { expr += "`"; } @@ -315,15 +320,15 @@ std::string FLTGetBinaryComparisonCommonExpression(FilterEncodingNode *psFilterN return expr; } -static -std::string FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +static std::string +FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilterNode, + layerObj *lp) { std::string expr; /* -------------------------------------------------------------------- */ /* OR and AND */ /* -------------------------------------------------------------------- */ if (psFilterNode->psLeftNode && psFilterNode->psRightNode) { - char* pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); + char *pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); if (!pszTmp) return std::string(); @@ -346,8 +351,9 @@ std::string FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilter /* -------------------------------------------------------------------- */ /* NOT */ /* -------------------------------------------------------------------- */ - else if (psFilterNode->psLeftNode && strcasecmp(psFilterNode->pszValue, "NOT") == 0) { - char* pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); + else if (psFilterNode->psLeftNode && + strcasecmp(psFilterNode->pszValue, "NOT") == 0) { + char *pszTmp = FLTGetCommonExpression(psFilterNode->psLeftNode, lp); if (!pszTmp) return std::string(); @@ -360,12 +366,12 @@ std::string FLTGetLogicalComparisonCommonExpression(FilterEncodingNode *psFilter return expr; } -static -std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp) -{ +static std::string +FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, + layerObj *lp) { std::string expr; double dfDistance = -1; - shapeObj *psTmpShape=NULL; + shapeObj *psTmpShape = NULL; bool bBBoxQuery = false; bool bAlreadyReprojected = false; @@ -379,28 +385,28 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, char szPolygon[512]; snprintf(szPolygon, sizeof(szPolygon), - "POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f))", - sQueryRect.minx, sQueryRect.miny, - sQueryRect.minx, sQueryRect.maxy, - sQueryRect.maxx, sQueryRect.maxy, - sQueryRect.maxx, sQueryRect.miny, + "POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f " + "%.18f))", + sQueryRect.minx, sQueryRect.miny, sQueryRect.minx, sQueryRect.maxy, + sQueryRect.maxx, sQueryRect.maxy, sQueryRect.maxx, sQueryRect.miny, sQueryRect.minx, sQueryRect.miny); psTmpShape = msShapeFromWKT(szPolygon); - /* + /* ** This is a horrible hack to deal with world-extent requests and - ** reprojection. msProjectRect() detects if reprojection from longlat to - ** projected SRS, and in that case it transforms the bbox to -1e-15,-1e-15,1e15,1e15 + ** reprojection. msProjectRect() detects if reprojection from longlat to + ** projected SRS, and in that case it transforms the bbox to + *-1e-15,-1e-15,1e15,1e15 ** to ensure that all features are returned. ** - ** Make wfs_200_cite_filter_bbox_world.xml and wfs_200_cite_postgis_bbox_world.xml pass + ** Make wfs_200_cite_filter_bbox_world.xml and + *wfs_200_cite_postgis_bbox_world.xml pass */ if (fabs(sQueryRect.minx - -180.0) < 1e-5 && fabs(sQueryRect.miny - -90.0) < 1e-5 && fabs(sQueryRect.maxx - 180.0) < 1e-5 && - fabs(sQueryRect.maxy - 90.0) < 1e-5) - { + fabs(sQueryRect.maxy - 90.0) < 1e-5) { if (lp->projection.numargs > 0) { projectionObj sProjTmp; if (psNode->pszSRS) { @@ -408,7 +414,8 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, msProjectionInheritContextFrom(&sProjTmp, &lp->projection); } if (psNode->pszSRS) { - /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */ + /* Use the non EPSG variant since axis swapping is done in + * FLTDoAxisSwappingIfNecessary */ if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) { msProjectRect(&sProjTmp, &lp->projection, &sQueryRect); } @@ -420,7 +427,7 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, if (sQueryRect.minx <= -1e14) { msFreeShape(psTmpShape); msFree(psTmpShape); - psTmpShape = (shapeObj*) msSmallMalloc(sizeof(shapeObj)); + psTmpShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(psTmpShape); msRectToPolygon(sQueryRect, psTmpShape); bAlreadyReprojected = true; @@ -431,20 +438,27 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, } else { /* other geos type operations */ - /* project shape to layer projection. If the proj is not part of the filter query, - assume that the cooredinates are in the map projection */ + /* project shape to layer projection. If the proj is not part of the filter + query, assume that the cooredinates are in the map projection */ int nUnit = -1; - shapeObj* psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit); + shapeObj *psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit); - if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0 ) && dfDistance > 0) { + if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || + strcasecmp(psNode->pszValue, "Beyond") == 0) && + dfDistance > 0) { int nLayerUnit = lp->units; - if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->projection); - if(nLayerUnit == -1) nLayerUnit = lp->map->units; - if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->map->projection); + if (nLayerUnit == -1) + nLayerUnit = GetMapserverUnitUsingProj(&lp->projection); + if (nLayerUnit == -1) + nLayerUnit = lp->map->units; + if (nLayerUnit == -1) + nLayerUnit = GetMapserverUnitUsingProj(&lp->map->projection); if (nUnit >= 0 && nUnit != nLayerUnit) - dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(nLayerUnit,0); /* target is layer units */ + dfDistance *= + msInchesPerUnit(nUnit, 0) / + msInchesPerUnit(nLayerUnit, 0); /* target is layer units */ } psTmpShape = psQueryShape; @@ -462,7 +476,8 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, msProjectionInheritContextFrom(&sProjTmp, &lp->projection); } if (psNode->pszSRS) { - /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */ + /* Use the non EPSG variant since axis swapping is done in + * FLTDoAxisSwappingIfNecessary */ if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) { msProjectShape(&sProjTmp, &lp->projection, psTmpShape); } @@ -486,13 +501,15 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, expr += "([shape],fromText('"; /* filter geometry */ - char* pszWktText = msGEOSShapeToWKT(psTmpShape); + char *pszWktText = msGEOSShapeToWKT(psTmpShape); expr += pszWktText ? pszWktText : "Cannot translate shape to WKT"; expr += "')"; msGEOSFreeWKT(pszWktText); - /* (optional) beyond/dwithin distance, always 0.0 since we apply the distance as a buffer earlier */ - if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0)) { + /* (optional) beyond/dwithin distance, always 0.0 since we apply the + * distance as a buffer earlier */ + if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || + strcasecmp(psNode->pszValue, "Beyond") == 0)) { char szBuffer[256]; sprintf(szBuffer, ",%g", dfDistance); expr += szBuffer; @@ -513,29 +530,32 @@ std::string FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, return expr; } -static std::string FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +static std::string +FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterNode, + layerObj *lp) { std::string expr; -#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || defined(USE_SOS_SVR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) if (psFilterNode->pszValue) { - const char* pszAttribute = msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); + const char *pszAttribute = + msOWSLookupMetadata(&(lp->metadata), "OFG", "featureid"); if (pszAttribute) { - const auto tokens = msStringSplit(psFilterNode->pszValue,','); + const auto tokens = msStringSplit(psFilterNode->pszValue, ','); if (!tokens.empty()) { - for (size_t i=0; i < tokens.size(); i++) { - const char* pszId = tokens[i].c_str(); - const char* pszDot = strrchr(pszId, '.'); - if( pszDot ) + for (size_t i = 0; i < tokens.size(); i++) { + const char *pszId = tokens[i].c_str(); + const char *pszDot = strrchr(pszId, '.'); + if (pszDot) pszId = pszDot + 1; bool bString = false; if (i == 0) { - if(FLTIsNumeric(pszId) == MS_FALSE) + if (FLTIsNumeric(pszId) == MS_FALSE) bString = true; } - if (!expr.empty()) + if (!expr.empty()) expr += " OR "; else expr = '('; @@ -566,14 +586,14 @@ static std::string FLTGetFeatureIdCommonExpression(FilterEncodingNode *psFilterN return expr; } -std::string FLTGetTimeExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +std::string FLTGetTimeExpression(FilterEncodingNode *psFilterNode, + layerObj *lp) { if (lp == NULL) return std::string(); std::string expr; - const char* pszTimeField = nullptr; - const char* pszTimeValue = FLTGetDuring(psFilterNode, &pszTimeField); + const char *pszTimeField = nullptr; + const char *pszTimeValue = FLTGetDuring(psFilterNode, &pszTimeField); if (pszTimeField && pszTimeValue) { expressionObj old_filter; msInitExpression(&old_filter); @@ -589,28 +609,34 @@ std::string FLTGetTimeExpression(FilterEncodingNode *psFilterNode, layerObj *lp) return expr; } -char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) -{ +char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) { char *pszExpression = NULL; if (!psFilterNode) return NULL; if (psFilterNode->eType == FILTER_NODE_TYPE_COMPARISON) { - if ( psFilterNode->psLeftNode && psFilterNode->psRightNode) { + if (psFilterNode->psLeftNode && psFilterNode->psRightNode) { if (FLTIsBinaryComparisonFilterType(psFilterNode->pszValue)) - pszExpression = msStrdup(FLTGetBinaryComparisonCommonExpression(psFilterNode, lp).c_str()); + pszExpression = msStrdup( + FLTGetBinaryComparisonCommonExpression(psFilterNode, lp).c_str()); else if (strcasecmp(psFilterNode->pszValue, "PropertyIsLike") == 0) - pszExpression = msStrdup(FLTGetIsLikeComparisonCommonExpression(psFilterNode).c_str()); + pszExpression = msStrdup( + FLTGetIsLikeComparisonCommonExpression(psFilterNode).c_str()); else if (strcasecmp(psFilterNode->pszValue, "PropertyIsBetween") == 0) - pszExpression = msStrdup(FLTGetIsBetweenComparisonCommonExpresssion(psFilterNode, lp).c_str()); + pszExpression = msStrdup( + FLTGetIsBetweenComparisonCommonExpresssion(psFilterNode, lp) + .c_str()); } } else if (psFilterNode->eType == FILTER_NODE_TYPE_LOGICAL) { - pszExpression = msStrdup(FLTGetLogicalComparisonCommonExpression(psFilterNode, lp).c_str()); + pszExpression = msStrdup( + FLTGetLogicalComparisonCommonExpression(psFilterNode, lp).c_str()); } else if (psFilterNode->eType == FILTER_NODE_TYPE_SPATIAL) { - pszExpression = msStrdup(FLTGetSpatialComparisonCommonExpression(psFilterNode, lp).c_str()); - } else if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID) { - pszExpression = msStrdup(FLTGetFeatureIdCommonExpression(psFilterNode, lp).c_str()); + pszExpression = msStrdup( + FLTGetSpatialComparisonCommonExpression(psFilterNode, lp).c_str()); + } else if (psFilterNode->eType == FILTER_NODE_TYPE_FEATUREID) { + pszExpression = + msStrdup(FLTGetFeatureIdCommonExpression(psFilterNode, lp).c_str()); } else if (psFilterNode->eType == FILTER_NODE_TYPE_TEMPORAL) { pszExpression = msStrdup(FLTGetTimeExpression(psFilterNode, lp).c_str()); } @@ -618,14 +644,16 @@ char *FLTGetCommonExpression(FilterEncodingNode *psFilterNode, layerObj *lp) return pszExpression; } -int FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, const char *pszExpression) -{ - return FLTApplyFilterToLayerCommonExpressionWithRect(map, iLayerIndex, pszExpression, map->extent); +int FLTApplyFilterToLayerCommonExpression(mapObj *map, int iLayerIndex, + const char *pszExpression) { + return FLTApplyFilterToLayerCommonExpressionWithRect( + map, iLayerIndex, pszExpression, map->extent); } /* rect must be in map->projection */ -int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, const char *pszExpression, rectObj rect) -{ +int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, + const char *pszExpression, + rectObj rect) { int retval; const int save_startindex = map->query.startindex; @@ -633,7 +661,8 @@ int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, const int save_only_cache_result_count = map->query.only_cache_result_count; const int save_cache_shapes = map->query.cache_shapes; const int save_max_cached_shape_count = map->query.max_cached_shape_count; - const int save_max_cached_shape_ram_amount = map->query.max_cached_shape_ram_amount; + const int save_max_cached_shape_ram_amount = + map->query.max_cached_shape_ram_amount; msInitQuery(&(map->query)); map->query.startindex = save_startindex; map->query.maxfeatures = save_maxfeatures; @@ -647,17 +676,14 @@ int FLTApplyFilterToLayerCommonExpressionWithRect(mapObj *map, int iLayerIndex, map->query.rect = rect; - if( pszExpression ) - { + if (pszExpression) { map->query.type = MS_QUERY_BY_FILTER; msInitExpression(&map->query.filter); map->query.filter.string = msStrdup(pszExpression); map->query.filter.type = MS_EXPRESSION; /* a logical expression */ retval = msQueryByFilter(map); - } - else - { + } else { map->query.type = MS_QUERY_BY_RECT; retval = msQueryByRect(map); } diff --git a/mapogcsld.c b/mapogcsld.c index bbf2187a43..7d5f978387 100644 --- a/mapogcsld.c +++ b/mapogcsld.c @@ -36,7 +36,9 @@ extern int yyparse(parseObj *); #if defined(USE_CURL) -static inline void IGUR_sizet(size_t ignored) { (void)ignored; } /* Ignore GCC Unused Result */ +static inline void IGUR_sizet(size_t ignored) { + (void)ignored; +} /* Ignore GCC Unused Result */ #endif #define SLD_LINE_SYMBOL_NAME "sld_line_symbol" @@ -62,56 +64,72 @@ static inline void IGUR_sizet(size_t ignored) { (void)ignored; } /* Ignore GCC /* used to do the match. */ /************************************************************************/ int msSLDApplySLDURL(mapObj *map, const char *szURL, int iLayer, - const char *pszStyleLayerName, char **ppszLayerNames) -{ + const char *pszStyleLayerName, char **ppszLayerNames) { /* needed for libcurl function msHTTPGetFile in maphttp.c */ #if defined(USE_CURL) char *pszSLDTmpFile = NULL; int status = 0; - char *pszSLDbuf=NULL; + char *pszSLDbuf = NULL; FILE *fp = NULL; int nStatus = MS_FAILURE; if (map && szURL) { - map->sldurl = (char*)szURL; + map->sldurl = (char *)szURL; pszSLDTmpFile = msTmpFile(map, map->mappath, NULL, "sld.xml"); if (pszSLDTmpFile == NULL) { - pszSLDTmpFile = msTmpFile(map, NULL, NULL, "sld.xml" ); + pszSLDTmpFile = msTmpFile(map, NULL, NULL, "sld.xml"); } if (pszSLDTmpFile == NULL) { - msSetError(MS_WMSERR, "Could not determine temporary file. Please make sure that the temporary path is set. The temporary path can be defined for example by setting TEMPPATH in the map file. Please check the MapServer documentation on temporary path settings.", "msSLDApplySLDURL()"); + msSetError( + MS_WMSERR, + "Could not determine temporary file. Please make sure that the " + "temporary path is set. The temporary path can be defined for " + "example by setting TEMPPATH in the map file. Please check the " + "MapServer documentation on temporary path settings.", + "msSLDApplySLDURL()"); } else { int nMaxRemoteSLDBytes; - const char *pszMaxRemoteSLDBytes = msOWSLookupMetadata(&(map->web.metadata), "MO", "remote_sld_max_bytes"); - if(!pszMaxRemoteSLDBytes) { - nMaxRemoteSLDBytes = 1024*1024; /* 1 megaByte */ + const char *pszMaxRemoteSLDBytes = msOWSLookupMetadata( + &(map->web.metadata), "MO", "remote_sld_max_bytes"); + if (!pszMaxRemoteSLDBytes) { + nMaxRemoteSLDBytes = 1024 * 1024; /* 1 megaByte */ } else { nMaxRemoteSLDBytes = atoi(pszMaxRemoteSLDBytes); } - if (msHTTPGetFile(szURL, pszSLDTmpFile, &status,-1, 0, 0, nMaxRemoteSLDBytes) == MS_SUCCESS) { + if (msHTTPGetFile(szURL, pszSLDTmpFile, &status, -1, 0, 0, + nMaxRemoteSLDBytes) == MS_SUCCESS) { if ((fp = fopen(pszSLDTmpFile, "rb")) != NULL) { - int nBufsize=0; + int nBufsize = 0; fseek(fp, 0, SEEK_END); nBufsize = ftell(fp); - if(nBufsize > 0) { + if (nBufsize > 0) { rewind(fp); - pszSLDbuf = (char*)malloc((nBufsize+1)*sizeof(char)); + pszSLDbuf = (char *)malloc((nBufsize + 1) * sizeof(char)); IGUR_sizet(fread(pszSLDbuf, 1, nBufsize, fp)); pszSLDbuf[nBufsize] = '\0'; } else { - msSetError(MS_WMSERR, "Could not open SLD %s as it appears empty", "msSLDApplySLDURL", szURL); + msSetError(MS_WMSERR, "Could not open SLD %s as it appears empty", + "msSLDApplySLDURL", szURL); } fclose(fp); unlink(pszSLDTmpFile); } } else { unlink(pszSLDTmpFile); - msSetError(MS_WMSERR, "Could not open SLD %s and save it in a temporary file. Please make sure that the sld url is valid and that the temporary path is set. The temporary path can be defined for example by setting TEMPPATH in the map file. Please check the MapServer documentation on temporary path settings.", "msSLDApplySLDURL", szURL); + msSetError( + MS_WMSERR, + "Could not open SLD %s and save it in a temporary file. Please " + "make sure that the sld url is valid and that the temporary path " + "is set. The temporary path can be defined for example by setting " + "TEMPPATH in the map file. Please check the MapServer " + "documentation on temporary path settings.", + "msSLDApplySLDURL", szURL); } msFree(pszSLDTmpFile); if (pszSLDbuf) - nStatus = msSLDApplySLD(map, pszSLDbuf, iLayer, pszStyleLayerName, ppszLayerNames); + nStatus = msSLDApplySLD(map, pszSLDbuf, iLayer, pszStyleLayerName, + ppszLayerNames); } map->sldurl = NULL; } @@ -121,54 +139,58 @@ int msSLDApplySLDURL(mapObj *map, const char *szURL, int iLayer, return nStatus; #else - msSetError(MS_MISCERR, "WMS/WFS client support is not enabled .", "msSLDApplySLDURL()"); - return(MS_FAILURE); + msSetError(MS_MISCERR, "WMS/WFS client support is not enabled .", + "msSLDApplySLDURL()"); + return (MS_FAILURE); #endif } -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) /* -------------------------------------------------------------------- */ /* If the same layer is given more that once, we need to */ /* duplicate it. */ /* -------------------------------------------------------------------- */ -static void msSLDApplySLD_DuplicateLayers(mapObj *map, int nSLDLayers, layerObj *pasSLDLayers) -{ - int m; - for (m=0; mvtable) { - if( msInitializeVirtualTable(psTmpLayer) != MS_SUCCESS ) { - MS_REFCNT_DECR(psTmpLayer); - continue; - } +static void msSLDApplySLD_DuplicateLayers(mapObj *map, int nSLDLayers, + layerObj *pasSLDLayers) { + int m; + for (m = 0; m < nSLDLayers; m++) { + int l; + int nIndex = msGetLayerIndex(map, pasSLDLayers[m].name); + if (pasSLDLayers[m].name == NULL) + continue; + if (nIndex < 0) + continue; + for (l = m + 1; l < nSLDLayers; l++) { + if (pasSLDLayers[l].name == NULL) + continue; + if (strcasecmp(pasSLDLayers[m].name, pasSLDLayers[l].name) == 0) { + layerObj *psTmpLayer = (layerObj *)malloc(sizeof(layerObj)); + char tmpId[128]; + + initLayer(psTmpLayer, map); + msCopyLayer(psTmpLayer, GET_LAYER(map, nIndex)); + /* open the source layer */ + if (!psTmpLayer->vtable) { + if (msInitializeVirtualTable(psTmpLayer) != MS_SUCCESS) { + MS_REFCNT_DECR(psTmpLayer); + continue; } - - /*make the name unique*/ - snprintf(tmpId, sizeof(tmpId), "%lx_%x_%d",(long)time(NULL),(int)getpid(), - map->numlayers); - if (psTmpLayer->name) - msFree(psTmpLayer->name); - psTmpLayer->name = msStrdup(tmpId); - msFree(pasSLDLayers[l].name); - pasSLDLayers[l].name = msStrdup(tmpId); - msInsertLayer(map, psTmpLayer, -1); - MS_REFCNT_DECR(psTmpLayer); } + + /*make the name unique*/ + snprintf(tmpId, sizeof(tmpId), "%lx_%x_%d", (long)time(NULL), + (int)getpid(), map->numlayers); + if (psTmpLayer->name) + msFree(psTmpLayer->name); + psTmpLayer->name = msStrdup(tmpId); + msFree(pasSLDLayers[l].name); + pasSLDLayers[l].name = msStrdup(tmpId); + msInsertLayer(map, psTmpLayer, -1); + MS_REFCNT_DECR(psTmpLayer); } } + } } #endif @@ -180,33 +202,34 @@ static void msSLDApplySLD_DuplicateLayers(mapObj *map, int nSLDLayers, layerObj /* they have the same name, copy the classes associated with */ /* the SLD layers onto the map layers. */ /************************************************************************/ -int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *pszStyleLayerName, char **ppszLayerNames) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, + const char *pszStyleLayerName, char **ppszLayerNames) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) int nSLDLayers = 0; layerObj *pasSLDLayers = NULL; int nStatus = MS_SUCCESS; /*const char *pszSLDNotSupported = NULL;*/ pasSLDLayers = msSLDParseSLD(map, psSLDXML, &nSLDLayers); - if( pasSLDLayers == NULL ) { - errorObj* psError = msGetErrorObj(); - if( psError && psError->code != MS_NOERR ) + if (pasSLDLayers == NULL) { + errorObj *psError = msGetErrorObj(); + if (psError && psError->code != MS_NOERR) return MS_FAILURE; } - if (pasSLDLayers && nSLDLayers>0) { + if (pasSLDLayers && nSLDLayers > 0) { int i; msSLDApplySLD_DuplicateLayers(map, nSLDLayers, pasSLDLayers); - for (i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { layerObj *lp = NULL; const char *pszWMSLayerName = NULL; int j; int bUseSpecificLayer = 0; - if (iLayer >=0 && iLayer< map->numlayers) { + if (iLayer >= 0 && iLayer < map->numlayers) { i = iLayer; bUseSpecificLayer = 1; } @@ -216,31 +239,36 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz /* compare layer name to wms_name as well */ pszWMSLayerName = msOWSLookupMetadata(&(lp->metadata), "MO", "name"); - for (j=0; jname && pszStyleLayerName == NULL && ((strcasecmp(lp->name, sldLayer->name) == 0 || - (pszWMSLayerName && strcasecmp(pszWMSLayerName, sldLayer->name) == 0))|| - (lp->group && - strcasecmp(lp->group, sldLayer->name) == 0))) || + (pszWMSLayerName && + strcasecmp(pszWMSLayerName, sldLayer->name) == 0)) || + (lp->group && strcasecmp(lp->group, sldLayer->name) == 0))) || (bUseSpecificLayer && pszStyleLayerName && sldLayer->name && strcasecmp(sldLayer->name, pszStyleLayerName) == 0)) { #ifdef notdef - /*this is a test code if we decide to flag some layers as not supporting SLD*/ - pszSLDNotSupported = msOWSLookupMetadata(&(lp->metadata), "M", "SLD_NOT_SUPPORTED"); + /*this is a test code if we decide to flag some layers as not + * supporting SLD*/ + pszSLDNotSupported = + msOWSLookupMetadata(&(lp->metadata), "M", "SLD_NOT_SUPPORTED"); if (pszSLDNotSupported) { - msSetError(MS_WMSERR, "Layer %s does not support SLD", "msSLDApplySLD", sldLayer->name); + msSetError(MS_WMSERR, "Layer %s does not support SLD", + "msSLDApplySLD", sldLayer->name); nsStatus = MS_FAILURE; goto sld_cleanup; } #endif - if ( sldLayer->numclasses > 0) { + if (sldLayer->numclasses > 0) { int iClass = 0; int k; int bSLDHasNamedClass = MS_FALSE; @@ -248,17 +276,17 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz lp->type = sldLayer->type; lp->rendermode = MS_ALL_MATCHING_CLASSES; - for (k=0; k < sldLayer->numclasses; k++) { - if( sldLayer->class[k]->group ) { - bSLDHasNamedClass = MS_TRUE; - break; - } + for (k = 0; k < sldLayer->numclasses; k++) { + if (sldLayer->class[k] -> group) { + bSLDHasNamedClass = MS_TRUE; + break; + } } - for(k=0; knumclasses; k++) { + for (k = 0; k < lp->numclasses; k++) { if (lp->class[k] != NULL) { - lp->class[k]->layer=NULL; - if (freeClass(lp->class[k]) == MS_SUCCESS ) { + lp->class[k]->layer = NULL; + if (freeClass(lp->class[k]) == MS_SUCCESS) { msFree(lp->class[k]); lp->class[k] = NULL; } @@ -266,48 +294,52 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz } lp->numclasses = 0; - if( bSLDHasNamedClass && sldLayer->classgroup ) { - /* Set the class group to the class that has UserStyle.IsDefault */ - msFree( lp->classgroup); - lp->classgroup = msStrdup(sldLayer->classgroup); - } - else { - /*unset the classgroup on the layer if it was set. This allows the layer to render - with all the classes defined in the SLD*/ - msFree(lp->classgroup); - lp->classgroup = NULL; + if (bSLDHasNamedClass && sldLayer->classgroup) { + /* Set the class group to the class that has UserStyle.IsDefault + */ + msFree(lp->classgroup); + lp->classgroup = msStrdup(sldLayer->classgroup); + } else { + /*unset the classgroup on the layer if it was set. This allows the + layer to render with all the classes defined in the SLD*/ + msFree(lp->classgroup); + lp->classgroup = NULL; } - for (k=0; k < sldLayer->numclasses; k++) { + for (k = 0; k < sldLayer->numclasses; k++) { if (msGrowLayerClasses(lp) == NULL) return MS_FAILURE; initClass(lp->class[iClass]); - msCopyClass(lp->class[iClass], - sldLayer->class[k], NULL); + msCopyClass(lp->class[iClass], sldLayer -> class[k], NULL); lp->class[iClass]->layer = lp; lp->numclasses++; - /*aliases may have been used as part of the sld text symbolizer for - label element. Try to process it if that is the case #3114*/ + /*aliases may have been used as part of the sld text symbolizer + for label element. Try to process it if that is the case #3114*/ if (msLayerOpen(lp) == MS_SUCCESS) { if (msLayerGetItems(lp) == MS_SUCCESS && - lp->class[iClass]->text.string) { + lp->class[iClass] -> text.string) { int z; - for(z=0; znumitems; z++) { - const char* pszFullName; + for (z = 0; z < lp->numitems; z++) { + const char *pszFullName; char szTmp[512]; - char* pszTmp1; + char *pszTmp1; if (!lp->items[z] || strlen(lp->items[z]) == 0) continue; snprintf(szTmp, sizeof(szTmp), "%s_alias", lp->items[z]); - pszFullName = msOWSLookupMetadata(&(lp->metadata), "G", szTmp); - pszTmp1 = msStrdup( lp->class[iClass]->text.string); - if (pszFullName != NULL && (strstr(pszTmp1, pszFullName) != NULL)) { - char *tmpstr1= msReplaceSubstring(pszTmp1, pszFullName, lp->items[z]); - char* pszTmp2 = (char *)malloc(sizeof(char)*(strlen(tmpstr1)+3)); - sprintf(pszTmp2,"(%s)",tmpstr1); - msLoadExpressionString(&(lp->class[iClass]->text), pszTmp2); + pszFullName = + msOWSLookupMetadata(&(lp->metadata), "G", szTmp); + pszTmp1 = msStrdup(lp->class[iClass] -> text.string); + if (pszFullName != NULL && + (strstr(pszTmp1, pszFullName) != NULL)) { + char *tmpstr1 = msReplaceSubstring(pszTmp1, pszFullName, + lp->items[z]); + char *pszTmp2 = + (char *)malloc(sizeof(char) * (strlen(tmpstr1) + 3)); + sprintf(pszTmp2, "(%s)", tmpstr1); + msLoadExpressionString(&(lp->class[iClass] -> text), + pszTmp2); msFree(pszTmp2); } msFree(pszTmp1); @@ -322,14 +354,14 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz /*this is probably an SLD that uses Named styles*/ if (sldLayer->classgroup) { int k; - for (k=0; knumclasses; k++) { - if (lp->class[k]->group && - strcasecmp(lp->class[k]->group, - sldLayer->classgroup) == 0) + for (k = 0; k < lp->numclasses; k++) { + if (lp->class[k] -> group && + strcasecmp(lp->class[k] -> group, + sldLayer -> classgroup) == 0) break; } if (k < lp->numclasses) { - msFree( lp->classgroup); + msFree(lp->classgroup); lp->classgroup = msStrdup(sldLayer->classgroup); } else { /* TODO we throw an exception ?*/ @@ -351,79 +383,81 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz } /* opacity for sld raster */ - if (lp->type == MS_LAYER_RASTER && - sldLayer->compositer && sldLayer->compositer->opacity != 100) + if (lp->type == MS_LAYER_RASTER && sldLayer->compositer && + sldLayer->compositer->opacity != 100) msSetLayerOpacity(lp, sldLayer->compositer->opacity); /* mark as auto-generate SLD */ if (lp->connectiontype == MS_WMS) - msInsertHashTable(&(lp->metadata), - "wms_sld_body", "auto" ); + msInsertHashTable(&(lp->metadata), "wms_sld_body", "auto"); /* The SLD might have a FeatureTypeConstraint */ - if( sldLayer->filter.type == MS_EXPRESSION ) - { - if( lp->filter.string && lp->filter.type == MS_EXPRESSION ) - { - char* pszBuffer = msStringConcatenate(NULL, "(("); - pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); - pszBuffer = msStringConcatenate(pszBuffer, ") AND ("); - pszBuffer = msStringConcatenate(pszBuffer, sldLayer->filter.string); - pszBuffer = msStringConcatenate(pszBuffer, "))"); - msFreeExpression(&lp->filter); - msInitExpression(&lp->filter); - lp->filter.string = pszBuffer; - lp->filter.type = MS_EXPRESSION; - } - else - { - msFreeExpression(&lp->filter); - msInitExpression(&lp->filter); - lp->filter.string = msStrdup(sldLayer->filter.string); - lp->filter.type = MS_EXPRESSION; - } + if (sldLayer->filter.type == MS_EXPRESSION) { + if (lp->filter.string && lp->filter.type == MS_EXPRESSION) { + char *pszBuffer = msStringConcatenate(NULL, "(("); + pszBuffer = msStringConcatenate(pszBuffer, lp->filter.string); + pszBuffer = msStringConcatenate(pszBuffer, ") AND ("); + pszBuffer = + msStringConcatenate(pszBuffer, sldLayer->filter.string); + pszBuffer = msStringConcatenate(pszBuffer, "))"); + msFreeExpression(&lp->filter); + msInitExpression(&lp->filter); + lp->filter.string = pszBuffer; + lp->filter.type = MS_EXPRESSION; + } else { + msFreeExpression(&lp->filter); + msInitExpression(&lp->filter); + lp->filter.string = msStrdup(sldLayer->filter.string); + lp->filter.type = MS_EXPRESSION; + } } - /*in some cases it would make sense to concatenate all the class expressions and use it to set the filter on the layer. This could increase performance. Will do it for db types layers #2840*/ - if (lp->filter.string == NULL || (lp->filter.string && lp->filter.type == MS_STRING && !lp->filteritem)) { - if (lp->connectiontype == MS_POSTGIS || lp->connectiontype == MS_ORACLESPATIAL || lp->connectiontype == MS_PLUGIN) { - if (lp->numclasses > 0) { - /* check first that all classes have an expression type. That is - the only way we can concatenate them and set the filter - expression */ - int k; - for (k=0; knumclasses; k++) { - if (lp->class[k]->expression.type != MS_EXPRESSION) - break; + if (lp->filter.string == NULL || + (lp->filter.string && lp->filter.type == MS_STRING && + !lp->filteritem)) { + if (lp->connectiontype == MS_POSTGIS || + lp->connectiontype == MS_ORACLESPATIAL || + lp->connectiontype == MS_PLUGIN) { + if (lp->numclasses > 0) { + /* check first that all classes have an expression type. That is + the only way we can concatenate them and set the filter + expression */ + int k; + for (k = 0; k < lp->numclasses; k++) { + if (lp->class[k] -> expression.type != MS_EXPRESSION) + break; + } + if (k == lp->numclasses) { + char szTmp[512]; + char *pszBuffer = NULL; + for (k = 0; k < lp->numclasses; k++) { + if (pszBuffer == NULL) + snprintf(szTmp, sizeof(szTmp), "%s", + "(("); /* we a building a string expression, + explicitly set type below */ + else + snprintf(szTmp, sizeof(szTmp), "%s", " OR "); + + pszBuffer = msStringConcatenate(pszBuffer, szTmp); + pszBuffer = msStringConcatenate( + pszBuffer, lp->class[k] -> expression.string); } - if (k == lp->numclasses) { - char szTmp[512]; - char* pszBuffer = NULL; - for (k=0; knumclasses; k++) { - if (pszBuffer == NULL) - snprintf(szTmp, sizeof(szTmp), "%s", "(("); /* we a building a string expression, explicitly set type below */ - else - snprintf(szTmp, sizeof(szTmp), "%s", " OR "); - - pszBuffer = msStringConcatenate(pszBuffer, szTmp); - pszBuffer = msStringConcatenate(pszBuffer, lp->class[k]->expression.string); - } - snprintf(szTmp, sizeof(szTmp), "%s", "))"); - pszBuffer =msStringConcatenate(pszBuffer, szTmp); + snprintf(szTmp, sizeof(szTmp), "%s", "))"); + pszBuffer = msStringConcatenate(pszBuffer, szTmp); - msFreeExpression(&lp->filter); - msInitExpression(&lp->filter); - lp->filter.string = msStrdup(pszBuffer); - lp->filter.type = MS_EXPRESSION; + msFreeExpression(&lp->filter); + msInitExpression(&lp->filter); + lp->filter.string = msStrdup(pszBuffer); + lp->filter.type = MS_EXPRESSION; - msFree(pszBuffer); - } + msFree(pszBuffer); } } + } } break; } @@ -438,38 +472,36 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz /* -------------------------------------------------------------------- */ if (ppszLayerNames) { char *pszTmp = NULL; - for (i=0; idebug == MS_DEBUGLEVEL_VVV) { - char* tmpfilename = msTmpFile(map, map->mappath, NULL, "_sld.map"); + if (map->debug == MS_DEBUGLEVEL_VVV) { + char *tmpfilename = msTmpFile(map, map->mappath, NULL, "_sld.map"); if (tmpfilename == NULL) { - tmpfilename = msTmpFile(map, NULL, NULL, "_sld.map" ); + tmpfilename = msTmpFile(map, NULL, NULL, "_sld.map"); } if (tmpfilename) { - msSaveMap(map,tmpfilename); + msSaveMap(map, tmpfilename); msDebug("msApplySLD(): Map file after SLD was applied %s", tmpfilename); msFree(tmpfilename); } @@ -477,32 +509,26 @@ int msSLDApplySLD(mapObj *map, const char *psSLDXML, int iLayer, const char *psz return nStatus; #else - msSetError(MS_MISCERR, "OWS support is not available.", - "msSLDApplySLD()"); - return(MS_FAILURE); + msSetError(MS_MISCERR, "OWS support is not available.", "msSLDApplySLD()"); + return (MS_FAILURE); #endif } - - -static CPLXMLNode* FindNextChild(CPLXMLNode* psNode, const char* pszChildName) -{ - while( psNode ) - { - if( psNode->eType == CXT_Element && - strcasecmp(psNode->pszValue, pszChildName) == 0 ) - { - return psNode; - } - psNode = psNode->psNext; +static CPLXMLNode *FindNextChild(CPLXMLNode *psNode, const char *pszChildName) { + while (psNode) { + if (psNode->eType == CXT_Element && + strcasecmp(psNode->pszValue, pszChildName) == 0) { + return psNode; } - return NULL; + psNode = psNode->psNext; + } + return NULL; } -#define LOOP_ON_CHILD_ELEMENT(psParent_, psChild_, pszChildName_) \ - for( psChild_ = FindNextChild(psParent_->psChild, pszChildName_); \ - psChild_ != NULL; \ - psChild_ = FindNextChild(psChild_->psNext, pszChildName_) ) +#define LOOP_ON_CHILD_ELEMENT(psParent_, psChild_, pszChildName_) \ + for (psChild_ = FindNextChild(psParent_->psChild, pszChildName_); \ + psChild_ != NULL; \ + psChild_ = FindNextChild(psChild_->psNext, pszChildName_)) /************************************************************************/ /* msSLDParseSLD */ @@ -513,15 +539,13 @@ static CPLXMLNode* FindNextChild(CPLXMLNode* psNode, const char* pszChildName) /* Returns an array of mapserver layers. The pnLayres if */ /* provided will indicate the size of the returned array. */ /************************************************************************/ -layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) -{ +layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) { CPLXMLNode *psRoot = NULL; CPLXMLNode *psSLD, *psNamedLayer; layerObj *pasLayers = NULL; int iLayer = 0; int nLayers = 0; - if (map == NULL || psSLDXML == NULL || strlen(psSLDXML) == 0 || (strstr(psSLDXML, "StyledLayerDescriptor") == NULL)) { msSetError(MS_WMSERR, "Invalid SLD document", ""); @@ -529,7 +553,7 @@ layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) } psRoot = CPLParseXMLString(psSLDXML); - if( psRoot == NULL) { + if (psRoot == NULL) { msSetError(MS_WMSERR, "Invalid SLD document : %s", "", psSLDXML); return NULL; } @@ -540,7 +564,6 @@ layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) CPLStripXMLNamespace(psRoot, "gml", 1); CPLStripXMLNamespace(psRoot, "se", 1); - /* -------------------------------------------------------------------- */ /* get the root element (StyledLayerDescriptor). */ /* -------------------------------------------------------------------- */ @@ -553,35 +576,31 @@ layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) /* -------------------------------------------------------------------- */ /* Parse the named layers. */ /* -------------------------------------------------------------------- */ - LOOP_ON_CHILD_ELEMENT(psSLD, psNamedLayer, "NamedLayer") - { - nLayers++; - } + LOOP_ON_CHILD_ELEMENT(psSLD, psNamedLayer, "NamedLayer") { nLayers++; } if (nLayers > 0) - pasLayers = (layerObj *)malloc(sizeof(layerObj)*nLayers); + pasLayers = (layerObj *)malloc(sizeof(layerObj) * nLayers); else return NULL; - LOOP_ON_CHILD_ELEMENT(psSLD, psNamedLayer, "NamedLayer") - { - CPLXMLNode* psName = CPLGetXMLNode(psNamedLayer, "Name"); - initLayer(&pasLayers[iLayer], map); - - if (psName && psName->psChild && psName->psChild->pszValue) - pasLayers[iLayer].name = msStrdup(psName->psChild->pszValue); - - if( msSLDParseNamedLayer(psNamedLayer, &pasLayers[iLayer]) != MS_SUCCESS ) { - int i; - for (i=0; i<=iLayer; i++) - freeLayer(&pasLayers[i]); - msFree(pasLayers); - nLayers = 0; - pasLayers = NULL; - break; - } + LOOP_ON_CHILD_ELEMENT(psSLD, psNamedLayer, "NamedLayer") { + CPLXMLNode *psName = CPLGetXMLNode(psNamedLayer, "Name"); + initLayer(&pasLayers[iLayer], map); + + if (psName && psName->psChild && psName->psChild->pszValue) + pasLayers[iLayer].name = msStrdup(psName->psChild->pszValue); - iLayer++; + if (msSLDParseNamedLayer(psNamedLayer, &pasLayers[iLayer]) != MS_SUCCESS) { + int i; + for (i = 0; i <= iLayer; i++) + freeLayer(&pasLayers[i]); + msFree(pasLayers); + nLayers = 0; + pasLayers = NULL; + break; + } + + iLayer++; } if (pnLayers) @@ -593,89 +612,80 @@ layerObj *msSLDParseSLD(mapObj *map, const char *psSLDXML, int *pnLayers) return pasLayers; } - /************************************************************************/ /* _SLDApplyRuleValues */ /* */ /* Utility function to set the scale, title/name for the */ /* classes created by a Rule. */ /************************************************************************/ -void _SLDApplyRuleValues(CPLXMLNode *psRule, layerObj *psLayer, - int nNewClasses) -{ - CPLXMLNode *psMinScale=NULL, *psMaxScale=NULL; - CPLXMLNode *psName=NULL, *psTitle=NULL; - double dfMinScale=0, dfMaxScale=0; - char *pszName=NULL, *pszTitle=NULL; +void _SLDApplyRuleValues(CPLXMLNode *psRule, layerObj *psLayer, + int nNewClasses) { + CPLXMLNode *psMinScale = NULL, *psMaxScale = NULL; + CPLXMLNode *psName = NULL, *psTitle = NULL; + double dfMinScale = 0, dfMaxScale = 0; + char *pszName = NULL, *pszTitle = NULL; if (psRule && psLayer && nNewClasses > 0) { /* -------------------------------------------------------------------- */ /* parse minscale and maxscale. */ /* -------------------------------------------------------------------- */ - psMinScale = CPLGetXMLNode(psRule, - "MinScaleDenominator"); - if (psMinScale && psMinScale->psChild && - psMinScale->psChild->pszValue) + psMinScale = CPLGetXMLNode(psRule, "MinScaleDenominator"); + if (psMinScale && psMinScale->psChild && psMinScale->psChild->pszValue) dfMinScale = atof(psMinScale->psChild->pszValue); - psMaxScale = CPLGetXMLNode(psRule, - "MaxScaleDenominator"); - if (psMaxScale && psMaxScale->psChild && - psMaxScale->psChild->pszValue) + psMaxScale = CPLGetXMLNode(psRule, "MaxScaleDenominator"); + if (psMaxScale && psMaxScale->psChild && psMaxScale->psChild->pszValue) dfMaxScale = atof(psMaxScale->psChild->pszValue); /* -------------------------------------------------------------------- */ /* parse name and title. */ /* -------------------------------------------------------------------- */ psName = CPLGetXMLNode(psRule, "Name"); - if (psName && psName->psChild && - psName->psChild->pszValue) + if (psName && psName->psChild && psName->psChild->pszValue) pszName = psName->psChild->pszValue; psTitle = CPLGetXMLNode(psRule, "Title"); - if (psTitle && psTitle->psChild && - psTitle->psChild->pszValue) + if (psTitle && psTitle->psChild && psTitle->psChild->pszValue) pszTitle = psTitle->psChild->pszValue; /* -------------------------------------------------------------------- */ /* set the scale to all the classes created by the rule. */ /* -------------------------------------------------------------------- */ if (dfMinScale > 0 || dfMaxScale > 0) { - for (int i=0; i 0) - psLayer->class[psLayer->numclasses-1-i]->minscaledenom = dfMinScale; + psLayer->class[psLayer->numclasses - 1 - i]->minscaledenom = + dfMinScale; if (dfMaxScale) - psLayer->class[psLayer->numclasses-1-i]->maxscaledenom = dfMaxScale; + psLayer->class[psLayer->numclasses - 1 - i]->maxscaledenom = + dfMaxScale; } } /* -------------------------------------------------------------------- */ /* set name and title to the classes created by the rule. */ /* -------------------------------------------------------------------- */ - for (int i=0; iclass[psLayer->numclasses-1-i]->name) { + for (int i = 0; i < nNewClasses; i++) { + if (!psLayer->class[psLayer->numclasses - 1 - i] -> name) { if (pszName) - psLayer->class[psLayer->numclasses-1-i]->name = msStrdup(pszName); + psLayer->class[psLayer->numclasses - 1 - i]->name = msStrdup(pszName); else if (pszTitle) - psLayer->class[psLayer->numclasses-1-i]->name = msStrdup(pszTitle); - else - { + psLayer->class[psLayer->numclasses - 1 - i]->name = + msStrdup(pszTitle); + else { // Build a name from layer and class info char szTmp[256]; snprintf(szTmp, sizeof(szTmp), "%s#%d", psLayer->name, - psLayer->numclasses-1-i); - psLayer->class[psLayer->numclasses-1-i]->name = msStrdup(szTmp); + psLayer->numclasses - 1 - i); + psLayer->class[psLayer->numclasses - 1 - i]->name = msStrdup(szTmp); } } } if (pszTitle) { - for (int i=0; iclass[psLayer->numclasses-1-i]->title = - msStrdup(pszTitle); + for (int i = 0; i < nNewClasses; i++) { + psLayer->class[psLayer->numclasses - 1 - i]->title = msStrdup(pszTitle); } } - } - } /************************************************************************/ @@ -684,72 +694,72 @@ void _SLDApplyRuleValues(CPLXMLNode *psRule, layerObj *psLayer, /* Get a common expression valid from the filter valid for the */ /* temporary layer. */ /************************************************************************/ -static char* msSLDGetCommonExpressionFromFilter(CPLXMLNode* psFilter, - layerObj *psLayer) -{ - char *pszExpression = NULL; - CPLXMLNode *psTmpNextNode = NULL; - CPLXMLNode *psTmpNode = NULL; - FilterEncodingNode *psNode = NULL; - char *pszTmpFilter = NULL; - layerObj *psCurrentLayer = NULL; - const char *pszWmsName=NULL; - const char *key=NULL; - - /* clone the tree and set the next node to null */ - /* so we only have the Filter node */ - psTmpNode = CPLCloneXMLTree(psFilter); - psTmpNextNode = psTmpNode->psNext; - psTmpNode->psNext = NULL; - pszTmpFilter = CPLSerializeXMLTree(psTmpNode); - psTmpNode->psNext = psTmpNextNode; - CPLDestroyXMLNode(psTmpNode); - - if (pszTmpFilter) { - psNode = FLTParseFilterEncoding(pszTmpFilter); - - CPLFree(pszTmpFilter); - } - - if (psNode) { - int j; - - /*preparse the filter for possible gml aliases set on the layer's metadata: - "gml_NA3DESC_alias" "alias_name" and filter could be - alias_name #3079*/ - for (j=0; jmap->numlayers; j++) { - psCurrentLayer = GET_LAYER(psLayer->map, j); - - pszWmsName = msOWSLookupMetadata(&(psCurrentLayer->metadata), "MO", "name"); - - if ((psCurrentLayer->name && psLayer->name && - strcasecmp(psCurrentLayer->name, psLayer->name) == 0) || - (psCurrentLayer->group && psLayer->name && - strcasecmp(psCurrentLayer->group, psLayer->name) == 0) || - (psLayer->name && pszWmsName && - strcasecmp(pszWmsName, psLayer->name) == 0)) - break; - } - if (j < psLayer->map->numlayers) { - /*make sure that the tmp layer has all the metadata that - the original layer has, allowing to do parsing for - such things as gml_attribute_type #3052*/ - while (1) { - key = msNextKeyFromHashTable(&psCurrentLayer->metadata, key); - if (!key) - break; - else - msInsertHashTable(&psLayer->metadata, key, - msLookupHashTable(&psCurrentLayer->metadata, key)); - } - FLTPreParseFilterForAliasAndGroup(psNode, psLayer->map, j, "G"); - } +static char *msSLDGetCommonExpressionFromFilter(CPLXMLNode *psFilter, + layerObj *psLayer) { + char *pszExpression = NULL; + CPLXMLNode *psTmpNextNode = NULL; + CPLXMLNode *psTmpNode = NULL; + FilterEncodingNode *psNode = NULL; + char *pszTmpFilter = NULL; + layerObj *psCurrentLayer = NULL; + const char *pszWmsName = NULL; + const char *key = NULL; + + /* clone the tree and set the next node to null */ + /* so we only have the Filter node */ + psTmpNode = CPLCloneXMLTree(psFilter); + psTmpNextNode = psTmpNode->psNext; + psTmpNode->psNext = NULL; + pszTmpFilter = CPLSerializeXMLTree(psTmpNode); + psTmpNode->psNext = psTmpNextNode; + CPLDestroyXMLNode(psTmpNode); + + if (pszTmpFilter) { + psNode = FLTParseFilterEncoding(pszTmpFilter); + + CPLFree(pszTmpFilter); + } - pszExpression = FLTGetCommonExpression(psNode, psLayer); - FLTFreeFilterEncodingNode(psNode); + if (psNode) { + int j; + + /*preparse the filter for possible gml aliases set on the layer's metadata: + "gml_NA3DESC_alias" "alias_name" and filter could be + alias_name #3079*/ + for (j = 0; j < psLayer->map->numlayers; j++) { + psCurrentLayer = GET_LAYER(psLayer->map, j); + + pszWmsName = + msOWSLookupMetadata(&(psCurrentLayer->metadata), "MO", "name"); + + if ((psCurrentLayer->name && psLayer->name && + strcasecmp(psCurrentLayer->name, psLayer->name) == 0) || + (psCurrentLayer->group && psLayer->name && + strcasecmp(psCurrentLayer->group, psLayer->name) == 0) || + (psLayer->name && pszWmsName && + strcasecmp(pszWmsName, psLayer->name) == 0)) + break; + } + if (j < psLayer->map->numlayers) { + /*make sure that the tmp layer has all the metadata that + the original layer has, allowing to do parsing for + such things as gml_attribute_type #3052*/ + while (1) { + key = msNextKeyFromHashTable(&psCurrentLayer->metadata, key); + if (!key) + break; + else + msInsertHashTable(&psLayer->metadata, key, + msLookupHashTable(&psCurrentLayer->metadata, key)); + } + FLTPreParseFilterForAliasAndGroup(psNode, psLayer->map, j, "G"); } - return pszExpression; + pszExpression = FLTGetCommonExpression(psNode, psLayer); + FLTFreeFilterEncodingNode(psNode); + } + + return pszExpression; } /************************************************************************/ @@ -758,94 +768,85 @@ static char* msSLDGetCommonExpressionFromFilter(CPLXMLNode* psFilter, /* Parse UserStyle node. */ /************************************************************************/ -static void msSLDParseUserStyle(CPLXMLNode* psUserStyle, layerObj *psLayer) -{ - CPLXMLNode *psFeatureTypeStyle; - const char* pszUserStyleName = CPLGetXMLValue(psUserStyle, "Name", NULL); - if( pszUserStyleName ) - { - const char* pszIsDefault = CPLGetXMLValue(psUserStyle, "IsDefault", "0"); - if( EQUAL(pszIsDefault, "true") || EQUAL(pszIsDefault, "1") ) - { - msFree(psLayer->classgroup); - psLayer->classgroup = msStrdup(pszUserStyleName); - } +static void msSLDParseUserStyle(CPLXMLNode *psUserStyle, layerObj *psLayer) { + CPLXMLNode *psFeatureTypeStyle; + const char *pszUserStyleName = CPLGetXMLValue(psUserStyle, "Name", NULL); + if (pszUserStyleName) { + const char *pszIsDefault = CPLGetXMLValue(psUserStyle, "IsDefault", "0"); + if (EQUAL(pszIsDefault, "true") || EQUAL(pszIsDefault, "1")) { + msFree(psLayer->classgroup); + psLayer->classgroup = msStrdup(pszUserStyleName); } + } - LOOP_ON_CHILD_ELEMENT(psUserStyle, psFeatureTypeStyle, - "FeatureTypeStyle") - { - CPLXMLNode* psRule; + LOOP_ON_CHILD_ELEMENT(psUserStyle, psFeatureTypeStyle, "FeatureTypeStyle") { + CPLXMLNode *psRule; - /* -------------------------------------------------------------------- */ - /* Parse rules with no Else filter. */ - /* -------------------------------------------------------------------- */ - LOOP_ON_CHILD_ELEMENT(psFeatureTypeStyle, psRule, "Rule") - { - CPLXMLNode *psFilter = NULL; - CPLXMLNode *psElseFilter = NULL; - int nNewClasses=0, nClassBeforeFilter=0, nClassAfterFilter=0; - int nClassAfterRule=0, nClassBeforeRule=0; - - /* used for scale setting */ - nClassBeforeRule = psLayer->numclasses; - - psElseFilter = CPLGetXMLNode(psRule, "ElseFilter"); - nClassBeforeFilter = psLayer->numclasses; - if (psElseFilter == NULL) - msSLDParseRule(psRule, psLayer, pszUserStyleName); - nClassAfterFilter = psLayer->numclasses; - - /* -------------------------------------------------------------------- */ - /* Parse the filter and apply it to the latest class created by */ - /* the rule. */ - /* NOTE : Spatial Filter is not supported. */ - /* -------------------------------------------------------------------- */ - psFilter = CPLGetXMLNode(psRule, "Filter"); - if (psFilter && psFilter->psChild && psFilter->psChild->pszValue) { - char* pszExpression = msSLDGetCommonExpressionFromFilter(psFilter, - psLayer); - if (pszExpression) { - int i; - nNewClasses = - nClassAfterFilter - nClassBeforeFilter; - for (i=0; i - class[psLayer->numclasses-1-i]-> - expression); - msFreeExpression(exp); - msInitExpression(exp); - exp->string = msStrdup(pszExpression); - exp->type = MS_EXPRESSION; - } - msFree(pszExpression); - pszExpression = NULL; - } - } - nClassAfterRule = psLayer->numclasses; - nNewClasses = nClassAfterRule - nClassBeforeRule; + /* -------------------------------------------------------------------- */ + /* Parse rules with no Else filter. */ + /* -------------------------------------------------------------------- */ + LOOP_ON_CHILD_ELEMENT(psFeatureTypeStyle, psRule, "Rule") { + CPLXMLNode *psFilter = NULL; + CPLXMLNode *psElseFilter = NULL; + int nNewClasses = 0, nClassBeforeFilter = 0, nClassAfterFilter = 0; + int nClassAfterRule = 0, nClassBeforeRule = 0; - /* apply scale and title to newly created classes */ - _SLDApplyRuleValues(psRule, psLayer, nNewClasses); + /* used for scale setting */ + nClassBeforeRule = psLayer->numclasses; - /* TODO : parse legendgraphic */ - } - /* -------------------------------------------------------------------- */ - /* First parse rules with the else filter. These rules will */ - /* create the classes that are placed at the end of class */ - /* list. (See how classes are applied to layers in function */ - /* msSLDApplySLD). */ - /* -------------------------------------------------------------------- */ - LOOP_ON_CHILD_ELEMENT(psFeatureTypeStyle, psRule, "Rule") - { - CPLXMLNode* psElseFilter = CPLGetXMLNode(psRule, "ElseFilter"); - if (psElseFilter) { - msSLDParseRule(psRule, psLayer, pszUserStyleName); - _SLDApplyRuleValues(psRule, psLayer, 1); - psLayer->class[psLayer->numclasses-1]->isfallback = TRUE; + psElseFilter = CPLGetXMLNode(psRule, "ElseFilter"); + nClassBeforeFilter = psLayer->numclasses; + if (psElseFilter == NULL) + msSLDParseRule(psRule, psLayer, pszUserStyleName); + nClassAfterFilter = psLayer->numclasses; + + /* -------------------------------------------------------------------- */ + /* Parse the filter and apply it to the latest class created by */ + /* the rule. */ + /* NOTE : Spatial Filter is not supported. */ + /* -------------------------------------------------------------------- */ + psFilter = CPLGetXMLNode(psRule, "Filter"); + if (psFilter && psFilter->psChild && psFilter->psChild->pszValue) { + char *pszExpression = + msSLDGetCommonExpressionFromFilter(psFilter, psLayer); + if (pszExpression) { + int i; + nNewClasses = nClassAfterFilter - nClassBeforeFilter; + for (i = 0; i < nNewClasses; i++) { + expressionObj *exp = + &(psLayer->class[psLayer->numclasses - 1 - i] -> expression); + msFreeExpression(exp); + msInitExpression(exp); + exp->string = msStrdup(pszExpression); + exp->type = MS_EXPRESSION; } + msFree(pszExpression); + pszExpression = NULL; } + } + nClassAfterRule = psLayer->numclasses; + nNewClasses = nClassAfterRule - nClassBeforeRule; + + /* apply scale and title to newly created classes */ + _SLDApplyRuleValues(psRule, psLayer, nNewClasses); + + /* TODO : parse legendgraphic */ + } + /* -------------------------------------------------------------------- */ + /* First parse rules with the else filter. These rules will */ + /* create the classes that are placed at the end of class */ + /* list. (See how classes are applied to layers in function */ + /* msSLDApplySLD). */ + /* -------------------------------------------------------------------- */ + LOOP_ON_CHILD_ELEMENT(psFeatureTypeStyle, psRule, "Rule") { + CPLXMLNode *psElseFilter = CPLGetXMLNode(psRule, "ElseFilter"); + if (psElseFilter) { + msSLDParseRule(psRule, psLayer, pszUserStyleName); + _SLDApplyRuleValues(psRule, psLayer, 1); + psLayer->class[psLayer->numclasses - 1]->isfallback = TRUE; + } } + } } /************************************************************************/ @@ -853,8 +854,7 @@ static void msSLDParseUserStyle(CPLXMLNode* psUserStyle, layerObj *psLayer) /* */ /* Parse NamedLayer root. */ /************************************************************************/ -int msSLDParseNamedLayer(CPLXMLNode *psRoot, layerObj *psLayer) -{ +int msSLDParseNamedLayer(CPLXMLNode *psRoot, layerObj *psLayer) { CPLXMLNode *psLayerFeatureConstraints = NULL; if (!psRoot || !psLayer) @@ -862,17 +862,16 @@ int msSLDParseNamedLayer(CPLXMLNode *psRoot, layerObj *psLayer) if (CPLGetXMLNode(psRoot, "UserStyle")) { CPLXMLNode *psUserStyle; - LOOP_ON_CHILD_ELEMENT(psRoot, psUserStyle, "UserStyle") - { - msSLDParseUserStyle(psUserStyle, psLayer); + LOOP_ON_CHILD_ELEMENT(psRoot, psUserStyle, "UserStyle") { + msSLDParseUserStyle(psUserStyle, psLayer); } } /* check for Named styles*/ else { - CPLXMLNode* psNamedStyle = CPLGetXMLNode(psRoot, "NamedStyle"); + CPLXMLNode *psNamedStyle = CPLGetXMLNode(psRoot, "NamedStyle"); if (psNamedStyle) { - CPLXMLNode* psSLDName = CPLGetXMLNode(psNamedStyle, "Name"); - if (psSLDName && psSLDName->psChild && psSLDName->psChild->pszValue) { + CPLXMLNode *psSLDName = CPLGetXMLNode(psNamedStyle, "Name"); + if (psSLDName && psSLDName->psChild && psSLDName->psChild->pszValue) { msFree(psLayer->classgroup); psLayer->classgroup = msStrdup(psSLDName->psChild->pszValue); } @@ -881,42 +880,48 @@ int msSLDParseNamedLayer(CPLXMLNode *psRoot, layerObj *psLayer) /* Deal with LayerFeatureConstraints */ psLayerFeatureConstraints = CPLGetXMLNode(psRoot, "LayerFeatureConstraints"); - if( psLayerFeatureConstraints != NULL ) { - CPLXMLNode* psIter = psLayerFeatureConstraints->psChild; - CPLXMLNode* psFeatureTypeConstraint = NULL; - for(; psIter != NULL; psIter = psIter->psNext ) { - if( psIter->eType == CXT_Element && - strcmp(psIter->pszValue, "FeatureTypeConstraint") == 0 ) { - if( psFeatureTypeConstraint == NULL ) { + if (psLayerFeatureConstraints != NULL) { + CPLXMLNode *psIter = psLayerFeatureConstraints->psChild; + CPLXMLNode *psFeatureTypeConstraint = NULL; + for (; psIter != NULL; psIter = psIter->psNext) { + if (psIter->eType == CXT_Element && + strcmp(psIter->pszValue, "FeatureTypeConstraint") == 0) { + if (psFeatureTypeConstraint == NULL) { psFeatureTypeConstraint = psIter; } else { - msSetError(MS_WMSERR, "Only one single FeatureTypeConstraint element " - "per LayerFeatureConstraints is supported", ""); + msSetError(MS_WMSERR, + "Only one single FeatureTypeConstraint element " + "per LayerFeatureConstraints is supported", + ""); return MS_FAILURE; } } } - if( psFeatureTypeConstraint != NULL ) { - CPLXMLNode* psFilter; - if( CPLGetXMLNode(psFeatureTypeConstraint, "FeatureTypeName") != NULL ) { - msSetError(MS_WMSERR, "FeatureTypeName element is not " - "supported in FeatureTypeConstraint", ""); + if (psFeatureTypeConstraint != NULL) { + CPLXMLNode *psFilter; + if (CPLGetXMLNode(psFeatureTypeConstraint, "FeatureTypeName") != NULL) { + msSetError(MS_WMSERR, + "FeatureTypeName element is not " + "supported in FeatureTypeConstraint", + ""); return MS_FAILURE; } - if( CPLGetXMLNode(psFeatureTypeConstraint, "Extent") != NULL ) { - msSetError(MS_WMSERR, "Extent element is not " - "supported in FeatureTypeConstraint", ""); + if (CPLGetXMLNode(psFeatureTypeConstraint, "Extent") != NULL) { + msSetError(MS_WMSERR, + "Extent element is not " + "supported in FeatureTypeConstraint", + ""); return MS_FAILURE; } psFilter = CPLGetXMLNode(psFeatureTypeConstraint, "Filter"); if (psFilter && psFilter->psChild && psFilter->psChild->pszValue) { - char* pszExpression = msSLDGetCommonExpressionFromFilter(psFilter, - psLayer); + char *pszExpression = + msSLDGetCommonExpressionFromFilter(psFilter, psLayer); if (pszExpression) { - msFreeExpression(&psLayer->filter); - msInitExpression(&psLayer->filter); - psLayer->filter.string = pszExpression; - psLayer->filter.type = MS_EXPRESSION; + msFreeExpression(&psLayer->filter); + msInitExpression(&psLayer->filter); + psLayer->filter.string = pszExpression; + psLayer->filter.type = MS_EXPRESSION; } } } @@ -925,21 +930,20 @@ int msSLDParseNamedLayer(CPLXMLNode *psRoot, layerObj *psLayer) return MS_SUCCESS; } - /************************************************************************/ /* msSLDParseRule() */ /* */ /* Parse a Rule node into classes for a specific layer. */ /************************************************************************/ -int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, const char* pszUserStyleName) -{ +int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, + const char *pszUserStyleName) { CPLXMLNode *psLineSymbolizer = NULL; CPLXMLNode *psPolygonSymbolizer = NULL; CPLXMLNode *psPointSymbolizer = NULL; CPLXMLNode *psTextSymbolizer = NULL; CPLXMLNode *psRasterSymbolizer = NULL; - int nSymbolizer=0; + int nSymbolizer = 0; if (!psRoot || !psLayer) return MS_FAILURE; @@ -951,52 +955,45 @@ int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, const char* pszUserSty /* ==================================================================== */ /* Raster symbolizer */ - LOOP_ON_CHILD_ELEMENT(psRoot, psRasterSymbolizer, "RasterSymbolizer") - { + LOOP_ON_CHILD_ELEMENT(psRoot, psRasterSymbolizer, "RasterSymbolizer") { msSLDParseRasterSymbolizer(psRasterSymbolizer, psLayer, pszUserStyleName); /* cppcheck-suppress knownConditionTrueFalse */ - if (nSymbolizer == 0) - { + if (nSymbolizer == 0) { psLayer->type = MS_LAYER_RASTER; } } /* Polygon symbolizer */ - LOOP_ON_CHILD_ELEMENT(psRoot, psPolygonSymbolizer, "PolygonSymbolizer") - { + LOOP_ON_CHILD_ELEMENT(psRoot, psPolygonSymbolizer, "PolygonSymbolizer") { /* cppcheck-suppress knownConditionTrueFalse */ const int bNewClass = (nSymbolizer == 0); - msSLDParsePolygonSymbolizer(psPolygonSymbolizer, psLayer, - bNewClass, pszUserStyleName); + msSLDParsePolygonSymbolizer(psPolygonSymbolizer, psLayer, bNewClass, + pszUserStyleName); psLayer->type = MS_LAYER_POLYGON; nSymbolizer++; } /* line symbolizer */ - LOOP_ON_CHILD_ELEMENT(psRoot, psLineSymbolizer, "LineSymbolizer") - { + LOOP_ON_CHILD_ELEMENT(psRoot, psLineSymbolizer, "LineSymbolizer") { const int bNewClass = (nSymbolizer == 0); msSLDParseLineSymbolizer(psLineSymbolizer, psLayer, bNewClass, pszUserStyleName); - if (bNewClass) - { + if (bNewClass) { psLayer->type = MS_LAYER_LINE; } - if (psLayer->type == MS_LAYER_POLYGON) - { + if (psLayer->type == MS_LAYER_POLYGON) { const int nClassId = psLayer->numclasses - 1; - if (nClassId >= 0) - { + if (nClassId >= 0) { const int nStyleId = psLayer->class[nClassId]->numstyles - 1; - if (nStyleId >= 0) - { - styleObj * psStyle = psLayer->class[nClassId]->styles[nStyleId]; + if (nStyleId >= 0) { + styleObj *psStyle = psLayer->class[nClassId]->styles[nStyleId]; psStyle->outlinecolor = psStyle->color; - MS_INIT_COLOR(psStyle->color,-1,-1,-1,255); - MS_COPYSTRING(psStyle->exprBindings[MS_STYLE_BINDING_OUTLINECOLOR].string, + MS_INIT_COLOR(psStyle->color, -1, -1, -1, 255); + MS_COPYSTRING( + psStyle->exprBindings[MS_STYLE_BINDING_OUTLINECOLOR].string, psStyle->exprBindings[MS_STYLE_BINDING_COLOR].string); psStyle->exprBindings[MS_STYLE_BINDING_OUTLINECOLOR].type = - psStyle->exprBindings[MS_STYLE_BINDING_COLOR].type; + psStyle->exprBindings[MS_STYLE_BINDING_COLOR].type; msFreeExpression(&(psStyle->exprBindings[MS_STYLE_BINDING_COLOR])); msInitExpression(&(psStyle->exprBindings[MS_STYLE_BINDING_COLOR])); } @@ -1006,26 +1003,20 @@ int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, const char* pszUserSty } /* Point Symbolizer */ - LOOP_ON_CHILD_ELEMENT(psRoot, psPointSymbolizer, "PointSymbolizer") - { + LOOP_ON_CHILD_ELEMENT(psRoot, psPointSymbolizer, "PointSymbolizer") { const int bNewClass = (nSymbolizer == 0); msSLDParsePointSymbolizer(psPointSymbolizer, psLayer, bNewClass, pszUserStyleName); - if (bNewClass) - { + if (bNewClass) { psLayer->type = MS_LAYER_POINT; } - if (psLayer->type == MS_LAYER_POLYGON - || psLayer->type == MS_LAYER_LINE - || psLayer->type == MS_LAYER_RASTER) - { + if (psLayer->type == MS_LAYER_POLYGON || psLayer->type == MS_LAYER_LINE || + psLayer->type == MS_LAYER_RASTER) { const int nClassId = psLayer->numclasses - 1; - if (nClassId >= 0) - { + if (nClassId >= 0) { const int nStyleId = psLayer->class[nClassId]->numstyles - 1; - if (nStyleId >= 0) - { - styleObj * psStyle = psLayer->class[nClassId]->styles[nStyleId]; + if (nStyleId >= 0) { + styleObj *psStyle = psLayer->class[nClassId]->styles[nStyleId]; msStyleSetGeomTransform(psStyle, "centroid"); } } @@ -1044,11 +1035,11 @@ int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, const char* pszUserSty /* - If there are no other symbolizers, a new class will be */ /* created to contain the label object. */ /* ==================================================================== */ - LOOP_ON_CHILD_ELEMENT(psRoot, psTextSymbolizer, "TextSymbolizer") - { + LOOP_ON_CHILD_ELEMENT(psRoot, psTextSymbolizer, "TextSymbolizer") { if (nSymbolizer == 0) psLayer->type = MS_LAYER_POINT; - msSLDParseTextSymbolizer(psTextSymbolizer, psLayer, nSymbolizer > 0, pszUserStyleName); + msSLDParseTextSymbolizer(psTextSymbolizer, psLayer, nSymbolizer > 0, + pszUserStyleName); } return MS_SUCCESS; @@ -1058,56 +1049,57 @@ int msSLDParseRule(CPLXMLNode *psRoot, layerObj *psLayer, const char* pszUserSty /* getClassId() */ /************************************************************************/ -static int getClassId(layerObj *psLayer, - int bNewClass, - const char* pszUserStyleName) -{ - int nClassId; - if (bNewClass || psLayer->numclasses <= 0) { - if (msGrowLayerClasses(psLayer) == NULL) - return -1; - initClass(psLayer->class[psLayer->numclasses]); - nClassId = psLayer->numclasses; - if( pszUserStyleName ) - psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); - psLayer->numclasses++; - } else { - nClassId = psLayer->numclasses-1; - } - return nClassId; +static int getClassId(layerObj *psLayer, int bNewClass, + const char *pszUserStyleName) { + int nClassId; + if (bNewClass || psLayer->numclasses <= 0) { + if (msGrowLayerClasses(psLayer) == NULL) + return -1; + initClass(psLayer->class[psLayer->numclasses]); + nClassId = psLayer->numclasses; + if (pszUserStyleName) + psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); + psLayer->numclasses++; + } else { + nClassId = psLayer->numclasses - 1; + } + return nClassId; } /************************************************************************/ /* msSLDParseUomAttribute() */ /************************************************************************/ -int msSLDParseUomAttribute(CPLXMLNode *node, enum MS_UNITS * sizeunits) -{ - const struct - { +int msSLDParseUomAttribute(CPLXMLNode *node, enum MS_UNITS *sizeunits) { + const struct { enum MS_UNITS unit; - char * values[10]; - } known_uoms[] = - { - { MS_INCHES, { "inch", "inches", NULL } }, - { MS_FEET, { "foot", "feet", "http://www.opengeospatial.org/se/units/foot", NULL } }, - { MS_MILES, { "mile", "miles", NULL } }, - { MS_METERS, { "meter", "meters", "metre", "metres", "http://www.opengeospatial.org/se/units/metre", NULL } }, - { MS_KILOMETERS, { "kilometer", "kilometers", "kilometre", "kilometres", NULL } }, - { MS_DD, { "dd", NULL } }, - { MS_PIXELS, { "pixel", "pixels", "px", "http://www.opengeospatial.org/se/units/pixel", NULL } }, - { MS_PERCENTAGES, { "percent", "percents", "percentage", "percentages", NULL } }, - { MS_NAUTICALMILES, { "nauticalmile", "nauticalmiles", "nautical_mile", "nautical_miles", NULL } }, - { 0, { NULL } } - }; - - const char * uom = CPLGetXMLValue(node, "uom", NULL); - if (uom) - { - for (int i=0 ; known_uoms[i].values[0] ; i++) - for (int j=0 ; known_uoms[i].values[j] ; j++) - if (strcmp(uom,known_uoms[i].values[j]) == 0) - { + char *values[10]; + } known_uoms[] = { + {MS_INCHES, {"inch", "inches", NULL}}, + {MS_FEET, + {"foot", "feet", "http://www.opengeospatial.org/se/units/foot", NULL}}, + {MS_MILES, {"mile", "miles", NULL}}, + {MS_METERS, + {"meter", "meters", "metre", "metres", + "http://www.opengeospatial.org/se/units/metre", NULL}}, + {MS_KILOMETERS, + {"kilometer", "kilometers", "kilometre", "kilometres", NULL}}, + {MS_DD, {"dd", NULL}}, + {MS_PIXELS, + {"pixel", "pixels", "px", "http://www.opengeospatial.org/se/units/pixel", + NULL}}, + {MS_PERCENTAGES, + {"percent", "percents", "percentage", "percentages", NULL}}, + {MS_NAUTICALMILES, + {"nauticalmile", "nauticalmiles", "nautical_mile", "nautical_miles", + NULL}}, + {0, {NULL}}}; + + const char *uom = CPLGetXMLValue(node, "uom", NULL); + if (uom) { + for (int i = 0; known_uoms[i].values[0]; i++) + for (int j = 0; known_uoms[i].values[j]; j++) + if (strcmp(uom, known_uoms[i].values[j]) == 0) { // Match found *sizeunits = known_uoms[i].unit; return MS_SUCCESS; @@ -1120,7 +1112,6 @@ int msSLDParseUomAttribute(CPLXMLNode *node, enum MS_UNITS * sizeunits) return MS_SUCCESS; } - /************************************************************************/ /* msSLDParseLineSymbolizer() */ /* */ @@ -1166,47 +1157,46 @@ int msSLDParseUomAttribute(CPLXMLNode *node, enum MS_UNITS * sizeunits) /* ... */ /************************************************************************/ int msSLDParseLineSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, - int bNewClass, const char* pszUserStyleName) -{ - CPLXMLNode *psStroke=NULL, *psOffset=NULL; + int bNewClass, const char *pszUserStyleName) { + CPLXMLNode *psStroke = NULL, *psOffset = NULL; if (!psRoot || !psLayer) return MS_FAILURE; // Get uom if any, defaults to MS_PIXELS enum MS_UNITS sizeunits = MS_PIXELS; - if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) - { - msSetError(MS_WMSERR, "Invalid uom attribute value.", "msSLDParsePolygonSymbolizer()"); + if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) { + msSetError(MS_WMSERR, "Invalid uom attribute value.", + "msSLDParsePolygonSymbolizer()"); return MS_FAILURE; } - psStroke = CPLGetXMLNode(psRoot, "Stroke"); + psStroke = CPLGetXMLNode(psRoot, "Stroke"); if (psStroke) { int nClassId = getClassId(psLayer, bNewClass, pszUserStyleName); - if( nClassId < 0 ) - return MS_FAILURE; + if (nClassId < 0) + return MS_FAILURE; const int iStyle = psLayer->class[nClassId]->numstyles; msMaybeAllocateClassStyle(psLayer->class[nClassId], iStyle); psLayer->class[nClassId]->styles[iStyle]->sizeunits = sizeunits; - msSLDParseStroke(psStroke, psLayer->class[nClassId]->styles[iStyle], - psLayer->map, 0); + msSLDParseStroke(psStroke, psLayer->class[nClassId] -> styles[iStyle], + psLayer -> map, 0); /*parse PerpendicularOffset SLD 1.1.10*/ psOffset = CPLGetXMLNode(psRoot, "PerpendicularOffset"); if (psOffset && psOffset->psChild && psOffset->psChild->pszValue) { - psLayer->class[nClassId]->styles[iStyle]->offsetx = atoi(psOffset->psChild->pszValue); - psLayer->class[nClassId]->styles[iStyle]->offsety = MS_STYLE_SINGLE_SIDED_OFFSET; + psLayer->class[nClassId]->styles[iStyle]->offsetx = + atoi(psOffset->psChild->pszValue); + psLayer->class[nClassId]->styles[iStyle]->offsety = + MS_STYLE_SINGLE_SIDED_OFFSET; } } return MS_SUCCESS; } - - /************************************************************************/ /* void msSLDParseStroke(CPLXMLNode *psStroke, styleObj */ /* *psStyle, int iColorParam) */ @@ -1217,10 +1207,9 @@ int msSLDParseLineSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* 0 : for color */ /* 1 : outlinecolor */ /************************************************************************/ -int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, - mapObj *map, int iColorParam) -{ - CPLXMLNode *psCssParam = NULL, *psGraphicFill=NULL; +int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, mapObj *map, + int iColorParam) { + CPLXMLNode *psCssParam = NULL, *psGraphicFill = NULL; char *psStrkName = NULL; char *pszDashValue = NULL; @@ -1228,54 +1217,54 @@ int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, return MS_FAILURE; /* parse css parameters */ - psCssParam = CPLGetXMLNode(psStroke, "CssParameter"); + psCssParam = CPLGetXMLNode(psStroke, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psStroke, "SvgParameter"); + psCssParam = CPLGetXMLNode(psStroke, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - psStrkName = (char*)CPLGetXMLValue(psCssParam, "name", NULL); + psStrkName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); if (psStrkName) { if (strcasecmp(psStrkName, "stroke") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + if (psCssParam->psChild && psCssParam->psChild->psNext) { switch (iColorParam) { - case 0: - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); - break; - case 1: - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_OUTLINECOLOR, MS_OBJ_STYLE); - break; + case 0: + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); + break; + case 1: + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_OUTLINECOLOR, + MS_OBJ_STYLE); + break; } } } else if (strcasecmp(psStrkName, "stroke-width") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + if (psCssParam->psChild && psCssParam->psChild->psNext) { msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, MS_STYLE_BINDING_WIDTH, MS_OBJ_STYLE); } } else if (strcasecmp(psStrkName, "stroke-dasharray") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext && + if (psCssParam->psChild && psCssParam->psChild->psNext && psCssParam->psChild->psNext->pszValue) { int nDash = 0, i; char **aszValues = NULL; int nMaxDash; - if(pszDashValue) free(pszDashValue); /* free previous if multiple stroke-dasharray attributes were found */ - pszDashValue = - msStrdup(psCssParam->psChild->psNext->pszValue); + if (pszDashValue) + free(pszDashValue); /* free previous if multiple stroke-dasharray + attributes were found */ + pszDashValue = msStrdup(psCssParam->psChild->psNext->pszValue); aszValues = msStringSplit(pszDashValue, ' ', &nDash); if (nDash > 0) { nMaxDash = nDash; if (nDash > MS_MAXPATTERNLENGTH) - nMaxDash = MS_MAXPATTERNLENGTH; + nMaxDash = MS_MAXPATTERNLENGTH; psStyle->patternlength = nMaxDash; - for (i=0; ipattern[i] = atof(aszValues[i]); psStyle->linecap = MS_CJC_BUTT; @@ -1283,10 +1272,9 @@ int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, msFreeCharArray(aszValues, nDash); } } else if (strcasecmp(psStrkName, "stroke-opacity") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); } } } @@ -1298,10 +1286,10 @@ int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, /* TODO : It seems inconsistent to me since the only difference */ /* between them seems to be fill (fill) or not fill (stroke). And */ /* then again the fill parameter can be used inside both elements. */ - psGraphicFill = CPLGetXMLNode(psStroke, "GraphicFill"); + psGraphicFill = CPLGetXMLNode(psStroke, "GraphicFill"); if (psGraphicFill) msSLDParseGraphicFillOrStroke(psGraphicFill, pszDashValue, psStyle, map); - psGraphicFill = CPLGetXMLNode(psStroke, "GraphicStroke"); + psGraphicFill = CPLGetXMLNode(psStroke, "GraphicStroke"); if (psGraphicFill) msSLDParseGraphicFillOrStroke(psGraphicFill, pszDashValue, psStyle, map); @@ -1311,8 +1299,6 @@ int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, return MS_SUCCESS; } - - /************************************************************************/ /* int msSLDParseOgcExpression(CPLXMLNode *psRoot, styleObj *psStyle, */ /* enum MS_STYLE_BINDING_ENUM binding) */ @@ -1320,255 +1306,234 @@ int msSLDParseStroke(CPLXMLNode *psStroke, styleObj *psStyle, /* Parse an OGC expression in a */ /************************************************************************/ int msSLDParseOgcExpression(CPLXMLNode *psRoot, void *psObj, int binding, - enum objType objtype) -{ + enum objType objtype) { int status = MS_FAILURE; - const char * ops = "Add+Sub-Mul*Div/"; - styleObj * psStyle = psObj; - labelObj * psLabel = psObj; + const char *ops = "Add+Sub-Mul*Div/"; + styleObj *psStyle = psObj; + labelObj *psLabel = psObj; int lbinding; expressionObj *exprBindings; int *nexprbindings; enum { MS_STYLE_BASE = 0, MS_LABEL_BASE = 100 }; - switch (objtype) - { - case MS_OBJ_STYLE: - lbinding = binding + MS_STYLE_BASE; - exprBindings = psStyle->exprBindings; - nexprbindings = &psStyle->nexprbindings; + switch (objtype) { + case MS_OBJ_STYLE: + lbinding = binding + MS_STYLE_BASE; + exprBindings = psStyle->exprBindings; + nexprbindings = &psStyle->nexprbindings; + break; + case MS_OBJ_LABEL: + lbinding = binding + MS_LABEL_BASE; + exprBindings = psLabel->exprBindings; + nexprbindings = &psLabel->nexprbindings; + break; + default: + return MS_FAILURE; + break; + } + + switch (psRoot->eType) { + case CXT_Text: + // Parse a raw value + { + msStringBuffer *literal = msStringBufferAlloc(); + msStringBufferAppend(literal, "("); + msStringBufferAppend(literal, psRoot->pszValue); + msStringBufferAppend(literal, ")"); + msFreeExpression(&(exprBindings[binding])); + msInitExpression(&(exprBindings[binding])); + exprBindings[binding].string = + msStringBufferReleaseStringAndFree(literal); + exprBindings[binding].type = MS_STRING; + } + switch (lbinding) { + case MS_STYLE_BASE + MS_STYLE_BINDING_OFFSET_X: + psStyle->offsetx = atoi(psRoot->pszValue); + status = MS_SUCCESS; break; - case MS_OBJ_LABEL: - lbinding = binding + MS_LABEL_BASE; - exprBindings = psLabel->exprBindings; - nexprbindings = &psLabel->nexprbindings; + case MS_STYLE_BASE + MS_STYLE_BINDING_OFFSET_Y: + psStyle->offsety = atoi(psRoot->pszValue); + status = MS_SUCCESS; break; - default: - return MS_FAILURE; + case MS_STYLE_BASE + MS_STYLE_BINDING_ANGLE: + psStyle->angle = atof(psRoot->pszValue); + status = MS_SUCCESS; break; - } - - switch (psRoot->eType) - { - case CXT_Text: - // Parse a raw value - { - msStringBuffer * literal = msStringBufferAlloc(); - msStringBufferAppend(literal, "("); - msStringBufferAppend(literal, psRoot->pszValue); - msStringBufferAppend(literal, ")"); - msFreeExpression(&(exprBindings[binding])); - msInitExpression(&(exprBindings[binding])); - exprBindings[binding].string = - msStringBufferReleaseStringAndFree(literal); - exprBindings[binding].type = MS_STRING; + case MS_STYLE_BASE + MS_STYLE_BINDING_SIZE: + psStyle->size = atof(psRoot->pszValue); + status = MS_SUCCESS; + break; + case MS_STYLE_BASE + MS_STYLE_BINDING_WIDTH: + psStyle->width = atof(psRoot->pszValue); + status = MS_SUCCESS; + break; + case MS_STYLE_BASE + MS_STYLE_BINDING_OPACITY: + psStyle->opacity = atof(psRoot->pszValue) * 100; + status = MS_SUCCESS; + // Apply opacity as the alpha channel color(s) + if (psStyle->opacity < 100) { + int alpha = MS_NINT(psStyle->opacity * 2.55); + psStyle->color.alpha = alpha; + psStyle->outlinecolor.alpha = alpha; + psStyle->mincolor.alpha = alpha; + psStyle->maxcolor.alpha = alpha; } - switch (lbinding) - { - case MS_STYLE_BASE + MS_STYLE_BINDING_OFFSET_X: - psStyle->offsetx = atoi(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_OFFSET_Y: - psStyle->offsety = atoi(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_ANGLE: - psStyle->angle = atof(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_SIZE: - psStyle->size = atof(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_WIDTH: - psStyle->width = atof(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_OPACITY: - psStyle->opacity = atof(psRoot->pszValue)*100; - status = MS_SUCCESS; - // Apply opacity as the alpha channel color(s) - if(psStyle->opacity < 100) - { - int alpha = MS_NINT(psStyle->opacity*2.55); - psStyle->color.alpha = alpha; - psStyle->outlinecolor.alpha = alpha; - psStyle->mincolor.alpha = alpha; - psStyle->maxcolor.alpha = alpha; - } - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_COLOR: - if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') - { - psStyle->color.red = msHexToInt(psRoot->pszValue+1); - psStyle->color.green = msHexToInt(psRoot->pszValue+3); - psStyle->color.blue = msHexToInt(psRoot->pszValue+5); - status = MS_SUCCESS; - } - break; - case MS_STYLE_BASE + MS_STYLE_BINDING_OUTLINECOLOR: - if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') - { - psStyle->outlinecolor.red = msHexToInt(psRoot->pszValue+1); - psStyle->outlinecolor.green = msHexToInt(psRoot->pszValue+3); - psStyle->outlinecolor.blue = msHexToInt(psRoot->pszValue+5); - status = MS_SUCCESS; - } - break; - - case MS_LABEL_BASE + MS_LABEL_BINDING_SIZE: - psLabel->size = atof(psRoot->pszValue); - if (psLabel->size <= 0.0) - { - psLabel->size = 10.0; - } - status = MS_SUCCESS; - break; - case MS_LABEL_BASE + MS_LABEL_BINDING_ANGLE: - psLabel->angle = atof(psRoot->pszValue); - status = MS_SUCCESS; - break; - case MS_LABEL_BASE + MS_LABEL_BINDING_COLOR: - if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') - { - psLabel->color.red = msHexToInt(psRoot->pszValue+1); - psLabel->color.green = msHexToInt(psRoot->pszValue+3); - psLabel->color.blue= msHexToInt(psRoot->pszValue+5); - status = MS_SUCCESS; - } - break; - case MS_LABEL_BASE + MS_LABEL_BINDING_OUTLINECOLOR: - if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') - { - psLabel->outlinecolor.red = msHexToInt(psRoot->pszValue+1); - psLabel->outlinecolor.green = msHexToInt(psRoot->pszValue+3); - psLabel->outlinecolor.blue= msHexToInt(psRoot->pszValue+5); - status = MS_SUCCESS; - } - break; - default: - break; + break; + case MS_STYLE_BASE + MS_STYLE_BINDING_COLOR: + if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') { + psStyle->color.red = msHexToInt(psRoot->pszValue + 1); + psStyle->color.green = msHexToInt(psRoot->pszValue + 3); + psStyle->color.blue = msHexToInt(psRoot->pszValue + 5); + status = MS_SUCCESS; } break; - case CXT_Element: - if (strcasecmp(psRoot->pszValue,"Literal") == 0 && psRoot->psChild) - { - // Parse a element - status = msSLDParseOgcExpression(psRoot->psChild, psObj, binding, objtype); + case MS_STYLE_BASE + MS_STYLE_BINDING_OUTLINECOLOR: + if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') { + psStyle->outlinecolor.red = msHexToInt(psRoot->pszValue + 1); + psStyle->outlinecolor.green = msHexToInt(psRoot->pszValue + 3); + psStyle->outlinecolor.blue = msHexToInt(psRoot->pszValue + 5); + status = MS_SUCCESS; } - else if (strcasecmp(psRoot->pszValue,"PropertyName") == 0 - && psRoot->psChild) - { - // Parse a element - msStringBuffer * property = msStringBufferAlloc(); - const char * strDelim = ""; + break; - switch (lbinding) - { - case MS_STYLE_BASE + MS_STYLE_BINDING_COLOR: - case MS_STYLE_BASE + MS_STYLE_BINDING_OUTLINECOLOR: - case MS_LABEL_BASE + MS_LABEL_BINDING_COLOR: - case MS_LABEL_BASE + MS_LABEL_BINDING_OUTLINECOLOR: - strDelim = "\""; - /* FALLTHROUGH */ - default: - msStringBufferAppend(property, strDelim); - msStringBufferAppend(property, "["); - msStringBufferAppend(property, psRoot->psChild->pszValue); - msStringBufferAppend(property, "]"); - msStringBufferAppend(property, strDelim); - msInitExpression(&(exprBindings[binding])); - exprBindings[binding].string = - msStringBufferReleaseStringAndFree(property); - exprBindings[binding].type = MS_EXPRESSION; - (*nexprbindings)++; - break; - } + case MS_LABEL_BASE + MS_LABEL_BINDING_SIZE: + psLabel->size = atof(psRoot->pszValue); + if (psLabel->size <= 0.0) { + psLabel->size = 10.0; + } + status = MS_SUCCESS; + break; + case MS_LABEL_BASE + MS_LABEL_BINDING_ANGLE: + psLabel->angle = atof(psRoot->pszValue); + status = MS_SUCCESS; + break; + case MS_LABEL_BASE + MS_LABEL_BINDING_COLOR: + if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') { + psLabel->color.red = msHexToInt(psRoot->pszValue + 1); + psLabel->color.green = msHexToInt(psRoot->pszValue + 3); + psLabel->color.blue = msHexToInt(psRoot->pszValue + 5); status = MS_SUCCESS; } - else if (strcasecmp(psRoot->pszValue,"Function") == 0 - && psRoot->psChild - && CPLGetXMLValue(psRoot,"name",NULL) - && psRoot->psChild->psNext) - { - // Parse a element - msStringBuffer * function = msStringBufferAlloc(); - - // Parse function name - const char * funcname = CPLGetXMLValue(psRoot,"name",NULL); - msStringBufferAppend(function, funcname); - msStringBufferAppend(function, "("); + break; + case MS_LABEL_BASE + MS_LABEL_BINDING_OUTLINECOLOR: + if (strlen(psRoot->pszValue) == 7 && psRoot->pszValue[0] == '#') { + psLabel->outlinecolor.red = msHexToInt(psRoot->pszValue + 1); + psLabel->outlinecolor.green = msHexToInt(psRoot->pszValue + 3); + psLabel->outlinecolor.blue = msHexToInt(psRoot->pszValue + 5); + status = MS_SUCCESS; + } + break; + default: + break; + } + break; + case CXT_Element: + if (strcasecmp(psRoot->pszValue, "Literal") == 0 && psRoot->psChild) { + // Parse a element + status = + msSLDParseOgcExpression(psRoot->psChild, psObj, binding, objtype); + } else if (strcasecmp(psRoot->pszValue, "PropertyName") == 0 && + psRoot->psChild) { + // Parse a element + msStringBuffer *property = msStringBufferAlloc(); + const char *strDelim = ""; + + switch (lbinding) { + case MS_STYLE_BASE + MS_STYLE_BINDING_COLOR: + case MS_STYLE_BASE + MS_STYLE_BINDING_OUTLINECOLOR: + case MS_LABEL_BASE + MS_LABEL_BINDING_COLOR: + case MS_LABEL_BASE + MS_LABEL_BINDING_OUTLINECOLOR: + strDelim = "\""; + /* FALLTHROUGH */ + default: + msStringBufferAppend(property, strDelim); + msStringBufferAppend(property, "["); + msStringBufferAppend(property, psRoot->psChild->pszValue); + msStringBufferAppend(property, "]"); + msStringBufferAppend(property, strDelim); msInitExpression(&(exprBindings[binding])); - - // Parse arguments - char * sep =""; - for (CPLXMLNode * argument = psRoot->psChild->psNext ; argument ; argument = argument->psNext) - { - status = msSLDParseOgcExpression(argument, psObj, binding, objtype); - if (status != MS_SUCCESS) - break; - msStringBufferAppend(function, sep); - msStringBufferAppend(function, exprBindings[binding].string); - msFree(exprBindings[binding].string); - msInitExpression(&(exprBindings[binding])); - sep = ","; - } - msStringBufferAppend(function, ")"); exprBindings[binding].string = - msStringBufferReleaseStringAndFree(function); + msStringBufferReleaseStringAndFree(property); exprBindings[binding].type = MS_EXPRESSION; (*nexprbindings)++; - status = MS_SUCCESS; + break; } - else if (strstr(ops, psRoot->pszValue) - && psRoot->psChild && psRoot->psChild->psNext) - { - // Parse an arithmetic element , , , - const char operator[2] = { *(strstr(ops, psRoot->pszValue)+3), '\0' }; - msStringBuffer * expression = msStringBufferAlloc(); - - // Parse first operand - msStringBufferAppend(expression, "("); + status = MS_SUCCESS; + } else if (strcasecmp(psRoot->pszValue, "Function") == 0 && + psRoot->psChild && CPLGetXMLValue(psRoot, "name", NULL) && + psRoot->psChild->psNext) { + // Parse a element + msStringBuffer *function = msStringBufferAlloc(); + + // Parse function name + const char *funcname = CPLGetXMLValue(psRoot, "name", NULL); + msStringBufferAppend(function, funcname); + msStringBufferAppend(function, "("); + msInitExpression(&(exprBindings[binding])); + + // Parse arguments + char *sep = ""; + for (CPLXMLNode *argument = psRoot->psChild->psNext; argument; + argument = argument->psNext) { + status = msSLDParseOgcExpression(argument, psObj, binding, objtype); + if (status != MS_SUCCESS) + break; + msStringBufferAppend(function, sep); + msStringBufferAppend(function, exprBindings[binding].string); + msFree(exprBindings[binding].string); msInitExpression(&(exprBindings[binding])); - status = msSLDParseOgcExpression(psRoot->psChild, psObj, binding, objtype); - - // Parse second operand - if (status == MS_SUCCESS) - { + sep = ","; + } + msStringBufferAppend(function, ")"); + exprBindings[binding].string = + msStringBufferReleaseStringAndFree(function); + exprBindings[binding].type = MS_EXPRESSION; + (*nexprbindings)++; + status = MS_SUCCESS; + } else if (strstr(ops, psRoot->pszValue) && psRoot->psChild && + psRoot->psChild->psNext) { + // Parse an arithmetic element , , , + const char operator[2] = {*(strstr(ops, psRoot->pszValue) + 3), '\0'}; + msStringBuffer *expression = msStringBufferAlloc(); + + // Parse first operand + msStringBufferAppend(expression, "("); + msInitExpression(&(exprBindings[binding])); + status = + msSLDParseOgcExpression(psRoot->psChild, psObj, binding, objtype); + + // Parse second operand + if (status == MS_SUCCESS) { + msStringBufferAppend(expression, exprBindings[binding].string); + msStringBufferAppend(expression, operator); + msFree(exprBindings[binding].string); + msInitExpression(&(exprBindings[binding])); + status = msSLDParseOgcExpression(psRoot->psChild->psNext, psObj, + binding, objtype); + if (status == MS_SUCCESS) { msStringBufferAppend(expression, exprBindings[binding].string); - msStringBufferAppend(expression, operator); + msStringBufferAppend(expression, ")"); msFree(exprBindings[binding].string); - msInitExpression(&(exprBindings[binding])); - status = msSLDParseOgcExpression(psRoot->psChild->psNext, - psObj, binding, objtype); - if (status == MS_SUCCESS) - { - msStringBufferAppend(expression, exprBindings[binding].string); - msStringBufferAppend(expression, ")"); - msFree(exprBindings[binding].string); - exprBindings[binding].string = - msStringBufferReleaseStringAndFree(expression); - expression = NULL; - exprBindings[binding].type = MS_EXPRESSION; - (*nexprbindings)++; - } - } - if (expression != NULL) - { - msStringBufferFree(expression); - msInitExpression(&(exprBindings[binding])); + exprBindings[binding].string = + msStringBufferReleaseStringAndFree(expression); + expression = NULL; + exprBindings[binding].type = MS_EXPRESSION; + (*nexprbindings)++; } } - break; - default: - break; + if (expression != NULL) { + msStringBufferFree(expression); + msInitExpression(&(exprBindings[binding])); + } + } + break; + default: + break; } return status; } - /************************************************************************/ /* msSLDParsePolygonSymbolizer() */ /* */ @@ -1594,8 +1559,10 @@ int msSLDParseOgcExpression(CPLXMLNode *psRoot, void *psObj, int binding, /* */ /* */ /* Here, the CssParameter names are fill instead of stroke and */ -/* fill-opacity instead of stroke-opacity. None of the other CssParameters*/ -/* in Stroke are available for filling and the default value for the fill color in this context is 50% gray (value #808080).*/ +/* fill-opacity instead of stroke-opacity. None of the other + * CssParameters*/ +/* in Stroke are available for filling and the default value for the fill + * color in this context is 50% gray (value #808080).*/ /* */ /* */ /* */ @@ -1623,8 +1590,10 @@ int msSLDParseOgcExpression(CPLXMLNode *psRoot, void *psObj, int binding, /* */ /* */ /* */ -/* The default if neither an ExternalGraphic nor a Mark is specified is to use the default*/ -/* mark of a square with a 50%-gray fill and a black outline, with a size of 6 pixels.*/ +/* The default if neither an ExternalGraphic nor a Mark is specified is to + * use the default*/ +/* mark of a square with a 50%-gray fill and a black outline, with a size + * of 6 pixels.*/ /* */ /* */ /* */ @@ -1637,28 +1606,32 @@ int msSLDParseOgcExpression(CPLXMLNode *psRoot, void *psObj, int binding, /* */ /* */ /* */ -/* The WellKnownName element gives the well-known name of the shape of the mark.*/ +/* The WellKnownName element gives the well-known name of the shape of the + * mark.*/ /* Allowed values include at least square, circle, triangle, star, cross,*/ -/* and x, though map servers may draw a different symbol instead if they don't have a*/ -/* shape for all of these. The default WellKnownName is square. Renderings of these*/ -/* marks may be made solid or hollow depending on Fill and Stroke elements.*/ +/* and x, though map servers may draw a different symbol instead if they + * don't have a*/ +/* shape for all of these. The default WellKnownName is square. Renderings + * of these*/ +/* marks may be made solid or hollow depending on Fill and Stroke + * elements.*/ /* */ /************************************************************************/ int msSLDParsePolygonSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, - int bNewClass, const char* pszUserStyleName) -{ + int bNewClass, const char *pszUserStyleName) { CPLXMLNode *psFill, *psStroke; - CPLXMLNode *psDisplacement=NULL, *psDisplacementX=NULL, *psDisplacementY=NULL; - int nOffsetX=-1, nOffsetY=-1; + CPLXMLNode *psDisplacement = NULL, *psDisplacementX = NULL, + *psDisplacementY = NULL; + int nOffsetX = -1, nOffsetY = -1; if (!psRoot || !psLayer) return MS_FAILURE; // Get uom if any, defaults to MS_PIXELS enum MS_UNITS sizeunits = MS_PIXELS; - if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) - { - msSetError(MS_WMSERR, "Invalid uom attribute value.", "msSLDParsePolygonSymbolizer()"); + if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) { + msSetError(MS_WMSERR, "Invalid uom attribute value.", + "msSLDParsePolygonSymbolizer()"); return MS_FAILURE; } @@ -1668,29 +1641,26 @@ int msSLDParsePolygonSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, psDisplacementX = CPLGetXMLNode(psDisplacement, "DisplacementX"); psDisplacementY = CPLGetXMLNode(psDisplacement, "DisplacementY"); /* psCssParam->psChild->psNext->pszValue) */ - if (psDisplacementX && - psDisplacementX->psChild && - psDisplacementX->psChild->pszValue && - psDisplacementY && - psDisplacementY->psChild && - psDisplacementY->psChild->pszValue) { + if (psDisplacementX && psDisplacementX->psChild && + psDisplacementX->psChild->pszValue && psDisplacementY && + psDisplacementY->psChild && psDisplacementY->psChild->pszValue) { nOffsetX = atoi(psDisplacementX->psChild->pszValue); nOffsetY = atoi(psDisplacementY->psChild->pszValue); } } - psFill = CPLGetXMLNode(psRoot, "Fill"); + psFill = CPLGetXMLNode(psRoot, "Fill"); if (psFill) { const int nClassId = getClassId(psLayer, bNewClass, pszUserStyleName); - if( nClassId < 0 ) - return MS_FAILURE; + if (nClassId < 0) + return MS_FAILURE; const int iStyle = psLayer->class[nClassId]->numstyles; msMaybeAllocateClassStyle(psLayer->class[nClassId], iStyle); psLayer->class[nClassId]->styles[iStyle]->sizeunits = sizeunits; - msSLDParsePolygonFill(psFill, psLayer->class[nClassId]->styles[iStyle], - psLayer->map); + msSLDParsePolygonFill(psFill, psLayer->class[nClassId] -> styles[iStyle], + psLayer -> map); if (nOffsetX > 0 && nOffsetY > 0) { psLayer->class[nClassId]->styles[iStyle]->offsetx = nOffsetX; @@ -1699,7 +1669,7 @@ int msSLDParsePolygonSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, } /* stroke which corresponds to the outline in mapserver */ /* is drawn after the fill */ - psStroke = CPLGetXMLNode(psRoot, "Stroke"); + psStroke = CPLGetXMLNode(psRoot, "Stroke"); if (psStroke) { /* -------------------------------------------------------------------- */ /* there was a fill so add a style to the last class created */ @@ -1708,22 +1678,21 @@ int msSLDParsePolygonSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, int nClassId; int iStyle; if (psFill && psLayer->numclasses > 0) { - nClassId =psLayer->numclasses-1; + nClassId = psLayer->numclasses - 1; iStyle = psLayer->class[nClassId]->numstyles; msMaybeAllocateClassStyle(psLayer->class[nClassId], iStyle); psLayer->class[nClassId]->styles[iStyle]->sizeunits = sizeunits; } else { nClassId = getClassId(psLayer, bNewClass, pszUserStyleName); - if( nClassId < 0 ) + if (nClassId < 0) return MS_FAILURE; iStyle = psLayer->class[nClassId]->numstyles; msMaybeAllocateClassStyle(psLayer->class[nClassId], iStyle); psLayer->class[nClassId]->styles[iStyle]->sizeunits = sizeunits; - } - msSLDParseStroke(psStroke, psLayer->class[nClassId]->styles[iStyle], - psLayer->map, 1); + msSLDParseStroke(psStroke, psLayer->class[nClassId] -> styles[iStyle], + psLayer -> map, 1); if (nOffsetX > 0 && nOffsetY > 0) { psLayer->class[nClassId]->styles[iStyle]->offsetx = nOffsetX; @@ -1734,18 +1703,15 @@ int msSLDParsePolygonSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, return MS_SUCCESS; } - /************************************************************************/ /* void msSLDParsePolygonFill(CPLXMLNode *psFill, styleObj *psStyle, */ /* mapObj *map) */ /* */ /* Parse the Fill node for a polygon into a style. */ /************************************************************************/ -int msSLDParsePolygonFill(CPLXMLNode *psFill, styleObj *psStyle, - mapObj *map) -{ +int msSLDParsePolygonFill(CPLXMLNode *psFill, styleObj *psStyle, mapObj *map) { CPLXMLNode *psCssParam, *psGraphicFill; - char *psFillName=NULL; + char *psFillName = NULL; if (!psFill || !psStyle || !map) return MS_FAILURE; @@ -1755,27 +1721,25 @@ int msSLDParsePolygonFill(CPLXMLNode *psFill, styleObj *psStyle, psStyle->color.green = 128; psStyle->color.blue = 128; - psCssParam = CPLGetXMLNode(psFill, "CssParameter"); + psCssParam = CPLGetXMLNode(psFill, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); + psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - psFillName = (char*)CPLGetXMLValue(psCssParam, "name", NULL); + psFillName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); if (psFillName) { if (strcasecmp(psFillName, "fill") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); } } else if (strcasecmp(psFillName, "fill-opacity") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); } } } @@ -1786,34 +1750,32 @@ int msSLDParsePolygonFill(CPLXMLNode *psFill, styleObj *psStyle, /* TODO : It seems inconsistent to me since the only diffrence */ /* between them seems to be fill (fill) or not fill (stroke). And */ /* then again the fill parameter can be used inside both elements. */ - psGraphicFill = CPLGetXMLNode(psFill, "GraphicFill"); + psGraphicFill = CPLGetXMLNode(psFill, "GraphicFill"); if (psGraphicFill) msSLDParseGraphicFillOrStroke(psGraphicFill, NULL, psStyle, map); - psGraphicFill = CPLGetXMLNode(psFill, "GraphicStroke"); + psGraphicFill = CPLGetXMLNode(psFill, "GraphicStroke"); if (psGraphicFill) msSLDParseGraphicFillOrStroke(psGraphicFill, NULL, psStyle, map); - return MS_SUCCESS; } - /************************************************************************/ /* msSLDParseGraphicFillOrStroke */ /* */ /* Parse the GraphicFill Or GraphicStroke node : look for a */ /* Marker symbol and set the style for that symbol. */ /************************************************************************/ -int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, - char *pszDashValue_unused, - styleObj *psStyle, mapObj *map) -{ +int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, char *pszDashValue_unused, + styleObj *psStyle, mapObj *map) { (void)pszDashValue_unused; - CPLXMLNode *psCssParam, *psGraphic, *psExternalGraphic, *psMark, *psSize, *psGap, *psInitialGap; + CPLXMLNode *psCssParam, *psGraphic, *psExternalGraphic, *psMark, *psSize, + *psGap, *psInitialGap; CPLXMLNode *psWellKnownName, *psStroke, *psFill; - CPLXMLNode *psDisplacement=NULL, *psDisplacementX=NULL, *psDisplacementY=NULL; - CPLXMLNode *psOpacity=NULL, *psRotation=NULL; - char *psName=NULL, *psValue = NULL; + CPLXMLNode *psDisplacement = NULL, *psDisplacementX = NULL, + *psDisplacementY = NULL; + CPLXMLNode *psOpacity = NULL, *psRotation = NULL; + char *psName = NULL, *psValue = NULL; char *pszSymbolName = NULL; int bFilled = 0; @@ -1821,69 +1783,64 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, return MS_FAILURE; /* ==================================================================== */ /* This a definition taken from the specification (11.3.2) : */ - /* Graphics can either be referenced from an external URL in a common format (such as*/ - /* GIF or SVG) or may be derived from a Mark. Multiple external URLs and marks may be*/ - /* referenced with the semantic that they all provide the equivalent graphic in different*/ + /* Graphics can either be referenced from an external URL in a common + * format (such as*/ + /* GIF or SVG) or may be derived from a Mark. Multiple external URLs and + * marks may be*/ + /* referenced with the semantic that they all provide the equivalent + * graphic in different*/ /* formats. */ /* */ /* For this reason, we only need to support one Mark and one */ /* ExtrnalGraphic ???? */ /* ==================================================================== */ - psGraphic = CPLGetXMLNode(psRoot, "Graphic"); + psGraphic = CPLGetXMLNode(psRoot, "Graphic"); if (psGraphic) { /* extract symbol size */ psSize = CPLGetXMLNode(psGraphic, "Size"); - if (psSize && psSize->psChild) - { - msSLDParseOgcExpression(psSize->psChild, - psStyle, MS_STYLE_BINDING_SIZE, MS_OBJ_STYLE); - } - else { + if (psSize && psSize->psChild) { + msSLDParseOgcExpression(psSize->psChild, psStyle, MS_STYLE_BINDING_SIZE, + MS_OBJ_STYLE); + } else { /*do not set a default for external symbols #2305*/ - psExternalGraphic = CPLGetXMLNode(psGraphic, "ExternalGraphic"); + psExternalGraphic = CPLGetXMLNode(psGraphic, "ExternalGraphic"); if (!psExternalGraphic) psStyle->size = 6; /* default value */ } /*SLD 1.1.0 extract opacity, rotation, displacement*/ psOpacity = CPLGetXMLNode(psGraphic, "Opacity"); - if (psOpacity && psOpacity->psChild) - { - msSLDParseOgcExpression(psOpacity->psChild, - psStyle, MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); + if (psOpacity && psOpacity->psChild) { + msSLDParseOgcExpression(psOpacity->psChild, psStyle, + MS_STYLE_BINDING_OPACITY, MS_OBJ_STYLE); } psRotation = CPLGetXMLNode(psGraphic, "Rotation"); - if (psRotation && psRotation->psChild) - { - msSLDParseOgcExpression(psRotation->psChild, - psStyle, MS_STYLE_BINDING_ANGLE, MS_OBJ_STYLE); + if (psRotation && psRotation->psChild) { + msSLDParseOgcExpression(psRotation->psChild, psStyle, + MS_STYLE_BINDING_ANGLE, MS_OBJ_STYLE); } psDisplacement = CPLGetXMLNode(psGraphic, "Displacement"); - if (psDisplacement && psDisplacement->psChild) - { + if (psDisplacement && psDisplacement->psChild) { psDisplacementX = CPLGetXMLNode(psDisplacement, "DisplacementX"); - if (psDisplacementX && psDisplacementX->psChild) - { - msSLDParseOgcExpression(psDisplacementX->psChild, - psStyle, MS_STYLE_BINDING_OFFSET_X, MS_OBJ_STYLE); + if (psDisplacementX && psDisplacementX->psChild) { + msSLDParseOgcExpression(psDisplacementX->psChild, psStyle, + MS_STYLE_BINDING_OFFSET_X, MS_OBJ_STYLE); } psDisplacementY = CPLGetXMLNode(psDisplacement, "DisplacementY"); - if (psDisplacementY && psDisplacementY->psChild) - { - msSLDParseOgcExpression(psDisplacementY->psChild, - psStyle, MS_STYLE_BINDING_OFFSET_Y, MS_OBJ_STYLE); + if (psDisplacementY && psDisplacementY->psChild) { + msSLDParseOgcExpression(psDisplacementY->psChild, psStyle, + MS_STYLE_BINDING_OFFSET_Y, MS_OBJ_STYLE); } } /* extract symbol */ - psMark = CPLGetXMLNode(psGraphic, "Mark"); + psMark = CPLGetXMLNode(psGraphic, "Mark"); if (psMark) { pszSymbolName = NULL; - psWellKnownName = CPLGetXMLNode(psMark, "WellKnownName"); + psWellKnownName = CPLGetXMLNode(psMark, "WellKnownName"); if (psWellKnownName && psWellKnownName->psChild && psWellKnownName->psChild->pszValue) - pszSymbolName = - msStrdup(psWellKnownName->psChild->pszValue); + pszSymbolName = msStrdup(psWellKnownName->psChild->pszValue); /* default symbol is square */ @@ -1894,13 +1851,13 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, strcasecmp(pszSymbolName, "star") != 0 && strcasecmp(pszSymbolName, "cross") != 0 && strcasecmp(pszSymbolName, "x") != 0)) { - if (!pszSymbolName || !*pszSymbolName || msGetSymbolIndex(&map->symbolset, pszSymbolName, MS_FALSE) < 0) { + if (!pszSymbolName || !*pszSymbolName || + msGetSymbolIndex(&map->symbolset, pszSymbolName, MS_FALSE) < 0) { msFree(pszSymbolName); pszSymbolName = msStrdup("square"); } } - /* check if the symbol should be filled or not */ psFill = CPLGetXMLNode(psMark, "Fill"); psStroke = CPLGetXMLNode(psMark, "Stroke"); @@ -1912,30 +1869,25 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, bFilled = 0; if (psFill) { - psCssParam = CPLGetXMLNode(psFill, "CssParameter"); + psCssParam = CPLGetXMLNode(psFill, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); + psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - psName = - (char*)CPLGetXMLValue(psCssParam, "name", NULL); - if (psName && - strcasecmp(psName, "fill") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); + psName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); + if (psName && strcasecmp(psName, "fill") == 0) { + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); } - } else if (psName && - strcasecmp(psName, "fill-opacity") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + } else if (psName && strcasecmp(psName, "fill-opacity") == 0) { + if (psCssParam->psChild && psCssParam->psChild->psNext) { psValue = psCssParam->psChild->psNext->pszValue; if (psValue) { - psStyle->color.alpha = (int)(atof(psValue)*255); + psStyle->color.alpha = (int)(atof(psValue) * 255); } } } @@ -1944,58 +1896,50 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, } } if (psStroke) { - psCssParam = CPLGetXMLNode(psStroke, "CssParameter"); + psCssParam = CPLGetXMLNode(psStroke, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psStroke, "SvgParameter"); + psCssParam = CPLGetXMLNode(psStroke, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - psName = - (char*)CPLGetXMLValue(psCssParam, "name", NULL); - if (psName && - strcasecmp(psName, "stroke") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + psName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); + if (psName && strcasecmp(psName, "stroke") == 0) { + if (psCssParam->psChild && psCssParam->psChild->psNext) { if (bFilled) { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_OUTLINECOLOR, MS_OBJ_STYLE); + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_OUTLINECOLOR, + MS_OBJ_STYLE); } else { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_COLOR, MS_OBJ_STYLE); } } - } else if (psName && - strcasecmp(psName, "stroke-opacity") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + } else if (psName && strcasecmp(psName, "stroke-opacity") == 0) { + if (psCssParam->psChild && psCssParam->psChild->psNext) { psValue = psCssParam->psChild->psNext->pszValue; if (psValue) { if (bFilled) { - psStyle->outlinecolor.alpha = (int)(atof(psValue)*255); + psStyle->outlinecolor.alpha = (int)(atof(psValue) * 255); } else { - psStyle->color.alpha = (int)(atof(psValue)*255); + psStyle->color.alpha = (int)(atof(psValue) * 255); } } } - } else if (psName && - strcasecmp(psName, "stroke-width") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psStyle, MS_STYLE_BINDING_WIDTH, MS_OBJ_STYLE); + } else if (psName && strcasecmp(psName, "stroke-width") == 0) { + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psStyle, + MS_STYLE_BINDING_WIDTH, MS_OBJ_STYLE); } } psCssParam = psCssParam->psNext; } } - } /* set the default color if color is not not already set */ - if ((psStyle->color.red < 0 || - psStyle->color.green == -1 || + if ((psStyle->color.red < 0 || psStyle->color.green == -1 || psStyle->color.blue == -1) && (psStyle->outlinecolor.red == -1 || psStyle->outlinecolor.green == -1 || @@ -2005,34 +1949,32 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, psStyle->color.blue = 128; } - /* Get the corresponding symbol id */ psStyle->symbol = msSLDGetMarkSymbol(map, pszSymbolName, bFilled); - if (psStyle->symbol > 0 && - psStyle->symbol < map->symbolset.numsymbols) + if (psStyle->symbol > 0 && psStyle->symbol < map->symbolset.numsymbols) psStyle->symbolname = - msStrdup(map->symbolset.symbol[psStyle->symbol]->name); + msStrdup(map->symbolset.symbol[psStyle->symbol]->name); } else { - psExternalGraphic = CPLGetXMLNode(psGraphic, "ExternalGraphic"); + psExternalGraphic = CPLGetXMLNode(psGraphic, "ExternalGraphic"); if (psExternalGraphic) msSLDParseExternalGraphic(psExternalGraphic, psStyle, map); } msFree(pszSymbolName); } - psGap = CPLGetXMLNode(psRoot, "Gap"); + psGap = CPLGetXMLNode(psRoot, "Gap"); if (psGap && psGap->psChild && psGap->psChild->pszValue) { psStyle->gap = atof(psGap->psChild->pszValue); } - psInitialGap = CPLGetXMLNode(psRoot, "InitialGap"); - if (psInitialGap && psInitialGap->psChild && psInitialGap->psChild->pszValue) { + psInitialGap = CPLGetXMLNode(psRoot, "InitialGap"); + if (psInitialGap && psInitialGap->psChild && + psInitialGap->psChild->pszValue) { psStyle->initialgap = atof(psInitialGap->psChild->pszValue); } return MS_SUCCESS; } - /************************************************************************/ /* msSLDGetMarkSymbol */ /* */ @@ -2040,8 +1982,7 @@ int msSLDParseGraphicFillOrStroke(CPLXMLNode *psRoot, /* square, circle, triangle, star, cross, x. */ /* If the symbol does not exist add it to the symbol list. */ /************************************************************************/ -int msSLDGetMarkSymbol(mapObj *map, char *pszSymbolName, int bFilled) -{ +int msSLDGetMarkSymbol(mapObj *map, char *pszSymbolName, int bFilled) { int nSymbolId = 0; symbolObj *psSymbol = NULL; @@ -2051,70 +1992,56 @@ int msSLDGetMarkSymbol(mapObj *map, char *pszSymbolName, int bFilled) if (strcasecmp(pszSymbolName, "square") == 0) { if (bFilled) nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_SQUARE_FILLED, - MS_FALSE); + SLD_MARK_SYMBOL_SQUARE_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_SQUARE, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_SQUARE, MS_FALSE); } else if (strcasecmp(pszSymbolName, "circle") == 0) { if (bFilled) nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_CIRCLE_FILLED, - MS_FALSE); + SLD_MARK_SYMBOL_CIRCLE_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_CIRCLE, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_CIRCLE, MS_FALSE); } else if (strcasecmp(pszSymbolName, "triangle") == 0) { if (bFilled) nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_TRIANGLE_FILLED, - MS_FALSE); + SLD_MARK_SYMBOL_TRIANGLE_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_TRIANGLE, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_TRIANGLE, MS_FALSE); } else if (strcasecmp(pszSymbolName, "star") == 0) { if (bFilled) - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_STAR_FILLED, + nSymbolId = msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_STAR_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_STAR, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_STAR, MS_FALSE); } else if (strcasecmp(pszSymbolName, "cross") == 0) { if (bFilled) nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_CROSS_FILLED, - MS_FALSE); + SLD_MARK_SYMBOL_CROSS_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_CROSS, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_CROSS, MS_FALSE); } else if (strcasecmp(pszSymbolName, "x") == 0) { if (bFilled) - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_X_FILLED, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_X_FILLED, MS_FALSE); else - nSymbolId = msGetSymbolIndex(&map->symbolset, - SLD_MARK_SYMBOL_X, - MS_FALSE); + nSymbolId = + msGetSymbolIndex(&map->symbolset, SLD_MARK_SYMBOL_X, MS_FALSE); } else { - nSymbolId = msGetSymbolIndex(&map->symbolset, - pszSymbolName, - MS_FALSE); + nSymbolId = msGetSymbolIndex(&map->symbolset, pszSymbolName, MS_FALSE); } if (nSymbolId <= 0) { - if( (psSymbol = msGrowSymbolSet(&(map->symbolset))) == NULL) + if ((psSymbol = msGrowSymbolSet(&(map->symbolset))) == NULL) return 0; /* returns 0 for no symbol */ nSymbolId = map->symbolset.numsymbols; @@ -2280,7 +2207,6 @@ int msSLDGetMarkSymbol(mapObj *map, char *pszSymbolName, int bFilled) psSymbol->points[psSymbol->numpoints].y = 0; psSymbol->numpoints++; } - } return nSymbolId; @@ -2292,16 +2218,14 @@ int msSLDGetMarkSymbol(mapObj *map, char *pszSymbolName, int bFilled) /* Create a symbol entry for an inmap pixmap symbol. Returns */ /* the symbol id. */ /************************************************************************/ -int msSLDGetGraphicSymbol(mapObj *map, char *pszFileName, char* extGraphicName, - int nGap_ignored) -{ +int msSLDGetGraphicSymbol(mapObj *map, char *pszFileName, char *extGraphicName, + int nGap_ignored) { (void)nGap_ignored; int nSymbolId = 0; symbolObj *psSymbol = NULL; - if (map && pszFileName) { - if( (psSymbol = msGrowSymbolSet(&(map->symbolset))) == NULL) + if ((psSymbol = msGrowSymbolSet(&(map->symbolset))) == NULL) return 0; /* returns 0 for no symbol */ nSymbolId = map->symbolset.numsymbols; map->symbolset.numsymbols++; @@ -2315,7 +2239,6 @@ int msSLDGetGraphicSymbol(mapObj *map, char *pszFileName, char* extGraphicName, return nSymbolId; } - /************************************************************************/ /* msSLDParsePointSymbolizer */ /* */ @@ -2331,8 +2254,7 @@ int msSLDGetGraphicSymbol(mapObj *map, char *pszFileName, char* extGraphicName, /* */ /************************************************************************/ int msSLDParsePointSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, - int bNewClass, const char* pszUserStyleName) -{ + int bNewClass, const char *pszUserStyleName) { int nClassId = 0; int iStyle = 0; @@ -2340,14 +2262,14 @@ int msSLDParsePointSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, return MS_FAILURE; nClassId = getClassId(psLayer, bNewClass, pszUserStyleName); - if( nClassId < 0 ) + if (nClassId < 0) return MS_FAILURE; // Get uom if any, defaults to MS_PIXELS enum MS_UNITS sizeunits = MS_PIXELS; - if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) - { - msSetError(MS_WMSERR, "Invalid uom attribute value.", "msSLDParsePolygonSymbolizer()"); + if (msSLDParseUomAttribute(psRoot, &sizeunits) != MS_SUCCESS) { + msSetError(MS_WMSERR, "Invalid uom attribute value.", + "msSLDParsePolygonSymbolizer()"); return MS_FAILURE; } @@ -2355,14 +2277,12 @@ int msSLDParsePointSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, msMaybeAllocateClassStyle(psLayer->class[nClassId], iStyle); psLayer->class[nClassId]->styles[iStyle]->sizeunits = sizeunits; - msSLDParseGraphicFillOrStroke(psRoot, NULL, - psLayer->class[nClassId]->styles[iStyle], - psLayer->map); + msSLDParseGraphicFillOrStroke( + psRoot, NULL, psLayer->class[nClassId] -> styles[iStyle], psLayer -> map); return MS_SUCCESS; } - /************************************************************************/ /* msSLDParseExternalGraphic */ /* */ @@ -2370,12 +2290,11 @@ int msSLDParsePointSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* by the URL and create a PIXMAP inmap symbol. Only GIF and */ /* PNG are supported. */ /************************************************************************/ -int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, - styleObj *psStyle, mapObj *map) -{ +int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, styleObj *psStyle, + mapObj *map) { char *pszFormat = NULL; - CPLXMLNode *psURL=NULL, *psFormat=NULL, *psTmp=NULL; - char *pszURL=NULL; + CPLXMLNode *psURL = NULL, *psFormat = NULL, *psTmp = NULL; + char *pszURL = NULL; if (!psExternalGraphic || !psStyle || !map) return MS_FAILURE; @@ -2385,32 +2304,31 @@ int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, pszFormat = psFormat->psChild->pszValue; /* supports GIF and PNG and SVG */ - if (pszFormat && - (strcasecmp(pszFormat, "GIF") == 0 || - strcasecmp(pszFormat, "image/gif") == 0 || - strcasecmp(pszFormat, "PNG") == 0 || - strcasecmp(pszFormat, "image/png") == 0 || - strcasecmp(pszFormat, "image/svg+xml") == 0)) { - - /* */ + if (pszFormat && (strcasecmp(pszFormat, "GIF") == 0 || + strcasecmp(pszFormat, "image/gif") == 0 || + strcasecmp(pszFormat, "PNG") == 0 || + strcasecmp(pszFormat, "image/png") == 0 || + strcasecmp(pszFormat, "image/svg+xml") == 0)) { + + /* + */ psURL = CPLGetXMLNode(psExternalGraphic, "OnlineResource"); if (psURL && psURL->psChild) { - psTmp = psURL->psChild; - while (psTmp != NULL && - psTmp->pszValue && + psTmp = psURL->psChild; + while (psTmp != NULL && psTmp->pszValue && strcasecmp(psTmp->pszValue, "xlink:href") != 0) { psTmp = psTmp->psNext; } if (psTmp && psTmp->psChild) { - pszURL = (char*)psTmp->psChild->pszValue; + pszURL = (char *)psTmp->psChild->pszValue; char *symbolurl = NULL; // Handle relative URL for ExternalGraphic - if (map->sldurl && !strstr(pszURL,"://")) - { + if (map->sldurl && !strstr(pszURL, "://")) { char *baseurl = NULL; char *relpath = NULL; - symbolurl = malloc(sizeof(char)*MS_MAXPATHLEN); + symbolurl = malloc(sizeof(char) * MS_MAXPATHLEN); if (pszURL[0] != '/') { // Symbol file is relative to SLD file // e.g. SLD : http://example.com/path/to/sld.xml @@ -2418,57 +2336,58 @@ int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, // lead to: http://example.com/path/to/assets/symbol.svg baseurl = msGetPath(map->sldurl); relpath = pszURL; - } - else - { + } else { // Symbol file is relative to the root of SLD server // e.g. SLD : http://example.com/path/to/sld.xml // and symbol: /path/to/assets/symbol.svg // lead to: http://example.com/path/to/assets/symbol.svg baseurl = msStrdup(map->sldurl); - relpath = pszURL+1; - char * sep = strstr(baseurl,"://"); + relpath = pszURL + 1; + char *sep = strstr(baseurl, "://"); if (sep) sep += 3; else sep = baseurl; - sep = strchr(sep,'/'); + sep = strchr(sep, '/'); if (!sep) sep = baseurl + strlen(baseurl); sep[1] = '\0'; } - msBuildPath(symbolurl,baseurl,relpath); + msBuildPath(symbolurl, baseurl, relpath); msFree(baseurl); - } - else - { + } else { // Absolute URL // e.g. symbol: http://example.com/path/to/assets/symbol.svg symbolurl = msStrdup(pszURL); } /* validate the ExternalGraphic parameter */ - if(msValidateParameter(symbolurl, msLookupHashTable(&(map->web.validation), "sld_external_graphic"), - NULL, NULL, NULL) != MS_SUCCESS) { - msSetError(MS_WEBERR, "SLD ExternalGraphic OnlineResource value fails to validate against sld_external_graphic VALIDATION", "mapserv()"); + if (msValidateParameter(symbolurl, + msLookupHashTable(&(map->web.validation), + "sld_external_graphic"), + NULL, NULL, NULL) != MS_SUCCESS) { + msSetError(MS_WEBERR, + "SLD ExternalGraphic OnlineResource value fails to " + "validate against sld_external_graphic VALIDATION", + "mapserv()"); msFree(symbolurl); return MS_FAILURE; } - - /*external symbols using http will be automaticallly downloaded. The file should be - saved in a temporary directory (msAddImageSymbol) #2305*/ - psStyle->symbol = msGetSymbolIndex(&map->symbolset, - symbolurl, - MS_TRUE); + /*external symbols using http will be automaticallly downloaded. The + file should be saved in a temporary directory (msAddImageSymbol) + #2305*/ + psStyle->symbol = msGetSymbolIndex(&map->symbolset, symbolurl, MS_TRUE); msFree(symbolurl); if (psStyle->symbol > 0 && psStyle->symbol < map->symbolset.numsymbols) - psStyle->symbolname = msStrdup(map->symbolset.symbol[psStyle->symbol]->name); + psStyle->symbolname = + msStrdup(map->symbolset.symbol[psStyle->symbol]->name); /* set the color parameter if not set. Does not make sense */ /* for pixmap but mapserver needs it. */ - if (psStyle->color.red == -1 || psStyle->color.green || psStyle->color.blue) { + if (psStyle->color.red == -1 || psStyle->color.green || + psStyle->color.blue) { psStyle->color.red = 0; psStyle->color.green = 0; psStyle->color.blue = 0; @@ -2480,7 +2399,6 @@ int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, return MS_SUCCESS; } - /************************************************************************/ /* msSLDParseTextSymbolizer */ /* */ @@ -2574,9 +2492,9 @@ int msSLDParseExternalGraphic(CPLXMLNode *psExternalGraphic, /* */ /************************************************************************/ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, - int bOtherSymboliser, const char* pszUserStyleName) -{ - int nStyleId=0, nClassId=0; + int bOtherSymboliser, + const char *pszUserStyleName) { + int nStyleId = 0, nClassId = 0; if (!psRoot || !psLayer) return MS_FAILURE; @@ -2586,26 +2504,23 @@ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, return MS_FAILURE; initClass(psLayer->class[psLayer->numclasses]); nClassId = psLayer->numclasses; - if( pszUserStyleName ) - psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); + if (pszUserStyleName) + psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); psLayer->numclasses++; msMaybeAllocateClassStyle(psLayer->class[nClassId], 0); nStyleId = 0; } else { nClassId = psLayer->numclasses - 1; - if (nClassId >= 0)/* should always be true */ - nStyleId = psLayer->class[nClassId]->numstyles -1; + if (nClassId >= 0) /* should always be true */ + nStyleId = psLayer->class[nClassId]->numstyles - 1; } if (nStyleId >= 0 && nClassId >= 0) /* should always be true */ - msSLDParseTextParams(psRoot, psLayer, - psLayer->class[nClassId]); + msSLDParseTextParams(psRoot, psLayer, psLayer->class[nClassId]); return MS_SUCCESS; } - - /************************************************************************/ /* msSLDParseRasterSymbolizer */ /* */ @@ -2645,7 +2560,8 @@ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* */ /* SLD 1.1 */ /* */ -/* */ +/* */ /* */ /* */ /* */ @@ -2671,7 +2587,8 @@ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* */ /* */ /* */ -/* */ +/* */ /* */ /* */ /* */ @@ -2683,7 +2600,8 @@ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* */ /* */ /* */ -/* */ +/* */ /* */ /* */ /* */ @@ -2699,21 +2617,20 @@ int msSLDParseTextSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* */ /************************************************************************/ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, - const char* pszUserStyleName) -{ - CPLXMLNode *psColorMap = NULL, *psColorEntry = NULL, *psOpacity=NULL; - char *pszColor=NULL, *pszQuantity=NULL; - char *pszPreviousColor=NULL, *pszPreviousQuality=NULL; + const char *pszUserStyleName) { + CPLXMLNode *psColorMap = NULL, *psColorEntry = NULL, *psOpacity = NULL; + char *pszColor = NULL, *pszQuantity = NULL; + char *pszPreviousColor = NULL, *pszPreviousQuality = NULL; colorObj sColor; char szExpression[100]; double dfOpacity = 1.0; - char *pszLabel = NULL, *pszPreviousLabel = NULL; - char *pch = NULL, *pchPrevious=NULL; + char *pszLabel = NULL, *pszPreviousLabel = NULL; + char *pch = NULL, *pchPrevious = NULL; - CPLXMLNode *psNode=NULL, *psCategorize=NULL; + CPLXMLNode *psNode = NULL, *psCategorize = NULL; char *pszTmp = NULL; - int nValues=0, nThresholds=0; - int i,nMaxValues= 100, nMaxThreshold=100; + int nValues = 0, nThresholds = 0; + int i, nMaxValues = 100, nMaxThreshold = 100; if (!psRoot || !psLayer) return MS_FAILURE; @@ -2723,11 +2640,14 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, if (psOpacity->psChild && psOpacity->psChild->pszValue) dfOpacity = atof(psOpacity->psChild->pszValue); - /* values in sld goes from 0.0 (for transparent) to 1.0 (for full opacity); */ - if (dfOpacity >=0.0 && dfOpacity <=1.0) - msSetLayerOpacity(psLayer,(int)(dfOpacity * 100)); + /* values in sld goes from 0.0 (for transparent) to 1.0 (for full opacity); + */ + if (dfOpacity >= 0.0 && dfOpacity <= 1.0) + msSetLayerOpacity(psLayer, (int)(dfOpacity * 100)); else { - msSetError(MS_WMSERR, "Invalid opacity value. Values should be between 0.0 and 1.0", "msSLDParseRasterSymbolizer()"); + msSetError(MS_WMSERR, + "Invalid opacity value. Values should be between 0.0 and 1.0", + "msSLDParseRasterSymbolizer()"); return MS_FAILURE; } } @@ -2744,47 +2664,41 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, if (pszColor && pszQuantity) { if (pszPreviousColor && pszPreviousQuality) { - if (strlen(pszPreviousColor) == 7 && - pszPreviousColor[0] == '#' && + if (strlen(pszPreviousColor) == 7 && pszPreviousColor[0] == '#' && strlen(pszColor) == 7 && pszColor[0] == '#') { - sColor.red = msHexToInt(pszPreviousColor+1); - sColor.green= msHexToInt(pszPreviousColor+3); - sColor.blue = msHexToInt(pszPreviousColor+5); + sColor.red = msHexToInt(pszPreviousColor + 1); + sColor.green = msHexToInt(pszPreviousColor + 3); + sColor.blue = msHexToInt(pszPreviousColor + 5); /* pszQuantity and pszPreviousQuality may be integer or float */ - pchPrevious=strchr(pszPreviousQuality,'.'); - pch=strchr(pszQuantity,'.'); - if (pchPrevious==NULL && pch==NULL) { + pchPrevious = strchr(pszPreviousQuality, '.'); + pch = strchr(pszQuantity, '.'); + if (pchPrevious == NULL && pch == NULL) { snprintf(szExpression, sizeof(szExpression), "([pixel] >= %d AND [pixel] < %d)", - atoi(pszPreviousQuality), - atoi(pszQuantity)); - } else if (pchPrevious != NULL && pch==NULL) { + atoi(pszPreviousQuality), atoi(pszQuantity)); + } else if (pchPrevious != NULL && pch == NULL) { snprintf(szExpression, sizeof(szExpression), "([pixel] >= %f AND [pixel] < %d)", - atof(pszPreviousQuality), - atoi(pszQuantity)); + atof(pszPreviousQuality), atoi(pszQuantity)); } else if (pchPrevious == NULL && pch != NULL) { snprintf(szExpression, sizeof(szExpression), "([pixel] >= %d AND [pixel] < %f)", - atoi(pszPreviousQuality), - atof(pszQuantity)); + atoi(pszPreviousQuality), atof(pszQuantity)); } else { snprintf(szExpression, sizeof(szExpression), "([pixel] >= %f AND [pixel] < %f)", - atof(pszPreviousQuality), - atof(pszQuantity)); + atof(pszPreviousQuality), atof(pszQuantity)); } - if (msGrowLayerClasses(psLayer) == NULL) return MS_FAILURE; else { initClass(psLayer->class[psLayer->numclasses]); psLayer->numclasses++; - const int nClassId = psLayer->numclasses-1; - if( pszUserStyleName ) - psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); + const int nClassId = psLayer->numclasses - 1; + if (pszUserStyleName) + psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); /*set the class name using the label. If label not defined set it with the quantity*/ @@ -2795,52 +2709,46 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, msMaybeAllocateClassStyle(psLayer->class[nClassId], 0); - psLayer->class[nClassId]->styles[0]->color.red = - sColor.red; - psLayer->class[nClassId]->styles[0]->color.green = - sColor.green; - psLayer->class[nClassId]->styles[0]->color.blue = - sColor.blue; + psLayer->class[nClassId]->styles[0]->color.red = sColor.red; + psLayer->class[nClassId]->styles[0]->color.green = sColor.green; + psLayer->class[nClassId]->styles[0]->color.blue = sColor.blue; if (psLayer->classitem && strcasecmp(psLayer->classitem, "[pixel]") != 0) free(psLayer->classitem); psLayer->classitem = msStrdup("[pixel]"); - msLoadExpressionString(&psLayer->class[nClassId]->expression, + msLoadExpressionString(&psLayer->class[nClassId] -> expression, szExpression); - - } } else { - msSetError(MS_WMSERR, - "Invalid ColorMap Entry.", + msSetError(MS_WMSERR, "Invalid ColorMap Entry.", "msSLDParseRasterSymbolizer()"); return MS_FAILURE; } - } pszPreviousColor = pszColor; pszPreviousQuality = pszQuantity; pszPreviousLabel = pszLabel; - } psColorEntry = psColorEntry->psNext; } /* do the last Color Map Entry */ if (pszColor && pszQuantity) { if (strlen(pszColor) == 7 && pszColor[0] == '#') { - sColor.red = msHexToInt(pszColor+1); - sColor.green= msHexToInt(pszColor+3); - sColor.blue = msHexToInt(pszColor+5); + sColor.red = msHexToInt(pszColor + 1); + sColor.green = msHexToInt(pszColor + 3); + sColor.blue = msHexToInt(pszColor + 5); /* pszQuantity may be integer or float */ - pch=strchr(pszQuantity,'.'); - if (pch==NULL) { - snprintf(szExpression, sizeof(szExpression), "([pixel] = %d)", atoi(pszQuantity)); + pch = strchr(pszQuantity, '.'); + if (pch == NULL) { + snprintf(szExpression, sizeof(szExpression), "([pixel] = %d)", + atoi(pszQuantity)); } else { - snprintf(szExpression, sizeof(szExpression), "([pixel] = %f)", atof(pszQuantity)); + snprintf(szExpression, sizeof(szExpression), "([pixel] = %f)", + atof(pszQuantity)); } if (msGrowLayerClasses(psLayer) == NULL) @@ -2848,9 +2756,9 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, else { initClass(psLayer->class[psLayer->numclasses]); psLayer->numclasses++; - const int nClassId = psLayer->numclasses-1; - if( pszUserStyleName ) - psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); + const int nClassId = psLayer->numclasses - 1; + if (pszUserStyleName) + psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); msMaybeAllocateClassStyle(psLayer->class[nClassId], 0); if (pszLabel) @@ -2858,119 +2766,118 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, else psLayer->class[nClassId]->name = msStrdup(pszQuantity); psLayer->class[nClassId]->numstyles = 1; - psLayer->class[nClassId]->styles[0]->color.red = - sColor.red; - psLayer->class[nClassId]->styles[0]->color.green = - sColor.green; - psLayer->class[nClassId]->styles[0]->color.blue = - sColor.blue; + psLayer->class[nClassId]->styles[0]->color.red = sColor.red; + psLayer->class[nClassId]->styles[0]->color.green = sColor.green; + psLayer->class[nClassId]->styles[0]->color.blue = sColor.blue; if (psLayer->classitem && strcasecmp(psLayer->classitem, "[pixel]") != 0) free(psLayer->classitem); psLayer->classitem = msStrdup("[pixel]"); - msLoadExpressionString(&psLayer->class[nClassId]->expression, + msLoadExpressionString(&psLayer->class[nClassId] -> expression, szExpression); } } } } else if ((psCategorize = CPLGetXMLNode(psColorMap, "Categorize"))) { - char** papszValues = (char **)msSmallMalloc(sizeof(char*)*nMaxValues); - char** papszThresholds = (char **)msSmallMalloc(sizeof(char*)*nMaxThreshold); - psNode = CPLGetXMLNode(psCategorize, "Value"); - while (psNode && psNode->pszValue && - psNode->psChild && psNode->psChild->pszValue) + char **papszValues = (char **)msSmallMalloc(sizeof(char *) * nMaxValues); + char **papszThresholds = + (char **)msSmallMalloc(sizeof(char *) * nMaxThreshold); + psNode = CPLGetXMLNode(psCategorize, "Value"); + while (psNode && psNode->pszValue && psNode->psChild && + psNode->psChild->pszValue) { if (strcasecmp(psNode->pszValue, "Value") == 0) { - papszValues[nValues] = psNode->psChild->pszValue; + papszValues[nValues] = psNode->psChild->pszValue; nValues++; if (nValues == nMaxValues) { - nMaxValues +=100; - papszValues = (char **)msSmallRealloc(papszValues, sizeof(char*)*nMaxValues); + nMaxValues += 100; + papszValues = (char **)msSmallRealloc(papszValues, + sizeof(char *) * nMaxValues); } } else if (strcasecmp(psNode->pszValue, "Threshold") == 0) { - papszThresholds[nThresholds] = psNode->psChild->pszValue; + papszThresholds[nThresholds] = psNode->psChild->pszValue; nThresholds++; if (nValues == nMaxThreshold) { nMaxThreshold += 100; - papszThresholds = (char **)msSmallRealloc(papszThresholds, sizeof(char*)*nMaxThreshold); + papszThresholds = (char **)msSmallRealloc( + papszThresholds, sizeof(char *) * nMaxThreshold); } } psNode = psNode->psNext; } - if (nThresholds > 0 && nValues == nThresholds+1) { + if (nThresholds > 0 && nValues == nThresholds + 1) { /*free existing classes*/ - for(i=0; inumclasses; i++) { + for (i = 0; i < psLayer->numclasses; i++) { if (psLayer->class[i] != NULL) { - psLayer->class[i]->layer=NULL; - if ( freeClass(psLayer->class[i]) == MS_SUCCESS ) { + psLayer->class[i]->layer = NULL; + if (freeClass(psLayer->class[i]) == MS_SUCCESS) { msFree(psLayer->class[i]); - psLayer->class[i]=NULL; + psLayer->class[i] = NULL; } } } - psLayer->numclasses=0; - for (i=0; inumclasses = 0; + for (i = 0; i < nValues; i++) { pszTmp = (papszValues[i]); if (pszTmp && strlen(pszTmp) == 7 && pszTmp[0] == '#') { - sColor.red = msHexToInt(pszTmp+1); - sColor.green= msHexToInt(pszTmp+3); - sColor.blue = msHexToInt(pszTmp+5); + sColor.red = msHexToInt(pszTmp + 1); + sColor.green = msHexToInt(pszTmp + 3); + sColor.blue = msHexToInt(pszTmp + 5); if (i == 0) { - if (strchr(papszThresholds[i],'.')) - snprintf(szExpression, sizeof(szExpression), "([pixel] < %f)", atof(papszThresholds[i])); + if (strchr(papszThresholds[i], '.')) + snprintf(szExpression, sizeof(szExpression), "([pixel] < %f)", + atof(papszThresholds[i])); else - snprintf(szExpression, sizeof(szExpression), "([pixel] < %d)", atoi(papszThresholds[i])); + snprintf(szExpression, sizeof(szExpression), "([pixel] < %d)", + atoi(papszThresholds[i])); - } else if (i < nValues-1) { - if (strchr(papszThresholds[i],'.')) - snprintf(szExpression, sizeof(szExpression), + } else if (i < nValues - 1) { + if (strchr(papszThresholds[i], '.')) + snprintf(szExpression, sizeof(szExpression), "([pixel] >= %f AND [pixel] < %f)", - atof(papszThresholds[i-1]), + atof(papszThresholds[i - 1]), atof(papszThresholds[i])); else snprintf(szExpression, sizeof(szExpression), "([pixel] >= %d AND [pixel] < %d)", - atoi(papszThresholds[i-1]), + atoi(papszThresholds[i - 1]), atoi(papszThresholds[i])); } else { - if (strchr(papszThresholds[i-1],'.')) - snprintf(szExpression, sizeof(szExpression), "([pixel] >= %f)", atof(papszThresholds[i-1])); + if (strchr(papszThresholds[i - 1], '.')) + snprintf(szExpression, sizeof(szExpression), "([pixel] >= %f)", + atof(papszThresholds[i - 1])); else - snprintf(szExpression, sizeof(szExpression), "([pixel] >= %d)", atoi(papszThresholds[i-1])); + snprintf(szExpression, sizeof(szExpression), "([pixel] >= %d)", + atoi(papszThresholds[i - 1])); } if (msGrowLayerClasses(psLayer)) { initClass(psLayer->class[psLayer->numclasses]); psLayer->numclasses++; - const int nClassId = psLayer->numclasses-1; - if( pszUserStyleName ) + const int nClassId = psLayer->numclasses - 1; + if (pszUserStyleName) psLayer->class[nClassId]->group = msStrdup(pszUserStyleName); msMaybeAllocateClassStyle(psLayer->class[nClassId], 0); psLayer->class[nClassId]->numstyles = 1; - psLayer->class[nClassId]->styles[0]->color.red = - sColor.red; - psLayer->class[nClassId]->styles[0]->color.green = - sColor.green; - psLayer->class[nClassId]->styles[0]->color.blue = - sColor.blue; + psLayer->class[nClassId]->styles[0]->color.red = sColor.red; + psLayer->class[nClassId]->styles[0]->color.green = sColor.green; + psLayer->class[nClassId]->styles[0]->color.blue = sColor.blue; if (psLayer->classitem && strcasecmp(psLayer->classitem, "[pixel]") != 0) free(psLayer->classitem); psLayer->classitem = msStrdup("[pixel]"); - msLoadExpressionString(&psLayer->class[nClassId]->expression, + msLoadExpressionString(&psLayer->class[nClassId] -> expression, szExpression); } - } } } msFree(papszValues); msFree(papszThresholds); - } else { msSetError(MS_WMSERR, "Invalid SLD document. msSLDParseRaster", ""); return MS_FAILURE; @@ -2985,24 +2892,26 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer, /* Parse text parameters like font, placement and color. */ /************************************************************************/ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, - classObj *psClass) -{ + classObj *psClass) { char szFontName[100]; - CPLXMLNode *psLabel=NULL, *psFont=NULL; + CPLXMLNode *psLabel = NULL, *psFont = NULL; CPLXMLNode *psCssParam = NULL; - char *pszName=NULL, *pszFontFamily=NULL, *pszFontStyle=NULL; - char *pszFontWeight=NULL; - CPLXMLNode *psLabelPlacement=NULL, *psPointPlacement=NULL, *psLinePlacement=NULL; - CPLXMLNode *psFill = NULL, *psHalo=NULL, *psHaloRadius=NULL, *psHaloFill=NULL; + char *pszName = NULL, *pszFontFamily = NULL, *pszFontStyle = NULL; + char *pszFontWeight = NULL; + CPLXMLNode *psLabelPlacement = NULL, *psPointPlacement = NULL, + *psLinePlacement = NULL; + CPLXMLNode *psFill = NULL, *psHalo = NULL, *psHaloRadius = NULL, + *psHaloFill = NULL; labelObj *psLabelObj = NULL; - szFontName[0]='\0'; + szFontName[0] = '\0'; if (!psRoot || !psClass || !psLayer) return MS_FAILURE; - if(psClass->numlabels == 0) { - if(msGrowClassLabels(psClass) == NULL) return(MS_FAILURE); + if (psClass->numlabels == 0) { + if (msGrowClassLabels(psClass) == NULL) + return (MS_FAILURE); initLabel(psClass->labels[0]); psClass->numlabels++; } @@ -3012,59 +2921,54 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, modified Label Placement #2806*/ psLabelObj->anglemode = MS_AUTO; - /* label */ /* support literal expression and propertyname - - - + - + Bug 1857 */ psLabel = CPLGetXMLNode(psRoot, "Label"); - if (psLabel) - { - char * sep = ""; - msStringBuffer * classtext = msStringBufferAlloc(); + if (psLabel) { + char *sep = ""; + msStringBuffer *classtext = msStringBufferAlloc(); msStringBufferAppend(classtext, "("); - for (CPLXMLNode * psTmpNode = psLabel->psChild ; psTmpNode ; psTmpNode = psTmpNode->psNext) - { - if (psTmpNode->eType == CXT_Text && psTmpNode->pszValue) - { + for (CPLXMLNode *psTmpNode = psLabel->psChild; psTmpNode; + psTmpNode = psTmpNode->psNext) { + if (psTmpNode->eType == CXT_Text && psTmpNode->pszValue) { msStringBufferAppend(classtext, sep); msStringBufferAppend(classtext, "\""); msStringBufferAppend(classtext, psTmpNode->pszValue); msStringBufferAppend(classtext, "\""); sep = "+"; - } - else if (psTmpNode->eType == CXT_Element - && strcasecmp(psTmpNode->pszValue,"Literal") == 0 - && psTmpNode->psChild) - { + } else if (psTmpNode->eType == CXT_Element && + strcasecmp(psTmpNode->pszValue, "Literal") == 0 && + psTmpNode->psChild) { msStringBufferAppend(classtext, sep); msStringBufferAppend(classtext, "\""); msStringBufferAppend(classtext, psTmpNode->psChild->pszValue); msStringBufferAppend(classtext, "\""); sep = "+"; - } - else if (psTmpNode->eType == CXT_Element - && strcasecmp(psTmpNode->pszValue,"PropertyName") == 0 - && psTmpNode->psChild) - { + } else if (psTmpNode->eType == CXT_Element && + strcasecmp(psTmpNode->pszValue, "PropertyName") == 0 && + psTmpNode->psChild) { msStringBufferAppend(classtext, sep); msStringBufferAppend(classtext, "\"["); msStringBufferAppend(classtext, psTmpNode->psChild->pszValue); msStringBufferAppend(classtext, "]\""); sep = "+"; - } - else if (psTmpNode->eType == CXT_Element - && strcasecmp(psTmpNode->pszValue,"Function") == 0 - && psTmpNode->psChild) - { + } else if (psTmpNode->eType == CXT_Element && + strcasecmp(psTmpNode->pszValue, "Function") == 0 && + psTmpNode->psChild) { msStringBufferAppend(classtext, sep); msStringBufferAppend(classtext, "tostring("); labelObj tempExpressionCollector; initLabel(&tempExpressionCollector); - msSLDParseOgcExpression(psTmpNode,&tempExpressionCollector,MS_LABEL_BINDING_SIZE,MS_OBJ_LABEL); - msStringBufferAppend(classtext,tempExpressionCollector.exprBindings[MS_LABEL_BINDING_SIZE].string); + msSLDParseOgcExpression(psTmpNode, &tempExpressionCollector, + MS_LABEL_BINDING_SIZE, MS_OBJ_LABEL); + msStringBufferAppend( + classtext, + tempExpressionCollector.exprBindings[MS_LABEL_BINDING_SIZE].string); freeLabel(&tempExpressionCollector); msStringBufferAppend(classtext, ",\"%g\")"); @@ -3072,10 +2976,9 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, } } msStringBufferAppend(classtext, ")"); - const char * expressionstring = msStringBufferGetString(classtext); - if (strlen(expressionstring) > 2) - { - msLoadExpressionString(&psClass->text, (char*)expressionstring); + const char *expressionstring = msStringBufferGetString(classtext); + if (strlen(expressionstring) > 2) { + msLoadExpressionString(&psClass->text, (char *)expressionstring); } msStringBufferFree(classtext); @@ -3083,39 +2986,38 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, /* font */ psFont = CPLGetXMLNode(psRoot, "Font"); if (psFont) { - psCssParam = CPLGetXMLNode(psFont, "CssParameter"); + psCssParam = CPLGetXMLNode(psFont, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psFont, "SvgParameter"); + psCssParam = CPLGetXMLNode(psFont, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - pszName = (char*)CPLGetXMLValue(psCssParam, "name", NULL); + pszName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); if (pszName) { if (strcasecmp(pszName, "font-family") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext && + if (psCssParam->psChild && psCssParam->psChild->psNext && psCssParam->psChild->psNext->pszValue) pszFontFamily = psCssParam->psChild->psNext->pszValue; } /* normal, italic, oblique */ else if (strcasecmp(pszName, "font-style") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext && + if (psCssParam->psChild && psCssParam->psChild->psNext && psCssParam->psChild->psNext->pszValue) pszFontStyle = psCssParam->psChild->psNext->pszValue; } /* normal or bold */ else if (strcasecmp(pszName, "font-weight") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext && + if (psCssParam->psChild && psCssParam->psChild->psNext && psCssParam->psChild->psNext->pszValue) pszFontWeight = psCssParam->psChild->psNext->pszValue; } /* default is 10 pix */ else if (strcasecmp(pszName, "font-size") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, - psLabelObj, MS_LABEL_BINDING_SIZE, MS_OBJ_LABEL); + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression(psCssParam->psChild->psNext, psLabelObj, + MS_LABEL_BINDING_SIZE, MS_OBJ_LABEL); } } } @@ -3128,10 +3030,8 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, /* -------------------------------------------------------------------- */ psLabelPlacement = CPLGetXMLNode(psRoot, "LabelPlacement"); if (psLabelPlacement) { - psPointPlacement = CPLGetXMLNode(psLabelPlacement, - "PointPlacement"); - psLinePlacement = CPLGetXMLNode(psLabelPlacement, - "LinePlacement"); + psPointPlacement = CPLGetXMLNode(psLabelPlacement, "PointPlacement"); + psLinePlacement = CPLGetXMLNode(psLabelPlacement, "LinePlacement"); if (psPointPlacement) ParseTextPointPlacement(psPointPlacement, psClass); if (psLinePlacement) @@ -3156,7 +3056,8 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, strlcat(szFontName, pszFontStyle, sizeof(szFontName)); } - if ((msLookupHashTable(&(psLayer->map->fontset.fonts), szFontName) !=NULL)) { + if ((msLookupHashTable(&(psLayer->map->fontset.fonts), szFontName) != + NULL)) { psLabelObj->font = msStrdup(szFontName); } } @@ -3166,63 +3067,60 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, /* -------------------------------------------------------------------- */ psHalo = CPLGetXMLNode(psRoot, "Halo"); if (psHalo) { - psHaloRadius = CPLGetXMLNode(psHalo, "Radius"); - if (psHaloRadius && psHaloRadius->psChild && psHaloRadius->psChild->pszValue) + psHaloRadius = CPLGetXMLNode(psHalo, "Radius"); + if (psHaloRadius && psHaloRadius->psChild && + psHaloRadius->psChild->pszValue) psLabelObj->outlinewidth = atoi(psHaloRadius->psChild->pszValue); - psHaloFill = CPLGetXMLNode(psHalo, "Fill"); + psHaloFill = CPLGetXMLNode(psHalo, "Fill"); if (psHaloFill) { - psCssParam = CPLGetXMLNode(psHaloFill, "CssParameter"); + psCssParam = CPLGetXMLNode(psHaloFill, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psHaloFill, "SvgParameter"); + psCssParam = CPLGetXMLNode(psHaloFill, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - pszName = (char*)CPLGetXMLValue(psCssParam, "name", NULL); + pszName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); if (pszName) { if (strcasecmp(pszName, "fill") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { - msSLDParseOgcExpression(psCssParam->psChild->psNext, psLabelObj, + if (psCssParam->psChild && psCssParam->psChild->psNext) { + msSLDParseOgcExpression( + psCssParam->psChild->psNext, psLabelObj, MS_LABEL_BINDING_OUTLINECOLOR, MS_OBJ_LABEL); } } } psCssParam = psCssParam->psNext; } - } - } /* -------------------------------------------------------------------- */ /* Parse the color */ /* -------------------------------------------------------------------- */ psFill = CPLGetXMLNode(psRoot, "Fill"); if (psFill) { - psCssParam = CPLGetXMLNode(psFill, "CssParameter"); + psCssParam = CPLGetXMLNode(psFill, "CssParameter"); /*sld 1.1 used SvgParameter*/ if (psCssParam == NULL) - psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); + psCssParam = CPLGetXMLNode(psFill, "SvgParameter"); while (psCssParam && psCssParam->pszValue && (strcasecmp(psCssParam->pszValue, "CssParameter") == 0 || strcasecmp(psCssParam->pszValue, "SvgParameter") == 0)) { - pszName = (char*)CPLGetXMLValue(psCssParam, "name", NULL); + pszName = (char *)CPLGetXMLValue(psCssParam, "name", NULL); if (pszName) { if (strcasecmp(pszName, "fill") == 0) { - if(psCssParam->psChild && psCssParam->psChild->psNext) - { + if (psCssParam->psChild && psCssParam->psChild->psNext) { msSLDParseOgcExpression(psCssParam->psChild->psNext, psLabelObj, - MS_LABEL_BINDING_COLOR, MS_OBJ_LABEL); + MS_LABEL_BINDING_COLOR, MS_OBJ_LABEL); } } } psCssParam = psCssParam->psNext; } } - } } @@ -3234,17 +3132,17 @@ int msSLDParseTextParams(CPLXMLNode *psRoot, layerObj *psLayer, /* */ /* point placement node for the text symbolizer. */ /************************************************************************/ -int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) -{ +int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) { CPLXMLNode *psAnchor, *psAnchorX, *psAnchorY; CPLXMLNode *psDisplacement, *psDisplacementX, *psDisplacementY; - CPLXMLNode *psRotation=NULL; + CPLXMLNode *psRotation = NULL; labelObj *psLabelObj = NULL; if (!psRoot || !psClass) return MS_FAILURE; - if(psClass->numlabels == 0) { - if(msGrowClassLabels(psClass) == NULL) return(MS_FAILURE); + if (psClass->numlabels == 0) { + if (msGrowClassLabels(psClass) == NULL) + return (MS_FAILURE); initLabel(psClass->labels[0]); psClass->numlabels++; } @@ -3262,12 +3160,8 @@ int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) psAnchorX = CPLGetXMLNode(psAnchor, "AnchorPointX"); psAnchorY = CPLGetXMLNode(psAnchor, "AnchorPointY"); /* psCssParam->psChild->psNext->pszValue) */ - if (psAnchorX && - psAnchorX->psChild && - psAnchorX->psChild->pszValue && - psAnchorY && - psAnchorY->psChild && - psAnchorY->psChild->pszValue) { + if (psAnchorX && psAnchorX->psChild && psAnchorX->psChild->pszValue && + psAnchorY && psAnchorY->psChild && psAnchorY->psChild->pszValue) { const double dfAnchorX = atof(psAnchorX->psChild->pszValue); const double dfAnchorY = atof(psAnchorY->psChild->pszValue); @@ -3305,12 +3199,9 @@ int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) psDisplacementX = CPLGetXMLNode(psDisplacement, "DisplacementX"); psDisplacementY = CPLGetXMLNode(psDisplacement, "DisplacementY"); /* psCssParam->psChild->psNext->pszValue) */ - if (psDisplacementX && - psDisplacementX->psChild && - psDisplacementX->psChild->pszValue && - psDisplacementY && - psDisplacementY->psChild && - psDisplacementY->psChild->pszValue) { + if (psDisplacementX && psDisplacementX->psChild && + psDisplacementX->psChild->pszValue && psDisplacementY && + psDisplacementY->psChild && psDisplacementY->psChild->pszValue) { psLabelObj->offsetx = atoi(psDisplacementX->psChild->pszValue); psLabelObj->offsety = atoi(psDisplacementY->psChild->pszValue); } @@ -3320,10 +3211,9 @@ int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) /* parse rotation. */ /* -------------------------------------------------------------------- */ psRotation = CPLGetXMLNode(psRoot, "Rotation"); - if (psRotation && psRotation->psChild) - { + if (psRotation && psRotation->psChild) { msSLDParseOgcExpression(psRotation->psChild, psLabelObj, - MS_LABEL_BINDING_ANGLE, MS_OBJ_LABEL); + MS_LABEL_BINDING_ANGLE, MS_OBJ_LABEL); } return MS_SUCCESS; @@ -3334,16 +3224,16 @@ int ParseTextPointPlacement(CPLXMLNode *psRoot, classObj *psClass) /* */ /* Lineplacement node fro the text symbolizer. */ /************************************************************************/ -int ParseTextLinePlacement(CPLXMLNode *psRoot, classObj *psClass) -{ - CPLXMLNode *psOffset = NULL, *psAligned=NULL; +int ParseTextLinePlacement(CPLXMLNode *psRoot, classObj *psClass) { + CPLXMLNode *psOffset = NULL, *psAligned = NULL; labelObj *psLabelObj = NULL; if (!psRoot || !psClass) return MS_FAILURE; - if(psClass->numlabels == 0) { - if(msGrowClassLabels(psClass) == NULL) return(MS_FAILURE); + if (psClass->numlabels == 0) { + if (msGrowClassLabels(psClass) == NULL) + return (MS_FAILURE); initLabel(psClass->labels[0]); psClass->numlabels++; } @@ -3379,7 +3269,6 @@ int ParseTextLinePlacement(CPLXMLNode *psRoot, classObj *psClass) return MS_SUCCESS; } - /************************************************************************/ /* void msSLDSetColorObject(char *psHexColor, colorObj */ /* *psColor) */ @@ -3388,14 +3277,13 @@ int ParseTextLinePlacement(CPLXMLNode *psRoot, classObj *psClass) /* color string (format is : #aaff08) and set it in the color */ /* object. */ /************************************************************************/ -int msSLDSetColorObject(char *psHexColor, colorObj *psColor) -{ - if (psHexColor && psColor && strlen(psHexColor)== 7 && +int msSLDSetColorObject(char *psHexColor, colorObj *psColor) { + if (psHexColor && psColor && strlen(psHexColor) == 7 && psHexColor[0] == '#') { - psColor->red = msHexToInt(psHexColor+1); - psColor->green = msHexToInt(psHexColor+3); - psColor->blue= msHexToInt(psHexColor+5); + psColor->red = msHexToInt(psHexColor + 1); + psColor->green = msHexToInt(psHexColor + 3); + psColor->blue = msHexToInt(psHexColor + 5); } return MS_SUCCESS; @@ -3415,9 +3303,9 @@ int msSLDSetColorObject(char *psHexColor, colorObj *psColor) /* */ /* The caller should free the returned string. */ /************************************************************************/ -char *msSLDGenerateSLD(mapObj *map, int iLayer, const char *pszVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +char *msSLDGenerateSLD(mapObj *map, int iLayer, const char *pszVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) char szTmp[500]; int i = 0; @@ -3429,24 +3317,42 @@ char *msSLDGenerateSLD(mapObj *map, int iLayer, const char *pszVersion) sld_version = msOWSParseVersionString(pszVersion); if (sld_version == OWS_VERSION_NOTSET || - (sld_version!= OWS_1_0_0 && sld_version!= OWS_1_1_0)) + (sld_version != OWS_1_0_0 && sld_version != OWS_1_1_0)) sld_version = OWS_1_0_0; if (map) { schemalocation = msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); - if (sld_version == OWS_1_0_0) - snprintf(szTmp, sizeof(szTmp), "\n",schemalocation ); + if (sld_version == OWS_1_0_0) + snprintf(szTmp, sizeof(szTmp), + "\n", + schemalocation); else - snprintf(szTmp, sizeof(szTmp), "\n", schemalocation); + snprintf(szTmp, sizeof(szTmp), + "\n", + schemalocation); free(schemalocation); pszSLD = msStringConcatenate(pszSLD, szTmp); - if (iLayer < 0 || iLayer > map->numlayers -1) { - for (i=0; inumlayers; i++) { + if (iLayer < 0 || iLayer > map->numlayers - 1) { + for (i = 0; i < map->numlayers; i++) { pszTmp = msSLDGenerateSLDLayer(GET_LAYER(map, i), sld_version); if (pszTmp) { - pszSLD= msStringConcatenate(pszSLD, pszTmp); + pszSLD = msStringConcatenate(pszSLD, pszTmp); free(pszTmp); } } @@ -3471,27 +3377,25 @@ char *msSLDGenerateSLD(mapObj *map, int iLayer, const char *pszVersion) #endif } - - /************************************************************************/ /* msSLDGetGraphicSLD */ /* */ /* Get an SLD for a style containing a symbol (Mark or external). */ /************************************************************************/ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, - int bNeedMarkSybol, int nVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) + int bNeedMarkSybol, int nVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) - msStringBuffer * sldString = msStringBufferAlloc(); + msStringBuffer *sldString = msStringBufferAlloc(); int nSymbol = -1; symbolObj *psSymbol = NULL; char szTmp[512]; char szFormat[4]; int i = 0, nLength = 0; - int bColorAvailable=0; + int bColorAvailable = 0; int bGenerateDefaultSymbol = 0; - char *pszSymbolName= NULL; + char *pszSymbolName = NULL; char sNameSpace[10]; char sCssParam[30]; @@ -3510,17 +3414,17 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, if (psStyle->symbol > 0) nSymbol = psStyle->symbol; else if (psStyle->symbolname) - nSymbol = msGetSymbolIndex(&psLayer->map->symbolset, - psStyle->symbolname, MS_FALSE); + nSymbol = msGetSymbolIndex(&psLayer->map->symbolset, psStyle->symbolname, + MS_FALSE); bGenerateDefaultSymbol = 0; if (bNeedMarkSybol && - (nSymbol <=0 || nSymbol >= psLayer->map->symbolset.numsymbols)) + (nSymbol <= 0 || nSymbol >= psLayer->map->symbolset.numsymbols)) bGenerateDefaultSymbol = 1; if (nSymbol > 0 && nSymbol < psLayer->map->symbolset.numsymbols) { - psSymbol = psLayer->map->symbolset.symbol[nSymbol]; + psSymbol = psLayer->map->symbolset.symbol[nSymbol]; if (psSymbol->type == MS_SYMBOL_VECTOR || psSymbol->type == MS_SYMBOL_ELLIPSE) { /* Mark symbol */ @@ -3534,30 +3438,26 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, strcasecmp(psSymbol->name, "cross") == 0 || strcasecmp(psSymbol->name, "x") == 0) pszSymbolName = msStrdup(psSymbol->name); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_square", 22) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_square", 22) == + 0) pszSymbolName = msStrdup("square"); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_triangle", 24) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_triangle", + 24) == 0) pszSymbolName = msStrdup("triangle"); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_circle", 22) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_circle", 22) == + 0) pszSymbolName = msStrdup("circle"); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_star", 20) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_star", 20) == 0) pszSymbolName = msStrdup("star"); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_cross", 21) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_cross", 21) == + 0) pszSymbolName = msStrdup("cross"); - else if (strncasecmp(psSymbol->name, - "sld_mark_symbol_x", 17) == 0) + else if (strncasecmp(psSymbol->name, "sld_mark_symbol_x", 17) == 0) pszSymbolName = msStrdup("X"); - - if (pszSymbolName) { - colorObj sTmpFillColor = { 128, 128, 128, 255 }; - colorObj sTmpStrokeColor = { 0, 0, 0, 255 }; + colorObj sTmpFillColor = {128, 128, 128, 255}; + colorObj sTmpStrokeColor = {0, 0, 0, 255}; int hasFillColor = 0; int hasStrokeColor = 0; @@ -3567,14 +3467,13 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, snprintf(szTmp, sizeof(szTmp), "<%sMark>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%sWellKnownName>%s\n", - sNameSpace, pszSymbolName, sNameSpace); + snprintf(szTmp, sizeof(szTmp), + "<%sWellKnownName>%s\n", sNameSpace, + pszSymbolName, sNameSpace); msStringBufferAppend(sldString, szTmp); - if (psStyle->color.red != -1 && - psStyle->color.green != -1 && - psStyle->color.blue != -1) - { + if (psStyle->color.red != -1 && psStyle->color.green != -1 && + psStyle->color.blue != -1) { sTmpFillColor.red = psStyle->color.red; sTmpFillColor.green = psStyle->color.green; sTmpFillColor.blue = psStyle->color.blue; @@ -3583,25 +3482,20 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, } if (psStyle->outlinecolor.red != -1 && psStyle->outlinecolor.green != -1 && - psStyle->outlinecolor.blue != -1) - { + psStyle->outlinecolor.blue != -1) { sTmpStrokeColor.red = psStyle->outlinecolor.red; sTmpStrokeColor.green = psStyle->outlinecolor.green; sTmpStrokeColor.blue = psStyle->outlinecolor.blue; sTmpStrokeColor.alpha = psStyle->outlinecolor.alpha; hasStrokeColor = 1; // Make defaults implicit - if (sTmpStrokeColor.red == 0 && - sTmpStrokeColor.green == 0 && - sTmpStrokeColor.blue == 0 && - sTmpStrokeColor.alpha == 255 && - psStyle->width == 1) - { + if (sTmpStrokeColor.red == 0 && sTmpStrokeColor.green == 0 && + sTmpStrokeColor.blue == 0 && sTmpStrokeColor.alpha == 255 && + psStyle->width == 1) { hasStrokeColor = 0; } } - if (!hasFillColor && !hasStrokeColor) - { + if (!hasFillColor && !hasStrokeColor) { sTmpFillColor.red = 128; sTmpFillColor.green = 128; sTmpFillColor.blue = 128; @@ -3612,19 +3506,15 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, if (hasFillColor) { snprintf(szTmp, sizeof(szTmp), "<%sFill>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill\">#%02x%02x%02x\n", - sCssParam, - sTmpFillColor.red, - sTmpFillColor.green, - sTmpFillColor.blue, - sCssParam); + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"fill\">#%02x%02x%02x\n", sCssParam, + sTmpFillColor.red, sTmpFillColor.green, + sTmpFillColor.blue, sCssParam); msStringBufferAppend(sldString, szTmp); - if (sTmpFillColor.alpha != 255 && sTmpFillColor.alpha != -1) - { - snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill-opacity\">%.2f\n", - sCssParam, - (float)sTmpFillColor.alpha/255.0, - sCssParam); + if (sTmpFillColor.alpha != 255 && sTmpFillColor.alpha != -1) { + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"fill-opacity\">%.2f\n", sCssParam, + (float)sTmpFillColor.alpha / 255.0, sCssParam); msStringBufferAppend(sldString, szTmp); } snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); @@ -3633,27 +3523,21 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, if (hasStrokeColor) { snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke\">#%02x%02x%02x\n", - sCssParam, - sTmpStrokeColor.red, - sTmpStrokeColor.green, - sTmpStrokeColor.blue, - sCssParam); + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"stroke\">#%02x%02x%02x\n", sCssParam, + sTmpStrokeColor.red, sTmpStrokeColor.green, + sTmpStrokeColor.blue, sCssParam); msStringBufferAppend(sldString, szTmp); - if (psStyle->width > 0) - { - snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-width\">%g\n", - sCssParam, - psStyle->width, - sCssParam); + if (psStyle->width > 0) { + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"stroke-width\">%g\n", sCssParam, + psStyle->width, sCssParam); msStringBufferAppend(sldString, szTmp); } - if (sTmpStrokeColor.alpha != 255 && sTmpStrokeColor.alpha != -1) - { - snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-opacity\">%.2f\n", - sCssParam, - (float)sTmpStrokeColor.alpha/255.0, - sCssParam); + if (sTmpStrokeColor.alpha != 255 && sTmpStrokeColor.alpha != -1) { + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"stroke-opacity\">%.2f\n", sCssParam, + (float)sTmpStrokeColor.alpha / 255.0, sCssParam); msStringBufferAppend(sldString, szTmp); } snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); @@ -3665,33 +3549,33 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, if (psStyle->size > 0) { snprintf(szTmp, sizeof(szTmp), "<%sSize>%g\n", - sNameSpace, psStyle->size, sNameSpace); + sNameSpace, psStyle->size, sNameSpace); msStringBufferAppend(sldString, szTmp); } - if (fmod(psStyle->angle, 360)) - { + if (fmod(psStyle->angle, 360)) { snprintf(szTmp, sizeof(szTmp), "<%sRotation>%g\n", - sNameSpace, psStyle->angle, sNameSpace); + sNameSpace, psStyle->angle, sNameSpace); msStringBufferAppend(sldString, szTmp); } - // Style opacity is already reported to alpha channel of color and outlinecolor - // if (psStyle->opacity < 100) - // { - // snprintf(szTmp, sizeof(szTmp), "<%sOpacity>%g\n", - // sNameSpace, psStyle->opacity/100.0, sNameSpace); - // pszSLD = msStringConcatenate(pszSLD, szTmp); - // } - - if (psStyle->offsetx != 0 || psStyle->offsety != 0) - { + // Style opacity is already reported to alpha channel of color and + // outlinecolor if (psStyle->opacity < 100) + // { + // snprintf(szTmp, sizeof(szTmp), "<%sOpacity>%g\n", + // sNameSpace, psStyle->opacity/100.0, sNameSpace); + // pszSLD = msStringConcatenate(pszSLD, szTmp); + // } + + if (psStyle->offsetx != 0 || psStyle->offsety != 0) { snprintf(szTmp, sizeof(szTmp), "<%sDisplacement>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%sDisplacementX>%g\n", - sNameSpace, psStyle->offsetx, sNameSpace); + snprintf(szTmp, sizeof(szTmp), + "<%sDisplacementX>%g\n", sNameSpace, + psStyle->offsetx, sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%sDisplacementY>%g\n", - sNameSpace, psStyle->offsety, sNameSpace); + snprintf(szTmp, sizeof(szTmp), + "<%sDisplacementY>%g\n", sNameSpace, + psStyle->offsety, sNameSpace); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); @@ -3704,71 +3588,76 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, free(pszSymbolName); } } else - bGenerateDefaultSymbol =1; - } else if (psSymbol->type == MS_SYMBOL_PIXMAP || psSymbol->type == MS_SYMBOL_SVG) { + bGenerateDefaultSymbol = 1; + } else if (psSymbol->type == MS_SYMBOL_PIXMAP || + psSymbol->type == MS_SYMBOL_SVG) { if (psSymbol->name) { - const char *pszURL = msLookupHashTable(&(psLayer->metadata), "WMS_SLD_SYMBOL_URL"); + const char *pszURL = + msLookupHashTable(&(psLayer->metadata), "WMS_SLD_SYMBOL_URL"); if (!pszURL) - pszURL = msLookupHashTable(&(psLayer->map->web.metadata), "WMS_SLD_SYMBOL_URL"); + pszURL = msLookupHashTable(&(psLayer->map->web.metadata), + "WMS_SLD_SYMBOL_URL"); if (pszURL) { snprintf(szTmp, sizeof(szTmp), "<%sGraphic>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - - snprintf(szTmp, sizeof(szTmp), "<%sExternalGraphic>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%sOnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"%s%s\"/>\n", sNameSpace, - pszURL,psSymbol->imagepath); + snprintf(szTmp, sizeof(szTmp), + "<%sOnlineResource " + "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " + "xlink:type=\"simple\" xlink:href=\"%s%s\"/>\n", + sNameSpace, pszURL, psSymbol->imagepath); msStringBufferAppend(sldString, szTmp); /* TODO : extract format from symbol */ szFormat[0] = '\0'; nLength = strlen(psSymbol->imagepath); if (nLength > 3) { - for (i=0; i<=2; i++) - szFormat[2-i] = psSymbol->imagepath[nLength-1-i]; + for (i = 0; i <= 2; i++) + szFormat[2 - i] = psSymbol->imagepath[nLength - 1 - i]; szFormat[3] = '\0'; } - if (strlen(szFormat) > 0 && - ((strcasecmp (szFormat, "GIF") == 0) || - (strcasecmp (szFormat, "PNG") == 0))) { - if (strcasecmp (szFormat, "GIF") == 0) - snprintf(szTmp, sizeof(szTmp), "<%sFormat>image/gif\n", - sNameSpace, sNameSpace); + if (strlen(szFormat) > 0 && ((strcasecmp(szFormat, "GIF") == 0) || + (strcasecmp(szFormat, "PNG") == 0))) { + if (strcasecmp(szFormat, "GIF") == 0) + snprintf(szTmp, sizeof(szTmp), + "<%sFormat>image/gif\n", sNameSpace, + sNameSpace); else - snprintf(szTmp, sizeof(szTmp), "<%sFormat>image/png\n", - sNameSpace, sNameSpace); + snprintf(szTmp, sizeof(szTmp), + "<%sFormat>image/png\n", sNameSpace, + sNameSpace); } else - snprintf(szTmp, sizeof(szTmp), "<%sFormat>%s\n", sNameSpace, - (psSymbol->type ==MS_SYMBOL_SVG)?"image/svg+xml":"image/gif",sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sFormat>%s\n", + sNameSpace, + (psSymbol->type == MS_SYMBOL_SVG) ? "image/svg+xml" + : "image/gif", + sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", + sNameSpace); msStringBufferAppend(sldString, szTmp); if (psStyle->size > 0) - snprintf(szTmp, sizeof(szTmp), "<%sSize>%g\n", sNameSpace, psStyle->size, - sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sSize>%g\n", + sNameSpace, psStyle->size, sNameSpace); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - } } - } } if (bGenerateDefaultSymbol) { /* generate a default square symbol */ snprintf(szTmp, sizeof(szTmp), "<%sGraphic>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - - snprintf(szTmp, sizeof(szTmp), "<%sMark>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); @@ -3777,17 +3666,13 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, msStringBufferAppend(sldString, szTmp); bColorAvailable = 0; - if (psStyle->color.red != -1 && - psStyle->color.green != -1 && + if (psStyle->color.red != -1 && psStyle->color.green != -1 && psStyle->color.blue != -1) { snprintf(szTmp, sizeof(szTmp), "<%sFill>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill\">#%02x%02x%02x\n", - sCssParam, - psStyle->color.red, - psStyle->color.green, - psStyle->color.blue, - sCssParam); + sCssParam, psStyle->color.red, psStyle->color.green, + psStyle->color.blue, sCssParam); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); @@ -3798,12 +3683,10 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, psStyle->outlinecolor.blue != -1) { snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%s name=\"Stroke\">#%02x%02x%02x\n", - sCssParam, - psStyle->outlinecolor.red, - psStyle->outlinecolor.green, - psStyle->outlinecolor.blue, - sCssParam); + snprintf(szTmp, sizeof(szTmp), + "<%s name=\"Stroke\">#%02x%02x%02x\n", sCssParam, + psStyle->outlinecolor.red, psStyle->outlinecolor.green, + psStyle->outlinecolor.blue, sCssParam); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); @@ -3813,9 +3696,8 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, /* default color */ snprintf(szTmp, sizeof(szTmp), "<%sFill>\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"fill\">%s\n", - sCssParam, "#808080", sCssParam); + snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill\">%s\n", sCssParam, + "#808080", sCssParam); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); @@ -3828,13 +3710,12 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, snprintf(szTmp, sizeof(szTmp), "<%sSize>%g\n", sNameSpace, psStyle->size, sNameSpace); else - snprintf(szTmp, sizeof(szTmp), "<%sSize>%d\n", sNameSpace,1,sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sSize>%d\n", sNameSpace, 1, + sNameSpace); msStringBufferAppend(sldString, szTmp); snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); msStringBufferAppend(sldString, szTmp); - - } } @@ -3844,20 +3725,16 @@ char *msSLDGetGraphicSLD(styleObj *psStyle, layerObj *psLayer, return NULL; #endif - } - - - /************************************************************************/ /* msSLDGenerateLineSLD */ /* */ /* Generate SLD for a Line layer. */ /************************************************************************/ -char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) char *pszSLD = NULL; char szTmp[100]; @@ -3870,45 +3747,47 @@ char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) char sCssParam[30]; char sNameSpace[10]; - if ( msCheckParentPointer(psLayer->map,"map")==MS_FAILURE ) + if (msCheckParentPointer(psLayer->map, "map") == MS_FAILURE) return NULL; sCssParam[0] = '\0'; if (nVersion > OWS_1_0_0) - strcpy( sCssParam, "se:SvgParameter"); + strcpy(sCssParam, "se:SvgParameter"); else - strcpy( sCssParam, "CssParameter"); + strcpy(sCssParam, "CssParameter"); sNameSpace[0] = '\0'; if (nVersion > OWS_1_0_0) strcpy(sNameSpace, "se:"); - snprintf(szTmp, sizeof(szTmp), "<%sLineSymbolizer>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sLineSymbolizer>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); - snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszGraphicSLD = msSLDGetGraphicSLD(psStyle, psLayer, 0, nVersion); if (pszGraphicSLD) { - snprintf(szTmp, sizeof(szTmp), "<%sGraphicStroke>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sGraphicStroke>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszSLD = msStringConcatenate(pszSLD, pszGraphicSLD); - if(nVersion >= OWS_1_1_0) { - if(psStyle->gap > 0) { - snprintf(szTmp, sizeof(szTmp), "<%sGap>%.2f\n", sNameSpace,psStyle->gap,sNameSpace); + if (nVersion >= OWS_1_1_0) { + if (psStyle->gap > 0) { + snprintf(szTmp, sizeof(szTmp), "<%sGap>%.2f\n", sNameSpace, + psStyle->gap, sNameSpace); } - if(psStyle->initialgap > 0) { - snprintf(szTmp, sizeof(szTmp), "<%sInitialGap>%.2f\n", sNameSpace,psStyle->initialgap,sNameSpace); + if (psStyle->initialgap > 0) { + snprintf(szTmp, sizeof(szTmp), "<%sInitialGap>%.2f\n", + sNameSpace, psStyle->initialgap, sNameSpace); } } - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); @@ -3916,37 +3795,33 @@ char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) pszGraphicSLD = NULL; } - if (psStyle->color.red != -1 && - psStyle->color.green != -1 && + if (psStyle->color.red != -1 && psStyle->color.green != -1 && psStyle->color.blue != -1) - sprintf(szHexColor,"%02x%02x%02x",psStyle->color.red, - psStyle->color.green,psStyle->color.blue); + sprintf(szHexColor, "%02x%02x%02x", psStyle->color.red, + psStyle->color.green, psStyle->color.blue); else - sprintf(szHexColor,"%02x%02x%02x",psStyle->outlinecolor.red, - psStyle->outlinecolor.green,psStyle->outlinecolor.blue); + sprintf(szHexColor, "%02x%02x%02x", psStyle->outlinecolor.red, + psStyle->outlinecolor.green, psStyle->outlinecolor.blue); - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke\">#%s\n", - sCssParam, szHexColor, sCssParam); + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke\">#%s\n", sCssParam, + szHexColor, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); - if(psStyle->color.alpha != 255 && psStyle->color.alpha!=-1) { - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke-opacity\">%.2f\n", - sCssParam, (float)psStyle->color.alpha/255.0, sCssParam); + if (psStyle->color.alpha != 255 && psStyle->color.alpha != -1) { + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-opacity\">%.2f\n", + sCssParam, (float)psStyle->color.alpha / 255.0, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); } - nSymbol = -1; if (psStyle->symbol >= 0) nSymbol = psStyle->symbol; else if (psStyle->symbolname) - nSymbol = msGetSymbolIndex(&psLayer->map->symbolset, - psStyle->symbolname, MS_FALSE); + nSymbol = msGetSymbolIndex(&psLayer->map->symbolset, psStyle->symbolname, + MS_FALSE); - if (nSymbol <0) + if (nSymbol < 0) dfSize = 1.0; else { if (psStyle->size > 0) @@ -3957,8 +3832,7 @@ char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) dfSize = 1; } - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke-width\">%.2f\n", + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-width\">%.2f\n", sCssParam, dfSize, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); @@ -3966,24 +3840,22 @@ char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) /* dash array */ /* -------------------------------------------------------------------- */ - if (psStyle->patternlength > 0) { - for (i=0; ipatternlength; i++) { + for (i = 0; i < psStyle->patternlength; i++) { snprintf(szTmp, sizeof(szTmp), "%.2f ", psStyle->pattern[i]); pszDashArray = msStringConcatenate(pszDashArray, szTmp); } - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke-dasharray\">%s\n", + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-dasharray\">%s\n", sCssParam, pszDashArray, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); msFree(pszDashArray); } - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); @@ -3994,15 +3866,15 @@ char *msSLDGenerateLineSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) #endif } - /************************************************************************/ /* msSLDGeneratePolygonSLD */ /* */ /* Generate SLD for a Polygon layer. */ /************************************************************************/ -char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, + int nVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) char szTmp[100]; char *pszSLD = NULL; @@ -4022,26 +3894,26 @@ char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion if (nVersion > OWS_1_0_0) strcpy(sNameSpace, "se:"); - snprintf(szTmp, sizeof(szTmp), "<%sPolygonSymbolizer>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sPolygonSymbolizer>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); /* fill */ if (psStyle->color.red != -1 && psStyle->color.green != -1 && psStyle->color.blue != -1) { - snprintf(szTmp, sizeof(szTmp), "<%sFill>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sFill>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszGraphicSLD = msSLDGetGraphicSLD(psStyle, psLayer, 0, nVersion); if (pszGraphicSLD) { - snprintf(szTmp, sizeof(szTmp), "<%sGraphicFill>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sGraphicFill>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszSLD = msStringConcatenate(pszSLD, pszGraphicSLD); - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); @@ -4049,46 +3921,40 @@ char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion pszGraphicSLD = NULL; } - sprintf(szHexColor,"%02x%02x%02x",psStyle->color.red, - psStyle->color.green,psStyle->color.blue); + sprintf(szHexColor, "%02x%02x%02x", psStyle->color.red, + psStyle->color.green, psStyle->color.blue); - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"fill\">#%s\n", - sCssParam, szHexColor, sCssParam); + snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill\">#%s\n", sCssParam, + szHexColor, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); - if(psStyle->color.alpha != 255 && psStyle->color.alpha!=-1) { - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"fill-opacity\">%.2f\n", - sCssParam, (float)psStyle->color.alpha/255, sCssParam); + if (psStyle->color.alpha != 255 && psStyle->color.alpha != -1) { + snprintf(szTmp, sizeof(szTmp), "<%s name=\"fill-opacity\">%.2f\n", + sCssParam, (float)psStyle->color.alpha / 255, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); } - - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); } /* stroke */ - if (psStyle->outlinecolor.red != -1 && - psStyle->outlinecolor.green != -1 && + if (psStyle->outlinecolor.red != -1 && psStyle->outlinecolor.green != -1 && psStyle->outlinecolor.blue != -1) { - snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sStroke>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); - - /* If there is a symbol to be used for stroke, the color in the */ /* style should be set to -1. Else It won't apply here. */ if (psStyle->color.red == -1 && psStyle->color.green == -1 && psStyle->color.blue == -1) { pszGraphicSLD = msSLDGetGraphicSLD(psStyle, psLayer, 0, nVersion); if (pszGraphicSLD) { - snprintf(szTmp, sizeof(szTmp), "<%sGraphicFill>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sGraphicFill>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszSLD = msStringConcatenate(pszSLD, pszGraphicSLD); - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); free(pszGraphicSLD); @@ -4096,13 +3962,11 @@ char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion } } - sprintf(szHexColor,"%02x%02x%02x",psStyle->outlinecolor.red, - psStyle->outlinecolor.green, - psStyle->outlinecolor.blue); + sprintf(szHexColor, "%02x%02x%02x", psStyle->outlinecolor.red, + psStyle->outlinecolor.green, psStyle->outlinecolor.blue); - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke\">#%s\n", - sCssParam, szHexColor, sCssParam); + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke\">#%s\n", sCssParam, + szHexColor, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); dfSize = 1.0; @@ -4111,20 +3975,18 @@ char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion else if (psStyle->width > 0) dfSize = psStyle->width; - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke-width\">%.2f\n", - sCssParam,dfSize,sCssParam); + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-width\">%.2f\n", + sCssParam, dfSize, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); - if(psStyle->outlinecolor.alpha != 255 && psStyle->outlinecolor.alpha != -1) - { - snprintf(szTmp, sizeof(szTmp), - "<%s name=\"stroke-opacity\">%.2f\n", - sCssParam, psStyle->outlinecolor.alpha/255.0, sCssParam); + if (psStyle->outlinecolor.alpha != 255 && + psStyle->outlinecolor.alpha != -1) { + snprintf(szTmp, sizeof(szTmp), "<%s name=\"stroke-opacity\">%.2f\n", + sCssParam, psStyle->outlinecolor.alpha / 255.0, sCssParam); pszSLD = msStringConcatenate(pszSLD, szTmp); } - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); } @@ -4143,9 +4005,10 @@ char *msSLDGeneratePolygonSLD(styleObj *psStyle, layerObj *psLayer, int nVersion /* */ /* Generate SLD for a Point layer. */ /************************************************************************/ -char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, + int nVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) char *pszSLD = NULL; char *pszGraphicSLD = NULL; char szTmp[100]; @@ -4155,7 +4018,7 @@ char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) if (nVersion > OWS_1_0_0) strcpy(sNameSpace, "se:"); - snprintf(szTmp, sizeof(szTmp), "<%sPointSymbolizer>\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "<%sPointSymbolizer>\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); pszGraphicSLD = msSLDGetGraphicSLD(psStyle, psLayer, 1, nVersion); @@ -4164,7 +4027,7 @@ char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) free(pszGraphicSLD); } - snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); + snprintf(szTmp, sizeof(szTmp), "\n", sNameSpace); pszSLD = msStringConcatenate(pszSLD, szTmp); return pszSLD; @@ -4175,17 +4038,15 @@ char *msSLDGeneratePointSLD(styleObj *psStyle, layerObj *psLayer, int nVersion) #endif } - - /************************************************************************/ /* msSLDGenerateTextSLD */ /* */ /* Generate a TextSymboliser SLD xml based on the class's label */ /* object. */ /************************************************************************/ -char *msSLDGenerateTextSLD(classObj *psClass, layerObj *psLayer, int nVersion) -{ -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) +char *msSLDGenerateTextSLD(classObj *psClass, layerObj *psLayer, int nVersion) { +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) char *pszSLD = NULL; char szTmp[1000]; @@ -4209,41 +4070,32 @@ char *msSLDGenerateTextSLD(classObj *psClass, layerObj *psLayer, int nVersion) if (nVersion > OWS_1_0_0) strcpy(sNameSpace, "se:"); + if (!psLayer || !psClass) + return pszSLD; - if (!psLayer || !psClass) return pszSLD; - - for (lid=0 ; lid < psClass->numlabels ; lid++) - { - char * psLabelText; + for (lid = 0; lid < psClass->numlabels; lid++) { + char *psLabelText; expressionObj psLabelExpr; parseObj p; msInitExpression(&psLabelExpr); psLabelObj = psClass->labels[lid]; - if (psLabelObj->text.string) - { + if (psLabelObj->text.string) { psLabelExpr.string = msStrdup(psLabelObj->text.string); psLabelExpr.type = psLabelObj->text.type; - } - else if (psClass->text.string) - { + } else if (psClass->text.string) { psLabelExpr.string = msStrdup(psClass->text.string); psLabelExpr.type = psClass->text.type; - } - else if (psLayer->labelitem) - { + } else if (psLayer->labelitem) { psLabelExpr.string = msStrdup(psLayer->labelitem); psLabelExpr.type = MS_STRING; - } - else - { + } else { msFreeExpression(&psLabelExpr); continue; // Can't find text content for this
\n", tabspace); } @@ -2475,17 +2634,18 @@ void msOWSPrintContactInfo( FILE *stream, const char *tabspace, ** layer->extent member, and if not found will open layer to read extent. ** */ -int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, rectObj *ext) -{ +int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, + rectObj *ext) { (void)map; const char *value; - if ((value = msOWSLookupMetadata(&(lp->metadata), namespaces, "extent")) != NULL) { + if ((value = msOWSLookupMetadata(&(lp->metadata), namespaces, "extent")) != + NULL) { char **tokens; int n; tokens = msStringSplit(value, ' ', &n); - if (tokens==NULL || n != 4) { + if (tokens == NULL || n != 4) { msSetError(MS_WMSERR, "Wrong number of arguments for EXTENT metadata.", "msOWSGetLayerExtent()"); return MS_FAILURE; @@ -2504,7 +2664,6 @@ int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, rectO return MS_FAILURE; } - /********************************************************************** * msOWSExecuteRequests() * @@ -2512,22 +2671,23 @@ int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, rectO * update layerObj information with the result of the requests. **********************************************************************/ int msOWSExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, - mapObj *map, int bCheckLocalCache) -{ + mapObj *map, int bCheckLocalCache) { int nStatus, iReq; /* Execute requests */ #if defined(USE_CURL) nStatus = msHTTPExecuteRequests(pasReqInfo, numRequests, bCheckLocalCache); #else - msSetError(MS_WMSERR, "msOWSExecuteRequests() called apparently without libcurl configured, msHTTPExecuteRequests() not available.", + msSetError(MS_WMSERR, + "msOWSExecuteRequests() called apparently without libcurl " + "configured, msHTTPExecuteRequests() not available.", "msOWSExecuteRequests()"); return MS_FAILURE; #endif /* Scan list of layers and call the handler for each layer type to */ /* pass them the request results. */ - for(iReq=0; iReq= 0 && pasReqInfo[iReq].nLayerId < map->numlayers) { layerObj *lp; @@ -2546,32 +2706,31 @@ int msOWSExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, * msOWSProcessException() * **********************************************************************/ -void msOWSProcessException(layerObj *lp, const char *pszFname, - int nErrorCode, const char *pszFuncName) -{ +void msOWSProcessException(layerObj *lp, const char *pszFname, int nErrorCode, + const char *pszFuncName) { FILE *fp; if ((fp = fopen(pszFname, "r")) != NULL) { - char *pszBuf=NULL; - int nBufSize=0; + char *pszBuf = NULL; + int nBufSize = 0; char *pszStart, *pszEnd; fseek(fp, 0, SEEK_END); nBufSize = ftell(fp); - if(nBufSize < 0) { + if (nBufSize < 0) { msSetError(MS_IOERR, NULL, "msOWSProcessException()"); fclose(fp); return; } rewind(fp); - pszBuf = (char*)malloc((nBufSize+1)*sizeof(char)); + pszBuf = (char *)malloc((nBufSize + 1) * sizeof(char)); if (pszBuf == NULL) { msSetError(MS_MEMERR, NULL, "msOWSProcessException()"); fclose(fp); return; } - if ((int) fread(pszBuf, 1, nBufSize, fp) != nBufSize) { + if ((int)fread(pszBuf, 1, nBufSize, fp) != nBufSize) { msSetError(MS_IOERR, NULL, "msOWSProcessException()"); free(pszBuf); fclose(fp); @@ -2580,21 +2739,22 @@ void msOWSProcessException(layerObj *lp, const char *pszFname, pszBuf[nBufSize] = '\0'; - /* OK, got the data in the buffer. Look for the tags */ - if ((strstr(pszBuf, "") && /* WFS style */ + if ((strstr(pszBuf, "") && /* WFS style */ (pszStart = strstr(pszBuf, "")) && - (pszEnd = strstr(pszStart, "")) ) || - (strstr(pszBuf, "") && /* WMS style */ + (pszEnd = strstr(pszStart, ""))) || + (strstr(pszBuf, "") && /* WMS style */ (pszStart = strstr(pszBuf, "")) && - (pszEnd = strstr(pszStart, "")) )) { - pszStart = strchr(pszStart, '>')+1; + (pszEnd = strstr(pszStart, "")))) { + pszStart = strchr(pszStart, '>') + 1; *pszEnd = '\0'; msSetError(nErrorCode, "Got Remote Server Exception for layer %s: %s", - pszFuncName, lp->name?lp->name:"(null)", pszStart); + pszFuncName, lp->name ? lp->name : "(null)", pszStart); } else { - msSetError(MS_WFSCONNERR, "Unable to parse Remote Server Exception Message for layer %s.", - pszFuncName, lp->name?lp->name:"(null)"); + msSetError( + MS_WFSCONNERR, + "Unable to parse Remote Server Exception Message for layer %s.", + pszFuncName, lp->name ? lp->name : "(null)"); } free(pszBuf); @@ -2612,18 +2772,16 @@ void msOWSProcessException(layerObj *lp, const char *pszFname, * NULL in case of error. **********************************************************************/ char *msOWSBuildURLFilename(const char *pszPath, const char *pszURL, - const char *pszExt) -{ + const char *pszExt) { char *pszBuf, *pszPtr; - int i; + int i; size_t nBufLen = 0; - - nBufLen = strlen(pszURL) + strlen(pszExt) +2; + nBufLen = strlen(pszURL) + strlen(pszExt) + 2; if (pszPath) - nBufLen += (strlen(pszPath)+1); + nBufLen += (strlen(pszPath) + 1); - pszBuf = (char*)malloc(nBufLen); + pszBuf = (char *)malloc(nBufLen); if (pszBuf == NULL) { msSetError(MS_MEMERR, NULL, "msOWSBuildURLFilename()"); return NULL; @@ -2632,13 +2790,13 @@ char *msOWSBuildURLFilename(const char *pszPath, const char *pszURL, if (pszPath) { #ifdef _WIN32 - if (pszPath[strlen(pszPath) -1] != '/' && - pszPath[strlen(pszPath) -1] != '\\') + if (pszPath[strlen(pszPath) - 1] != '/' && + pszPath[strlen(pszPath) - 1] != '\\') snprintf(pszBuf, nBufLen, "%s\\", pszPath); else snprintf(pszBuf, nBufLen, "%s", pszPath); #else - if (pszPath[strlen(pszPath) -1] != '/') + if (pszPath[strlen(pszPath) - 1] != '/') snprintf(pszBuf, nBufLen, "%s/", pszPath); else snprintf(pszBuf, nBufLen, "%s", pszPath); @@ -2647,7 +2805,7 @@ char *msOWSBuildURLFilename(const char *pszPath, const char *pszURL, pszPtr = pszBuf + strlen(pszBuf); - for(i=0; pszURL[i] != '\0'; i++) { + for (i = 0; pszURL[i] != '\0'; i++) { if (isalnum(pszURL[i])) *pszPtr = pszURL[i]; else @@ -2668,19 +2826,18 @@ char *msOWSBuildURLFilename(const char *pszPath, const char *pszURL, ** The returned buffer is dynamically allocated, and must be freed by the ** caller. */ -char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, const char *namespaces, int bReturnOnlyFirstOne) -{ +char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, + const char *namespaces, int bReturnOnlyFirstOne) { char *result; char **tokens; int numtokens, i; char *oldStyle = NULL; - - msOWSGetEPSGProj( proj, metadata, namespaces, bReturnOnlyFirstOne, &oldStyle ); - if( oldStyle == NULL || - strncmp(oldStyle,"CRS:",4) == 0 || - strncmp(oldStyle,"AUTO:",5) == 0 || - strncmp(oldStyle,"AUTO2:",6) == 0 ) { + msOWSGetEPSGProj(proj, metadata, namespaces, bReturnOnlyFirstOne, &oldStyle); + + if (oldStyle == NULL || strncmp(oldStyle, "CRS:", 4) == 0 || + strncmp(oldStyle, "AUTO:", 5) == 0 || + strncmp(oldStyle, "AUTO2:", 6) == 0) { msFree(oldStyle); return NULL; } @@ -2689,39 +2846,39 @@ char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, const char *n tokens = msStringSplit(oldStyle, ' ', &numtokens); msFree(oldStyle); - for(i=0; tokens != NULL && i 0 ) { - const size_t bufferSize = strlen(result)+strlen(urn)+2; - result = (char *) msSmallRealloc(result, bufferSize); + if (strlen(urn) > 0) { + const size_t bufferSize = strlen(result) + strlen(urn) + 2; + result = (char *)msSmallRealloc(result, bufferSize); - if( strlen(result) > 0 ) - strlcat( result, " ", bufferSize); - strlcat( result, urn , bufferSize); + if (strlen(result) > 0) + strlcat(result, " ", bufferSize); + strlcat(result, urn, bufferSize); } else { - msDebug( "msOWSGetProjURN(): Failed to process SRS '%s', ignored.", - tokens[i] ); + msDebug("msOWSGetProjURN(): Failed to process SRS '%s', ignored.", + tokens[i]); } } msFreeCharArray(tokens, numtokens); - if( strlen(result) == 0 ) { - msFree( result ); + if (strlen(result) == 0) { + msFree(result); return NULL; } else return result; @@ -2731,20 +2888,21 @@ char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, const char *n ** msOWSGetProjURI() ** ** Fetch an OGC URI for this layer or map. Similar to msOWSGetEPSGProj() -** but returns the result in the form "http://www.opengis.net/def/crs/EPSG/0/27700". +** but returns the result in the form +*"http://www.opengis.net/def/crs/EPSG/0/27700". ** The returned buffer is dynamically allocated, and must be freed by the ** caller. */ -char *msOWSGetProjURI(projectionObj *proj, hashTableObj *metadata, const char *namespaces, int bReturnOnlyFirstOne) -{ +char *msOWSGetProjURI(projectionObj *proj, hashTableObj *metadata, + const char *namespaces, int bReturnOnlyFirstOne) { char *result; char **tokens; int numtokens, i; char *oldStyle = NULL; - - msOWSGetEPSGProj( proj, metadata, namespaces, bReturnOnlyFirstOne, &oldStyle); - if( oldStyle == NULL || !EQUALN(oldStyle,"EPSG:",5) ) { + msOWSGetEPSGProj(proj, metadata, namespaces, bReturnOnlyFirstOne, &oldStyle); + + if (oldStyle == NULL || !EQUALN(oldStyle, "EPSG:", 5)) { msFree(oldStyle); // avoid leak return NULL; } @@ -2753,40 +2911,41 @@ char *msOWSGetProjURI(projectionObj *proj, hashTableObj *metadata, const char *n tokens = msStringSplit(oldStyle, ' ', &numtokens); msFree(oldStyle); - for(i=0; tokens != NULL && i 0 ) { - result = (char *) msSmallRealloc(result,strlen(result)+strlen(urn)+2); + if (strlen(urn) > 0) { + result = (char *)msSmallRealloc(result, strlen(result) + strlen(urn) + 2); - if( strlen(result) > 0 ) - strcat( result, " " ); - strcat( result, urn ); + if (strlen(result) > 0) + strcat(result, " "); + strcat(result, urn); } else { - msDebug( "msOWSGetProjURI(): Failed to process SRS '%s', ignored.", - tokens[i] ); + msDebug("msOWSGetProjURI(): Failed to process SRS '%s', ignored.", + tokens[i]); } } msFreeCharArray(tokens, numtokens); - if( strlen(result) == 0 ) { - msFree( result ); + if (strlen(result) == 0) { + msFree(result); return NULL; } else return result; } - /* ** msOWSGetDimensionInfo() ** @@ -2804,67 +2963,71 @@ void msOWSGetDimensionInfo(layerObj *layer, const char *pszDimension, const char **papszDimDefault, const char **papszDimNearValue, const char **papszDimUnitSymbol, - const char **papszDimMultiValue) -{ + const char **papszDimMultiValue) { char *pszDimensionItem; size_t bufferSize = 0; - if(pszDimension == NULL || layer == NULL) + if (pszDimension == NULL || layer == NULL) return; - bufferSize = strlen(pszDimension)+50; - pszDimensionItem = (char*)malloc(bufferSize); + bufferSize = strlen(pszDimension) + 50; + pszDimensionItem = (char *)malloc(bufferSize); /* units (mandatory in map context) */ - if(papszDimUnits != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_units", pszDimension); - *papszDimUnits = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimUnits != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_units", pszDimension); + *papszDimUnits = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* unitSymbol (mandatory in map context) */ - if(papszDimUnitSymbol != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_unitsymbol", pszDimension); - *papszDimUnitSymbol = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimUnitSymbol != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_unitsymbol", + pszDimension); + *papszDimUnitSymbol = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* userValue (mandatory in map context) */ - if(papszDimUserValue != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_uservalue", pszDimension); - *papszDimUserValue = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimUserValue != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_uservalue", + pszDimension); + *papszDimUserValue = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* default */ - if(papszDimDefault != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_default", pszDimension); - *papszDimDefault = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimDefault != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_default", + pszDimension); + *papszDimDefault = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* multipleValues */ - if(papszDimMultiValue != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_multiplevalues", pszDimension); - *papszDimMultiValue = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimMultiValue != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_multiplevalues", + pszDimension); + *papszDimMultiValue = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* nearestValue */ - if(papszDimNearValue != NULL) { - snprintf(pszDimensionItem, bufferSize, "dimension_%s_nearestvalue", pszDimension); - *papszDimNearValue = msOWSLookupMetadata(&(layer->metadata), "MO", - pszDimensionItem); + if (papszDimNearValue != NULL) { + snprintf(pszDimensionItem, bufferSize, "dimension_%s_nearestvalue", + pszDimension); + *papszDimNearValue = + msOWSLookupMetadata(&(layer->metadata), "MO", pszDimensionItem); } /* Use default time value if necessary */ - if(strcasecmp(pszDimension, "time") == 0) { - if(papszDimUserValue != NULL && *papszDimUserValue == NULL) - *papszDimUserValue = msOWSLookupMetadata(&(layer->metadata), - "MO", "time"); - if(papszDimDefault != NULL && *papszDimDefault == NULL) - *papszDimDefault = msOWSLookupMetadata(&(layer->metadata), - "MO", "timedefault"); - if(papszDimUnits != NULL && *papszDimUnits == NULL) + if (strcasecmp(pszDimension, "time") == 0) { + if (papszDimUserValue != NULL && *papszDimUserValue == NULL) + *papszDimUserValue = + msOWSLookupMetadata(&(layer->metadata), "MO", "time"); + if (papszDimDefault != NULL && *papszDimDefault == NULL) + *papszDimDefault = + msOWSLookupMetadata(&(layer->metadata), "MO", "timedefault"); + if (papszDimUnits != NULL && *papszDimUnits == NULL) *papszDimUnits = "ISO8601"; - if(papszDimUnitSymbol != NULL && *papszDimUnitSymbol == NULL) + if (papszDimUnitSymbol != NULL && *papszDimUnitSymbol == NULL) *papszDimUnitSymbol = "t"; - if(papszDimNearValue != NULL && *papszDimNearValue == NULL) + if (papszDimNearValue != NULL && *papszDimNearValue == NULL) *papszDimNearValue = "0"; } @@ -2887,8 +3050,8 @@ void msOWSGetDimensionInfo(layerObj *layer, const char *pszDimension, * 0: equal */ -int msOWSNegotiateUpdateSequence(const char *requested_updatesequence, const char *updatesequence) -{ +int msOWSNegotiateUpdateSequence(const char *requested_updatesequence, + const char *updatesequence) { int i; int valtype1 = 1; /* default datatype for updatesequence passed by client */ int valtype2 = 1; /* default datatype for updatesequence set by server */ @@ -2896,10 +3059,11 @@ int msOWSNegotiateUpdateSequence(const char *requested_updatesequence, const cha /* if not specified by client, or set by server, server responds with latest Capabilities XML */ - if (! requested_updatesequence || ! updatesequence) + if (!requested_updatesequence || !updatesequence) return -1; - /* test to see if server value is an integer (1), string (2) or timestamp (3) */ + /* test to see if server value is an integer (1), string (2) or timestamp (3) + */ if (msStringIsInteger(updatesequence) == MS_FAILURE) valtype1 = 2; @@ -2910,13 +3074,15 @@ int msOWSNegotiateUpdateSequence(const char *requested_updatesequence, const cha msResetErrorList(); } - /* test to see if client value is an integer (1), string (2) or timestamp (3) */ + /* test to see if client value is an integer (1), string (2) or timestamp (3) + */ if (msStringIsInteger(requested_updatesequence) == MS_FAILURE) valtype2 = 2; if (valtype2 == 2) { /* test if timestamp */ msTimeInit(&tm_requested_updatesequence); - if (msParseTime(requested_updatesequence, &tm_requested_updatesequence) == MS_TRUE) + if (msParseTime(requested_updatesequence, &tm_requested_updatesequence) == + MS_TRUE) valtype2 = 3; msResetErrorList(); } @@ -2950,37 +3116,36 @@ int msOWSNegotiateUpdateSequence(const char *requested_updatesequence, const cha return -1; } - /************************************************************************/ /* msOwsIsOutputFormatValid */ /* */ /* Utlity function to parse a comma separated list in a */ /* metedata object and select and outputformat. */ /************************************************************************/ -outputFormatObj* msOwsIsOutputFormatValid(mapObj *map, const char *format, - hashTableObj *metadata, - const char *namespaces, const char *name) -{ - char **tokens=NULL; - int i,n; +outputFormatObj *msOwsIsOutputFormatValid(mapObj *map, const char *format, + hashTableObj *metadata, + const char *namespaces, + const char *name) { + char **tokens = NULL; + int i, n; outputFormatObj *psFormat = NULL; - const char * format_list=NULL; + const char *format_list = NULL; if (map && format && metadata && namespaces && name) { msApplyDefaultOutputFormats(map); format_list = msOWSLookupMetadata(metadata, namespaces, name); n = 0; - if ( format_list) - tokens = msStringSplit(format_list, ',', &n); + if (format_list) + tokens = msStringSplit(format_list, ',', &n); if (tokens && n > 0) { - for (i=0; ioutputformatlist[iFormat]->mimetype; + mimetype = map->outputformatlist[iFormat]->mimetype; msStringTrim(tokens[i]); if (strcasecmp(tokens[i], format) == 0) @@ -2989,13 +3154,15 @@ outputFormatObj* msOwsIsOutputFormatValid(mapObj *map, const char *format, break; } if (i < n) - psFormat = msSelectOutputFormat( map, format); + psFormat = msSelectOutputFormat(map, format); } - if(tokens) + if (tokens) msFreeCharArray(tokens, n); } return psFormat; } -#endif /* defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) */ +#endif /* defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined \ + (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || \ + defined(USE_WFS_LYR) */ diff --git a/mapows.h b/mapows.h index 537354b25c..c1662d6ab7 100644 --- a/mapows.h +++ b/mapows.h @@ -27,7 +27,6 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - #ifndef MAPOWS_H #define MAPOWS_H @@ -38,17 +37,16 @@ * default for OGC services unless the ows_schemas_lcoation web metadata * is set in the mapfile. */ -#define OWS_DEFAULT_SCHEMAS_LOCATION "http://schemas.opengis.net" +#define OWS_DEFAULT_SCHEMAS_LOCATION "http://schemas.opengis.net" #if defined USE_LIBXML2 && defined USE_WFS_SVR -#include +#include #endif #ifdef __cplusplus extern "C" { #endif - /*==================================================================== * mapows.c *====================================================================*/ @@ -72,12 +70,14 @@ typedef struct { int nStartIndex; char *pszAcceptVersions; char *pszSections; - char *pszSortBy; /* Not implemented yet */ - char *pszLanguage; /* Inspire extension */ + char *pszSortBy; /* Not implemented yet */ + char *pszLanguage; /* Inspire extension */ char *pszValueReference; /* For GetValueReference */ - char *pszStoredQueryId; /* For DescribeStoredQueries */ - int countGetFeatureById; /* Number of urn:ogc:def:query:OGC-WFS::GetFeatureById GetFeature requests */ - int bHasPostStoredQuery; /* TRUE if a XML GetFeature StoredQuery is present */ + char *pszStoredQueryId; /* For DescribeStoredQueries */ + int countGetFeatureById; /* Number of + urn:ogc:def:query:OGC-WFS::GetFeatureById + GetFeature requests */ + int bHasPostStoredQuery; /* TRUE if a XML GetFeature StoredQuery is present */ } wfsParamsObj; /* @@ -112,14 +112,15 @@ typedef struct { * Used to preprocess WMS request parameters and combine layers that can * be comined in a GetMap request. */ -typedef struct { - char *onlineresource; +typedef struct { + char *onlineresource; hashTableObj *params; - int numparams; - char *httpcookiedata; + int numparams; + char *httpcookiedata; } wmsParamsObj; -/* metadataParamsObj: Represent a metadata specific request with its enabled layers */ +/* metadataParamsObj: Represent a metadata specific request with its enabled + * layers */ typedef struct { char *pszRequest; char *pszLayer; @@ -139,122 +140,146 @@ typedef struct { void *document; /* xmlDocPtr or CPLXMLNode* */ } owsRequestObj; -MS_DLL_EXPORT int msOWSDispatch(mapObj *map, cgiRequestObj *request, int ows_mode); - -MS_DLL_EXPORT const char * msOWSLookupMetadata(hashTableObj *metadata, - const char *namespaces, const char *name); -MS_DLL_EXPORT const char * msOWSLookupMetadataWithLanguage(hashTableObj *metadata, - const char *namespaces, const char *name, const char *validated_language); -MS_DLL_EXPORT const char * msOWSLookupMetadata2(hashTableObj *pri, - hashTableObj *sec, - const char *namespaces, - const char *name); - -MS_DLL_EXPORT int msUpdateGMLFieldMetadata(layerObj *layer, const char *field_name, - const char *gml_type, const char *gml_width, const char *gml_precision, const short nullable); +MS_DLL_EXPORT int msOWSDispatch(mapObj *map, cgiRequestObj *request, + int ows_mode); + +MS_DLL_EXPORT const char *msOWSLookupMetadata(hashTableObj *metadata, + const char *namespaces, + const char *name); +MS_DLL_EXPORT const char * +msOWSLookupMetadataWithLanguage(hashTableObj *metadata, const char *namespaces, + const char *name, + const char *validated_language); +MS_DLL_EXPORT const char *msOWSLookupMetadata2(hashTableObj *pri, + hashTableObj *sec, + const char *namespaces, + const char *name); + +MS_DLL_EXPORT int +msUpdateGMLFieldMetadata(layerObj *layer, const char *field_name, + const char *gml_type, const char *gml_width, + const char *gml_precision, const short nullable); void msOWSInitRequestObj(owsRequestObj *ows_request); void msOWSClearRequestObj(owsRequestObj *ows_request); MS_DLL_EXPORT int msOWSRequestIsEnabled(mapObj *map, layerObj *layer, - const char *namespaces, const char *name, int check_all_layers); -MS_DLL_EXPORT void msOWSRequestLayersEnabled(mapObj *map, const char *namespaces, - const char *request, owsRequestObj *request_layers); -MS_DLL_EXPORT int msOWSParseRequestMetadata(const char *metadata, const char *request, - int *disabled); + const char *namespaces, + const char *name, int check_all_layers); +MS_DLL_EXPORT void msOWSRequestLayersEnabled(mapObj *map, + const char *namespaces, + const char *request, + owsRequestObj *request_layers); +MS_DLL_EXPORT int msOWSParseRequestMetadata(const char *metadata, + const char *request, int *disabled); /* Constants for OWS Service version numbers */ -#define OWS_0_1_2 0x000102 -#define OWS_0_1_4 0x000104 -#define OWS_0_1_6 0x000106 -#define OWS_0_1_7 0x000107 -#define OWS_1_0_0 0x010000 -#define OWS_1_0_1 0x010001 -#define OWS_1_0_6 0x010006 -#define OWS_1_0_7 0x010007 -#define OWS_1_0_8 0x010008 -#define OWS_1_1_0 0x010100 -#define OWS_1_1_1 0x010101 -#define OWS_1_1_2 0x010102 -#define OWS_1_3_0 0x010300 -#define OWS_2_0_0 0x020000 -#define OWS_2_0_1 0x020001 -#define OWS_VERSION_MAXLEN 20 /* Buffer size for msOWSGetVersionString() */ -#define OWS_VERSION_NOTSET -1 +#define OWS_0_1_2 0x000102 +#define OWS_0_1_4 0x000104 +#define OWS_0_1_6 0x000106 +#define OWS_0_1_7 0x000107 +#define OWS_1_0_0 0x010000 +#define OWS_1_0_1 0x010001 +#define OWS_1_0_6 0x010006 +#define OWS_1_0_7 0x010007 +#define OWS_1_0_8 0x010008 +#define OWS_1_1_0 0x010100 +#define OWS_1_1_1 0x010101 +#define OWS_1_1_2 0x010102 +#define OWS_1_3_0 0x010300 +#define OWS_2_0_0 0x020000 +#define OWS_2_0_1 0x020001 +#define OWS_VERSION_MAXLEN 20 /* Buffer size for msOWSGetVersionString() */ +#define OWS_VERSION_NOTSET -1 #define OWS_VERSION_BADFORMAT -2 MS_DLL_EXPORT int msOWSParseVersionString(const char *pszVersion); MS_DLL_EXPORT const char *msOWSGetVersionString(int nVersion, char *pszBuffer); MS_DLL_EXPORT const char *msOWSGetLanguage(mapObj *map, const char *context); -MS_DLL_EXPORT char *msOWSGetOnlineResource(mapObj *map, const char *namespaces, const char *metadata_name, cgiRequestObj *req); +MS_DLL_EXPORT char *msOWSGetOnlineResource(mapObj *map, const char *namespaces, + const char *metadata_name, + cgiRequestObj *req); MS_DLL_EXPORT const char *msOWSGetSchemasLocation(mapObj *map); MS_DLL_EXPORT char *msOWSTerminateOnlineResource(const char *src_url); -void msOWSGetEPSGProj(projectionObj *proj, hashTableObj *metadata, const char *namespaces, int bReturnOnlyFirstOne, char **epsgProj); +void msOWSGetEPSGProj(projectionObj *proj, hashTableObj *metadata, + const char *namespaces, int bReturnOnlyFirstOne, + char **epsgProj); void msOWSProjectToWGS84(projectionObj *srcproj, rectObj *ext); -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) MS_DLL_EXPORT int msOWSMakeAllLayersUnique(mapObj *map); -MS_DLL_EXPORT int msOWSNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions); -MS_DLL_EXPORT char *msOWSGetOnlineResource2(mapObj *map, const char *namespaces, const char *metadata_name, cgiRequestObj *req, const char *validated_language); +MS_DLL_EXPORT int msOWSNegotiateVersion(int requested_version, + const int supported_versions[], + int num_supported_versions); +MS_DLL_EXPORT char *msOWSGetOnlineResource2(mapObj *map, const char *namespaces, + const char *metadata_name, + cgiRequestObj *req, + const char *validated_language); MS_DLL_EXPORT const char *msOWSGetInspireSchemasLocation(mapObj *map); -MS_DLL_EXPORT char **msOWSGetLanguageList(mapObj *map, const char *namespaces, int *numitems); -MS_DLL_EXPORT char *msOWSGetLanguageFromList(mapObj *map, const char *namespaces, const char *requested_language); -MS_DLL_EXPORT char *msOWSLanguageNegotiation(mapObj *map, const char *namespaces, char **accept_languages, int num_accept_languages); - +MS_DLL_EXPORT char **msOWSGetLanguageList(mapObj *map, const char *namespaces, + int *numitems); +MS_DLL_EXPORT char *msOWSGetLanguageFromList(mapObj *map, + const char *namespaces, + const char *requested_language); +MS_DLL_EXPORT char *msOWSLanguageNegotiation(mapObj *map, + const char *namespaces, + char **accept_languages, + int num_accept_languages); /* OWS_NOERR and OWS_WARN passed as action_if_not_found to printMetadata() */ -#define OWS_NOERR 0 -#define OWS_WARN 1 +#define OWS_NOERR 0 +#define OWS_WARN 1 /* OWS_WMS and OWS_WFS used for functions that differ in behavior between */ /* WMS and WFS services (e.g. msOWSPrintLatLonBoundingBox()) */ -typedef enum -{ - OWS_WMS = 1, - OWS_WFS = 2, - OWS_WCS = 3 -} OWSServiceType; - -MS_DLL_EXPORT int msOWSPrintInspireCommonExtendedCapabilities(FILE *stream, mapObj *map, const char *namespaces, - int action_if_not_found, const char *tag_name, const char* tag_ns, - const char *validated_language, const OWSServiceType service); -int msOWSPrintInspireCommonMetadata(FILE *stream, mapObj *map, const char *namespaces, - int action_if_not_found, const OWSServiceType service); -int msOWSPrintInspireCommonLanguages(FILE *stream, mapObj *map, const char *namespaces, - int action_if_not_found, const char *validated_language); +typedef enum { OWS_WMS = 1, OWS_WFS = 2, OWS_WCS = 3 } OWSServiceType; + +MS_DLL_EXPORT int msOWSPrintInspireCommonExtendedCapabilities( + FILE *stream, mapObj *map, const char *namespaces, int action_if_not_found, + const char *tag_name, const char *tag_ns, const char *validated_language, + const OWSServiceType service); +int msOWSPrintInspireCommonMetadata(FILE *stream, mapObj *map, + const char *namespaces, + int action_if_not_found, + const OWSServiceType service); +int msOWSPrintInspireCommonLanguages(FILE *stream, mapObj *map, + const char *namespaces, + int action_if_not_found, + const char *validated_language); MS_DLL_EXPORT int msOWSPrintMetadata(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - int action_if_not_found, const char *format, + int action_if_not_found, + const char *format, const char *default_value); int msOWSPrintEncodeMetadata(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - int action_if_not_found, - const char *format, const char *default_value) ; + int action_if_not_found, const char *format, + const char *default_value); int msOWSPrintEncodeMetadata2(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - int action_if_not_found, - const char *format, const char *default_value, + int action_if_not_found, const char *format, + const char *default_value, const char *validated_language); -char *msOWSGetEncodeMetadata(hashTableObj *metadata, - const char *namespaces, const char *name, - const char *default_value); +char *msOWSGetEncodeMetadata(hashTableObj *metadata, const char *namespaces, + const char *name, const char *default_value); int msOWSPrintValidateMetadata(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - int action_if_not_found, - const char *format, const char *default_value); -int msOWSPrintGroupMetadata(FILE *stream, mapObj *map, char* pszGroupName, + int action_if_not_found, const char *format, + const char *default_value); +int msOWSPrintGroupMetadata(FILE *stream, mapObj *map, char *pszGroupName, const char *namespaces, const char *name, - int action_if_not_found, - const char *format, const char *default_value); -int msOWSPrintGroupMetadata2(FILE *stream, mapObj *map, char* pszGroupName, + int action_if_not_found, const char *format, + const char *default_value); +int msOWSPrintGroupMetadata2(FILE *stream, mapObj *map, char *pszGroupName, const char *namespaces, const char *name, - int action_if_not_found, - const char *format, const char *default_value, + int action_if_not_found, const char *format, + const char *default_value, const char *validated_language); int msOWSPrintURLType(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, @@ -276,70 +301,70 @@ int msOWSPrintEncodeParam(FILE *stream, const char *name, const char *value, const char *default_value); int msOWSPrintMetadataList(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - const char *startTag, - const char *endTag, const char *itemFormat, - const char *default_value); + const char *startTag, const char *endTag, + const char *itemFormat, const char *default_value); int msOWSPrintEncodeMetadataList(FILE *stream, hashTableObj *metadata, const char *namespaces, const char *name, - const char *startTag, - const char *endTag, const char *itemFormat, + const char *startTag, const char *endTag, + const char *itemFormat, const char *default_value); -int msOWSPrintEncodeParamList(FILE *stream, const char *name, - const char *value, int action_if_not_found, - char delimiter, const char *startTag, - const char *endTag, const char *format, - const char *default_value); +int msOWSPrintEncodeParamList(FILE *stream, const char *name, const char *value, + int action_if_not_found, char delimiter, + const char *startTag, const char *endTag, + const char *format, const char *default_value); void msOWSPrintLatLonBoundingBox(FILE *stream, const char *tabspace, rectObj *extent, projectionObj *srcproj, - projectionObj *wfsproj, OWSServiceType nService); + projectionObj *wfsproj, + OWSServiceType nService); void msOWSPrintEX_GeographicBoundingBox(FILE *stream, const char *tabspace, - rectObj *extent, projectionObj *srcproj); - -void msOWSPrintBoundingBox(FILE *stream, const char *tabspace, - rectObj *extent, - projectionObj *srcproj, - hashTableObj *layer_meta, - hashTableObj *map_meta, - const char *namespaces, + rectObj *extent, + projectionObj *srcproj); + +void msOWSPrintBoundingBox(FILE *stream, const char *tabspace, rectObj *extent, + projectionObj *srcproj, hashTableObj *layer_meta, + hashTableObj *map_meta, const char *namespaces, int wms_version); -void msOWSPrintContactInfo( FILE *stream, const char *tabspace, - int nVersion, hashTableObj *metadata, - const char *namespaces ); -int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, rectObj *ext); +void msOWSPrintContactInfo(FILE *stream, const char *tabspace, int nVersion, + hashTableObj *metadata, const char *namespaces); +int msOWSGetLayerExtent(mapObj *map, layerObj *lp, const char *namespaces, + rectObj *ext); int msOWSExecuteRequests(httpRequestObj *pasReqInfo, int numRequests, mapObj *map, int bCheckLocalCache); -void msOWSProcessException(layerObj *lp, const char *pszFname, - int nErrorCode, const char *pszFuncName); +void msOWSProcessException(layerObj *lp, const char *pszFname, int nErrorCode, + const char *pszFuncName); char *msOWSBuildURLFilename(const char *pszPath, const char *pszURL, const char *pszExt); -char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, const char *namespaces, int bReturnOnlyFirstOne); -char *msOWSGetProjURI(projectionObj *proj, hashTableObj *metadata, const char *namespaces, int bReturnOnlyFirstOne); +char *msOWSGetProjURN(projectionObj *proj, hashTableObj *metadata, + const char *namespaces, int bReturnOnlyFirstOne); +char *msOWSGetProjURI(projectionObj *proj, hashTableObj *metadata, + const char *namespaces, int bReturnOnlyFirstOne); void msOWSGetDimensionInfo(layerObj *layer, const char *pszDimension, const char **pszDimUserValue, - const char **pszDimUnits, - const char **pszDimDefault, + const char **pszDimUnits, const char **pszDimDefault, const char **pszDimNearValue, const char **pszDimUnitSymbol, const char **pszDimMultiValue); -int msOWSNegotiateUpdateSequence(const char *requested_updateSequence, const char *updatesequence); +int msOWSNegotiateUpdateSequence(const char *requested_updateSequence, + const char *updatesequence); -outputFormatObj *msOwsIsOutputFormatValid(mapObj *map, const char *format, hashTableObj *metadata, - const char *namespaces, const char *name); +outputFormatObj *msOwsIsOutputFormatValid(mapObj *map, const char *format, + hashTableObj *metadata, + const char *namespaces, + const char *name); #endif /* #if any wxs service enabled */ /*==================================================================== * mapgml.c *====================================================================*/ -typedef enum -{ - OWS_GML2, /* 2.1.2 */ - OWS_GML3, /* 3.1.1 */ - OWS_GML32 /* 3.2.1 */ +typedef enum { + OWS_GML2, /* 2.1.2 */ + OWS_GML3, /* 3.1.1 */ + OWS_GML32 /* 3.2.1 */ } OWSGMLVersion; #define OWS_WFS_FEATURE_COLLECTION_NAME "msFeatureCollection" @@ -349,20 +374,27 @@ typedef enum /* TODO, there must be a better way to generalize these lists of objects... */ typedef struct { - char *name; /* name of the item */ - char *alias; /* is the item aliased for presentation? (NULL if not) */ - char *type; /* raw type for this item (NULL for a "string") (TODO: should this be a lookup table instead?) */ + char *name; /* name of the item */ + char *alias; /* is the item aliased for presentation? (NULL if not) */ + char *type; /* raw type for this item (NULL for a "string") (TODO: should this + be a lookup table instead?) */ #ifndef __cplusplus - char *template; /* presentation string for this item, needs to be a complete XML tag */ + char *template; /* presentation string for this item, needs to be a complete + XML tag */ #else - char *_template; /* presentation string for this item, needs to be a complete XML tag */ + char *_template; /* presentation string for this item, needs to be a complete + XML tag */ #endif - int encode; /* should the value be HTML encoded? Default is MS_TRUE */ - int visible; /* should this item be output, default is MS_FALSE */ - int width; /* field width, zero if unknown */ - int precision; /* field precision (decimal places), zero if unknown or N/A */ - int outputByDefault; /* whether this should be output in a GetFeature without PropertyName. MS_TRUE by default, unless gml_default_items is specified and the item name is not in it */ - int minOccurs; /* 0 by default. Can be set to 1 by specifying item name in gml_mandatory_items */ + int encode; /* should the value be HTML encoded? Default is MS_TRUE */ + int visible; /* should this item be output, default is MS_FALSE */ + int width; /* field width, zero if unknown */ + int precision; /* field precision (decimal places), zero if unknown or N/A */ + int outputByDefault; /* whether this should be output in a GetFeature without + PropertyName. MS_TRUE by default, unless + gml_default_items is specified and the item name is + not in it */ + int minOccurs; /* 0 by default. Can be set to 1 by specifying item name in + gml_mandatory_items */ } gmlItemObj; typedef struct { @@ -371,9 +403,10 @@ typedef struct { } gmlItemListObj; typedef struct { - char *name; /* name of the constant */ - char *type; /* raw type for this item (NULL for a "string") */ - char *value; /* output value for this constant (output will look like: value) */ + char *name; /* name of the constant */ + char *type; /* raw type for this item (NULL for a "string") */ + char *value; /* output value for this constant (output will look like: + value) */ } gmlConstantObj; typedef struct { @@ -382,9 +415,10 @@ typedef struct { } gmlConstantListObj; typedef struct { - char *name; /* name of the geometry (type of GML property) */ - char *type; /* raw type for these geometries (point|multipoint|line|multiline|polygon|multipolygon */ - int occurmin, occurmax; /* number of occurances (default 0,1) */ + char *name; /* name of the geometry (type of GML property) */ + char *type; /* raw type for these geometries + (point|multipoint|line|multiline|polygon|multipolygon */ + int occurmin, occurmax; /* number of occurances (default 0,1) */ } gmlGeometryObj; typedef struct { @@ -393,10 +427,10 @@ typedef struct { } gmlGeometryListObj; typedef struct { - char *name; /* name of the group */ - char **items; /* list of items in the group */ - int numitems; /* number of items */ - char *type; /* name of the complex type */ + char *name; /* name of the group */ + char **items; /* list of items in the group */ + int numitems; /* number of items */ + char *type; /* name of the complex type */ } gmlGroupObj; typedef struct { @@ -415,52 +449,62 @@ typedef struct { int numnamespaces; } gmlNamespaceListObj; -MS_DLL_EXPORT gmlItemListObj *msGMLGetItems(layerObj *layer, const char *metadata_namespaces); +MS_DLL_EXPORT gmlItemListObj *msGMLGetItems(layerObj *layer, + const char *metadata_namespaces); MS_DLL_EXPORT void msGMLFreeItems(gmlItemListObj *itemList); -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) MS_DLL_EXPORT int msItemInGroups(const char *name, gmlGroupListObj *groupList); -MS_DLL_EXPORT gmlConstantListObj *msGMLGetConstants(layerObj *layer, const char *metadata_namespaces); +MS_DLL_EXPORT gmlConstantListObj * +msGMLGetConstants(layerObj *layer, const char *metadata_namespaces); MS_DLL_EXPORT void msGMLFreeConstants(gmlConstantListObj *constantList); -MS_DLL_EXPORT gmlGeometryListObj *msGMLGetGeometries(layerObj *layer, const char *metadata_namespaces, int bWithDefaultGeom); +MS_DLL_EXPORT gmlGeometryListObj * +msGMLGetGeometries(layerObj *layer, const char *metadata_namespaces, + int bWithDefaultGeom); MS_DLL_EXPORT void msGMLFreeGeometries(gmlGeometryListObj *geometryList); -MS_DLL_EXPORT gmlNamespaceListObj *msGMLGetNamespaces(webObj *web, const char *metadata_namespaces); +MS_DLL_EXPORT gmlNamespaceListObj * +msGMLGetNamespaces(webObj *web, const char *metadata_namespaces); MS_DLL_EXPORT void msGMLFreeNamespaces(gmlNamespaceListObj *namespaceList); #endif -MS_DLL_EXPORT gmlGroupListObj *msGMLGetGroups(layerObj *layer, const char *metadata_namespaces); +MS_DLL_EXPORT gmlGroupListObj *msGMLGetGroups(layerObj *layer, + const char *metadata_namespaces); MS_DLL_EXPORT void msGMLFreeGroups(gmlGroupListObj *groupList); /* export to fix bug 851 */ -MS_DLL_EXPORT int msGMLWriteQuery(mapObj *map, char *filename, const char *namespaces); - +MS_DLL_EXPORT int msGMLWriteQuery(mapObj *map, char *filename, + const char *namespaces); #ifdef USE_WFS_SVR void msGMLWriteWFSBounds(mapObj *map, FILE *stream, const char *tab, - OWSGMLVersion outputformat, int nWFSVersion, int bUseURN); + OWSGMLVersion outputformat, int nWFSVersion, + int bUseURN); -MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, const char *wfs_namespace, - OWSGMLVersion outputformat, int nWFSVersion, int bUseURN, +MS_DLL_EXPORT int msGMLWriteWFSQuery(mapObj *map, FILE *stream, + const char *wfs_namespace, + OWSGMLVersion outputformat, + int nWFSVersion, int bUseURN, int bGetPropertyValueRequest); #endif - /*==================================================================== * mapwms.c *====================================================================*/ -int msWMSDispatch(mapObj *map, cgiRequestObj *req, owsRequestObj *ows_request, int force_wms_mode); -MS_DLL_EXPORT int msWMSLoadGetMapParams(mapObj *map, int nVersion, - char **names, char **values, int numentries, - const char *wms_exception_format, const char *wms_request, owsRequestObj *ows_request); - +int msWMSDispatch(mapObj *map, cgiRequestObj *req, owsRequestObj *ows_request, + int force_wms_mode); +MS_DLL_EXPORT int msWMSLoadGetMapParams(mapObj *map, int nVersion, char **names, + char **values, int numentries, + const char *wms_exception_format, + const char *wms_request, + owsRequestObj *ows_request); /*==================================================================== * mapwmslayer.c *====================================================================*/ -#define WMS_GETMAP 1 +#define WMS_GETMAP 1 #define WMS_GETFEATUREINFO 2 #define WMS_GETLEGENDGRAPHIC 3 @@ -468,18 +512,21 @@ int msInitWmsParamsObj(wmsParamsObj *wmsparams); void msFreeWmsParamsObj(wmsParamsObj *wmsparams); int msPrepareWMSLayerRequest(int nLayerId, mapObj *map, layerObj *lp, - int nRequestType, enum MS_CONNECTION_TYPE lastconnectiontype, - wmsParamsObj *psLastWMSParams, - int nClickX, int nClickY, int nFeatureCount, const char *pszInfoFormat, + int nRequestType, + enum MS_CONNECTION_TYPE lastconnectiontype, + wmsParamsObj *psLastWMSParams, int nClickX, + int nClickY, int nFeatureCount, + const char *pszInfoFormat, httpRequestObj *pasReqInfo, int *numRequests); -int msDrawWMSLayerLow(int nLayerId, httpRequestObj *pasReqInfo, - int numRequests, mapObj *map, layerObj *lp, - imageObj *img); +int msDrawWMSLayerLow(int nLayerId, httpRequestObj *pasReqInfo, int numRequests, + mapObj *map, layerObj *lp, imageObj *img); MS_DLL_EXPORT char *msWMSGetFeatureInfoURL(mapObj *map, layerObj *lp, - int nClickX, int nClickY, int nFeatureCount, - const char *pszInfoFormat); -int msWMSLayerExecuteRequest(mapObj *map, int nOWSLayers, int nClickX, int nClickY, - int nFeatureCount, const char *pszInfoFormat, int type); + int nClickX, int nClickY, + int nFeatureCount, + const char *pszInfoFormat); +int msWMSLayerExecuteRequest(mapObj *map, int nOWSLayers, int nClickX, + int nClickY, int nFeatureCount, + const char *pszInfoFormat, int type); /*==================================================================== * mapmetadata.c @@ -497,7 +544,8 @@ void msMetadataSetGetMetadataURL(layerObj *lp, const char *url); MS_DLL_EXPORT int msWFSDispatch(mapObj *map, cgiRequestObj *requestobj, owsRequestObj *ows_request, int force_wfs_mode); wfsParamsObj *msWFSCreateParamsObj(void); -int msWFSHandleUpdateSequence(mapObj *map, wfsParamsObj *wfsparams, const char* pszFunction); +int msWFSHandleUpdateSequence(mapObj *map, wfsParamsObj *wfsparams, + const char *pszFunction); void msWFSFreeParamsObj(wfsParamsObj *wfsparams); int msWFSIsLayerSupported(layerObj *lp); int msWFSException(mapObj *map, const char *locator, const char *code, @@ -512,7 +560,7 @@ int msWFSGetCapabilities11(mapObj *map, wfsParamsObj *wfsparams, cgiRequestObj *req, owsRequestObj *ows_request); #ifdef USE_LIBXML2 xmlNodePtr msWFSDumpLayer11(mapObj *map, layerObj *lp, xmlNsPtr psNsOws, - int nWFSVersion, const char* validate_language, + int nWFSVersion, const char *validate_language, char *script_url); #endif char *msWFSGetOutputFormatList(mapObj *map, layerObj *layer, int nWFSVersion); @@ -524,10 +572,8 @@ int msWFSGetCapabilities20(mapObj *map, wfsParamsObj *params, int msWFSListStoredQueries20(mapObj *map, owsRequestObj *ows_request); int msWFSDescribeStoredQueries20(mapObj *map, wfsParamsObj *params, owsRequestObj *ows_request); -char* msWFSGetResolvedStoredQuery20(mapObj *map, - wfsParamsObj *wfsparams, - const char* id, - hashTableObj* hashTable); +char *msWFSGetResolvedStoredQuery20(mapObj *map, wfsParamsObj *wfsparams, + const char *id, hashTableObj *hashTable); #endif @@ -538,8 +584,8 @@ char* msWFSGetResolvedStoredQuery20(mapObj *map, int msPrepareWFSLayerRequest(int nLayerId, mapObj *map, layerObj *lp, httpRequestObj *pasReqInfo, int *numRequests); void msWFSUpdateRequestInfo(layerObj *lp, httpRequestObj *pasReqInfo); -int msWFSLayerOpen(layerObj *lp, - const char *pszGMLFilename, rectObj *defaultBBOX); +int msWFSLayerOpen(layerObj *lp, const char *pszGMLFilename, + rectObj *defaultBBOX); int msWFSLayerIsOpen(layerObj *lp); int msWFSLayerInitItemInfo(layerObj *layer); int msWFSLayerGetItems(layerObj *layer); @@ -553,27 +599,27 @@ MS_DLL_EXPORT char *msWFSExecuteGetFeature(layerObj *lp); MS_DLL_EXPORT int msWriteMapContext(mapObj *map, FILE *stream); MS_DLL_EXPORT int msSaveMapContext(mapObj *map, char *filename); -MS_DLL_EXPORT int msLoadMapContext(mapObj *map, const char *filename, int unique_layer_names); -MS_DLL_EXPORT int msLoadMapContextURL(mapObj *map, char *urlfilename, int unique_layer_names); - +MS_DLL_EXPORT int msLoadMapContext(mapObj *map, const char *filename, + int unique_layer_names); +MS_DLL_EXPORT int msLoadMapContextURL(mapObj *map, char *urlfilename, + int unique_layer_names); /*==================================================================== * mapwcs.c *====================================================================*/ -int msWCSDispatch(mapObj *map, cgiRequestObj *requestobj, owsRequestObj *ows_request); /* only 1 public function */ - - +int msWCSDispatch(mapObj *map, cgiRequestObj *requestobj, + owsRequestObj *ows_request); /* only 1 public function */ /*==================================================================== * mapogsos.c *====================================================================*/ -int msSOSDispatch(mapObj *map, cgiRequestObj *requestobj, owsRequestObj *ows_request); /* only 1 public function */ +int msSOSDispatch(mapObj *map, cgiRequestObj *requestobj, + owsRequestObj *ows_request); /* only 1 public function */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* MAPOWS_H */ - diff --git a/mapowscommon.c b/mapowscommon.c index a407eca5ff..8dca34357f 100644 --- a/mapowscommon.c +++ b/mapowscommon.c @@ -36,16 +36,12 @@ #ifdef USE_LIBXML2 -#include -#include +#include +#include #include "mapowscommon.h" #include "maplibxml2.h" - - - - /** * msOWSCommonServiceIdentification() * @@ -66,38 +62,50 @@ xmlNodePtr msOWSCommonServiceIdentification(xmlNsPtr psNsOws, mapObj *map, const char *servicetype, const char *supported_versions, const char *namespaces, - const char *validated_language) -{ - const char *value = NULL; + const char *validated_language) { + const char *value = NULL; - xmlNodePtr psRootNode = NULL; - xmlNodePtr psNode = NULL; + xmlNodePtr psRootNode = NULL; + xmlNodePtr psNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); /* create element name */ psRootNode = xmlNewNode(psNsOws, BAD_CAST "ServiceIdentification"); /* add child elements */ - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "title", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "title", validated_language); - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Title", BAD_CAST value); + psNode = + xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Title", BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_title\" missing for ows:Title")); + xmlAddSibling( + psNode, + xmlNewComment( + BAD_CAST + "WARNING: Optional metadata \"ows_title\" missing for ows:Title")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "abstract", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "abstract", validated_language); - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Abstract", BAD_CAST value); + psNode = + xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Abstract", BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_abstract\" was missing for ows:Abstract")); + xmlAddSibling(psNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_abstract\" " + "was missing for ows:Abstract")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "keywordlist", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "keywordlist", validated_language); if (value) { psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Keywords", NULL); @@ -105,29 +113,46 @@ xmlNodePtr msOWSCommonServiceIdentification(xmlNsPtr psNsOws, mapObj *map, } else { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_keywordlist\" was missing for ows:KeywordList")); + xmlAddSibling( + psNode, + xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_keywordlist\" " + "was missing for ows:KeywordList")); } - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ServiceType", BAD_CAST servicetype); + psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ServiceType", + BAD_CAST servicetype); xmlNewProp(psNode, BAD_CAST "codeSpace", BAD_CAST MS_OWSCOMMON_OGC_CODESPACE); - msLibXml2GenerateList(psRootNode, psNsOws, "ServiceTypeVersion", supported_versions, ','); + msLibXml2GenerateList(psRootNode, psNsOws, "ServiceTypeVersion", + supported_versions, ','); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "fees", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "fees", validated_language); - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Fees", BAD_CAST value); + psNode = + xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "Fees", BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_fees\" was missing for ows:Fees")); + xmlAddSibling(psNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_fees\" was " + "missing for ows:Fees")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "accessconstraints", validated_language); + value = + msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "accessconstraints", validated_language); - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "AccessConstraints", BAD_CAST value); + psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "AccessConstraints", + BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_accessconstraints\" was missing for ows:AccessConstraints")); + xmlAddSibling( + psNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_accessconstraints\" " + "was missing for ows:AccessConstraints")); } return psRootNode; @@ -150,169 +175,268 @@ xmlNodePtr msOWSCommonServiceIdentification(xmlNsPtr psNsOws, mapObj *map, xmlNodePtr msOWSCommonServiceProvider(xmlNsPtr psNsOws, xmlNsPtr psNsXLink, mapObj *map, const char *namespaces, - const char *validated_language) -{ + const char *validated_language) { const char *value = NULL; - xmlNodePtr psNode = NULL; - xmlNodePtr psRootNode = NULL; - xmlNodePtr psSubNode = NULL; - xmlNodePtr psSubSubNode = NULL; - xmlNodePtr psSubSubSubNode = NULL; + xmlNodePtr psNode = NULL; + xmlNodePtr psRootNode = NULL; + xmlNodePtr psSubNode = NULL; + xmlNodePtr psSubSubNode = NULL; + xmlNodePtr psSubSubSubNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); psRootNode = xmlNewNode(psNsOws, BAD_CAST "ServiceProvider"); /* add child elements */ - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactorganization", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactorganization", + validated_language); - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ProviderName", BAD_CAST value); + psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ProviderName", + BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Mandatory metadata \"ows_contactorganization\" was missing for ows:ProviderName")); + xmlAddSibling( + psNode, + xmlNewComment(BAD_CAST + "WARNING: Mandatory metadata \"ows_contactorganization\" " + "was missing for ows:ProviderName")); } psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ProviderSite", NULL); xmlNewNsProp(psNode, psNsXLink, BAD_CAST "type", BAD_CAST "simple"); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "service_onlineresource", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "service_onlineresource", + validated_language); xmlNewNsProp(psNode, psNsXLink, BAD_CAST "href", BAD_CAST value); if (!value) { - xmlAddSibling(psNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_service_onlineresource\" was missing for ows:ProviderSite/@xlink:href")); + xmlAddSibling( + psNode, xmlNewComment( + BAD_CAST + "WARNING: Optional metadata \"ows_service_onlineresource\" " + "was missing for ows:ProviderSite/@xlink:href")); } - psNode = xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ServiceContact", NULL); + psNode = + xmlNewTextChild(psRootNode, psNsOws, BAD_CAST "ServiceContact", NULL); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactperson", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactperson", validated_language); - psSubNode = xmlNewTextChild(psNode, psNsOws, BAD_CAST "IndividualName", BAD_CAST value); + psSubNode = xmlNewTextChild(psNode, psNsOws, BAD_CAST "IndividualName", + BAD_CAST value); if (!value) { - xmlAddSibling(psSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactperson\" was missing for ows:IndividualName")); + xmlAddSibling( + psSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_contactperson\" was " + "missing for ows:IndividualName")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactposition", validated_language); + value = msOWSLookupMetadataWithLanguage( + &(map->web.metadata), namespaces, "contactposition", validated_language); - psSubNode = xmlNewTextChild(psNode, psNsOws, BAD_CAST "PositionName", BAD_CAST value); + psSubNode = + xmlNewTextChild(psNode, psNsOws, BAD_CAST "PositionName", BAD_CAST value); if (!value) { - xmlAddSibling(psSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactposition\" was missing for ows:PositionName")); + xmlAddSibling( + psSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_contactposition\" was " + "missing for ows:PositionName")); } psSubNode = xmlNewTextChild(psNode, psNsOws, BAD_CAST "ContactInfo", NULL); psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "Phone", NULL); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactvoicetelephone", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactvoicetelephone", + validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Voice", BAD_CAST value); + psSubSubSubNode = + xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Voice", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactvoicetelephone\" was missing for ows:Voice")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment( + BAD_CAST "WARNING: Optional metadata \"ows_contactvoicetelephone\" " + "was missing for ows:Voice")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactfacsimiletelephone", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactfacsimiletelephone", + validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Facsimile", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Facsimile", + BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactfacsimiletelephone\" was missing for ows:Facsimile")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment( + BAD_CAST + "WARNING: Optional metadata \"ows_contactfacsimiletelephone\" was " + "missing for ows:Facsimile")); } psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "Address", NULL); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "address", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "address", validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "DeliveryPoint", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, + BAD_CAST "DeliveryPoint", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_address\" was missing for ows:DeliveryPoint")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_address\" was " + "missing for ows:DeliveryPoint")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "city", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "city", validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "City", BAD_CAST value); + psSubSubSubNode = + xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "City", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_city\" was missing for ows:City")); + xmlAddSibling(psSubSubSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_city\" was " + "missing for ows:City")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "stateorprovince", validated_language); + value = msOWSLookupMetadataWithLanguage( + &(map->web.metadata), namespaces, "stateorprovince", validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "AdministrativeArea", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild( + psSubSubNode, psNsOws, BAD_CAST "AdministrativeArea", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_stateorprovince\" was missing for ows:AdministrativeArea")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_stateorprovince\" was " + "missing for ows:AdministrativeArea")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "postcode", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "postcode", validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "PostalCode", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, + BAD_CAST "PostalCode", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_postcode\" was missing for ows:PostalCode")); + xmlAddSibling(psSubSubSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_postcode\" " + "was missing for ows:PostalCode")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "country", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "country", validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Country", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "Country", + BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_country\" was missing for ows:Country")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_country\" was " + "missing for ows:Country")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactelectronicmailaddress", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactelectronicmailaddress", + validated_language); - psSubSubSubNode = xmlNewTextChild(psSubSubNode, psNsOws, BAD_CAST "ElectronicMailAddress", BAD_CAST value); + psSubSubSubNode = xmlNewTextChild( + psSubSubNode, psNsOws, BAD_CAST "ElectronicMailAddress", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactelectronicmailaddress\" was missing for ows:ElectronicMailAddress")); + xmlAddSibling( + psSubSubSubNode, + xmlNewComment( + BAD_CAST + "WARNING: Optional metadata \"ows_contactelectronicmailaddress\" " + "was missing for ows:ElectronicMailAddress")); } - psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "OnlineResource", NULL); + psSubSubNode = + xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "OnlineResource", NULL); xmlNewNsProp(psSubSubNode, psNsXLink, BAD_CAST "type", BAD_CAST "simple"); - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "service_onlineresource", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "service_onlineresource", + validated_language); xmlNewNsProp(psSubSubNode, psNsXLink, BAD_CAST "href", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_service_onlineresource\" was missing for ows:OnlineResource/@xlink:href")); + xmlAddSibling( + psSubSubNode, + xmlNewComment( + BAD_CAST + "WARNING: Optional metadata \"ows_service_onlineresource\" was " + "missing for ows:OnlineResource/@xlink:href")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "hoursofservice", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "hoursofservice", validated_language); - psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "HoursOfService", BAD_CAST value); + psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "HoursOfService", + BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_hoursofservice\" was missing for ows:HoursOfService")); + xmlAddSibling( + psSubSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_hoursofservice\" was " + "missing for ows:HoursOfService")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "contactinstructions", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "contactinstructions", + validated_language); - psSubSubNode = xmlNewTextChild(psSubNode, psNsOws, BAD_CAST "ContactInstructions", BAD_CAST value); + psSubSubNode = xmlNewTextChild( + psSubNode, psNsOws, BAD_CAST "ContactInstructions", BAD_CAST value); if (!value) { - xmlAddSibling(psSubSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_contactinstructions\" was missing for ows:ContactInstructions")); + xmlAddSibling( + psSubSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_contactinstructions\" " + "was missing for ows:ContactInstructions")); } - value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, "role", validated_language); + value = msOWSLookupMetadataWithLanguage(&(map->web.metadata), namespaces, + "role", validated_language); psSubNode = xmlNewTextChild(psNode, psNsOws, BAD_CAST "Role", BAD_CAST value); if (!value) { - xmlAddSibling(psSubNode, xmlNewComment(BAD_CAST "WARNING: Optional metadata \"ows_role\" was missing for ows:Role")); + xmlAddSibling(psSubNode, + xmlNewComment(BAD_CAST + "WARNING: Optional metadata \"ows_role\" was " + "missing for ows:Role")); } return psRootNode; - } /** @@ -327,12 +451,12 @@ xmlNodePtr msOWSCommonServiceProvider(xmlNsPtr psNsOws, xmlNsPtr psNsXLink, * */ -xmlNodePtr msOWSCommonOperationsMetadata(xmlNsPtr psNsOws) -{ +xmlNodePtr msOWSCommonOperationsMetadata(xmlNsPtr psNsOws) { xmlNodePtr psRootNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); psRootNode = xmlNewNode(psNsOws, BAD_CAST "OperationsMetadata"); return psRootNode; @@ -347,22 +471,25 @@ xmlNodePtr msOWSCommonOperationsMetadata(xmlNsPtr psNsOws) * 1.1.0 subclause 7.4.6 * * @param name name of the Operation - * @param method HTTP method: OWS_METHOD_GET, OWS_METHOD_POST or OWS_METHOD_GETPOST) + * @param method HTTP method: OWS_METHOD_GET, OWS_METHOD_POST or + * OWS_METHOD_GETPOST) * @param url online resource URL * * @return psRootNode xmlNodePtr pointer of XML construct */ -xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, xmlNsPtr psXLinkNs, const char *name, int method, const char *url) -{ - xmlNodePtr psRootNode = NULL; - xmlNodePtr psNode = NULL; - xmlNodePtr psSubNode = NULL; - xmlNodePtr psSubSubNode = NULL; +xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, + xmlNsPtr psXLinkNs, + const char *name, int method, + const char *url) { + xmlNodePtr psRootNode = NULL; + xmlNodePtr psNode = NULL; + xmlNodePtr psSubNode = NULL; + xmlNodePtr psSubSubNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); - + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); psRootNode = xmlNewNode(psNsOws, BAD_CAST "Operation"); @@ -372,13 +499,13 @@ xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, xmlNsPtr psX psSubNode = xmlNewChild(psNode, psNsOws, BAD_CAST "HTTP", NULL); - if (method == OWS_METHOD_GET || method == OWS_METHOD_GETPOST ) { + if (method == OWS_METHOD_GET || method == OWS_METHOD_GETPOST) { psSubSubNode = xmlNewChild(psSubNode, psNsOws, BAD_CAST "Get", NULL); xmlNewNsProp(psSubSubNode, psXLinkNs, BAD_CAST "type", BAD_CAST "simple"); xmlNewNsProp(psSubSubNode, psXLinkNs, BAD_CAST "href", BAD_CAST url); } - if (method == OWS_METHOD_POST || method == OWS_METHOD_GETPOST ) { + if (method == OWS_METHOD_POST || method == OWS_METHOD_GETPOST) { psSubSubNode = xmlNewChild(psSubNode, psNsOws, BAD_CAST "Post", NULL); xmlNewNsProp(psSubSubNode, psXLinkNs, BAD_CAST "type", BAD_CAST "simple"); xmlNewNsProp(psSubSubNode, psXLinkNs, BAD_CAST "href", BAD_CAST url); @@ -405,13 +532,17 @@ xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, xmlNsPtr psX * */ -xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, xmlNsPtr psNsOws, const char *elname, const char *name, const char *values) -{ +xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, + xmlNsPtr psNsOws, + const char *elname, + const char *name, + const char *values) { xmlNodePtr psRootNode = NULL; xmlNodePtr psNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); psRootNode = xmlNewNode(psNsOws, BAD_CAST elname); @@ -437,7 +568,8 @@ xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, xmlNsPtr psNsOws * @param schemas_location URL to OGC Schemas Location base * @param version the version of the calling specification * @param language ISO3166 code of language - * @param exceptionCode a code from the calling specification's list of exceptions, or from OWS Common + * @param exceptionCode a code from the calling specification's list of + * exceptions, or from OWS Common * @param locator where the exception was encountered (i.e. "layers" keyword) * @param ExceptionText the actual error message * @@ -445,18 +577,23 @@ xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, xmlNsPtr psNsOws * */ -xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, const char *schemas_location, const char *version, const char *language, const char *exceptionCode, const char *locator, const char *ExceptionText) -{ +xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, + const char *schemas_location, + const char *version, const char *language, + const char *exceptionCode, + const char *locator, + const char *ExceptionText) { char *xsi_schemaLocation = NULL; char szVersionBuf[OWS_VERSION_MAXLEN]; - xmlNsPtr psNsXsi = NULL; - xmlNodePtr psRootNode = NULL; - xmlNodePtr psMainNode = NULL; + xmlNsPtr psNsXsi = NULL; + xmlNodePtr psRootNode = NULL; + xmlNodePtr psMainNode = NULL; psRootNode = xmlNewNode(psNsOws, BAD_CAST "ExceptionReport"); - psNsXsi = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_PREFIX); + psNsXsi = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_W3C_XSI_NAMESPACE_PREFIX); /* add attributes to root element */ xmlNewProp(psRootNode, BAD_CAST "version", BAD_CAST version); @@ -470,13 +607,18 @@ xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, const c xsi_schemaLocation = msStrdup((char *)psNsOws->href); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, " "); - xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, (char *)schemas_location); + xsi_schemaLocation = + msStringConcatenate(xsi_schemaLocation, (char *)schemas_location); xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, "/ows/"); - xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, (char *)msOWSGetVersionString(ows_version, szVersionBuf)); - xsi_schemaLocation = msStringConcatenate(xsi_schemaLocation, "/owsExceptionReport.xsd"); + xsi_schemaLocation = msStringConcatenate( + xsi_schemaLocation, + (char *)msOWSGetVersionString(ows_version, szVersionBuf)); + xsi_schemaLocation = + msStringConcatenate(xsi_schemaLocation, "/owsExceptionReport.xsd"); /* add namespace'd attributes to root element */ - xmlNewNsProp(psRootNode, psNsXsi, BAD_CAST "schemaLocation", BAD_CAST xsi_schemaLocation); + xmlNewNsProp(psRootNode, psNsXsi, BAD_CAST "schemaLocation", + BAD_CAST xsi_schemaLocation); /* add child element */ psMainNode = xmlNewChild(psRootNode, NULL, BAD_CAST "Exception", NULL); @@ -489,7 +631,8 @@ xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, const c } if (ExceptionText != NULL) { - xmlNewTextChild(psMainNode, NULL, BAD_CAST "ExceptionText", BAD_CAST ExceptionText); + xmlNewTextChild(psMainNode, NULL, BAD_CAST "ExceptionText", + BAD_CAST ExceptionText); } free(xsi_schemaLocation); @@ -515,28 +658,29 @@ xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, const c * @return psRootNode xmlNodePtr pointer of XML construct */ -xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, int dimensions, double minx, double miny, double maxx, double maxy) -{ +xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, + int dimensions, double minx, double miny, + double maxx, double maxy) { char LowerCorner[100]; char UpperCorner[100]; char dim_string[100]; xmlNodePtr psRootNode = NULL; /* Do we need to reorient tuple axes? */ - if(crs && strstr(crs, "imageCRS") == NULL) { + if (crs && strstr(crs, "imageCRS") == NULL) { projectionObj proj; - msInitProjection( &proj ); - if( msLoadProjectionString( &proj, (char *) crs ) == 0 ) { - msAxisNormalizePoints( &proj, 1, &minx, &miny ); - msAxisNormalizePoints( &proj, 1, &maxx, &maxy ); + msInitProjection(&proj); + if (msLoadProjectionString(&proj, (char *)crs) == 0) { + msAxisNormalizePoints(&proj, 1, &minx, &miny); + msAxisNormalizePoints(&proj, 1, &maxx, &maxy); } - msFreeProjection( &proj ); + msFreeProjection(&proj); } - if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); /* create element name */ psRootNode = xmlNewNode(psNsOws, BAD_CAST "BoundingBox"); @@ -544,15 +688,17 @@ xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, int dimensi /* add attributes to the root element */ xmlNewProp(psRootNode, BAD_CAST "crs", BAD_CAST crs); - snprintf( dim_string, sizeof(dim_string), "%d", dimensions ); + snprintf(dim_string, sizeof(dim_string), "%d", dimensions); xmlNewProp(psRootNode, BAD_CAST "dimensions", BAD_CAST dim_string); snprintf(LowerCorner, sizeof(LowerCorner), "%.15g %.15g", minx, miny); snprintf(UpperCorner, sizeof(UpperCorner), "%.15g %.15g", maxx, maxy); /* add child elements */ - xmlNewChild(psRootNode, psNsOws,BAD_CAST "LowerCorner",BAD_CAST LowerCorner); - xmlNewChild(psRootNode, psNsOws,BAD_CAST "UpperCorner",BAD_CAST UpperCorner); + xmlNewChild(psRootNode, psNsOws, BAD_CAST "LowerCorner", + BAD_CAST LowerCorner); + xmlNewChild(psRootNode, psNsOws, BAD_CAST "UpperCorner", + BAD_CAST UpperCorner); return psRootNode; } @@ -572,8 +718,9 @@ xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, int dimensi * @return psRootNode xmlNodePtr pointer of XML construct */ -xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, double minx, double miny, double maxx, double maxy) -{ +xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, + double minx, double miny, double maxx, + double maxy) { char LowerCorner[100]; char UpperCorner[100]; char dim_string[100]; @@ -581,20 +728,23 @@ xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, double xmlNodePtr psRootNode = NULL; if (_validateNamespace(psNsOws) == MS_FAILURE) - psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); + psNsOws = xmlNewNs(psRootNode, BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_URI, + BAD_CAST MS_OWSCOMMON_OWS_NAMESPACE_PREFIX); /* create element name */ psRootNode = xmlNewNode(psNsOws, BAD_CAST "WGS84BoundingBox"); - snprintf( dim_string, sizeof(dim_string), "%d", dimensions ); + snprintf(dim_string, sizeof(dim_string), "%d", dimensions); xmlNewProp(psRootNode, BAD_CAST "dimensions", BAD_CAST dim_string); snprintf(LowerCorner, sizeof(LowerCorner), "%.6f %.6f", minx, miny); snprintf(UpperCorner, sizeof(UpperCorner), "%.6f %.6f", maxx, maxy); /* add child elements */ - xmlNewChild(psRootNode, psNsOws,BAD_CAST "LowerCorner",BAD_CAST LowerCorner); - xmlNewChild(psRootNode, psNsOws,BAD_CAST "UpperCorner",BAD_CAST UpperCorner); + xmlNewChild(psRootNode, psNsOws, BAD_CAST "LowerCorner", + BAD_CAST LowerCorner); + xmlNewChild(psRootNode, psNsOws, BAD_CAST "UpperCorner", + BAD_CAST UpperCorner); return psRootNode; } @@ -610,8 +760,7 @@ xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, double * */ -int _validateNamespace(xmlNsPtr psNsOws) -{ +int _validateNamespace(xmlNsPtr psNsOws) { char namespace_prefix[10]; snprintf(namespace_prefix, sizeof(namespace_prefix), "%s", psNsOws->prefix); if (strcmp(namespace_prefix, MS_OWSCOMMON_OWS_NAMESPACE_PREFIX) == 0) @@ -622,11 +771,11 @@ int _validateNamespace(xmlNsPtr psNsOws) /* * Valid an xml string against an XML schema - * Inpired from: http://xml.developpez.com/sources/?page=validation#validate_XSD_CppCLI_2 + * Inpired from: + * http://xml.developpez.com/sources/?page=validation#validate_XSD_CppCLI_2 * taken from tinyows.org */ -int msOWSSchemaValidation(const char* xml_schema, const char* xml) -{ +int msOWSSchemaValidation(const char *xml_schema, const char *xml) { xmlSchemaPtr schema; xmlSchemaParserCtxtPtr ctxt; xmlSchemaValidCtxtPtr validctxt; @@ -642,57 +791,65 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) /* To valide WFS 2.0 requests, we might need to explicitely import */ /* GML and FES 2.0 */ - if( strlen(xml_schema) > strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) && + if (strlen(xml_schema) > strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) && strcmp(xml_schema + strlen(xml_schema) - - strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION), MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) == 0 ) - { - const size_t nLenBaseLocation = strlen(xml_schema) - strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION); - char* pszInMemSchema = NULL; - char* pszBaseLocation = (char*)msSmallMalloc(nLenBaseLocation + 1); + strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION), + MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION) == 0) { + const size_t nLenBaseLocation = + strlen(xml_schema) - strlen(MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION); + char *pszInMemSchema = NULL; + char *pszBaseLocation = (char *)msSmallMalloc(nLenBaseLocation + 1); memcpy(pszBaseLocation, xml_schema, nLenBaseLocation); pszBaseLocation[nLenBaseLocation] = '\0'; - pszInMemSchema = msStringConcatenate(pszInMemSchema, + pszInMemSchema = msStringConcatenate( + pszInMemSchema, "\n"); - pszInMemSchema = msStringConcatenate(pszInMemSchema, - "\n"); - if( strstr(xml, MS_OWSCOMMON_FES_20_NAMESPACE_URI) != NULL ) - { - pszInMemSchema = msStringConcatenate(pszInMemSchema, - "\n"); + if (strstr(xml, MS_OWSCOMMON_FES_20_NAMESPACE_URI) != NULL) { + pszInMemSchema = msStringConcatenate( + pszInMemSchema, + "\n"); } - if( strstr(xml, MS_OWSCOMMON_GML_32_NAMESPACE_URI) != NULL ) - { - pszInMemSchema = msStringConcatenate(pszInMemSchema, - "\n"); + + } else if (strstr(xml, MS_OWSCOMMON_GML_NAMESPACE_URI) != NULL) { + if (strstr(xml, MS_OWSCOMMON_GML_212_SCHEMA_LOCATION) != NULL) { + pszInMemSchema = msStringConcatenate( + pszInMemSchema, + "\n"); - - } - else if( strstr(xml, MS_OWSCOMMON_GML_NAMESPACE_URI) != NULL ) - { - if( strstr(xml, MS_OWSCOMMON_GML_212_SCHEMA_LOCATION) != NULL ) - { - pszInMemSchema = msStringConcatenate(pszInMemSchema, - "\n"); - } - else if( strstr(xml, MS_OWSCOMMON_GML_311_SCHEMA_LOCATION) != NULL ) - { - pszInMemSchema = msStringConcatenate(pszInMemSchema, - "\n"); - } + pszInMemSchema = msStringConcatenate( + pszInMemSchema, MS_OWSCOMMON_GML_212_SCHEMA_LOCATION "\" />\n"); + } else if (strstr(xml, MS_OWSCOMMON_GML_311_SCHEMA_LOCATION) != NULL) { + pszInMemSchema = msStringConcatenate( + pszInMemSchema, + "\n"); + } } pszInMemSchema = msStringConcatenate(pszInMemSchema, "\n"); @@ -700,9 +857,7 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) ctxt = xmlSchemaNewMemParserCtxt(pszInMemSchema, strlen(pszInMemSchema)); msFree(pszInMemSchema); msFree(pszBaseLocation); - } - else - { + } else { /* Open XML Schema File */ ctxt = xmlSchemaNewParserCtxt(xml_schema); } @@ -710,7 +865,8 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) /* xmlSchemaSetParserErrors(ctxt, (xmlSchemaValidityErrorFunc) libxml2_callback, - (xmlSchemaValidityWarningFunc) libxml2_callback, stderr); + (xmlSchemaValidityWarningFunc) libxml2_callback, + stderr); */ schema = xmlSchemaParse(ctxt); @@ -731,7 +887,8 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) /* xmlSchemaSetValidErrors(validctxt, (xmlSchemaValidityErrorFunc) libxml2_callback, - (xmlSchemaValidityWarningFunc) libxml2_callback, stderr); + (xmlSchemaValidityWarningFunc) libxml2_callback, + stderr); */ /* validation */ ret = xmlSchemaValidateDoc(validctxt, doc); @@ -747,7 +904,6 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) #endif /* defined(USE_LIBXML2) */ - /** * msOWSCommonNegotiateVersion() * @@ -761,12 +917,13 @@ int msOWSSchemaValidation(const char* xml_schema, const char* xml) * */ -int msOWSCommonNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions) -{ +int msOWSCommonNegotiateVersion(int requested_version, + const int supported_versions[], + int num_supported_versions) { int i; /* if version is not set return error */ - if (! requested_version) + if (!requested_version) return -1; /* return the first entry that's equal to the requested version */ diff --git a/mapowscommon.h b/mapowscommon.h index 3869afc3d2..5b1b999ece 100644 --- a/mapowscommon.h +++ b/mapowscommon.h @@ -32,34 +32,35 @@ #ifdef USE_LIBXML2 -#include -#include +#include +#include #endif /* W3C namespaces */ -#define MS_OWSCOMMON_W3C_XLINK_NAMESPACE_URI "http://www.w3.org/1999/xlink" -#define MS_OWSCOMMON_W3C_XLINK_NAMESPACE_PREFIX "xlink" +#define MS_OWSCOMMON_W3C_XLINK_NAMESPACE_URI "http://www.w3.org/1999/xlink" +#define MS_OWSCOMMON_W3C_XLINK_NAMESPACE_PREFIX "xlink" -#define MS_OWSCOMMON_W3C_XSI_NAMESPACE_URI "http://www.w3.org/2001/XMLSchema-instance" -#define MS_OWSCOMMON_W3C_XSI_NAMESPACE_PREFIX "xsi" +#define MS_OWSCOMMON_W3C_XSI_NAMESPACE_URI \ + "http://www.w3.org/2001/XMLSchema-instance" +#define MS_OWSCOMMON_W3C_XSI_NAMESPACE_PREFIX "xsi" -#define MS_OWSCOMMON_W3C_XS_NAMESPACE_URI "http://www.w3.org/2001/XMLSchema" -#define MS_OWSCOMMON_W3C_XS_NAMESPACE_PREFIX "xs" +#define MS_OWSCOMMON_W3C_XS_NAMESPACE_URI "http://www.w3.org/2001/XMLSchema" +#define MS_OWSCOMMON_W3C_XS_NAMESPACE_PREFIX "xs" /* OGC namespaces */ -#define MS_OWSCOMMON_OGC_NAMESPACE_URI "http://www.opengis.net/ogc" -#define MS_OWSCOMMON_OGC_NAMESPACE_PREFIX "ogc" +#define MS_OWSCOMMON_OGC_NAMESPACE_URI "http://www.opengis.net/ogc" +#define MS_OWSCOMMON_OGC_NAMESPACE_PREFIX "ogc" -#define MS_OWSCOMMON_OWS_NAMESPACE_URI "http://www.opengis.net/ows" -#define MS_OWSCOMMON_OWS_NAMESPACE_PREFIX "ows" +#define MS_OWSCOMMON_OWS_NAMESPACE_URI "http://www.opengis.net/ows" +#define MS_OWSCOMMON_OWS_NAMESPACE_PREFIX "ows" -#define MS_OWSCOMMON_OWS_110_NAMESPACE_URI "http://www.opengis.net/ows/1.1" +#define MS_OWSCOMMON_OWS_110_NAMESPACE_URI "http://www.opengis.net/ows/1.1" -#define MS_OWSCOMMON_OWS_20_NAMESPACE_URI "http://www.opengis.net/ows/2.0" -#define MS_OWSCOMMON_OWS_20_SCHEMAS_LOCATION "/ows/2.0/owsAll.xsd" +#define MS_OWSCOMMON_OWS_20_NAMESPACE_URI "http://www.opengis.net/ows/2.0" +#define MS_OWSCOMMON_OWS_20_SCHEMAS_LOCATION "/ows/2.0/owsAll.xsd" /* OGC URNs */ @@ -75,79 +76,80 @@ /* WCS namespaces */ -#define MS_OWSCOMMON_WCS_20_NAMESPACE_URI "http://www.opengis.net/wcs/2.0" -#define MS_OWSCOMMON_WCS_20_SCHEMAS_LOCATION "/wcs/2.0/wcsAll.xsd" -#define MS_OWSCOMMON_WCS_NAMESPACE_PREFIX "wcs" +#define MS_OWSCOMMON_WCS_20_NAMESPACE_URI "http://www.opengis.net/wcs/2.0" +#define MS_OWSCOMMON_WCS_20_SCHEMAS_LOCATION "/wcs/2.0/wcsAll.xsd" +#define MS_OWSCOMMON_WCS_NAMESPACE_PREFIX "wcs" /* GML namespaces */ -#define MS_OWSCOMMON_GML_NAMESPACE_URI "http://www.opengis.net/gml" -#define MS_OWSCOMMON_GML_NAMESPACE_PREFIX "gml" +#define MS_OWSCOMMON_GML_NAMESPACE_URI "http://www.opengis.net/gml" +#define MS_OWSCOMMON_GML_NAMESPACE_PREFIX "gml" -#define MS_OWSCOMMON_GML_32_NAMESPACE_URI "http://www.opengis.net/gml/3.2" +#define MS_OWSCOMMON_GML_32_NAMESPACE_URI "http://www.opengis.net/gml/3.2" -#define MS_OWSCOMMON_GML_212_SCHEMA_LOCATION "/gml/2.1.2/feature.xsd" -#define MS_OWSCOMMON_GML_311_SCHEMA_LOCATION "/gml/3.1.1/base/gml.xsd" -#define MS_OWSCOMMON_GML_321_SCHEMA_LOCATION "/gml/3.2.1/gml.xsd" +#define MS_OWSCOMMON_GML_212_SCHEMA_LOCATION "/gml/2.1.2/feature.xsd" +#define MS_OWSCOMMON_GML_311_SCHEMA_LOCATION "/gml/3.1.1/base/gml.xsd" +#define MS_OWSCOMMON_GML_321_SCHEMA_LOCATION "/gml/3.2.1/gml.xsd" /* WFS namespaces */ -#define MS_OWSCOMMON_WFS_NAMESPACE_PREFIX "wfs" -#define MS_OWSCOMMON_WFS_NAMESPACE_URI "http://www.opengis.net/wfs" -#define MS_OWSCOMMON_WFS_20_NAMESPACE_URI "http://www.opengis.net/wfs/2.0" +#define MS_OWSCOMMON_WFS_NAMESPACE_PREFIX "wfs" +#define MS_OWSCOMMON_WFS_NAMESPACE_URI "http://www.opengis.net/wfs" +#define MS_OWSCOMMON_WFS_20_NAMESPACE_URI "http://www.opengis.net/wfs/2.0" -#define MS_OWSCOMMON_WFS_10_SCHEMA_LOCATION "/wfs/1.0.0/WFS-basic.xsd" -#define MS_OWSCOMMON_WFS_11_SCHEMA_LOCATION "/wfs/1.1.0/wfs.xsd" -#define MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION "/wfs/2.0/wfs.xsd" +#define MS_OWSCOMMON_WFS_10_SCHEMA_LOCATION "/wfs/1.0.0/WFS-basic.xsd" +#define MS_OWSCOMMON_WFS_11_SCHEMA_LOCATION "/wfs/1.1.0/wfs.xsd" +#define MS_OWSCOMMON_WFS_20_SCHEMA_LOCATION "/wfs/2.0/wfs.xsd" /* FES namespaces */ -#define MS_OWSCOMMON_FES_20_NAMESPACE_PREFIX "fes" -#define MS_OWSCOMMON_FES_20_NAMESPACE_URI "http://www.opengis.net/fes/2.0" +#define MS_OWSCOMMON_FES_20_NAMESPACE_PREFIX "fes" +#define MS_OWSCOMMON_FES_20_NAMESPACE_URI "http://www.opengis.net/fes/2.0" -#define MS_OWSCOMMON_FES_20_SCHEMA_LOCATION "/filter/2.0/filterAll.xsd" +#define MS_OWSCOMMON_FES_20_SCHEMA_LOCATION "/filter/2.0/filterAll.xsd" /* GMLCov namespaces */ -#define MS_OWSCOMMON_GMLCOV_10_NAMESPACE_URI "http://www.opengis.net/gmlcov/1.0" -#define MS_OWSCOMMON_GMLCOV_NAMESPACE_PREFIX "gmlcov" +#define MS_OWSCOMMON_GMLCOV_10_NAMESPACE_URI "http://www.opengis.net/gmlcov/1.0" +#define MS_OWSCOMMON_GMLCOV_NAMESPACE_PREFIX "gmlcov" /* SWE namespaces */ -#define MS_OWSCOMMON_SWE_20_NAMESPACE_URI "http://www.opengis.net/swe/2.0" -#define MS_OWSCOMMON_SWE_NAMESPACE_PREFIX "swe" +#define MS_OWSCOMMON_SWE_20_NAMESPACE_URI "http://www.opengis.net/swe/2.0" +#define MS_OWSCOMMON_SWE_NAMESPACE_PREFIX "swe" /* Inspire namespaces */ -#define MS_INSPIRE_COMMON_NAMESPACE_URI "http://inspire.ec.europa.eu/schemas/common/1.0" -#define MS_INSPIRE_COMMON_NAMESPACE_PREFIX "inspire_common" -#define MS_INSPIRE_COMMON_SCHEMA_LOCATION "/common/1.0/common.xsd" +#define MS_INSPIRE_COMMON_NAMESPACE_URI \ + "http://inspire.ec.europa.eu/schemas/common/1.0" +#define MS_INSPIRE_COMMON_NAMESPACE_PREFIX "inspire_common" +#define MS_INSPIRE_COMMON_SCHEMA_LOCATION "/common/1.0/common.xsd" -#define MS_INSPIRE_VS_NAMESPACE_URI "http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" -#define MS_INSPIRE_VS_NAMESPACE_PREFIX "inspire_vs" -#define MS_INSPIRE_VS_SCHEMA_LOCATION "/inspire_vs/1.0/inspire_vs.xsd" - -#define MS_INSPIRE_DLS_NAMESPACE_URI "http://inspire.ec.europa.eu/schemas/inspire_dls/1.0" -#define MS_INSPIRE_DLS_NAMESPACE_PREFIX "inspire_dls" -#define MS_INSPIRE_DLS_SCHEMA_LOCATION "/inspire_dls/1.0/inspire_dls.xsd" +#define MS_INSPIRE_VS_NAMESPACE_URI \ + "http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" +#define MS_INSPIRE_VS_NAMESPACE_PREFIX "inspire_vs" +#define MS_INSPIRE_VS_SCHEMA_LOCATION "/inspire_vs/1.0/inspire_vs.xsd" +#define MS_INSPIRE_DLS_NAMESPACE_URI \ + "http://inspire.ec.europa.eu/schemas/inspire_dls/1.0" +#define MS_INSPIRE_DLS_NAMESPACE_PREFIX "inspire_dls" +#define MS_INSPIRE_DLS_SCHEMA_LOCATION "/inspire_dls/1.0/inspire_dls.xsd" /* MapServer namespaces */ -#define MS_DEFAULT_NAMESPACE_PREFIX "ms" -#define MS_DEFAULT_NAMESPACE_URI "http://mapserver.gis.umn.edu/mapserver" - +#define MS_DEFAULT_NAMESPACE_PREFIX "ms" +#define MS_DEFAULT_NAMESPACE_URI "http://mapserver.gis.umn.edu/mapserver" /* OWS errors */ /* OWS 1.1.0 Table 25 */ -#define MS_OWS_ERROR_OPERATION_NOT_SUPPORTED "OperationNotSupported" -#define MS_OWS_ERROR_MISSING_PARAMETER_VALUE "MissingParameterValue" -#define MS_OWS_ERROR_INVALID_PARAMETER_VALUE "InvalidParameterValue" +#define MS_OWS_ERROR_OPERATION_NOT_SUPPORTED "OperationNotSupported" +#define MS_OWS_ERROR_MISSING_PARAMETER_VALUE "MissingParameterValue" +#define MS_OWS_ERROR_INVALID_PARAMETER_VALUE "InvalidParameterValue" #define MS_OWS_ERROR_VERSION_NEGOTIATION_FAILED "VersionNegotiationFailed" -#define MS_OWS_ERROR_INVALID_UPDATE_SEQUENCE "InvalidUpdateSequence" -#define MS_OWS_ERROR_OPTION_NOT_SUPPORTED "OptionNotSupported" -#define MS_OWS_ERROR_NO_APPLICABLE_CODE "NoApplicableCode" +#define MS_OWS_ERROR_INVALID_UPDATE_SEQUENCE "InvalidUpdateSequence" +#define MS_OWS_ERROR_OPTION_NOT_SUPPORTED "OptionNotSupported" +#define MS_OWS_ERROR_NO_APPLICABLE_CODE "NoApplicableCode" -#define MS_OWS_ERROR_NOT_FOUND "NotFound" +#define MS_OWS_ERROR_NOT_FOUND "NotFound" #define MS_WFS_ERROR_OPERATION_PROCESSING_FAILED "OperationProcessingFailed" @@ -159,42 +161,57 @@ extern "C" { /* function prototypes */ - xmlNodePtr msOWSCommonServiceIdentification(xmlNsPtr psNsOws, mapObj *map, const char *servicetype, const char *version, const char *namespaces, const char *validated_language); -xmlNodePtr msOWSCommonServiceProvider(xmlNsPtr psNsOws, - xmlNsPtr psXLinkNs, - mapObj *map, - const char *namespaces, +xmlNodePtr msOWSCommonServiceProvider(xmlNsPtr psNsOws, xmlNsPtr psXLinkNs, + mapObj *map, const char *namespaces, const char *validated_language); xmlNodePtr msOWSCommonOperationsMetadata(xmlNsPtr psNsOws); -#define OWS_METHOD_GET 1 -#define OWS_METHOD_POST 2 +#define OWS_METHOD_GET 1 +#define OWS_METHOD_POST 2 #define OWS_METHOD_GETPOST 3 -xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, xmlNsPtr psXLinkNs, const char *name, int method, const char *url); +xmlNodePtr msOWSCommonOperationsMetadataOperation(xmlNsPtr psNsOws, + xmlNsPtr psXLinkNs, + const char *name, int method, + const char *url); -xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, xmlNsPtr psNsOws, const char *elname, const char *name, const char *values); +xmlNodePtr msOWSCommonOperationsMetadataDomainType(int version, + xmlNsPtr psNsOws, + const char *elname, + const char *name, + const char *values); -xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, const char *schemas_location, const char *version, const char *language, const char *exceptionCode, const char *locator, const char *ExceptionText); +xmlNodePtr msOWSCommonExceptionReport(xmlNsPtr psNsOws, int ows_version, + const char *schemas_location, + const char *version, const char *language, + const char *exceptionCode, + const char *locator, + const char *ExceptionText); -xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, int dimensions, double minx, double miny, double maxx, double maxy); +xmlNodePtr msOWSCommonBoundingBox(xmlNsPtr psNsOws, const char *crs, + int dimensions, double minx, double miny, + double maxx, double maxy); -xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, double minx, double miny, double maxx, double maxy); +xmlNodePtr msOWSCommonWGS84BoundingBox(xmlNsPtr psNsOws, int dimensions, + double minx, double miny, double maxx, + double maxy); int _validateNamespace(xmlNsPtr psNsOws); -int msOWSSchemaValidation(const char* xml_schema, const char* xml); +int msOWSSchemaValidation(const char *xml_schema, const char *xml); #endif /* defined(USE_LIBXML2) */ -int msOWSCommonNegotiateVersion(int requested_version, const int supported_versions[], int num_supported_versions); +int msOWSCommonNegotiateVersion(int requested_version, + const int supported_versions[], + int num_supported_versions); #ifdef __cplusplus } /* extern C */ diff --git a/mappluginlayer.c b/mappluginlayer.c index 07d9890ad6..9fbd78ed1b 100644 --- a/mappluginlayer.c +++ b/mappluginlayer.c @@ -30,8 +30,6 @@ #include "mapserver.h" #include "mapthread.h" - - typedef struct { char *name; layerVTableObj vtable; @@ -40,15 +38,12 @@ typedef struct { typedef struct { unsigned int size; unsigned int first_free; - VTFactoryItemObj ** vtItems; + VTFactoryItemObj **vtItems; } VTFactoryObj; static VTFactoryObj gVirtualTableFactory = {0, 0, NULL}; - -static VTFactoryItemObj * -createVTFItem(const char *name) -{ +static VTFactoryItemObj *createVTFItem(const char *name) { VTFactoryItemObj *pVTFI; pVTFI = (VTFactoryItemObj *)malloc(sizeof(VTFactoryItemObj)); @@ -60,9 +55,7 @@ createVTFItem(const char *name) return pVTFI; } -static void -destroyVTFItem(VTFactoryItemObj **pVTFI) -{ +static void destroyVTFItem(VTFactoryItemObj **pVTFI) { free((*pVTFI)->name); (*pVTFI)->name = NULL; memset(&(*pVTFI)->vtable, 0, sizeof(layerVTableObj)); @@ -70,13 +63,10 @@ destroyVTFItem(VTFactoryItemObj **pVTFI) *pVTFI = NULL; } - -static VTFactoryItemObj * -lookupVTFItem(VTFactoryObj *VTFactory, - const char *key) -{ +static VTFactoryItemObj *lookupVTFItem(VTFactoryObj *VTFactory, + const char *key) { unsigned int i; - for (i=0; i < VTFactory->size && VTFactory->vtItems[i]; ++i) { + for (i = 0; i < VTFactory->size && VTFactory->vtItems[i]; ++i) { if (0 == strcasecmp(key, VTFactory->vtItems[i]->name)) { return VTFactory->vtItems[i]; } @@ -84,24 +74,24 @@ lookupVTFItem(VTFactoryObj *VTFactory, return NULL; } -static int -insertNewVTFItem(VTFactoryObj *pVTFactory, - VTFactoryItemObj *pVTFI) -{ +static int insertNewVTFItem(VTFactoryObj *pVTFactory, VTFactoryItemObj *pVTFI) { /* Ensure there is room for one more item in the array * (safe to use for initial alloc of the array as well) */ if (pVTFactory->first_free == pVTFactory->size) { VTFactoryItemObj **vtItemPtr; - vtItemPtr = (VTFactoryItemObj**)realloc(pVTFactory->vtItems, - (pVTFactory->size+MS_LAYER_ALLOCSIZE)*sizeof(VTFactoryItemObj*)); - MS_CHECK_ALLOC(vtItemPtr, (pVTFactory->size+MS_LAYER_ALLOCSIZE)*sizeof(VTFactoryItemObj*), MS_FAILURE); - + vtItemPtr = (VTFactoryItemObj **)realloc( + pVTFactory->vtItems, + (pVTFactory->size + MS_LAYER_ALLOCSIZE) * sizeof(VTFactoryItemObj *)); + MS_CHECK_ALLOC(vtItemPtr, + (pVTFactory->size + MS_LAYER_ALLOCSIZE) * + sizeof(VTFactoryItemObj *), + MS_FAILURE); pVTFactory->size += MS_LAYER_ALLOCSIZE; pVTFactory->vtItems = vtItemPtr; - for (unsigned i=pVTFactory->first_free; isize; i++) + for (unsigned i = pVTFactory->first_free; i < pVTFactory->size; i++) pVTFactory->vtItems[i] = NULL; } @@ -112,27 +102,29 @@ insertNewVTFItem(VTFactoryObj *pVTFactory, return MS_SUCCESS; } -static VTFactoryItemObj * -loadCustomLayerDLL(layerObj *layer, const char *library_path) -{ +static VTFactoryItemObj *loadCustomLayerDLL(layerObj *layer, + const char *library_path) { int (*pfnPluginInitVTable)(layerVTableObj *, layerObj *); VTFactoryItemObj *pVTFI; - pfnPluginInitVTable = msGetSymbol(library_path, "PluginInitializeVirtualTable"); - if ( ! pfnPluginInitVTable) { - msSetError(MS_MISCERR, "Failed to load dynamic Layer LIB: %s", "loadCustomLayerDLL", library_path); + pfnPluginInitVTable = + msGetSymbol(library_path, "PluginInitializeVirtualTable"); + if (!pfnPluginInitVTable) { + msSetError(MS_MISCERR, "Failed to load dynamic Layer LIB: %s", + "loadCustomLayerDLL", library_path); return NULL; } pVTFI = createVTFItem(library_path); - if ( ! pVTFI) { + if (!pVTFI) { return NULL; } if (pfnPluginInitVTable(&pVTFI->vtable, layer)) { destroyVTFItem(&pVTFI); - msSetError(MS_MISCERR, "Failed to initialize dynamic Layer: %s", "loadCustomLayerDLL", library_path); + msSetError(MS_MISCERR, "Failed to initialize dynamic Layer: %s", + "loadCustomLayerDLL", library_path); return NULL; } return pVTFI; @@ -149,53 +141,80 @@ loadCustomLayerDLL(layerObj *layer, const char *library_path) * Because of that, it is possible for plugin layer to use default * layer API default functions, just leave those function pointers to NULL. */ -static void -copyVirtualTable(layerVTableObj *dest, - const layerVTableObj *src) -{ - dest->LayerTranslateFilter = src->LayerTranslateFilter ? src->LayerTranslateFilter : dest->LayerTranslateFilter; - dest->LayerSupportsCommonFilters = src->LayerSupportsCommonFilters ? src->LayerSupportsCommonFilters : dest->LayerSupportsCommonFilters; - dest->LayerInitItemInfo = src->LayerInitItemInfo ? src->LayerInitItemInfo : dest->LayerInitItemInfo; - dest->LayerFreeItemInfo = src->LayerFreeItemInfo ? src->LayerFreeItemInfo : dest->LayerFreeItemInfo; +static void copyVirtualTable(layerVTableObj *dest, const layerVTableObj *src) { + dest->LayerTranslateFilter = src->LayerTranslateFilter + ? src->LayerTranslateFilter + : dest->LayerTranslateFilter; + dest->LayerSupportsCommonFilters = src->LayerSupportsCommonFilters + ? src->LayerSupportsCommonFilters + : dest->LayerSupportsCommonFilters; + dest->LayerInitItemInfo = + src->LayerInitItemInfo ? src->LayerInitItemInfo : dest->LayerInitItemInfo; + dest->LayerFreeItemInfo = + src->LayerFreeItemInfo ? src->LayerFreeItemInfo : dest->LayerFreeItemInfo; dest->LayerOpen = src->LayerOpen ? src->LayerOpen : dest->LayerOpen; dest->LayerIsOpen = src->LayerIsOpen ? src->LayerIsOpen : dest->LayerIsOpen; - dest->LayerWhichShapes = src->LayerWhichShapes ? src->LayerWhichShapes : dest->LayerWhichShapes; - dest->LayerNextShape = src->LayerNextShape ? src->LayerNextShape : dest->LayerNextShape; - dest->LayerGetShape = src->LayerGetShape ? src->LayerGetShape : dest->LayerGetShape; - /* dest->LayerResultsGetShape = src->LayerResultsGetShape ? src->LayerResultsGetShape : dest->LayerResultsGetShape; */ - dest->LayerGetShapeCount = src->LayerGetShapeCount ? src->LayerGetShapeCount : dest->LayerGetShapeCount; + dest->LayerWhichShapes = + src->LayerWhichShapes ? src->LayerWhichShapes : dest->LayerWhichShapes; + dest->LayerNextShape = + src->LayerNextShape ? src->LayerNextShape : dest->LayerNextShape; + dest->LayerGetShape = + src->LayerGetShape ? src->LayerGetShape : dest->LayerGetShape; + /* dest->LayerResultsGetShape = src->LayerResultsGetShape ? + * src->LayerResultsGetShape : dest->LayerResultsGetShape; */ + dest->LayerGetShapeCount = src->LayerGetShapeCount ? src->LayerGetShapeCount + : dest->LayerGetShapeCount; dest->LayerClose = src->LayerClose ? src->LayerClose : dest->LayerClose; - dest->LayerGetItems = src->LayerGetItems ? src->LayerGetItems : dest->LayerGetItems; - dest->LayerGetExtent = src->LayerGetExtent ? src->LayerGetExtent : dest->LayerGetExtent; - dest->LayerGetAutoStyle = src->LayerGetAutoStyle ? src->LayerGetAutoStyle : dest->LayerGetAutoStyle; - dest->LayerCloseConnection = src->LayerCloseConnection ? src->LayerCloseConnection : dest->LayerCloseConnection; - dest->LayerSetTimeFilter = src->LayerSetTimeFilter ? src->LayerSetTimeFilter : dest->LayerSetTimeFilter; - dest->LayerApplyFilterToLayer = src->LayerApplyFilterToLayer ? src->LayerApplyFilterToLayer : dest->LayerApplyFilterToLayer; - dest->LayerCreateItems = src->LayerCreateItems ? src->LayerCreateItems : dest->LayerCreateItems; - dest->LayerGetNumFeatures = src->LayerGetNumFeatures ? src->LayerGetNumFeatures : dest->LayerGetNumFeatures; - dest->LayerGetAutoProjection = src->LayerGetAutoProjection ? src->LayerGetAutoProjection: dest->LayerGetAutoProjection; - dest->LayerEscapeSQLParam = src->LayerEscapeSQLParam ? src->LayerEscapeSQLParam: dest->LayerEscapeSQLParam; - dest->LayerEscapePropertyName = src->LayerEscapePropertyName ? src->LayerEscapePropertyName: dest->LayerEscapePropertyName; - dest->LayerEscapeSQLParam = src->LayerEscapeSQLParam ? src->LayerEscapeSQLParam: dest->LayerEscapeSQLParam; - dest->LayerEnablePaging = src->LayerEnablePaging ? src->LayerEnablePaging: dest->LayerEnablePaging; - dest->LayerGetPaging = src->LayerGetPaging ? src->LayerGetPaging: dest->LayerGetPaging; + dest->LayerGetItems = + src->LayerGetItems ? src->LayerGetItems : dest->LayerGetItems; + dest->LayerGetExtent = + src->LayerGetExtent ? src->LayerGetExtent : dest->LayerGetExtent; + dest->LayerGetAutoStyle = + src->LayerGetAutoStyle ? src->LayerGetAutoStyle : dest->LayerGetAutoStyle; + dest->LayerCloseConnection = src->LayerCloseConnection + ? src->LayerCloseConnection + : dest->LayerCloseConnection; + dest->LayerSetTimeFilter = src->LayerSetTimeFilter ? src->LayerSetTimeFilter + : dest->LayerSetTimeFilter; + dest->LayerApplyFilterToLayer = src->LayerApplyFilterToLayer + ? src->LayerApplyFilterToLayer + : dest->LayerApplyFilterToLayer; + dest->LayerCreateItems = + src->LayerCreateItems ? src->LayerCreateItems : dest->LayerCreateItems; + dest->LayerGetNumFeatures = src->LayerGetNumFeatures + ? src->LayerGetNumFeatures + : dest->LayerGetNumFeatures; + dest->LayerGetAutoProjection = src->LayerGetAutoProjection + ? src->LayerGetAutoProjection + : dest->LayerGetAutoProjection; + dest->LayerEscapeSQLParam = src->LayerEscapeSQLParam + ? src->LayerEscapeSQLParam + : dest->LayerEscapeSQLParam; + dest->LayerEscapePropertyName = src->LayerEscapePropertyName + ? src->LayerEscapePropertyName + : dest->LayerEscapePropertyName; + dest->LayerEscapeSQLParam = src->LayerEscapeSQLParam + ? src->LayerEscapeSQLParam + : dest->LayerEscapeSQLParam; + dest->LayerEnablePaging = + src->LayerEnablePaging ? src->LayerEnablePaging : dest->LayerEnablePaging; + dest->LayerGetPaging = + src->LayerGetPaging ? src->LayerGetPaging : dest->LayerGetPaging; } -int -msPluginLayerInitializeVirtualTable(layerObj *layer) -{ +int msPluginLayerInitializeVirtualTable(layerObj *layer) { VTFactoryItemObj *pVTFI; - if (!layer->plugin_library){ - return MS_FAILURE; + if (!layer->plugin_library) { + return MS_FAILURE; } msAcquireLock(TLOCK_LAYER_VTABLE); pVTFI = lookupVTFItem(&gVirtualTableFactory, layer->plugin_library); - if ( ! pVTFI) { + if (!pVTFI) { pVTFI = loadCustomLayerDLL(layer, layer->plugin_library); - if ( ! pVTFI) { + if (!pVTFI) { msReleaseLock(TLOCK_LAYER_VTABLE); return MS_FAILURE; } @@ -214,12 +233,10 @@ msPluginLayerInitializeVirtualTable(layerObj *layer) /* msPluginFreeVirtualTableFactory() ** Called by msCleanup() to free the virtual table factory */ -void -msPluginFreeVirtualTableFactory() -{ +void msPluginFreeVirtualTableFactory() { msAcquireLock(TLOCK_LAYER_VTABLE); - for (unsigned i=0; idebug ) - msDebug( "msConnPoolRegister(%s,%s,%p)\n", - layer->name, layer->connection, conn_handle ); + if (layer->debug) + msDebug("msConnPoolRegister(%s,%s,%p)\n", layer->name, layer->connection, + conn_handle); /* -------------------------------------------------------------------- */ /* We can't meaningful keep a connection with no connection or */ /* connection type string on the layer. */ /* -------------------------------------------------------------------- */ - if( layer->connection == NULL ) { - if( layer->tileindex != NULL - && layer->connectiontype == MS_OGR ) { + if (layer->connection == NULL) { + if (layer->tileindex != NULL && layer->connectiontype == MS_OGR) { /* this is ok, no need to make a fuss */ } else { - msDebug( "%s: Missing CONNECTION on layer %s.\n", - "msConnPoolRegister()", - layer->name ); - - msSetError( MS_MISCERR, - "Missing CONNECTION on layer %s.", - "msConnPoolRegister()", - layer->name ); + msDebug("%s: Missing CONNECTION on layer %s.\n", "msConnPoolRegister()", + layer->name); + + msSetError(MS_MISCERR, "Missing CONNECTION on layer %s.", + "msConnPoolRegister()", layer->name); } return; } @@ -209,16 +203,15 @@ void msConnPoolRegister( layerObj *layer, /* -------------------------------------------------------------------- */ /* Grow the array of connection information objects if needed. */ /* -------------------------------------------------------------------- */ - msAcquireLock( TLOCK_POOL ); + msAcquireLock(TLOCK_POOL); - if( connectionCount == connectionMax ) { + if (connectionCount == connectionMax) { connectionMax += 10; - connectionObj* newConnections = (connectionObj *) - realloc(connections, - sizeof(connectionObj) * connectionMax ); - if( newConnections == NULL ) { + connectionObj *newConnections = (connectionObj *)realloc( + connections, sizeof(connectionObj) * connectionMax); + if (newConnections == NULL) { msSetError(MS_MEMERR, NULL, "msConnPoolRegister()"); - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); return; } connections = newConnections; @@ -232,7 +225,7 @@ void msConnPoolRegister( layerObj *layer, connectionCount++; conn->connectiontype = layer->connectiontype; - conn->connection = msStrdup( layer->connection ); + conn->connection = msStrdup(layer->connection); conn->close = close_func; conn->ref_count = 1; conn->thread_id = msGetThreadId(); @@ -243,30 +236,28 @@ void msConnPoolRegister( layerObj *layer, /* -------------------------------------------------------------------- */ /* Categorize the connection handling information. */ /* -------------------------------------------------------------------- */ - close_connection = - msLayerGetProcessingKey( layer, "CLOSE_CONNECTION" ); + close_connection = msLayerGetProcessingKey(layer, "CLOSE_CONNECTION"); - if( close_connection == NULL ) + if (close_connection == NULL) close_connection = "NORMAL"; - if( strcasecmp(close_connection,"NORMAL") == 0 ) + if (strcasecmp(close_connection, "NORMAL") == 0) conn->lifespan = MS_LIFE_ZEROREF; - else if( strcasecmp(close_connection,"DEFER") == 0 ) + else if (strcasecmp(close_connection, "DEFER") == 0) conn->lifespan = MS_LIFE_FOREVER; - else if( strcasecmp(close_connection,"ALWAYS") == 0 ) + else if (strcasecmp(close_connection, "ALWAYS") == 0) conn->lifespan = MS_LIFE_SINGLE; else { msDebug("msConnPoolRegister(): " "Unrecognised CLOSE_CONNECTION value '%s'\n", - close_connection ); + close_connection); - msSetError( MS_MISCERR, "Unrecognised CLOSE_CONNECTION value '%s'", - "msConnPoolRegister()", - close_connection ); + msSetError(MS_MISCERR, "Unrecognised CLOSE_CONNECTION value '%s'", + "msConnPoolRegister()", close_connection); conn->lifespan = MS_LIFE_ZEROREF; } - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); } /************************************************************************/ @@ -277,45 +268,40 @@ void msConnPoolRegister( layerObj *layer, /* well. */ /************************************************************************/ -static void msConnPoolClose( int conn_index ) +static void msConnPoolClose(int conn_index) { connectionObj *conn = connections + conn_index; - if( conn->ref_count > 0 ) { - if( conn->debug ) - msDebug( "msConnPoolClose(): " - "Closing connection %s even though ref_count=%d.\n", - conn->connection, conn->ref_count ); - - msSetError( MS_MISCERR, - "Closing connection %s even though ref_count=%d.", - "msConnPoolClose()", - conn->connection, - conn->ref_count ); + if (conn->ref_count > 0) { + if (conn->debug) + msDebug("msConnPoolClose(): " + "Closing connection %s even though ref_count=%d.\n", + conn->connection, conn->ref_count); + + msSetError(MS_MISCERR, "Closing connection %s even though ref_count=%d.", + "msConnPoolClose()", conn->connection, conn->ref_count); } - if( conn->debug ) - msDebug( "msConnPoolClose(%s,%p)\n", - conn->connection, conn->conn_handle ); + if (conn->debug) + msDebug("msConnPoolClose(%s,%p)\n", conn->connection, conn->conn_handle); - if( conn->close != NULL ) - conn->close( conn->conn_handle ); + if (conn->close != NULL) + conn->close(conn->conn_handle); /* free malloced() stuff in this connection */ - free( conn->connection ); + free(conn->connection); connectionCount--; - if( connectionCount == 0 ) { + if (connectionCount == 0) { /* if there are no connections left we will "cleanup". */ connectionMax = 0; - free( connections ); + free(connections); connections = NULL; } else { /* move the last connection in place of our now closed one */ - memcpy( connections + conn_index, - connections + connectionCount, - sizeof(connectionObj) ); + memcpy(connections + conn_index, connections + connectionCount, + sizeof(connectionObj)); } } @@ -328,48 +314,48 @@ static void msConnPoolClose( int conn_index ) /* return NULL. */ /************************************************************************/ -void *msConnPoolRequest( layerObj *layer ) +void *msConnPoolRequest(layerObj *layer) { - int i; - const char* close_connection; + int i; + const char *close_connection; - if( layer->connection == NULL ) + if (layer->connection == NULL) return NULL; /* check if we must always create a new connection */ - close_connection = msLayerGetProcessingKey( layer, "CLOSE_CONNECTION" ); - if( close_connection && strcasecmp(close_connection,"ALWAYS") == 0 ) + close_connection = msLayerGetProcessingKey(layer, "CLOSE_CONNECTION"); + if (close_connection && strcasecmp(close_connection, "ALWAYS") == 0) return NULL; - msAcquireLock( TLOCK_POOL ); - for( i = 0; i < connectionCount; i++ ) { + msAcquireLock(TLOCK_POOL); + for (i = 0; i < connectionCount; i++) { connectionObj *conn = connections + i; - if( layer->connectiontype == conn->connectiontype - && strcasecmp( layer->connection, conn->connection ) == 0 - && (conn->ref_count == 0 || conn->thread_id == msGetThreadId()) - && conn->lifespan != MS_LIFE_SINGLE) { + if (layer->connectiontype == conn->connectiontype && + strcasecmp(layer->connection, conn->connection) == 0 && + (conn->ref_count == 0 || conn->thread_id == msGetThreadId()) && + conn->lifespan != MS_LIFE_SINGLE) { void *conn_handle = NULL; conn->ref_count++; conn->thread_id = msGetThreadId(); conn->last_used = time(NULL); - if( layer->debug ) { - msDebug( "msConnPoolRequest(%s,%s) -> got %p\n", - layer->name, layer->connection, conn->conn_handle ); + if (layer->debug) { + msDebug("msConnPoolRequest(%s,%s) -> got %p\n", layer->name, + layer->connection, conn->conn_handle); conn->debug = layer->debug; } conn_handle = conn->conn_handle; - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); return conn_handle; } } - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); return NULL; } @@ -383,49 +369,47 @@ void *msConnPoolRequest( layerObj *layer ) /* acquired the pool lock. */ /************************************************************************/ -void msConnPoolRelease( layerObj *layer, void *conn_handle ) +void msConnPoolRelease(layerObj *layer, void *conn_handle) { - int i; + int i; - if( layer->debug ) - msDebug( "msConnPoolRelease(%s,%s,%p)\n", - layer->name, layer->connection, conn_handle ); + if (layer->debug) + msDebug("msConnPoolRelease(%s,%s,%p)\n", layer->name, layer->connection, + conn_handle); - if( layer->connection == NULL ) + if (layer->connection == NULL) return; - msAcquireLock( TLOCK_POOL ); - for( i = 0; i < connectionCount; i++ ) { + msAcquireLock(TLOCK_POOL); + for (i = 0; i < connectionCount; i++) { connectionObj *conn = connections + i; - if( layer->connectiontype == conn->connectiontype - && strcasecmp( layer->connection, conn->connection ) == 0 - && conn->conn_handle == conn_handle ) { + if (layer->connectiontype == conn->connectiontype && + strcasecmp(layer->connection, conn->connection) == 0 && + conn->conn_handle == conn_handle) { conn->ref_count--; conn->last_used = time(NULL); - if( conn->ref_count == 0 ) + if (conn->ref_count == 0) conn->thread_id = 0; - if( conn->ref_count == 0 && (conn->lifespan == MS_LIFE_ZEROREF || conn->lifespan == MS_LIFE_SINGLE) ) - msConnPoolClose( i ); + if (conn->ref_count == 0 && (conn->lifespan == MS_LIFE_ZEROREF || + conn->lifespan == MS_LIFE_SINGLE)) + msConnPoolClose(i); - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); return; } } - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); - msDebug( "%s: Unable to find handle for layer '%s'.\n", - "msConnPoolRelease()", - layer->name ); + msDebug("%s: Unable to find handle for layer '%s'.\n", "msConnPoolRelease()", + layer->name); - msSetError( MS_MISCERR, - "Unable to find handle for layer '%s'.", - "msConnPoolRelease()", - layer->name ); + msSetError(MS_MISCERR, "Unable to find handle for layer '%s'.", + "msConnPoolRelease()", layer->name); } /************************************************************************/ @@ -437,22 +421,22 @@ void msConnPoolRelease( layerObj *layer, void *conn_handle ) void msConnPoolCloseUnreferenced() { - int i; + int i; /* this really needs to be commented out before commiting. */ /* msDebug( "msConnPoolCloseUnreferenced()\n" ); */ - msAcquireLock( TLOCK_POOL ); - for( i = connectionCount - 1; i >= 0; i-- ) { + msAcquireLock(TLOCK_POOL); + for (i = connectionCount - 1; i >= 0; i--) { connectionObj *conn = connections + i; - if( conn->ref_count == 0 ) { + if (conn->ref_count == 0) { /* for now we don't assume the locks are re-entrant, so release */ /* it so msConnPoolClose() can get it. */ - msConnPoolClose( i ); + msConnPoolClose(i); } } - msReleaseLock( TLOCK_POOL ); + msReleaseLock(TLOCK_POOL); } /************************************************************************/ @@ -468,8 +452,8 @@ void msConnPoolFinalCleanup() /* this really needs to be commented out before commiting. */ /* msDebug( "msConnPoolFinalCleanup()\n" ); */ - msAcquireLock( TLOCK_POOL ); - while( connectionCount > 0 ) - msConnPoolClose( 0 ); - msReleaseLock( TLOCK_POOL ); + msAcquireLock(TLOCK_POOL); + while (connectionCount > 0) + msConnPoolClose(0); + msReleaseLock(TLOCK_POOL); } diff --git a/mappostgis.cpp b/mappostgis.cpp index b21fafce0d..7c06282b5d 100644 --- a/mappostgis.cpp +++ b/mappostgis.cpp @@ -45,7 +45,8 @@ ** as the client endianness. ** ** msPostGISLayerWhichShapes creates SQL based on DATA and LAYER state, -** executes it, and places the un-read PGresult handle in the layerinfo->pgresult, +** executes it, and places the un-read PGresult handle in the +*layerinfo->pgresult, ** setting the layerinfo->rownum to 0. ** ** msPostGISNextShape reads a row, increments layerinfo->rownum, and returns @@ -67,7 +68,7 @@ #include #define FP_EPSILON 1e-12 -#define FP_EQ(a, b) (fabs((a)-(b)) < FP_EPSILON) +#define FP_EQ(a, b) (fabs((a) - (b)) < FP_EPSILON) #define FP_LEFT -1 #define FP_RIGHT 1 #define FP_COLINEAR 0 @@ -78,8 +79,8 @@ #define WKBZOFFSET_NONISO 0x80000000 #define WKBMOFFSET_NONISO 0x40000000 -#define HAS_Z 0x1 -#define HAS_M 0x2 +#define HAS_Z 0x1 +#define HAS_M 0x2 #if TRANSFER_ENCODING == 256 #define RESULTSET_TYPE 1 @@ -91,43 +92,44 @@ /* They were copied from pg_type.h in src/include/catalog/pg_type.h */ #ifndef BOOLOID -#define BOOLOID 16 -#define BYTEAOID 17 -#define CHAROID 18 -#define NAMEOID 19 -#define INT8OID 20 -#define INT2OID 21 -#define INT2VECTOROID 22 -#define INT4OID 23 -#define REGPROCOID 24 -#define TEXTOID 25 -#define OIDOID 26 -#define TIDOID 27 -#define XIDOID 28 -#define CIDOID 29 -#define OIDVECTOROID 30 -#define FLOAT4OID 700 -#define FLOAT8OID 701 -#define INT4ARRAYOID 1007 -#define TEXTARRAYOID 1009 -#define BPCHARARRAYOID 1014 -#define VARCHARARRAYOID 1015 -#define FLOAT4ARRAYOID 1021 -#define FLOAT8ARRAYOID 1022 -#define BPCHAROID 1042 -#define VARCHAROID 1043 -#define DATEOID 1082 -#define TIMEOID 1083 -#define TIMETZOID 1266 -#define TIMESTAMPOID 1114 -#define TIMESTAMPTZOID 1184 -#define NUMERICOID 1700 +#define BOOLOID 16 +#define BYTEAOID 17 +#define CHAROID 18 +#define NAMEOID 19 +#define INT8OID 20 +#define INT2OID 21 +#define INT2VECTOROID 22 +#define INT4OID 23 +#define REGPROCOID 24 +#define TEXTOID 25 +#define OIDOID 26 +#define TIDOID 27 +#define XIDOID 28 +#define CIDOID 29 +#define OIDVECTOROID 30 +#define FLOAT4OID 700 +#define FLOAT8OID 701 +#define INT4ARRAYOID 1007 +#define TEXTARRAYOID 1009 +#define BPCHARARRAYOID 1014 +#define VARCHARARRAYOID 1015 +#define FLOAT4ARRAYOID 1021 +#define FLOAT8ARRAYOID 1022 +#define BPCHAROID 1042 +#define VARCHAROID 1043 +#define DATEOID 1082 +#define TIMEOID 1083 +#define TIMETZOID 1266 +#define TIMESTAMPOID 1114 +#define TIMESTAMPTZOID 1184 +#define NUMERICOID 1700 #endif #ifdef USE_POSTGIS static int wkbConvGeometryToShape(wkbObj *w, shapeObj *shape); -static int arcStrokeCircularString(wkbObj *w, double segment_angle, lineObj *line, int nZMFlag); +static int arcStrokeCircularString(wkbObj *w, double segment_angle, + lineObj *line, int nZMFlag); /* ** msPostGISCloseConnection() @@ -135,16 +137,14 @@ static int arcStrokeCircularString(wkbObj *w, double segment_angle, lineObj *lin ** Handler registered witih msConnPoolRegister so that Mapserver ** can clean up open connections during a shutdown. */ -static void msPostGISCloseConnection(void *pgconn) -{ - PQfinish((PGconn*)pgconn); +static void msPostGISCloseConnection(void *pgconn) { + PQfinish((PGconn *)pgconn); } /* ** msPostGISCreateLayerInfo() */ -static msPostGISLayerInfo *msPostGISCreateLayerInfo(void) -{ +static msPostGISLayerInfo *msPostGISCreateLayerInfo(void) { msPostGISLayerInfo *layerinfo = new msPostGISLayerInfo; layerinfo->paging = MS_TRUE; layerinfo->force2d = MS_FALSE; @@ -154,38 +154,35 @@ static msPostGISLayerInfo *msPostGISCreateLayerInfo(void) /* ** msPostGISFreeLayerInfo() */ -static void msPostGISFreeLayerInfo(layerObj *layer) -{ - msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo*)layer->layerinfo; - if ( layerinfo->pgresult ) PQclear(layerinfo->pgresult); - if ( layerinfo->pgconn ) msConnPoolRelease(layer, layerinfo->pgconn); +static void msPostGISFreeLayerInfo(layerObj *layer) { + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + if (layerinfo->pgresult) + PQclear(layerinfo->pgresult); + if (layerinfo->pgconn) + msConnPoolRelease(layer, layerinfo->pgconn); delete layerinfo; layer->layerinfo = nullptr; } - /* ** postgresqlNoticeHandler() ** ** Propagate messages from the database to the Mapserver log, ** set in PQsetNoticeProcessor during layer open. */ -static void postresqlNoticeHandler(void *arg, const char *message) -{ - layerObj *lp = (layerObj*)arg; +static void postresqlNoticeHandler(void *arg, const char *message) { + layerObj *lp = (layerObj *)arg; if (lp->debug) { msDebug("%s\n", message); } } - /* ** Expandable pointObj array. The lineObj unfortunately ** is not useful for this purpose, so we have this one. */ -static std::vector pointArrayNew(int maxpoints) -{ +static std::vector pointArrayNew(int maxpoints) { auto v = std::vector(); v.reserve(maxpoints); return v; @@ -194,9 +191,7 @@ static std::vector pointArrayNew(int maxpoints) /* ** Add a pointObj to the pointObjArray. */ -static void -pointArrayAddPoint(std::vector& v, const pointObj& p) -{ +static void pointArrayAddPoint(std::vector &v, const pointObj &p) { v.push_back(p); } @@ -205,44 +200,37 @@ pointArrayAddPoint(std::vector& v, const pointObj& p) ** type map array to handle the pre-2.0 incorrect WKB types */ -static int -wkbTypeMap(wkbObj *w, int type, int* pnZMFlag) -{ +static int wkbTypeMap(wkbObj *w, int type, int *pnZMFlag) { *pnZMFlag = 0; /* PostGIS >= 2 : ISO SQL/MM style Z types ? */ - if( type >= 1000 && type < 2000 ) - { + if (type >= 1000 && type < 2000) { type -= 1000; *pnZMFlag = HAS_Z; } /* PostGIS >= 2 : ISO SQL/MM style M types ? */ - else if( type >= 2000 && type < 3000 ) - { + else if (type >= 2000 && type < 3000) { type -= 2000; *pnZMFlag = HAS_M; } /* PostGIS >= 2 : ISO SQL/MM style ZM types ? */ - else if( type >= 3000 && type < 4000 ) - { + else if (type >= 3000 && type < 4000) { type -= 3000; *pnZMFlag = HAS_Z | HAS_M; } /* PostGIS 1.X EWKB : Extended WKB Z or ZM ? */ - else if( (type & WKBZOFFSET_NONISO) != 0 ) - { - if( (type & WKBMOFFSET_NONISO) != 0 ) - *pnZMFlag = HAS_Z | HAS_M; + else if ((type & WKBZOFFSET_NONISO) != 0) { + if ((type & WKBMOFFSET_NONISO) != 0) + *pnZMFlag = HAS_Z | HAS_M; else - *pnZMFlag = HAS_Z; + *pnZMFlag = HAS_Z; type &= 0x00FFFFFF; } /* PostGIS 1.X EWKB: Extended WKB M ? */ - else if( (type & WKBMOFFSET_NONISO) != 0 ) - { + else if ((type & WKBMOFFSET_NONISO) != 0) { *pnZMFlag = HAS_M; type &= 0x00FFFFFF; } - if ( type >= 0 && type < WKB_TYPE_COUNT ) + if (type >= 0 && type < WKB_TYPE_COUNT) return w->typemap[type]; else return 0; @@ -252,32 +240,26 @@ wkbTypeMap(wkbObj *w, int type, int* pnZMFlag) ** Read the WKB type number from a wkbObj without ** advancing the read pointer. */ -static int -wkbType(wkbObj *w, int* pnZMFlag) -{ +static int wkbType(wkbObj *w, int *pnZMFlag) { int t; memcpy(&t, (w->ptr + 1), sizeof(int)); - return wkbTypeMap(w,t, pnZMFlag); + return wkbTypeMap(w, t, pnZMFlag); } /* ** Read the type number of the first element of a ** collection without advancing the read pointer. */ -static int -wkbCollectionSubType(wkbObj *w, int* pnZMFlag) -{ +static int wkbCollectionSubType(wkbObj *w, int *pnZMFlag) { int t; memcpy(&t, (w->ptr + 1 + 4 + 4 + 1), sizeof(int)); - return wkbTypeMap(w,t, pnZMFlag); + return wkbTypeMap(w, t, pnZMFlag); } /* ** Read one byte from the WKB and advance the read pointer */ -static char -wkbReadChar(wkbObj *w) -{ +static char wkbReadChar(wkbObj *w) { char c; memcpy(&c, w->ptr, sizeof(char)); w->ptr += sizeof(char); @@ -288,9 +270,7 @@ wkbReadChar(wkbObj *w) ** Read one integer from the WKB and advance the read pointer. ** We assume the endianess of the WKB is the same as this machine. */ -static inline int -wkbReadInt(wkbObj *w) -{ +static inline int wkbReadInt(wkbObj *w) { int i; memcpy(&i, w->ptr, sizeof(int)); w->ptr += sizeof(int); @@ -301,30 +281,22 @@ wkbReadInt(wkbObj *w) ** Read one pointObj (two doubles) from the WKB and advance the read pointer. ** We assume the endianess of the WKB is the same as this machine. */ -static inline void -wkbReadPointP(wkbObj *w, pointObj *p, int nZMFlag) -{ +static inline void wkbReadPointP(wkbObj *w, pointObj *p, int nZMFlag) { memcpy(&(p->x), w->ptr, sizeof(double)); w->ptr += sizeof(double); memcpy(&(p->y), w->ptr, sizeof(double)); w->ptr += sizeof(double); - if( nZMFlag & HAS_Z ) - { - memcpy(&(p->z), w->ptr, sizeof(double)); - w->ptr += sizeof(double); - } - else - { - p->z = 0; - } - if( nZMFlag & HAS_M ) - { - memcpy(&(p->m), w->ptr, sizeof(double)); - w->ptr += sizeof(double); + if (nZMFlag & HAS_Z) { + memcpy(&(p->z), w->ptr, sizeof(double)); + w->ptr += sizeof(double); + } else { + p->z = 0; } - else - { - p->m = 0; + if (nZMFlag & HAS_M) { + memcpy(&(p->m), w->ptr, sizeof(double)); + w->ptr += sizeof(double); + } else { + p->m = 0; } } @@ -332,9 +304,7 @@ wkbReadPointP(wkbObj *w, pointObj *p, int nZMFlag) ** Read one pointObj (two doubles) from the WKB and advance the read pointer. ** We assume the endianess of the WKB is the same as this machine. */ -static inline pointObj -wkbReadPoint(wkbObj *w, int nZMFlag) -{ +static inline pointObj wkbReadPoint(wkbObj *w, int nZMFlag) { pointObj p; wkbReadPointP(w, &p, nZMFlag); return p; @@ -347,17 +317,15 @@ wkbReadPoint(wkbObj *w, int nZMFlag) ** Linestrings, circular strings, polygon rings, all show this ** form. */ -static void -wkbReadLine(wkbObj *w, lineObj *line, int nZMFlag) -{ +static void wkbReadLine(wkbObj *w, lineObj *line, int nZMFlag) { pointObj p; const int npoints = wkbReadInt(w); - if( npoints > (int)((w->size - (w->ptr - w->wkb)) / 16) ) + if (npoints > (int)((w->size - (w->ptr - w->wkb)) / 16)) return; line->numpoints = npoints; - line->point =(pointObj*) msSmallMalloc(npoints * sizeof(pointObj)); - for ( int i = 0; i < npoints; i++ ) { + line->point = (pointObj *)msSmallMalloc(npoints * sizeof(pointObj)); + for (int i = 0; i < npoints; i++) { wkbReadPointP(w, &p, nZMFlag); line->point[i] = p; } @@ -367,68 +335,67 @@ wkbReadLine(wkbObj *w, lineObj *line, int nZMFlag) ** Advance the read pointer past a geometry without returning any ** values. Used for skipping un-drawable elements in a collection. */ -static void -wkbSkipGeometry(wkbObj *w) -{ - /*endian = */wkbReadChar(w); +static void wkbSkipGeometry(wkbObj *w) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); - const int nCoordDim = 2 + (((nZMFlag & HAS_Z) != 0) ? 1 : 0) + (((nZMFlag & HAS_M) != 0) ? 1 : 0); - switch(type) { - case WKB_POINT: - w->ptr += nCoordDim * sizeof(double); - break; - case WKB_CIRCULARSTRING: - case WKB_LINESTRING: { + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); + const int nCoordDim = 2 + (((nZMFlag & HAS_Z) != 0) ? 1 : 0) + + (((nZMFlag & HAS_M) != 0) ? 1 : 0); + switch (type) { + case WKB_POINT: + w->ptr += nCoordDim * sizeof(double); + break; + case WKB_CIRCULARSTRING: + case WKB_LINESTRING: { + const int npoints = wkbReadInt(w); + w->ptr += npoints * nCoordDim * sizeof(double); + break; + } + case WKB_POLYGON: { + const int nrings = wkbReadInt(w); + if (nrings > (int)((w->size - (w->ptr - w->wkb)) / 4)) + return; + for (int i = 0; i < nrings; i++) { const int npoints = wkbReadInt(w); w->ptr += npoints * nCoordDim * sizeof(double); - break; - } - case WKB_POLYGON: { - const int nrings = wkbReadInt(w); - if( nrings > (int)((w->size - (w->ptr - w->wkb)) / 4) ) - return; - for ( int i = 0; i < nrings; i++ ) { - const int npoints = wkbReadInt(w); - w->ptr += npoints * nCoordDim * sizeof(double); - } - break; } - case WKB_MULTIPOINT: - case WKB_MULTILINESTRING: - case WKB_MULTIPOLYGON: - case WKB_GEOMETRYCOLLECTION: - case WKB_COMPOUNDCURVE: - case WKB_CURVEPOLYGON: - case WKB_MULTICURVE: - case WKB_MULTISURFACE: { - const int ngeoms = wkbReadInt(w); - if( ngeoms > (int)((w->size - (w->ptr - w->wkb)) / 4) ) - return; - for ( int i = 0; i < ngeoms; i++ ) { - wkbSkipGeometry(w); - } - break; + break; + } + case WKB_MULTIPOINT: + case WKB_MULTILINESTRING: + case WKB_MULTIPOLYGON: + case WKB_GEOMETRYCOLLECTION: + case WKB_COMPOUNDCURVE: + case WKB_CURVEPOLYGON: + case WKB_MULTICURVE: + case WKB_MULTISURFACE: { + const int ngeoms = wkbReadInt(w); + if (ngeoms > (int)((w->size - (w->ptr - w->wkb)) / 4)) + return; + for (int i = 0; i < ngeoms; i++) { + wkbSkipGeometry(w); } + break; + } } } /* ** Convert a WKB point to a shapeObj, advancing the read pointer as we go. */ -static int -wkbConvPointToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvPointToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w),&nZMFlag); + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); - if( type != WKB_POINT ) return MS_FAILURE; + if (type != WKB_POINT) + return MS_FAILURE; - if( ! (shape->type == MS_SHAPE_POINT) ) return MS_FAILURE; + if (!(shape->type == MS_SHAPE_POINT)) + return MS_FAILURE; lineObj line; line.numpoints = 1; - line.point = (pointObj*) msSmallMalloc(sizeof(pointObj)); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj)); line.point[0] = wkbReadPoint(w, nZMFlag); msAddLineDirectly(shape, &line); return MS_SUCCESS; @@ -437,17 +404,16 @@ wkbConvPointToShape(wkbObj *w, shapeObj *shape) /* ** Convert a WKB line string to a shapeObj, advancing the read pointer as we go. */ -static int -wkbConvLineStringToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvLineStringToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); - if( type != WKB_LINESTRING ) return MS_FAILURE; + if (type != WKB_LINESTRING) + return MS_FAILURE; lineObj line; - wkbReadLine(w,&line, nZMFlag); + wkbReadLine(w, &line, nZMFlag); msAddLineDirectly(shape, &line); return MS_SUCCESS; @@ -456,24 +422,23 @@ wkbConvLineStringToShape(wkbObj *w, shapeObj *shape) /* ** Convert a WKB polygon to a shapeObj, advancing the read pointer as we go. */ -static int -wkbConvPolygonToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvPolygonToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); - if( type != WKB_POLYGON ) return MS_FAILURE; + if (type != WKB_POLYGON) + return MS_FAILURE; /* How many rings? */ const int nrings = wkbReadInt(w); - if( nrings > (int)((w->size - (w->ptr - w->wkb)) / 4) ) + if (nrings > (int)((w->size - (w->ptr - w->wkb)) / 4)) return MS_FAILURE; /* Add each ring to the shape */ lineObj line; - for( int i = 0; i < nrings; i++ ) { - wkbReadLine(w,&line, nZMFlag); + for (int i = 0; i < nrings; i++) { + wkbReadLine(w, &line, nZMFlag); msAddLineDirectly(shape, &line); } @@ -481,69 +446,72 @@ wkbConvPolygonToShape(wkbObj *w, shapeObj *shape) } /* -** Convert a WKB curve polygon to a shapeObj, advancing the read pointer as we go. +** Convert a WKB curve polygon to a shapeObj, advancing the read pointer as we +*go. ** The arc portions of the rings will be stroked to linestrings as they ** are read by the underlying circular string handling. */ -static int -wkbConvCurvePolygonToShape(wkbObj *w, shapeObj *shape) -{ - const int was_poly = ( shape->type == MS_SHAPE_POLYGON ); +static int wkbConvCurvePolygonToShape(wkbObj *w, shapeObj *shape) { + const int was_poly = (shape->type == MS_SHAPE_POLYGON); - /*endian = */wkbReadChar(w); + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); - if( type != WKB_CURVEPOLYGON ) return MS_FAILURE; + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); + if (type != WKB_CURVEPOLYGON) + return MS_FAILURE; const int ncomponents = wkbReadInt(w); - if( ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4) ) + if (ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4)) return MS_FAILURE; /* Lower the allowed dimensionality so we can - * catch the linear ring components */ + * catch the linear ring components */ shape->type = MS_SHAPE_LINE; int failures = 0; - for ( int i = 0; i < ncomponents; i++ ) { - if ( wkbConvGeometryToShape(w, shape) == MS_FAILURE ) { + for (int i = 0; i < ncomponents; i++) { + if (wkbConvGeometryToShape(w, shape) == MS_FAILURE) { wkbSkipGeometry(w); failures++; } } /* Go back to expected dimensionality */ - if ( was_poly) shape->type = MS_SHAPE_POLYGON; + if (was_poly) + shape->type = MS_SHAPE_POLYGON; - if ( failures == ncomponents ) + if (failures == ncomponents) return MS_FAILURE; else return MS_SUCCESS; } /* -** Convert a WKB circular string to a shapeObj, advancing the read pointer as we go. +** Convert a WKB circular string to a shapeObj, advancing the read pointer as we +*go. ** Arcs will be stroked to linestrings. */ -static int -wkbConvCircularStringToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvCircularStringToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); - if( type != WKB_CIRCULARSTRING ) return MS_FAILURE; + if (type != WKB_CIRCULARSTRING) + return MS_FAILURE; lineObj line = {0, nullptr}; /* Stroke the string into a point array */ - if ( arcStrokeCircularString(w, SEGMENT_ANGLE, &line, nZMFlag) == MS_FAILURE ) { - if(line.point) free(line.point); + if (arcStrokeCircularString(w, SEGMENT_ANGLE, &line, nZMFlag) == MS_FAILURE) { + if (line.point) + free(line.point); return MS_FAILURE; } /* Fill in the lineObj */ - if ( line.numpoints > 0 ) { + if (line.numpoints > 0) { msAddLine(shape, &line); - if(line.point) free(line.point); + if (line.point) + free(line.point); } return MS_SUCCESS; @@ -556,52 +524,52 @@ wkbConvCircularStringToShape(wkbObj *w, shapeObj *shape) ** allows compound curves to serve as closed rings in ** curve polygons. */ -static int -wkbConvCompoundCurveToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvCompoundCurveToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - const int type = wkbTypeMap(w,wkbReadInt(w), &nZMFlag); + const int type = wkbTypeMap(w, wkbReadInt(w), &nZMFlag); /* Init our shape buffer */ shapeObj shapebuf; msInitShape(&shapebuf); - if( type != WKB_COMPOUNDCURVE ) return MS_FAILURE; + if (type != WKB_COMPOUNDCURVE) + return MS_FAILURE; /* How many components in the compound curve? */ const int ncomponents = wkbReadInt(w); - if( ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4) ) + if (ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4)) return MS_FAILURE; /* We'll load each component onto a line in a shape */ - for( int i = 0; i < ncomponents; i++ ) + for (int i = 0; i < ncomponents; i++) wkbConvGeometryToShape(w, &shapebuf); /* Do nothing on empty */ - if ( shapebuf.numlines == 0 ) + if (shapebuf.numlines == 0) return MS_FAILURE; /* Count the total number of points */ int npoints = 0; - for( int i = 0; i < shapebuf.numlines; i++ ) + for (int i = 0; i < shapebuf.numlines; i++) npoints += shapebuf.line[i].numpoints; /* Do nothing on empty */ - if ( npoints == 0 ) + if (npoints == 0) return MS_FAILURE; lineObj line; line.numpoints = npoints; - line.point = (pointObj*) msSmallMalloc(sizeof(pointObj) * npoints); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * npoints); /* Copy in the points */ npoints = 0; - for ( int i = 0; i < shapebuf.numlines; i++ ) { - for ( int j = 0; j < shapebuf.line[i].numpoints; j++ ) { + for (int i = 0; i < shapebuf.numlines; i++) { + for (int j = 0; j < shapebuf.line[i].numpoints; j++) { /* Don't add a start point that duplicates an endpoint */ - if( j == 0 && i > 0 && - memcmp(&(line.point[npoints - 1]),&(shapebuf.line[i].point[j]),sizeof(pointObj)) == 0 ) { + if (j == 0 && i > 0 && + memcmp(&(line.point[npoints - 1]), &(shapebuf.line[i].point[j]), + sizeof(pointObj)) == 0) { continue; } line.point[npoints++] = shapebuf.line[i].point[j]; @@ -619,34 +587,34 @@ wkbConvCompoundCurveToShape(wkbObj *w, shapeObj *shape) } /* -** Convert a WKB collection string to a shapeObj, advancing the read pointer as we go. +** Convert a WKB collection string to a shapeObj, advancing the read pointer as +*we go. ** Many WKB types (MultiPoint, MultiLineString, MultiPolygon, MultiSurface, ** MultiCurve, GeometryCollection) can be treated identically as collections -** (they start with endian, type number and count of sub-elements, then provide the +** (they start with endian, type number and count of sub-elements, then provide +*the ** subelements as WKB) so are handled with this one function. */ -static int -wkbConvCollectionToShape(wkbObj *w, shapeObj *shape) -{ - /*endian = */wkbReadChar(w); +static int wkbConvCollectionToShape(wkbObj *w, shapeObj *shape) { + /*endian = */ wkbReadChar(w); int nZMFlag; - /*type = */wkbTypeMap(w,wkbReadInt(w), &nZMFlag); + /*type = */ wkbTypeMap(w, wkbReadInt(w), &nZMFlag); const int ncomponents = wkbReadInt(w); - if( ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4) ) + if (ncomponents > (int)((w->size - (w->ptr - w->wkb)) / 4)) return MS_FAILURE; /* - * If we can draw any portion of the collection, we will, - * but if all the components fail, we will draw nothing. - */ + * If we can draw any portion of the collection, we will, + * but if all the components fail, we will draw nothing. + */ int failures = 0; - for ( int i = 0; i < ncomponents; i++ ) { - if ( wkbConvGeometryToShape(w, shape) == MS_FAILURE ) { + for (int i = 0; i < ncomponents; i++) { + if (wkbConvGeometryToShape(w, shape) == MS_FAILURE) { wkbSkipGeometry(w); failures++; } } - if ( failures == ncomponents || ncomponents == 0) + if (failures == ncomponents || ncomponents == 0) return MS_FAILURE; else return MS_SUCCESS; @@ -659,71 +627,69 @@ wkbConvCollectionToShape(wkbObj *w, shapeObj *shape) ** a MS_SHAPE_LINE layer, so if the type is WKB_POINT and the layer is ** MS_SHAPE_LINE, we exit before converting. */ -static int -wkbConvGeometryToShape(wkbObj *w, shapeObj *shape) -{ +static int wkbConvGeometryToShape(wkbObj *w, shapeObj *shape) { int nZMFlag; const int wkbtype = wkbType(w, &nZMFlag); /* Peak at the type number */ - switch(wkbtype) { - /* Recurse into anonymous collections */ - case WKB_GEOMETRYCOLLECTION: - return wkbConvCollectionToShape(w, shape); - /* Handle area types */ - case WKB_POLYGON: - return wkbConvPolygonToShape(w, shape); - case WKB_MULTIPOLYGON: - return wkbConvCollectionToShape(w, shape); - case WKB_CURVEPOLYGON: - return wkbConvCurvePolygonToShape(w, shape); - case WKB_MULTISURFACE: - return wkbConvCollectionToShape(w, shape); + switch (wkbtype) { + /* Recurse into anonymous collections */ + case WKB_GEOMETRYCOLLECTION: + return wkbConvCollectionToShape(w, shape); + /* Handle area types */ + case WKB_POLYGON: + return wkbConvPolygonToShape(w, shape); + case WKB_MULTIPOLYGON: + return wkbConvCollectionToShape(w, shape); + case WKB_CURVEPOLYGON: + return wkbConvCurvePolygonToShape(w, shape); + case WKB_MULTISURFACE: + return wkbConvCollectionToShape(w, shape); } /* We can't convert any of the following types into polygons */ - if ( shape->type == MS_SHAPE_POLYGON ) return MS_FAILURE; + if (shape->type == MS_SHAPE_POLYGON) + return MS_FAILURE; /* Handle linear types */ - switch(wkbtype) { - case WKB_LINESTRING: - return wkbConvLineStringToShape(w, shape); - case WKB_CIRCULARSTRING: - return wkbConvCircularStringToShape(w, shape); - case WKB_COMPOUNDCURVE: - return wkbConvCompoundCurveToShape(w, shape); - case WKB_MULTILINESTRING: - return wkbConvCollectionToShape(w, shape); - case WKB_MULTICURVE: - return wkbConvCollectionToShape(w, shape); + switch (wkbtype) { + case WKB_LINESTRING: + return wkbConvLineStringToShape(w, shape); + case WKB_CIRCULARSTRING: + return wkbConvCircularStringToShape(w, shape); + case WKB_COMPOUNDCURVE: + return wkbConvCompoundCurveToShape(w, shape); + case WKB_MULTILINESTRING: + return wkbConvCollectionToShape(w, shape); + case WKB_MULTICURVE: + return wkbConvCollectionToShape(w, shape); } /* We can't convert any of the following types into lines */ - if ( shape->type == MS_SHAPE_LINE ) return MS_FAILURE; + if (shape->type == MS_SHAPE_LINE) + return MS_FAILURE; /* Handle point types */ - switch(wkbtype) { - case WKB_POINT: - return wkbConvPointToShape(w, shape); - case WKB_MULTIPOINT: - return wkbConvCollectionToShape(w, shape); + switch (wkbtype) { + case WKB_POINT: + return wkbConvPointToShape(w, shape); + case WKB_MULTIPOINT: + return wkbConvCollectionToShape(w, shape); } /* This is a WKB type we don't know about! */ return MS_FAILURE; } - /* ** What side of p1->p2 is q on? */ -static inline int -arcSegmentSide(const pointObj &p1, const pointObj &p2, const pointObj &q) -{ - double side = ( (q.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q.y - p1.y) ); - if ( FP_EQ(side,0.0) ) { +static inline int arcSegmentSide(const pointObj &p1, const pointObj &p2, + const pointObj &q) { + double side = ((q.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (q.y - p1.y)); + if (FP_EQ(side, 0.0)) { return FP_COLINEAR; } else { - if ( side < 0.0 ) + if (side < 0.0) return FP_LEFT; else return FP_RIGHT; @@ -732,22 +698,23 @@ arcSegmentSide(const pointObj &p1, const pointObj &p2, const pointObj &q) /* ** Calculate the center of the circle defined by three points. -** Using matrix approach from http://mathforum.org/library/drmath/view/55239.html +** Using matrix approach from +*http://mathforum.org/library/drmath/view/55239.html */ -static int -arcCircleCenter(const pointObj& p1, const pointObj& p2, const pointObj& p3, pointObj *center, double *radius) -{ +static int arcCircleCenter(const pointObj &p1, const pointObj &p2, + const pointObj &p3, pointObj *center, + double *radius) { pointObj c{}; // initialize double r; /* Circle is closed, so p2 must be opposite p1 & p3. */ - if ((fabs(p1.x - p3.x) < FP_EPSILON) && (fabs(p1.y-p3.y) < FP_EPSILON)) { + if ((fabs(p1.x - p3.x) < FP_EPSILON) && (fabs(p1.y - p3.y) < FP_EPSILON)) { c.x = p1.x + (p2.x - p1.x) / 2.0; c.y = p1.y + (p2.y - p1.y) / 2.0; r = sqrt(pow(c.x - p1.x, 2.0) + pow(c.y - p1.y, 2.0)); } /* There is no circle here, the points are actually co-linear */ - else if ( arcSegmentSide(p1, p3, p2) == FP_COLINEAR ) { + else if (arcSegmentSide(p1, p3, p2) == FP_COLINEAR) { return MS_FAILURE; } /* Calculate the center and radius. */ @@ -762,7 +729,8 @@ arcCircleCenter(const pointObj& p1, const pointObj& p2, const pointObj& p3, poin const double h21 = pow(dx21, 2.0) + pow(dy21, 2.0); const double h31 = pow(dx31, 2.0) + pow(dy31, 2.0); - /* 2 * |Cross product|, d<0 means clockwise and d>0 counterclockwise sweeping angle */ + /* 2 * |Cross product|, d<0 means clockwise and d>0 counterclockwise + * sweeping angle */ const double d = 2 * (dx21 * dy31 - dx31 * dy21); c.x = p1.x + (h21 * dy31 - h31 * dy21) / d; @@ -770,33 +738,36 @@ arcCircleCenter(const pointObj& p1, const pointObj& p2, const pointObj& p3, poin r = sqrt(pow(c.x - p1.x, 2) + pow(c.y - p1.y, 2)); } - if ( radius ) *radius = r; - if ( center ) *center = c; + if (radius) + *radius = r; + if (center) + *center = c; return MS_SUCCESS; } /* ** Write a stroked version of the circle defined by three points into a -** point buffer. The segment_angle (degrees) is the coverage of each stroke segment, +** point buffer. The segment_angle (degrees) is the coverage of each stroke +*segment, ** and depending on whether this is the first arc in a circularstring, ** you might want to include_first */ -static int -arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, - double segment_angle, int include_first, std::vector& pa) -{ - const int side = arcSegmentSide(p1, p3, p2); /* What side of p1,p3 is the middle point? */ +static int arcStrokeCircle(const pointObj &p1, const pointObj &p2, + const pointObj &p3, double segment_angle, + int include_first, std::vector &pa) { + const int side = + arcSegmentSide(p1, p3, p2); /* What side of p1,p3 is the middle point? */ int is_closed = MS_FALSE; /* We need to know if we're dealing with a circle early */ - if ( FP_EQ(p1.x, p3.x) && FP_EQ(p1.y, p3.y) ) + if (FP_EQ(p1.x, p3.x) && FP_EQ(p1.y, p3.y)) is_closed = MS_TRUE; /* Check if the "arc" is actually straight */ - if ( ! is_closed && side == FP_COLINEAR ) { + if (!is_closed && side == FP_COLINEAR) { /* We just need to write in the end points */ - if ( include_first ) + if (include_first) pointArrayAddPoint(pa, p1); pointArrayAddPoint(pa, p3); return MS_SUCCESS; @@ -804,8 +775,8 @@ arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, /* We should always be able to find the center of a non-linear arc */ pointObj center; /* Center of our circular arc */ - double radius; /* Radius of our circular arc */ - if ( arcCircleCenter(p1, p2, p3, ¢er, &radius) == MS_FAILURE ) + double radius; /* Radius of our circular arc */ + if (arcCircleCenter(p1, p2, p3, ¢er, &radius) == MS_FAILURE) return MS_FAILURE; /* Calculate the angles relative to center that our three points represent */ @@ -814,23 +785,24 @@ arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, a2 = atan2(p2.y - center.y, p2.x - center.x); */ const double a3 = atan2(p3.y - center.y, p3.x - center.x); - double segment_angle_r = M_PI * segment_angle / 180.0; /* Segment angle in radians */ + double segment_angle_r = + M_PI * segment_angle / 180.0; /* Segment angle in radians */ double sweep_angle_r; /* Total angular size of our circular arc in radians */ /* Closed-circle case, we sweep the whole circle! */ - if ( is_closed ) { + if (is_closed) { sweep_angle_r = 2.0 * M_PI; } /* Clockwise sweep direction */ - else if ( side == FP_LEFT ) { - if ( a3 > a1 ) /* Wrapping past 180? */ + else if (side == FP_LEFT) { + if (a3 > a1) /* Wrapping past 180? */ sweep_angle_r = a1 + (2.0 * M_PI - a3); else sweep_angle_r = a1 - a3; } /* Counter-clockwise sweep direction */ - else if ( side == FP_RIGHT ) { - if ( a3 > a1 ) /* Wrapping past 180? */ + else if (side == FP_RIGHT) { + if (a3 > a1) /* Wrapping past 180? */ sweep_angle_r = a3 - a1; else sweep_angle_r = a3 + (2.0 * M_PI - a1); @@ -838,30 +810,30 @@ arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, sweep_angle_r = 0.0; /* We don't have enough resolution, let's invert our strategy. */ - if ( (sweep_angle_r / segment_angle_r) < SEGMENT_MINPOINTS ) { + if ((sweep_angle_r / segment_angle_r) < SEGMENT_MINPOINTS) { segment_angle_r = sweep_angle_r / (SEGMENT_MINPOINTS + 1); } /* We don't have enough resolution to stroke this arc, - * so just join the start to the end. */ - if ( sweep_angle_r < segment_angle_r ) { - if ( include_first ) + * so just join the start to the end. */ + if (sweep_angle_r < segment_angle_r) { + if (include_first) pointArrayAddPoint(pa, p1); pointArrayAddPoint(pa, p3); return MS_SUCCESS; } /* How many edges to generate (we add the final edge - * by sticking on the last point */ + * by sticking on the last point */ int num_edges = floor(sweep_angle_r / fabs(segment_angle_r)); /* Go backwards (negative angular steps) if we are stroking clockwise */ - if ( side == FP_LEFT ) + if (side == FP_LEFT) segment_angle_r *= -1; /* What point should we start with? */ double current_angle_r; /* What angle are we generating now (radians)? */ - if( include_first ) { + if (include_first) { current_angle_r = a1; } else { current_angle_r = a1 + segment_angle_r; @@ -869,14 +841,14 @@ arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, } /* For each edge, increment or decrement by our segment angle */ - for( int i = 0; i < num_edges; i++ ) { + for (int i = 0; i < num_edges; i++) { if (segment_angle_r > 0.0 && current_angle_r > M_PI) - current_angle_r -= 2*M_PI; - if (segment_angle_r < 0.0 && current_angle_r < -1*M_PI) - current_angle_r -= 2*M_PI; + current_angle_r -= 2 * M_PI; + if (segment_angle_r < 0.0 && current_angle_r < -1 * M_PI) + current_angle_r -= 2 * M_PI; pointObj p; - p.x = center.x + radius*cos(current_angle_r); - p.y = center.y + radius*sin(current_angle_r); + p.x = center.x + radius * cos(current_angle_r); + p.y = center.y + radius * sin(current_angle_r); pointArrayAddPoint(pa, p); current_angle_r += segment_angle_r; } @@ -892,31 +864,32 @@ arcStrokeCircle(const pointObj& p1, const pointObj& p2, const pointObj& p3, ** is stroked into a linestring and appended into the lineObj ** argument. */ -static int -arcStrokeCircularString(wkbObj *w, double segment_angle, lineObj *line, int nZMFlag) -{ - if ( ! w || ! line ) return MS_FAILURE; +static int arcStrokeCircularString(wkbObj *w, double segment_angle, + lineObj *line, int nZMFlag) { + if (!w || !line) + return MS_FAILURE; const int npoints = wkbReadInt(w); const int nedges = npoints / 2; /* All CircularStrings have an odd number of points */ - if ( npoints < 3 || npoints % 2 != 1 ) + if (npoints < 3 || npoints % 2 != 1) return MS_FAILURE; /* Make a large guess at how much space we'll need */ auto pa = pointArrayNew(nedges * 180 / segment_angle); pointObj p1, p2, p3; - wkbReadPointP(w,&p3,nZMFlag); + wkbReadPointP(w, &p3, nZMFlag); /* Fill out the point array with stroked arcs */ int edge = 0; - while( edge < nedges ) { + while (edge < nedges) { p1 = p3; - wkbReadPointP(w,&p2,nZMFlag); - wkbReadPointP(w,&p3,nZMFlag); - if ( arcStrokeCircle(p1, p2, p3, segment_angle, edge ? 0 : 1, pa) == MS_FAILURE ) { + wkbReadPointP(w, &p2, nZMFlag); + wkbReadPointP(w, &p3, nZMFlag); + if (arcStrokeCircle(p1, p2, p3, segment_angle, edge ? 0 : 1, pa) == + MS_FAILURE) { return MS_FAILURE; } edge++; @@ -924,13 +897,12 @@ arcStrokeCircularString(wkbObj *w, double segment_angle, lineObj *line, int nZMF /* Copy the point array into the line */ line->numpoints = static_cast(pa.size()); - line->point = (pointObj*) msSmallMalloc(line->numpoints * sizeof(pointObj)); + line->point = (pointObj *)msSmallMalloc(line->numpoints * sizeof(pointObj)); memcpy(line->point, pa.data(), line->numpoints * sizeof(pointObj)); return MS_SUCCESS; } - /* ** For LAYER types that are not the usual ones (charts, ** annotations, etc) we will convert to a shape type @@ -938,36 +910,34 @@ arcStrokeCircularString(wkbObj *w, double segment_angle, lineObj *line, int nZMF ** by peaking at the type number of the first collection ** sub-element. */ -static int -msPostGISFindBestType(wkbObj *w, shapeObj *shape) -{ +static int msPostGISFindBestType(wkbObj *w, shapeObj *shape) { /* What kind of geometry is this? */ int nZMFlag; int wkbtype = wkbType(w, &nZMFlag); /* Generic collection, we need to look a little deeper. */ - if ( wkbtype == WKB_GEOMETRYCOLLECTION ) + if (wkbtype == WKB_GEOMETRYCOLLECTION) wkbtype = wkbCollectionSubType(w, &nZMFlag); - switch ( wkbtype ) { - case WKB_POLYGON: - case WKB_CURVEPOLYGON: - case WKB_MULTIPOLYGON: - shape->type = MS_SHAPE_POLYGON; - break; - case WKB_LINESTRING: - case WKB_CIRCULARSTRING: - case WKB_COMPOUNDCURVE: - case WKB_MULTICURVE: - case WKB_MULTILINESTRING: - shape->type = MS_SHAPE_LINE; - break; - case WKB_POINT: - case WKB_MULTIPOINT: - shape->type = MS_SHAPE_POINT; - break; - default: - return MS_FAILURE; + switch (wkbtype) { + case WKB_POLYGON: + case WKB_CURVEPOLYGON: + case WKB_MULTIPOLYGON: + shape->type = MS_SHAPE_POLYGON; + break; + case WKB_LINESTRING: + case WKB_CIRCULARSTRING: + case WKB_COMPOUNDCURVE: + case WKB_MULTICURVE: + case WKB_MULTILINESTRING: + shape->type = MS_SHAPE_LINE; + break; + case WKB_POINT: + case WKB_MULTIPOINT: + shape->type = MS_SHAPE_POINT; + break; + default: + return MS_FAILURE; } return wkbConvGeometryToShape(w, shape); @@ -977,42 +947,44 @@ msPostGISFindBestType(wkbObj *w, shapeObj *shape) ** Get the PostGIS version number from the database as integer. ** Versions are multiplied out as with PgSQL: 1.5.2 -> 10502, 2.0.0 -> 20000. */ -static int -msPostGISRetrieveVersion(PGconn *pgconn) -{ - static const char* sql = "SELECT postgis_version()"; - if ( ! pgconn ) { - msSetError(MS_QUERYERR, "No open connection.", "msPostGISRetrieveVersion()"); +static int msPostGISRetrieveVersion(PGconn *pgconn) { + static const char *sql = "SELECT postgis_version()"; + if (!pgconn) { + msSetError(MS_QUERYERR, "No open connection.", + "msPostGISRetrieveVersion()"); return MS_FAILURE; } - PGresult* pgresult = PQexecParams(pgconn, sql,0, nullptr, nullptr, nullptr, nullptr, 0); + PGresult *pgresult = + PQexecParams(pgconn, sql, 0, nullptr, nullptr, nullptr, nullptr, 0); - if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { + if (!pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { msDebug("Error executing SQL: (%s) in msPostGISRetrieveVersion()", sql); - msSetError(MS_QUERYERR, "Error executing SQL. check server logs.", "msPostGISRetrieveVersion()"); + msSetError(MS_QUERYERR, "Error executing SQL. check server logs.", + "msPostGISRetrieveVersion()"); return MS_FAILURE; } if (PQgetisnull(pgresult, 0, 0)) { PQclear(pgresult); - msSetError(MS_QUERYERR,"Null result returned.","msPostGISRetrieveVersion()"); + msSetError(MS_QUERYERR, "Null result returned.", + "msPostGISRetrieveVersion()"); return MS_FAILURE; } std::string strVersion = PQgetvalue(pgresult, 0, 0); PQclear(pgresult); - char* ptr = &strVersion[0]; - char *strParts[3] = { nullptr, nullptr, nullptr }; + char *ptr = &strVersion[0]; + char *strParts[3] = {nullptr, nullptr, nullptr}; int j = 0; strParts[j++] = &strVersion[0]; - while( *ptr != '\0' && j < 3 ) { - if ( *ptr == '.' ) { + while (*ptr != '\0' && j < 3) { + if (*ptr == '.') { *ptr = '\0'; strParts[j++] = ptr + 1; } - if ( *ptr == ' ' ) { + if (*ptr == ' ') { *ptr = '\0'; break; } @@ -1021,7 +993,7 @@ msPostGISRetrieveVersion(PGconn *pgconn) int version = 0; int factor = 10000; - for( int i = 0; i < j; i++ ) { + for (int i = 0; i < j; i++) { version += factor * atoi(strParts[i]); factor = factor / 100; } @@ -1033,26 +1005,29 @@ msPostGISRetrieveVersion(PGconn *pgconn) ** Get the PostgreSQL server version number from the database as integer. ** 12.7.1 ==> 120701 */ -static int -msPostGISRetrievePostgreSQLVersion(PGconn *pgconn) -{ - static const char* sql = "SELECT version()"; - if ( ! pgconn ) { - msSetError(MS_QUERYERR, "No open connection.", "msPostGISRetrievePostgreSQLVersion()"); +static int msPostGISRetrievePostgreSQLVersion(PGconn *pgconn) { + static const char *sql = "SELECT version()"; + if (!pgconn) { + msSetError(MS_QUERYERR, "No open connection.", + "msPostGISRetrievePostgreSQLVersion()"); return MS_FAILURE; } - PGresult* pgresult = PQexecParams(pgconn, sql,0, nullptr, nullptr, nullptr, nullptr, 0); + PGresult *pgresult = + PQexecParams(pgconn, sql, 0, nullptr, nullptr, nullptr, nullptr, 0); - if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { - msDebug("Error executing SQL: (%s) in msPostGISRetrievePostgreSQLVersion()", sql); - msSetError(MS_QUERYERR, "Error executing SQL. check server logs.", "msPostGISRetrievePostgreSQLVersion()"); + if (!pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { + msDebug("Error executing SQL: (%s) in msPostGISRetrievePostgreSQLVersion()", + sql); + msSetError(MS_QUERYERR, "Error executing SQL. check server logs.", + "msPostGISRetrievePostgreSQLVersion()"); return MS_FAILURE; } if (PQgetisnull(pgresult, 0, 0)) { PQclear(pgresult); - msSetError(MS_QUERYERR,"Null result returned.","msPostGISRetrievePostgreSQLVersion()"); + msSetError(MS_QUERYERR, "Null result returned.", + "msPostGISRetrievePostgreSQLVersion()"); return MS_FAILURE; } @@ -1061,19 +1036,19 @@ msPostGISRetrievePostgreSQLVersion(PGconn *pgconn) // Skip leading "PostgreSQL " (or other vendorized name) auto nPos = strVersion.find(' '); - if( nPos == std::string::npos ) - return 0; + if (nPos == std::string::npos) + return 0; - char* ptr = &strVersion[nPos + 1]; - char *strParts[3] = { nullptr, nullptr, nullptr }; + char *ptr = &strVersion[nPos + 1]; + char *strParts[3] = {nullptr, nullptr, nullptr}; int j = 0; strParts[j++] = ptr; - while( *ptr != '\0' && j < 3 ) { - if ( *ptr == '.' ) { + while (*ptr != '\0' && j < 3) { + if (*ptr == '.') { *ptr = '\0'; strParts[j++] = ptr + 1; } - if ( *ptr == ' ' ) { + if (*ptr == ' ') { *ptr = '\0'; break; } @@ -1082,7 +1057,7 @@ msPostGISRetrievePostgreSQLVersion(PGconn *pgconn) int version = 0; int factor = 10000; - for( int i = 0; i < j; i++ ) { + for (int i = 0; i < j; i++) { version += factor * atoi(strParts[i]); factor = factor / 100; } @@ -1097,20 +1072,18 @@ msPostGISRetrievePostgreSQLVersion(PGconn *pgconn) ** The layerinfo->fromsource must already be populated and ** must not be a subquery. */ -static int -msPostGISRetrievePK(layerObj *layer) -{ +static int msPostGISRetrievePK(layerObj *layer) { char *sql = nullptr; if (layer->debug) { msDebug("msPostGISRetrievePK called.\n"); } - msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *) layer->layerinfo; - + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; if (layerinfo->pgconn == nullptr) { - msSetError(MS_QUERYERR, "Layer does not have a postgis connection.", "msPostGISRetrievePK()"); + msSetError(MS_QUERYERR, "Layer does not have a postgis connection.", + "msPostGISRetrievePK()"); return MS_FAILURE; } @@ -1124,7 +1097,8 @@ msPostGISRetrievePK(layerObj *layer) table = layerinfo->fromsource.substr(pos_sep + 1); if (layer->debug) { - msDebug("msPostGISRetrievePK(): Found schema %s, table %s.\n", schema.c_str(), table.c_str()); + msDebug("msPostGISRetrievePK(): Found schema %s, table %s.\n", + schema.c_str(), table.c_str()); } } /* @@ -1133,12 +1107,27 @@ msPostGISRetrievePK(layerObj *layer) ** pks are explicitly excluded from the query. */ if (!schema.empty()) { - static const char *v73sql = "select attname from pg_attribute, pg_constraint, pg_class, pg_namespace where pg_constraint.conrelid = pg_class.oid and pg_class.oid = pg_attribute.attrelid and pg_constraint.contype = 'p' and pg_constraint.conkey[1] = pg_attribute.attnum and pg_class.relname = '%s' and pg_class.relnamespace = pg_namespace.oid and pg_namespace.nspname = '%s' and pg_constraint.conkey[2] is null"; - sql = (char*) msSmallMalloc(schema.size() + table.size() + strlen(v73sql) + 1); + static const char *v73sql = + "select attname from pg_attribute, pg_constraint, pg_class, " + "pg_namespace where pg_constraint.conrelid = pg_class.oid and " + "pg_class.oid = pg_attribute.attrelid and pg_constraint.contype = " + "'p' and pg_constraint.conkey[1] = pg_attribute.attnum and " + "pg_class.relname = '%s' and pg_class.relnamespace = " + "pg_namespace.oid and pg_namespace.nspname = '%s' and " + "pg_constraint.conkey[2] is null"; + sql = (char *)msSmallMalloc(schema.size() + table.size() + + strlen(v73sql) + 1); sprintf(sql, v73sql, table.c_str(), schema.c_str()); } else { - static const char *v73sql = "select attname from pg_attribute, pg_constraint, pg_class where pg_constraint.conrelid = pg_class.oid and pg_class.oid = pg_attribute.attrelid and pg_constraint.contype = 'p' and pg_constraint.conkey[1] = pg_attribute.attnum and pg_class.relname = '%s' and pg_table_is_visible(pg_class.oid) and pg_constraint.conkey[2] is null"; - sql = (char*) msSmallMalloc(layerinfo->fromsource.size() + strlen(v73sql) + 1); + static const char *v73sql = + "select attname from pg_attribute, pg_constraint, pg_class where " + "pg_constraint.conrelid = pg_class.oid and pg_class.oid = " + "pg_attribute.attrelid and pg_constraint.contype = 'p' and " + "pg_constraint.conkey[1] = pg_attribute.attnum and pg_class.relname " + "= '%s' and pg_table_is_visible(pg_class.oid) and " + "pg_constraint.conkey[2] is null"; + sql = (char *)msSmallMalloc(layerinfo->fromsource.size() + + strlen(v73sql) + 1); sprintf(sql, v73sql, layerinfo->fromsource.c_str()); } } @@ -1147,16 +1136,18 @@ msPostGISRetrievePK(layerObj *layer) msDebug("msPostGISRetrievePK: %s\n", sql); } - layerinfo = (msPostGISLayerInfo *) layer->layerinfo; + layerinfo = (msPostGISLayerInfo *)layer->layerinfo; if (layerinfo->pgconn == nullptr) { - msSetError(MS_QUERYERR, "Layer does not have a postgis connection.", "msPostGISRetrievePK()"); + msSetError(MS_QUERYERR, "Layer does not have a postgis connection.", + "msPostGISRetrievePK()"); free(sql); return MS_FAILURE; } - PGresult *pgresult = PQexecParams(layerinfo->pgconn, sql, 0, nullptr, nullptr, nullptr, nullptr, 0); - if ( !pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { + PGresult *pgresult = PQexecParams(layerinfo->pgconn, sql, 0, nullptr, nullptr, + nullptr, nullptr, 0); + if (!pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { msSetError(MS_QUERYERR, "%s", "msPostGISRetrievePK()", (std::string("Error executing SQL: ") + sql).c_str()); return MS_FAILURE; @@ -1195,32 +1186,34 @@ msPostGISRetrievePK(layerObj *layer) return MS_SUCCESS; } - /* ** msPostGISParseData() ** ** Parse the DATA string for geometry column name, table name, ** unique id column, srid, and SQL string. */ -static int msPostGISParseData(layerObj *layer) -{ +static int msPostGISParseData(layerObj *layer) { assert(layer != nullptr); assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*)(layer->layerinfo); + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)(layer->layerinfo); if (layer->debug) { msDebug("msPostGISParseData called.\n"); } if (!layer->data) { - msSetError(MS_QUERYERR, "Missing DATA clause. DATA statement must contain 'geometry_column from table_name' or 'geometry_column from (sub-query) as sub'.", "msPostGISParseData()"); + msSetError( + MS_QUERYERR, + "Missing DATA clause. DATA statement must contain 'geometry_column " + "from table_name' or 'geometry_column from (sub-query) as sub'.", + "msPostGISParseData()"); return MS_FAILURE; } std::string data(layer->data); - for( char& ch: data ) { - if( ch == '\t' || ch == '\r' || ch == '\n' ) { + for (char &ch : data) { + if (ch == '\t' || ch == '\r' || ch == '\n') { ch = ' '; } } @@ -1236,53 +1229,57 @@ static int msPostGISParseData(layerObj *layer) /* ** Look for the optional ' using ' clauses. */ - const char* pos_srid = nullptr; - const char* pos_uid = nullptr; - const char* pos_use_1st = nullptr; - const char* pos_use_2nd = nullptr; + const char *pos_srid = nullptr; + const char *pos_uid = nullptr; + const char *pos_use_1st = nullptr; + const char *pos_use_2nd = nullptr; { - const char* tmp = strcasestr(data.c_str(), " using "); - while ( tmp ) - { + const char *tmp = strcasestr(data.c_str(), " using "); + while (tmp) { pos_use_1st = pos_use_2nd; pos_use_2nd = tmp + 1; - tmp = strcasestr(tmp+1, " using "); + tmp = strcasestr(tmp + 1, " using "); } } /* ** What clause appear after 2nd 'using', if set? */ - if ( pos_use_2nd ) - { - const char* tmp; - for ( tmp = pos_use_2nd + 5; *tmp == ' '; tmp++ ); - if ( strncasecmp ( tmp, "unique ", 7 ) == 0 ) - for ( pos_uid = tmp + 7; *pos_uid == ' '; pos_uid++ ); - if ( strncasecmp ( tmp, "srid=", 5 ) == 0 ) pos_srid = tmp + 5; + if (pos_use_2nd) { + const char *tmp; + for (tmp = pos_use_2nd + 5; *tmp == ' '; tmp++) + ; + if (strncasecmp(tmp, "unique ", 7) == 0) + for (pos_uid = tmp + 7; *pos_uid == ' '; pos_uid++) + ; + if (strncasecmp(tmp, "srid=", 5) == 0) + pos_srid = tmp + 5; }; /* ** What clause appear after 1st 'using', if set? */ - if ( pos_use_1st ) - { - const char* tmp; - for ( tmp = pos_use_1st + 5; *tmp == ' '; tmp++ ); - if ( strncasecmp ( tmp, "unique ", 7 ) == 0 ) - { - if ( pos_uid ) - { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. Too many 'USING UNIQUE' found! %s", "msPostGISParseData()", layer->data); + if (pos_use_1st) { + const char *tmp; + for (tmp = pos_use_1st + 5; *tmp == ' '; tmp++) + ; + if (strncasecmp(tmp, "unique ", 7) == 0) { + if (pos_uid) { + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. Too many 'USING " + "UNIQUE' found! %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; }; - for ( pos_uid = tmp + 7; *pos_uid == ' '; pos_uid++ ); + for (pos_uid = tmp + 7; *pos_uid == ' '; pos_uid++) + ; }; - if ( strncasecmp ( tmp, "srid=", 5 ) == 0 ) - { - if ( pos_srid ) - { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. Too many 'USING SRID' found! %s", "msPostGISParseData()", layer->data); + if (strncasecmp(tmp, "srid=", 5) == 0) { + if (pos_srid) { + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. Too many 'USING SRID' " + "found! %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; } pos_srid = tmp + 5; @@ -1294,7 +1291,7 @@ static int msPostGISParseData(layerObj *layer) */ if (pos_uid) { /* Find the end of this case 'using unique ftab_id using srid=33' */ - const char* tmp = strstr(pos_uid, " "); + const char *tmp = strstr(pos_uid, " "); /* Find the end of this case 'using srid=33 using unique ftab_id' */ if (!tmp) { tmp = pos_uid + strlen(pos_uid); @@ -1309,7 +1306,10 @@ static int msPostGISParseData(layerObj *layer) if (pos_srid) { const int slength = strspn(pos_srid, "-0123456789"); if (!slength) { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. You specified 'USING SRID' but didn't have any numbers! %s", "msPostGISParseData()", layer->data); + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. You specified 'USING " + "SRID' but didn't have any numbers! %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; } else { layerinfo->srid.assign(pos_srid, slength); @@ -1318,21 +1318,20 @@ static int msPostGISParseData(layerObj *layer) } /* - * This is a little hack so the rest of the code works. - * pos_opt should point to the start of the optional blocks. - * - * If they are both set, return the smaller one. - * If pos_use_1st set, then it smaller. - * If one or none is set, return the larger one. - */ - const char* pos_opt = pos_use_1st ? pos_use_1st : pos_use_2nd; + * This is a little hack so the rest of the code works. + * pos_opt should point to the start of the optional blocks. + * + * If they are both set, return the smaller one. + * If pos_use_1st set, then it smaller. + * If one or none is set, return the larger one. + */ + const char *pos_opt = pos_use_1st ? pos_use_1st : pos_use_2nd; /* No pos_opt? Move it to the end of the string. */ if (!pos_opt) { pos_opt = data.c_str() + data.size(); } /* Back after the last non-space character. */ - while( ( pos_opt > data.c_str() ) && ( *(pos_opt-1) == ' ' ) ) - { + while ((pos_opt > data.c_str()) && (*(pos_opt - 1) == ' ')) { --pos_opt; } @@ -1341,15 +1340,17 @@ static int msPostGISParseData(layerObj *layer) */ /* Find the first non-white character to start from */ - const char* pos_geom; - for ( pos_geom = data.c_str(); *pos_geom == ' '; pos_geom++ ) - { + const char *pos_geom; + for (pos_geom = data.c_str(); *pos_geom == ' '; pos_geom++) { } /* Find the end of the geom column name */ - const char* pos_scn = strcasestr(data.c_str(), " from "); + const char *pos_scn = strcasestr(data.c_str(), " from "); if (!pos_scn) { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. Must contain 'geometry from table' or 'geometry from (subselect) as foo'. %s", "msPostGISParseData()", layer->data); + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. Must contain 'geometry " + "from table' or 'geometry from (subselect) as foo'. %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; } @@ -1358,18 +1359,26 @@ static int msPostGISParseData(layerObj *layer) msStringTrim(layerinfo->geomcolumn); /* Copy the table name or sub-select clause */ - for ( pos_scn += 6; *pos_scn == ' '; pos_scn++ ); - if ( pos_opt - pos_scn < 1 ) - { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. Must contain 'geometry from table' or 'geometry from (subselect) as foo'. %s", "msPostGISParseData()", layer->data); + for (pos_scn += 6; *pos_scn == ' '; pos_scn++) + ; + if (pos_opt - pos_scn < 1) { + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. Must contain 'geometry " + "from table' or 'geometry from (subselect) as foo'. %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; }; - layerinfo->fromsource.assign(layer->data + (pos_scn - data.c_str()), pos_opt - pos_scn); + layerinfo->fromsource.assign(layer->data + (pos_scn - data.c_str()), + pos_opt - pos_scn); msStringTrim(layerinfo->fromsource); - /* Something is wrong, our goemetry column and table references are not there. */ + /* Something is wrong, our goemetry column and table references are not there. + */ if (layerinfo->fromsource.empty() || layerinfo->geomcolumn.empty()) { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. Must contain 'geometry from table' or 'geometry from (subselect) as foo'. %s", "msPostGISParseData()", layer->data); + msSetError(MS_QUERYERR, + "Error parsing PostGIS DATA variable. Must contain 'geometry " + "from table' or 'geometry from (subselect) as foo'. %s", + "msPostGISParseData()", layer->data); return MS_FAILURE; } @@ -1377,14 +1386,20 @@ static int msPostGISParseData(layerObj *layer) ** We didn't find a ' using unique ' in the DATA string so try and find a ** primary key on the table. */ - if ( layerinfo->uid.empty() ) { - if ( strstr(layerinfo->fromsource.c_str(), " ") ) { - msSetError(MS_QUERYERR, "Error parsing PostGIS DATA variable. You must specify 'using unique' when supplying a subselect in the data definition.", "msPostGISParseData()"); + if (layerinfo->uid.empty()) { + if (strstr(layerinfo->fromsource.c_str(), " ")) { + msSetError( + MS_QUERYERR, + "Error parsing PostGIS DATA variable. You must specify 'using " + "unique' when supplying a subselect in the data definition.", + "msPostGISParseData()"); return MS_FAILURE; } - if ( msPostGISRetrievePK(layer) != MS_SUCCESS ) { - if( layerinfo->pgconn && msPostGISRetrievePostgreSQLVersion(layerinfo->pgconn) < 120000 ) { - /* For PostgreSQL < 12: No user specified unique id so we will use the PostgreSQL oid */ + if (msPostGISRetrievePK(layer) != MS_SUCCESS) { + if (layerinfo->pgconn && + msPostGISRetrievePostgreSQLVersion(layerinfo->pgconn) < 120000) { + /* For PostgreSQL < 12: No user specified unique id so we will use the + * PostgreSQL oid */ layerinfo->uid = "oid"; } else { msSetError(MS_QUERYERR, @@ -1398,7 +1413,10 @@ static int msPostGISParseData(layerObj *layer) } if (layer->debug) { - msDebug("msPostGISParseData: unique_column=%s, srid=%s, geom_column_name=%s, table_name=%s\n", layerinfo->uid.c_str(), layerinfo->srid.c_str(), layerinfo->geomcolumn.c_str(), layerinfo->fromsource.c_str()); + msDebug("msPostGISParseData: unique_column=%s, srid=%s, " + "geom_column_name=%s, table_name=%s\n", + layerinfo->uid.c_str(), layerinfo->srid.c_str(), + layerinfo->geomcolumn.c_str(), layerinfo->fromsource.c_str()); } return MS_SUCCESS; } @@ -1411,58 +1429,53 @@ static int msPostGISParseData(layerObj *layer) ** Decode a hex character. */ static const unsigned char msPostGISHexDecodeChar[256] = { - /* not Hex characters */ - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - /* 0-9 */ - 0,1,2,3,4,5,6,7,8,9, - /* not Hex characters */ - 64,64,64,64,64,64,64, - /* A-F */ - 10,11,12,13,14,15, - /* not Hex characters */ - 64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64, - /* a-f */ - 10,11,12,13,14,15, - 64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - /* not Hex characters (upper 128 characters) */ - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, - 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64 -}; + /* not Hex characters */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + /* 0-9 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + /* not Hex characters */ + 64, 64, 64, 64, 64, 64, 64, + /* A-F */ + 10, 11, 12, 13, 14, 15, + /* not Hex characters */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, + /* a-f */ + 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + /* not Hex characters (upper 128 characters) */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; /* ** Decode hex string "src" (null terminated) ** into "dest" (not null terminated). ** Returns length of decoded array or 0 on failure. */ -static int msPostGISHexDecode(unsigned char *dest, const char *src, int srclen) -{ +static int msPostGISHexDecode(unsigned char *dest, const char *src, + int srclen) { - if (src && *src && (srclen % 2 == 0) ) { + if (src && *src && (srclen % 2 == 0)) { unsigned char *p = dest; int i; - for ( i=0; i>4) ); + *p++ = ((b1 << 2) | (b2 >> 4)); if (c3 != '=') { - *p++=(((b2&0xf)<<4)|(b3>>2) ); + *p++ = (((b2 & 0xf) << 4) | (b3 >> 2)); } if (c4 != '=') { - *p++=(((b3&0x3)<<6)|b4 ); + *p++ = (((b3 & 0x3) << 6) | b4); } } free(buf); - return(p-dest); + return (p - dest); } return 0; } @@ -1568,8 +1582,8 @@ static int msPostGISBase64Decode(unsigned char *dest, const char *src, int srcle ** ** Returns malloc'ed char* that must be freed by caller. */ -static char *msPostGISBuildSQLBox(layerObj *layer, const rectObj *rect, const char *strSRID) -{ +static char *msPostGISBuildSQLBox(layerObj *layer, const rectObj *rect, + const char *strSRID) { char *strBox = nullptr; size_t sz; @@ -1580,67 +1594,72 @@ static char *msPostGISBuildSQLBox(layerObj *layer, const rectObj *rect, const ch const bool bIsPoint = rect->minx == rect->maxx && rect->miny == rect->maxy; - if ( strSRID ) { - static const char *strBoxTemplate = "ST_GeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))',%s)"; - static const char *strBoxTemplatePoint = "ST_GeomFromText('POINT(%.15g %.15g)',%s)"; + if (strSRID) { + static const char *strBoxTemplate = + "ST_GeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g " + "%.15g,%.15g %.15g))',%s)"; + static const char *strBoxTemplatePoint = + "ST_GeomFromText('POINT(%.15g %.15g)',%s)"; /* 10 doubles + 1 integer + template characters */ sz = 10 * 22 + strlen(strSRID) + strlen(strBoxTemplate); - strBox = (char*)msSmallMalloc(sz+1); /* add space for terminating NULL */ - if ( (bIsPoint && sz <= static_cast(snprintf(strBox, sz, strBoxTemplatePoint, - rect->minx, rect->miny, strSRID))) || - (!bIsPoint && sz <= static_cast(snprintf(strBox, sz, strBoxTemplate, - rect->minx, rect->miny, - rect->minx, rect->maxy, - rect->maxx, rect->maxy, - rect->maxx, rect->miny, - rect->minx, rect->miny, - strSRID))) ) { - msSetError(MS_MISCERR,"Bounding box digits truncated.","msPostGISBuildSQLBox"); + strBox = (char *)msSmallMalloc(sz + 1); /* add space for terminating NULL */ + if ((bIsPoint && sz <= static_cast( + snprintf(strBox, sz, strBoxTemplatePoint, + rect->minx, rect->miny, strSRID))) || + (!bIsPoint && + sz <= static_cast(snprintf( + strBox, sz, strBoxTemplate, rect->minx, rect->miny, + rect->minx, rect->maxy, rect->maxx, rect->maxy, rect->maxx, + rect->miny, rect->minx, rect->miny, strSRID)))) { + msSetError(MS_MISCERR, "Bounding box digits truncated.", + "msPostGISBuildSQLBox"); return nullptr; } } else { - static const char *strBoxTemplate = "ST_GeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g %.15g))')"; - static const char *strBoxTemplatePoint = "ST_GeomFromText('POINT(%.15g %.15g)')"; + static const char *strBoxTemplate = + "ST_GeomFromText('POLYGON((%.15g %.15g,%.15g %.15g,%.15g %.15g,%.15g " + "%.15g,%.15g %.15g))')"; + static const char *strBoxTemplatePoint = + "ST_GeomFromText('POINT(%.15g %.15g)')"; /* 10 doubles + template characters */ sz = 10 * 22 + strlen(strBoxTemplate); - strBox = (char*)msSmallMalloc(sz+1); /* add space for terminating NULL */ - if ( (bIsPoint && sz <= static_cast(snprintf(strBox, sz, strBoxTemplatePoint, - rect->minx, rect->miny))) || - (!bIsPoint && sz <= static_cast(snprintf(strBox, sz, strBoxTemplate, - rect->minx, rect->miny, - rect->minx, rect->maxy, - rect->maxx, rect->maxy, - rect->maxx, rect->miny, - rect->minx, rect->miny))) ) { - msSetError(MS_MISCERR,"Bounding box digits truncated.","msPostGISBuildSQLBox"); + strBox = (char *)msSmallMalloc(sz + 1); /* add space for terminating NULL */ + if ((bIsPoint && + sz <= static_cast(snprintf(strBox, sz, strBoxTemplatePoint, + rect->minx, rect->miny))) || + (!bIsPoint && + sz <= static_cast( + snprintf(strBox, sz, strBoxTemplate, rect->minx, rect->miny, + rect->minx, rect->maxy, rect->maxx, rect->maxy, + rect->maxx, rect->miny, rect->minx, rect->miny)))) { + msSetError(MS_MISCERR, "Bounding box digits truncated.", + "msPostGISBuildSQLBox"); return nullptr; } } return strBox; - } - /* ** msPostGISBuildSQLItems() ** ** Returns malloc'ed char* that must be freed by caller. */ -static std::string msPostGISBuildSQLItems(layerObj *layer) -{ +static std::string msPostGISBuildSQLItems(layerObj *layer) { const char *strEndian = nullptr; if (layer->debug) { msDebug("msPostGISBuildSQLItems called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - if ( layerinfo->geomcolumn.empty() ) { - msSetError(MS_MISCERR, "layerinfo->geomcolumn is not initialized.", "msPostGISBuildSQLItems()"); + if (layerinfo->geomcolumn.empty()) { + msSetError(MS_MISCERR, "layerinfo->geomcolumn is not initialized.", + "msPostGISBuildSQLItems()"); return std::string(); } @@ -1665,36 +1684,41 @@ static std::string msPostGISBuildSQLItems(layerObj *layer) */ const char *force2d = ""; #if TRANSFER_ENCODING == 64 - const char *strGeomTemplate = "encode(ST_AsBinary(%s(\"%s\"),'%s'),'base64') as geom,\"%s\""; + const char *strGeomTemplate = + "encode(ST_AsBinary(%s(\"%s\"),'%s'),'base64') as geom,\"%s\""; #elif TRANSFER_ENCODING == 256 - const char *strGeomTemplate = "ST_AsBinary(%s(\"%s\"),'%s') as geom,\"%s\"::text"; + const char *strGeomTemplate = + "ST_AsBinary(%s(\"%s\"),'%s') as geom,\"%s\"::text"; #else - const char *strGeomTemplate = "encode(ST_AsBinary(%s(\"%s\"),'%s'),'hex') as geom,\"%s\""; + const char *strGeomTemplate = + "encode(ST_AsBinary(%s(\"%s\"),'%s'),'hex') as geom,\"%s\""; #endif - if( layerinfo->force2d ) { - if( layerinfo->version >= 20100 ) + if (layerinfo->force2d) { + if (layerinfo->version >= 20100) force2d = "ST_Force2D"; else force2d = "ST_Force_2D"; - } - else if( layerinfo->version < 20000 ) - { - /* Use AsEWKB() to get 3D */ + } else if (layerinfo->version < 20000) { + /* Use AsEWKB() to get 3D */ #if TRANSFER_ENCODING == 64 - strGeomTemplate = "encode(AsEWKB(%s(\"%s\"),'%s'),'base64') as geom,\"%s\""; + strGeomTemplate = + "encode(AsEWKB(%s(\"%s\"),'%s'),'base64') as geom,\"%s\""; #elif TRANSFER_ENCODING == 256 - strGeomTemplate = "AsEWKB(%s(\"%s\"),'%s') as geom,\"%s\"::text"; + strGeomTemplate = "AsEWKB(%s(\"%s\"),'%s') as geom,\"%s\"::text"; #else - strGeomTemplate = "encode(AsEWKB(%s(\"%s\"),'%s'),'hex') as geom,\"%s\""; + strGeomTemplate = "encode(AsEWKB(%s(\"%s\"),'%s'),'hex') as geom,\"%s\""; #endif } - strGeom.resize(strlen(strGeomTemplate) + strlen(force2d) + strlen(strEndian) + layerinfo->geomcolumn.size() + layerinfo->uid.size()); - snprintf(&strGeom[0], strGeom.size(), strGeomTemplate, force2d, layerinfo->geomcolumn.c_str(), strEndian, layerinfo->uid.c_str()); + strGeom.resize(strlen(strGeomTemplate) + strlen(force2d) + + strlen(strEndian) + layerinfo->geomcolumn.size() + + layerinfo->uid.size()); + snprintf(&strGeom[0], strGeom.size(), strGeomTemplate, force2d, + layerinfo->geomcolumn.c_str(), strEndian, layerinfo->uid.c_str()); strGeom.resize(strlen(strGeom.data())); } - if( layer->debug > 1 ) { - msDebug("msPostGISBuildSQLItems: %d items requested.\n",layer->numitems); + if (layer->debug > 1) { + msDebug("msPostGISBuildSQLItems: %d items requested.\n", layer->numitems); } /* @@ -1704,13 +1728,13 @@ static std::string msPostGISBuildSQLItems(layerObj *layer) /* ** Build SQL to pull all the items. */ - for ( int t = 0; t < layer->numitems; t++ ) { - strItems += "\""; - strItems += layer->items[t]; + for (int t = 0; t < layer->numitems; t++) { + strItems += "\""; + strItems += layer->items[t]; #if TRANSFER_ENCODING == 256 - strItems += "\"::text,"; + strItems += "\"::text,"; #else - strItems += "\","; + strItems += "\","; #endif } strItems += strGeom; @@ -1718,43 +1742,40 @@ static std::string msPostGISBuildSQLItems(layerObj *layer) return strItems; } - /* ** msPostGISFindTableName() */ -static std::string msPostGISFindTableName(const char* fromsource) -{ +static std::string msPostGISFindTableName(const char *fromsource) { std::string f_table_name; const char *pos = strchr(fromsource, ' '); - - if ( ! pos ) { + + if (!pos) { /* target table is one word */ f_table_name = fromsource; } else { /* target table is hiding in sub-select clause */ pos = strcasestr(fromsource, " from "); - if ( pos ) { + if (pos) { pos += 6; /* should be start of table name */ - const char* pos_paren = strstr(pos, ")"); /* first ) after table name */ - const char* pos_space = strstr(pos, " "); /* first space after table name */ - if ( pos_space < pos_paren ) { + const char *pos_paren = strstr(pos, ")"); /* first ) after table name */ + const char *pos_space = + strstr(pos, " "); /* first space after table name */ + if (pos_space < pos_paren) { /* found space first */ f_table_name.assign(pos, pos_space - pos); } else { /* found ) first */ - f_table_name.assign( pos, pos_paren - pos); + f_table_name.assign(pos, pos_paren - pos); } } } return f_table_name; } - /* ** msPostGISBuildSQLSRID() */ -static std::string msPostGISBuildSQLSRID(layerObj *layer) -{ +static std::string msPostGISBuildSQLSRID(layerObj *layer) { std::string strSRID; @@ -1762,14 +1783,14 @@ static std::string msPostGISBuildSQLSRID(layerObj *layer) msDebug("msPostGISBuildSQLSRID called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* An SRID was already provided in the DATA line. */ - if ( !layerinfo->srid.empty() ) { + if (!layerinfo->srid.empty()) { strSRID = layerinfo->srid; - if( layer->debug > 1 ) { + if (layer->debug > 1) { msDebug("msPostGISBuildSQLSRID: SRID provided (%s)\n", strSRID.c_str()); } } @@ -1779,7 +1800,7 @@ static std::string msPostGISBuildSQLSRID(layerObj *layer) ** or "(select ... from thetable where ...)". */ else { - if( layer->debug > 1 ) { + if (layer->debug > 1) { msDebug("msPostGISBuildSQLSRID: Building find_srid line.\n"); } @@ -1792,70 +1813,71 @@ static std::string msPostGISBuildSQLSRID(layerObj *layer) return strSRID; } - /* ** msPostGISReplaceBoxToken() ** -** Convert a fromsource data statement into something usable by replacing the !BOX! token. +** Convert a fromsource data statement into something usable by replacing the +*!BOX! token. */ -static std::string msPostGISReplaceBoxToken(layerObj *layer, const rectObj *rect, const char *fromsource) -{ +static std::string msPostGISReplaceBoxToken(layerObj *layer, + const rectObj *rect, + const char *fromsource) { std::string result(fromsource); - - if( layer->debug > 1 ) { + + if (layer->debug > 1) { msDebug("msPostGISReplaceBoxToken called.\n"); - } + } - if ( strstr(fromsource, BOXTOKEN) && rect ) { + if (strstr(fromsource, BOXTOKEN) && rect) { char *strBox = nullptr; /* We see to set the SRID on the box, but to what SRID? */ const std::string strSRID = msPostGISBuildSQLSRID(layer); - if ( strSRID.empty() ) { + if (strSRID.empty()) { return std::string(); } /* Create a suitable SQL string from the rectangle and SRID. */ strBox = msPostGISBuildSQLBox(layer, rect, strSRID.c_str()); - if ( ! strBox ) { - msSetError(MS_MISCERR, "Unable to build box SQL.", "msPostGISReplaceBoxToken()"); + if (!strBox) { + msSetError(MS_MISCERR, "Unable to build box SQL.", + "msPostGISReplaceBoxToken()"); return std::string(); } /* Do the substitution. */ size_t pos = 0; - while( true ) { - pos = result.find(BOXTOKEN, pos); - if( pos == std::string::npos ) { - break; - } - const auto resultAfter(result.substr(pos + BOXTOKENLENGTH)); - result.resize(pos); - result += strBox; - result += resultAfter; + while (true) { + pos = result.find(BOXTOKEN, pos); + if (pos == std::string::npos) { + break; + } + const auto resultAfter(result.substr(pos + BOXTOKENLENGTH)); + result.resize(pos); + result += strBox; + result += resultAfter; } free(strBox); } return result; - } /* ** msPostGISBuildSQLFrom() */ -static std::string msPostGISBuildSQLFrom(layerObj *layer, const rectObj *rect) -{ +static std::string msPostGISBuildSQLFrom(layerObj *layer, const rectObj *rect) { if (layer->debug) { msDebug("msPostGISBuildSQLFrom called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - if ( layerinfo->fromsource.empty() ) { - msSetError(MS_MISCERR, "Layerinfo->fromsource is not initialized.", "msPostGISBuildSQLFrom()"); + if (layerinfo->fromsource.empty()) { + msSetError(MS_MISCERR, "Layerinfo->fromsource is not initialized.", + "msPostGISBuildSQLFrom()"); return std::string(); } @@ -1869,82 +1891,82 @@ static std::string msPostGISBuildSQLFrom(layerObj *layer, const rectObj *rect) /* ** msPostGISBuildSQLWhere() */ -static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, const long *uid, const rectObj *rectInOtherSRID, int otherSRID) -{ +static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, + const long *uid, + const rectObj *rectInOtherSRID, + int otherSRID) { if (layer->debug) { msDebug("msPostGISBuildSQLWhere called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - if ( layerinfo->fromsource.empty() ) { - msSetError(MS_MISCERR, "Layerinfo->fromsource is not initialized.", "msPostGISBuildSQLWhere()"); + if (layerinfo->fromsource.empty()) { + msSetError(MS_MISCERR, "Layerinfo->fromsource is not initialized.", + "msPostGISBuildSQLWhere()"); return std::string(); } /* Populate strRect, if necessary. */ std::string strRect; - if ( rect && !layerinfo->geomcolumn.empty() ) { + if (rect && !layerinfo->geomcolumn.empty()) { /* We see to set the SRID on the box, but to what SRID? */ const std::string strSRID = msPostGISBuildSQLSRID(layer); - if ( strSRID.empty() ) { + if (strSRID.empty()) { return std::string(); } - char* strBox = msPostGISBuildSQLBox(layer, rect, strSRID.c_str()); + char *strBox = msPostGISBuildSQLBox(layer, rect, strSRID.c_str()); - if ( !strBox ) { - msSetError(MS_MISCERR, "Unable to build box SQL.", "msPostGISBuildSQLWhere()"); + if (!strBox) { + msSetError(MS_MISCERR, "Unable to build box SQL.", + "msPostGISBuildSQLWhere()"); return std::string(); } - if( strSRID.find("find_srid(") == std::string::npos ) - { - // If the SRID is known, we can safely use ST_Intersects() - // otherwise if find_srid() would return 0, ST_Intersects() would not - // work at all, which breaks the msautotest/query/query_postgis.map - // tests, related to bdry_counpy2 layer that has no SRID - if( layerinfo->version >= 20500 ) - { - strRect = "ST_Intersects(\""; - strRect += layerinfo->geomcolumn; - strRect += "\", "; - strRect += strBox; - strRect += ')'; - } - else - { - // ST_Intersects() before PostGIS 2.5 doesn't support collections - // See https://github.com/MapServer/MapServer/pull/6355#issuecomment-877355007 - strRect = "(\""; - strRect += layerinfo->geomcolumn; - strRect += "\" && "; - strRect += strBox; - strRect += ") AND ST_Distance(\""; - strRect += layerinfo->geomcolumn; - strRect += "\", "; - strRect += strBox; - strRect += ") = 0"; - } - } - else - { - strRect = '"'; + if (strSRID.find("find_srid(") == std::string::npos) { + // If the SRID is known, we can safely use ST_Intersects() + // otherwise if find_srid() would return 0, ST_Intersects() would not + // work at all, which breaks the msautotest/query/query_postgis.map + // tests, related to bdry_counpy2 layer that has no SRID + if (layerinfo->version >= 20500) { + strRect = "ST_Intersects(\""; + strRect += layerinfo->geomcolumn; + strRect += "\", "; + strRect += strBox; + strRect += ')'; + } else { + // ST_Intersects() before PostGIS 2.5 doesn't support collections + // See + // https://github.com/MapServer/MapServer/pull/6355#issuecomment-877355007 + strRect = "(\""; strRect += layerinfo->geomcolumn; strRect += "\" && "; strRect += strBox; + strRect += ") AND ST_Distance(\""; + strRect += layerinfo->geomcolumn; + strRect += "\", "; + strRect += strBox; + strRect += ") = 0"; + } + } else { + strRect = '"'; + strRect += layerinfo->geomcolumn; + strRect += "\" && "; + strRect += strBox; } free(strBox); /* Combine with other rectangle expressed in another SRS */ /* (generally equivalent to the above in current code paths) */ - if( rectInOtherSRID != nullptr && otherSRID > 0 ) - { - strBox = msPostGISBuildSQLBox(layer, rectInOtherSRID, std::to_string(otherSRID).c_str()); - if ( !strBox ) { - msSetError(MS_MISCERR, "Unable to build box SQL.", "msPostGISBuildSQLWhere()"); + if (rectInOtherSRID != nullptr && otherSRID > 0) { + strBox = msPostGISBuildSQLBox(layer, rectInOtherSRID, + std::to_string(otherSRID).c_str()); + if (!strBox) { + msSetError(MS_MISCERR, "Unable to build box SQL.", + "msPostGISBuildSQLWhere()"); return std::string(); } @@ -1965,17 +1987,17 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, strTmp += ')'; strRect = std::move(strTmp); - } - else if( rectInOtherSRID != nullptr && otherSRID < 0 ) - { + } else if (rectInOtherSRID != nullptr && otherSRID < 0) { const std::string strSRID = msPostGISBuildSQLSRID(layer); - if ( strSRID.empty() ) { + if (strSRID.empty()) { return std::string(); } - char* strBox = msPostGISBuildSQLBox(layer, rectInOtherSRID, strSRID.c_str()); + char *strBox = + msPostGISBuildSQLBox(layer, rectInOtherSRID, strSRID.c_str()); - if ( !strBox ) { - msSetError(MS_MISCERR, "Unable to build box SQL.", "msPostGISBuildSQLWhere()"); + if (!strBox) { + msSetError(MS_MISCERR, "Unable to build box SQL.", + "msPostGISBuildSQLWhere()"); return std::string(); } @@ -1999,14 +2021,14 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, bool insert_and = false; std::string strWhere; - if ( !strRect.empty() ) { + if (!strRect.empty()) { strWhere += strRect; insert_and = true; } /* Handle a translated filter (RFC91). */ - if ( layer->filter.native_string ) { - if ( insert_and ) { + if (layer->filter.native_string) { + if (insert_and) { strWhere += " AND "; insert_and = true; } @@ -2017,8 +2039,8 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, /* Handle a native filter set as a PROCESSING option (#5001). */ const char *native_filter = msLayerGetProcessingKey(layer, "NATIVE_FILTER"); - if ( native_filter ) { - if ( insert_and ) { + if (native_filter) { + if (insert_and) { strWhere += " AND "; insert_and = true; } @@ -2027,8 +2049,8 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, strWhere += ')'; } - if ( uid ) { - if ( insert_and ) { + if (uid) { + if (insert_and) { strWhere += " AND "; } strWhere += '"'; @@ -2037,27 +2059,27 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, strWhere += std::to_string(*uid); } - if( layer->sortBy.nProperties > 0 ) { - char* pszTmp = msLayerBuildSQLOrderBy(layer); + if (layer->sortBy.nProperties > 0) { + char *pszTmp = msLayerBuildSQLOrderBy(layer); strWhere += " ORDER BY "; strWhere += pszTmp; msFree(pszTmp); } - if ( layerinfo->paging && layer->maxfeatures >= 0 ) { + if (layerinfo->paging && layer->maxfeatures >= 0) { strWhere += " LIMIT "; strWhere += std::to_string(layer->maxfeatures); } /* Populate strOffset, if necessary. */ - if ( layerinfo->paging && layer->startindex > 0 ) { + if (layerinfo->paging && layer->startindex > 0) { strWhere += " OFFSET "; - strWhere += std::to_string(layer->startindex-1); + strWhere += std::to_string(layer->startindex - 1); } if (strWhere.empty()) { - // return all records - strWhere = "true"; + // return all records + strWhere = "true"; } return strWhere; @@ -2068,44 +2090,51 @@ static std::string msPostGISBuildSQLWhere(layerObj *layer, const rectObj *rect, ** ** rect is the search rectangle in layer SRS. It can be set to NULL ** uid can be set to NULL -** rectInOtherSRID is an additional rectangle potentially in another SRS. It can be set to NULL. +** rectInOtherSRID is an additional rectangle potentially in another SRS. It can +*be set to NULL. ** Only used if rect != NULL ** otherSRID is the SRID of the additional rectangle. It can be set to -1 if ** rectInOtherSRID is in the SRID of the layer. */ -static std::string msPostGISBuildSQL(layerObj *layer, const rectObj *rect, const long *uid, const rectObj *rectInOtherSRID, int otherSRID) -{ +static std::string msPostGISBuildSQL(layerObj *layer, const rectObj *rect, + const long *uid, + const rectObj *rectInOtherSRID, + int otherSRID) { if (layer->debug) { msDebug("msPostGISBuildSQL called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; const std::string strItems = msPostGISBuildSQLItems(layer); - if ( strItems.empty() ) { + if (strItems.empty()) { msSetError(MS_MISCERR, "Failed to build SQL items.", "msPostGISBuildSQL()"); return std::string(); } const std::string strFrom = msPostGISBuildSQLFrom(layer, rect); - if ( strFrom.empty() ) { - msSetError(MS_MISCERR, "Failed to build SQL 'from'.", "msPostGISBuildSQL()"); + if (strFrom.empty()) { + msSetError(MS_MISCERR, "Failed to build SQL 'from'.", + "msPostGISBuildSQL()"); return std::string(); } - /* If there's BOX hackery going on, we don't want to append a box index test at - the end of the query, the user is going to be responsible for making things - work with their hackery. */ + /* If there's BOX hackery going on, we don't want to append a box index test + at the end of the query, the user is going to be responsible for making + things work with their hackery. */ std::string strWhere; - if ( strstr(layerinfo->fromsource.c_str(), BOXTOKEN) ) - strWhere = msPostGISBuildSQLWhere(layer, nullptr, uid, rectInOtherSRID, otherSRID); + if (strstr(layerinfo->fromsource.c_str(), BOXTOKEN)) + strWhere = + msPostGISBuildSQLWhere(layer, nullptr, uid, rectInOtherSRID, otherSRID); else - strWhere = msPostGISBuildSQLWhere(layer, rect, uid, rectInOtherSRID, otherSRID); + strWhere = + msPostGISBuildSQLWhere(layer, rect, uid, rectInOtherSRID, otherSRID); - if ( strWhere.empty() ) { - msSetError(MS_MISCERR, "Failed to build SQL 'where'.", "msPostGISBuildSQL()"); + if (strWhere.empty()) { + msSetError(MS_MISCERR, "Failed to build SQL 'where'.", + "msPostGISBuildSQL()"); return std::string(); } @@ -2120,28 +2149,30 @@ static std::string msPostGISBuildSQL(layerObj *layer, const rectObj *rect, const } #define wkbstaticsize 4096 -static int msPostGISReadShape(layerObj *layer, shapeObj *shape) -{ +static int msPostGISReadShape(layerObj *layer, shapeObj *shape) { if (layer->debug) { msDebug("msPostGISReadShape called.\n"); } assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* Retrieve the geometry. */ - const char* wkbstr = PQgetvalue(layerinfo->pgresult, layerinfo->rownum, layer->numitems ); - const int wkbstrlen = PQgetlength(layerinfo->pgresult, layerinfo->rownum, layer->numitems); + const char *wkbstr = + PQgetvalue(layerinfo->pgresult, layerinfo->rownum, layer->numitems); + const int wkbstrlen = + PQgetlength(layerinfo->pgresult, layerinfo->rownum, layer->numitems); - if ( ! wkbstr ) { + if (!wkbstr) { msSetError(MS_QUERYERR, "WKB returned is null!", "msPostGISReadShape()"); return MS_FAILURE; } unsigned char wkbstatic[wkbstaticsize]; unsigned char *wkb = nullptr; - if(wkbstrlen > wkbstaticsize) { - wkb = static_cast(calloc(wkbstrlen, sizeof(unsigned char))); + if (wkbstrlen > wkbstaticsize) { + wkb = + static_cast(calloc(wkbstrlen, sizeof(unsigned char))); } else { wkb = wkbstatic; } @@ -2150,9 +2181,10 @@ static int msPostGISReadShape(layerObj *layer, shapeObj *shape) int result = 0; #if TRANSFER_ENCODING == 64 result = msPostGISBase64Decode(wkb, wkbstr, wkbstrlen - 1); - w.size = (wkbstrlen - 1)/2; - if( ! result ) { - if(wkb!=wkbstatic) free(wkb); + w.size = (wkbstrlen - 1) / 2; + if (!result) { + if (wkb != wkbstatic) + free(wkb); return MS_FAILURE; } #elif TRANSFER_ENCODING == 256 @@ -2160,131 +2192,134 @@ static int msPostGISReadShape(layerObj *layer, shapeObj *shape) w.size = wkbstrlen; #else result = msPostGISHexDecode(wkb, wkbstr, wkbstrlen); - w.size = (wkbstrlen - 1)/2; - if( ! result ) { - if(wkb!=wkbstatic) free(wkb); + w.size = (wkbstrlen - 1) / 2; + if (!result) { + if (wkb != wkbstatic) + free(wkb); return MS_FAILURE; } #endif /* Initialize our wkbObj */ - w.wkb = (char*)wkb; + w.wkb = (char *)wkb; w.ptr = w.wkb; - /* Set the type map according to what version of PostGIS we are dealing with */ - if( layerinfo->version >= 20000 ) /* PostGIS 2.0+ */ + /* Set the type map according to what version of PostGIS we are dealing with + */ + if (layerinfo->version >= 20000) /* PostGIS 2.0+ */ w.typemap = wkb_postgis20; - else - { + else { w.typemap = wkb_postgis15; - if( layerinfo->force2d == MS_FALSE ) - { - /* Is there SRID ? Skip it */ - if( w.size >= 9 && (w.ptr[4] & 0x20) != 0 ) - { - w.ptr[5] = w.ptr[1]; - w.ptr[6] = w.ptr[2]; - w.ptr[7] = w.ptr[3]; - w.ptr[8] = w.ptr[4] & ~(0x20); - w.ptr[4] = 1; - w.ptr += 4; - w.size -= 4; - } + if (layerinfo->force2d == MS_FALSE) { + /* Is there SRID ? Skip it */ + if (w.size >= 9 && (w.ptr[4] & 0x20) != 0) { + w.ptr[5] = w.ptr[1]; + w.ptr[6] = w.ptr[2]; + w.ptr[7] = w.ptr[3]; + w.ptr[8] = w.ptr[4] & ~(0x20); + w.ptr[4] = 1; + w.ptr += 4; + w.size -= 4; + } } } switch (layer->type) { - case MS_LAYER_POINT: - shape->type = MS_SHAPE_POINT; - result = wkbConvGeometryToShape(&w, shape); - break; + case MS_LAYER_POINT: + shape->type = MS_SHAPE_POINT; + result = wkbConvGeometryToShape(&w, shape); + break; - case MS_LAYER_LINE: - shape->type = MS_SHAPE_LINE; - result = wkbConvGeometryToShape(&w, shape); - break; + case MS_LAYER_LINE: + shape->type = MS_SHAPE_LINE; + result = wkbConvGeometryToShape(&w, shape); + break; - case MS_LAYER_POLYGON: - shape->type = MS_SHAPE_POLYGON; - result = wkbConvGeometryToShape(&w, shape); - break; + case MS_LAYER_POLYGON: + shape->type = MS_SHAPE_POLYGON; + result = wkbConvGeometryToShape(&w, shape); + break; - case MS_LAYER_QUERY: - case MS_LAYER_CHART: - result = msPostGISFindBestType(&w, shape); - break; + case MS_LAYER_QUERY: + case MS_LAYER_CHART: + result = msPostGISFindBestType(&w, shape); + break; - case MS_LAYER_RASTER: - msDebug("Ignoring MS_LAYER_RASTER in msPostGISReadShape.\n"); - break; + case MS_LAYER_RASTER: + msDebug("Ignoring MS_LAYER_RASTER in msPostGISReadShape.\n"); + break; - case MS_LAYER_CIRCLE: - msDebug("Ignoring MS_LAYER_RASTER in msPostGISReadShape.\n"); - break; + case MS_LAYER_CIRCLE: + msDebug("Ignoring MS_LAYER_RASTER in msPostGISReadShape.\n"); + break; - default: - msDebug("Unsupported layer type in msPostGISReadShape()!\n"); - break; + default: + msDebug("Unsupported layer type in msPostGISReadShape()!\n"); + break; } /* All done with WKB geometry, free it! */ - if(wkb!=wkbstatic) free(wkb); + if (wkb != wkbstatic) + free(wkb); if (result != MS_FAILURE) { /* Found a drawable shape, so now retreive the attributes. */ - shape->values = (char**) msSmallMalloc(sizeof(char*) * layer->numitems); - for ( int t = 0; t < layer->numitems; t++) { + shape->values = (char **)msSmallMalloc(sizeof(char *) * layer->numitems); + for (int t = 0; t < layer->numitems; t++) { const int size = PQgetlength(layerinfo->pgresult, layerinfo->rownum, t); const char *val = PQgetvalue(layerinfo->pgresult, layerinfo->rownum, t); const int isnull = PQgetisnull(layerinfo->pgresult, layerinfo->rownum, t); - if ( isnull ) { + if (isnull) { shape->values[t] = msStrdup(""); } else { - shape->values[t] = (char*) msSmallMalloc(size + 1); + shape->values[t] = (char *)msSmallMalloc(size + 1); memcpy(shape->values[t], val, size); shape->values[t][size] = '\0'; /* null terminate it */ // From https://www.postgresql.org/docs/9.0/datatype-character.html // fields of type Char are blank padded, but this blank is semantically // insignificant, so let's trim it - if( PQftype(layerinfo->pgresult, t) == CHAROID ) - msStringTrimBlanks(shape->values[t]); + if (PQftype(layerinfo->pgresult, t) == CHAROID) + msStringTrimBlanks(shape->values[t]); } - if( layer->debug > 4 ) { + if (layer->debug > 4) { msDebug("msPostGISReadShape: PQgetlength = %d\n", size); } - if( layer->debug > 1 ) { - msDebug("msPostGISReadShape: [%s] \"%s\"\n", layer->items[t], shape->values[t]); + if (layer->debug > 1) { + msDebug("msPostGISReadShape: [%s] \"%s\"\n", layer->items[t], + shape->values[t]); } } /* layer->numitems is the geometry, layer->numitems+1 is the uid */ - const char* tmp = PQgetvalue(layerinfo->pgresult, layerinfo->rownum, layer->numitems + 1); + const char *tmp = + PQgetvalue(layerinfo->pgresult, layerinfo->rownum, layer->numitems + 1); long uid = 0; - if( tmp ) { - uid = strtol( tmp, nullptr, 10 ); + if (tmp) { + uid = strtol(tmp, nullptr, 10); } - if( layer->debug > 4 ) { + if (layer->debug > 4) { msDebug("msPostGISReadShape: Setting shape->index = %ld\n", uid); - msDebug("msPostGISReadShape: Setting shape->resultindex = %ld\n", layerinfo->rownum); + msDebug("msPostGISReadShape: Setting shape->resultindex = %ld\n", + layerinfo->rownum); } shape->index = uid; shape->resultindex = layerinfo->rownum; - if( layer->debug > 2 ) { - msDebug("msPostGISReadShape: [index] %ld\n", shape->index); + if (layer->debug > 2) { + msDebug("msPostGISReadShape: [index] %ld\n", shape->index); } shape->numvalues = layer->numitems; msComputeBounds(shape); } else { - shape->type = MS_SHAPE_NULL; + shape->type = MS_SHAPE_NULL; } - if( layer->debug > 2 ) { + if (layer->debug > 2) { char *tmp = msShapeToWKT(shape); msDebug("msPostGISReadShape: [shape] %s\n", tmp); free(tmp); @@ -2295,14 +2330,12 @@ static int msPostGISReadShape(layerObj *layer, shapeObj *shape) #endif /* USE_POSTGIS */ - /* ** msPostGISLayerOpen() ** ** Registered vtable->LayerOpen function. */ -static int msPostGISLayerOpen(layerObj *layer) -{ +static int msPostGISLayerOpen(layerObj *layer) { #ifdef USE_POSTGIS assert(layer != nullptr); @@ -2314,21 +2347,22 @@ static int msPostGISLayerOpen(layerObj *layer) if (layer->debug) { msDebug("msPostGISLayerOpen: Layer is already open!\n"); } - return MS_SUCCESS; /* already open */ + return MS_SUCCESS; /* already open */ } if (!layer->data) { - msSetError(MS_QUERYERR, "Nothing specified in DATA statement.", "msPostGISLayerOpen()"); + msSetError(MS_QUERYERR, "Nothing specified in DATA statement.", + "msPostGISLayerOpen()"); return MS_FAILURE; } /* ** Initialize the layerinfo **/ - msPostGISLayerInfo* layerinfo = msPostGISCreateLayerInfo(); + msPostGISLayerInfo *layerinfo = msPostGISCreateLayerInfo(); int order_test = 1; - if (((char*) &order_test)[0] == 1) { + if (((char *)&order_test)[0] == 1) { layerinfo->endian = LITTLE_ENDIAN; } else { layerinfo->endian = BIG_ENDIAN; @@ -2337,16 +2371,18 @@ static int msPostGISLayerOpen(layerObj *layer) /* ** Get a database connection from the pool. */ - layerinfo->pgconn = (PGconn *) msConnPoolRequest(layer); + layerinfo->pgconn = (PGconn *)msConnPoolRequest(layer); /* No connection in the pool, so set one up. */ if (!layerinfo->pgconn) { if (layer->debug) { - msDebug("msPostGISLayerOpen: No connection in pool, creating a fresh one.\n"); + msDebug( + "msPostGISLayerOpen: No connection in pool, creating a fresh one.\n"); } if (!layer->connection) { - msSetError(MS_MISCERR, "Missing CONNECTION keyword.", "msPostGISLayerOpen()"); + msSetError(MS_MISCERR, "Missing CONNECTION keyword.", + "msPostGISLayerOpen()"); delete layerinfo; return MS_FAILURE; } @@ -2354,10 +2390,10 @@ static int msPostGISLayerOpen(layerObj *layer) /* ** Decrypt any encrypted token in connection string and attempt to connect. */ - char* conn_decrypted = msDecryptStringTokens(layer->map, layer->connection); + char *conn_decrypted = msDecryptStringTokens(layer->map, layer->connection); if (conn_decrypted == nullptr) { delete layerinfo; - return MS_FAILURE; /* An error should already have been produced */ + return MS_FAILURE; /* An error should already have been produced */ } layerinfo->pgconn = PQconnectdb(conn_decrypted); msFree(conn_decrypted); @@ -2370,32 +2406,49 @@ static int msPostGISLayerOpen(layerObj *layer) if (layer->debug) msDebug("msPostGISLayerOpen: Connection failure.\n"); - msDebug( "Database connection failed (%s) with connect string '%s'\nIs the database running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port? in msPostGISLayerOpen()", PQerrorMessage(layerinfo->pgconn), layer->connection); - msSetError(MS_QUERYERR, "Database connection failed. Check server logs for more details.Is the database running? Is it allowing connections? Does the specified user exist? Is the password valid? Is the database on the standard port?", "msPostGISLayerOpen()"); - - if(layerinfo->pgconn) PQfinish(layerinfo->pgconn); + msDebug("Database connection failed (%s) with connect string '%s'\nIs " + "the database running? Is it allowing connections? Does the " + "specified user exist? Is the password valid? Is the database on " + "the standard port? in msPostGISLayerOpen()", + PQerrorMessage(layerinfo->pgconn), layer->connection); + msSetError(MS_QUERYERR, + "Database connection failed. Check server logs for more " + "details.Is the database running? Is it allowing connections? " + "Does the specified user exist? Is the password valid? Is the " + "database on the standard port?", + "msPostGISLayerOpen()"); + + if (layerinfo->pgconn) + PQfinish(layerinfo->pgconn); delete layerinfo; return MS_FAILURE; } /* Register to receive notifications from the database. */ - PQsetNoticeProcessor(layerinfo->pgconn, postresqlNoticeHandler, (void *) layer); + PQsetNoticeProcessor(layerinfo->pgconn, postresqlNoticeHandler, + (void *)layer); /* Save this connection in the pool for later. */ msConnPoolRegister(layer, layerinfo->pgconn, msPostGISCloseConnection); } else { /* Connection in the pool should be tested to see if backend is alive. */ - if( PQstatus(layerinfo->pgconn) != CONNECTION_OK ) { + if (PQstatus(layerinfo->pgconn) != CONNECTION_OK) { /* Uh oh, bad connection. Can we reset it? */ PQreset(layerinfo->pgconn); - if( PQstatus(layerinfo->pgconn) != CONNECTION_OK ) { + if (PQstatus(layerinfo->pgconn) != CONNECTION_OK) { /* Nope, time to bail out. */ - msSetError(MS_QUERYERR, "PostgreSQL database connection. Check server logs for more details", "msPostGISLayerOpen()"); - msDebug( "PostgreSQL database connection gone bad (%s) in msPostGISLayerOpen()", PQerrorMessage(layerinfo->pgconn)); + msSetError(MS_QUERYERR, + "PostgreSQL database connection. Check server logs for more " + "details", + "msPostGISLayerOpen()"); + msDebug("PostgreSQL database connection gone bad (%s) in " + "msPostGISLayerOpen()", + PQerrorMessage(layerinfo->pgconn)); delete layerinfo; - /* FIXME: we should also release the connection from the pool in this case, but it is stale... - * for the time being we do not release it so it can never be used again. If this happens multiple - * times there will be a leak... */ + /* FIXME: we should also release the connection from the pool in this + * case, but it is stale... for the time being we do not release it so + * it can never be used again. If this happens multiple times there will + * be a leak... */ return MS_FAILURE; } } @@ -2403,32 +2456,32 @@ static int msPostGISLayerOpen(layerObj *layer) /* Get the PostGIS version number from the database */ layerinfo->version = msPostGISRetrieveVersion(layerinfo->pgconn); - if( layerinfo->version == MS_FAILURE ) { + if (layerinfo->version == MS_FAILURE) { msConnPoolRelease(layer, layerinfo->pgconn); delete layerinfo; return MS_FAILURE; } if (layer->debug) - msDebug("msPostGISLayerOpen: Got PostGIS version %d.\n", layerinfo->version); + msDebug("msPostGISLayerOpen: Got PostGIS version %d.\n", + layerinfo->version); - const char* force2d_processing = msLayerGetProcessingKey( layer, "FORCE2D" ); - if(force2d_processing && !strcasecmp(force2d_processing,"no")) { + const char *force2d_processing = msLayerGetProcessingKey(layer, "FORCE2D"); + if (force2d_processing && !strcasecmp(force2d_processing, "no")) { layerinfo->force2d = MS_FALSE; - } - else if(force2d_processing && !strcasecmp(force2d_processing,"yes")) { + } else if (force2d_processing && !strcasecmp(force2d_processing, "yes")) { layerinfo->force2d = MS_TRUE; } if (layer->debug) - msDebug("msPostGISLayerOpen: Forcing 2D geometries: %s.\n", (layerinfo->force2d)?"yes":"no"); + msDebug("msPostGISLayerOpen: Forcing 2D geometries: %s.\n", + (layerinfo->force2d) ? "yes" : "no"); /* Save the layerinfo in the layerObj. */ - layer->layerinfo = (void*)layerinfo; + layer->layerinfo = (void *)layerinfo; return MS_SUCCESS; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerOpen()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerOpen()"); return MS_FAILURE; #endif } @@ -2438,35 +2491,31 @@ static int msPostGISLayerOpen(layerObj *layer) ** ** Registered vtable->LayerClose function. */ -static int msPostGISLayerClose(layerObj *layer) -{ +static int msPostGISLayerClose(layerObj *layer) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISLayerClose called: %s\n", layer->data); } - if( layer->layerinfo ) { + if (layer->layerinfo) { msPostGISFreeLayerInfo(layer); } return MS_SUCCESS; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerClose()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerClose()"); return MS_FAILURE; #endif } - /* ** msPostGISLayerIsOpen() ** ** Registered vtable->LayerIsOpen function. */ -static int msPostGISLayerIsOpen(layerObj *layer) -{ +static int msPostGISLayerIsOpen(layerObj *layer) { #ifdef USE_POSTGIS if (layer->debug) { @@ -2478,21 +2527,18 @@ static int msPostGISLayerIsOpen(layerObj *layer) else return MS_FALSE; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerIsOpen()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerIsOpen()"); return MS_FAILURE; #endif } - /* ** msPostGISLayerFreeItemInfo() ** ** Registered vtable->LayerFreeItemInfo function. */ -static void msPostGISLayerFreeItemInfo(layerObj *layer) -{ +static void msPostGISLayerFreeItemInfo(layerObj *layer) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISLayerFreeItemInfo called.\n"); @@ -2511,8 +2557,7 @@ static void msPostGISLayerFreeItemInfo(layerObj *layer) ** Registered vtable->LayerInitItemInfo function. ** Our iteminfo is list of indexes from 1..numitems. */ -static int msPostGISLayerInitItemInfo(layerObj *layer) -{ +static int msPostGISLayerInitItemInfo(layerObj *layer) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISLayerInitItemInfo called.\n"); @@ -2532,47 +2577,52 @@ static int msPostGISLayerInitItemInfo(layerObj *layer) return MS_FAILURE; } - int* itemindexes = (int*)layer->iteminfo; + int *itemindexes = (int *)layer->iteminfo; for (int i = 0; i < layer->numitems; i++) { - itemindexes[i] = i; /* Last item is always the geometry. The rest are non-geometry. */ + itemindexes[i] = + i; /* Last item is always the geometry. The rest are non-geometry. */ } return MS_SUCCESS; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerInitItemInfo()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerInitItemInfo()"); return MS_FAILURE; #endif } #ifdef USE_POSTGIS -static std::vector buildBindValues(layerObj *layer) -{ +static std::vector buildBindValues(layerObj *layer) { /* try to get the first bind value */ - const char* bind_value = msLookupHashTable(&layer->bindvals, "1"); - std::vector layer_bind_values; - while(bind_value != nullptr) { + const char *bind_value = msLookupHashTable(&layer->bindvals, "1"); + std::vector layer_bind_values; + while (bind_value != nullptr) { /* put the bind value on the stack */ layer_bind_values.push_back(bind_value); /* get the bind_value */ - bind_value = msLookupHashTable(&layer->bindvals, - std::to_string(static_cast(layer_bind_values.size())+1).c_str()); + bind_value = msLookupHashTable( + &layer->bindvals, + std::to_string(static_cast(layer_bind_values.size()) + 1) + .c_str()); } return layer_bind_values; } -static PGresult* runPQexecParamsWithBindSubstitution(layerObj *layer, const char* strSQL, int binary) -{ +static PGresult *runPQexecParamsWithBindSubstitution(layerObj *layer, + const char *strSQL, + int binary) { PGresult *pgresult = nullptr; - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; const auto layer_bind_values = buildBindValues(layer); - if( !layer_bind_values.empty() ) { - pgresult = PQexecParams(layerinfo->pgconn, strSQL, static_cast(layer_bind_values.size()), nullptr, layer_bind_values.data(), nullptr, nullptr, binary); + if (!layer_bind_values.empty()) { + pgresult = PQexecParams(layerinfo->pgconn, strSQL, + static_cast(layer_bind_values.size()), nullptr, + layer_bind_values.data(), nullptr, nullptr, binary); } else { - pgresult = PQexecParams(layerinfo->pgconn, strSQL, 0, nullptr, nullptr, nullptr, nullptr, binary); + pgresult = PQexecParams(layerinfo->pgconn, strSQL, 0, nullptr, nullptr, + nullptr, nullptr, binary); } return pgresult; @@ -2585,8 +2635,8 @@ static PGresult* runPQexecParamsWithBindSubstitution(layerObj *layer, const char ** Registered vtable->LayerWhichShapes function. */ // cppcheck-suppress passedByValue -static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) -{ +static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, + int isQuery) { (void)isQuery; #ifdef USE_POSTGIS assert(layer != nullptr); @@ -2597,7 +2647,7 @@ static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) } /* Fill out layerinfo with our current DATA state. */ - if ( msPostGISParseData(layer) != MS_SUCCESS) { + if (msPostGISParseData(layer) != MS_SUCCESS) { return MS_FAILURE; } @@ -2605,12 +2655,14 @@ static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) ** This comes *after* parsedata, because parsedata fills in ** layer->layerinfo. */ - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* Build a SQL query based on our current state. */ - const std::string strSQL = msPostGISBuildSQL(layer, &rect, nullptr, nullptr, -1); - if ( strSQL.empty() ) { - msSetError(MS_QUERYERR, "Failed to build query SQL.", "msPostGISLayerWhichShapes()"); + const std::string strSQL = + msPostGISBuildSQL(layer, &rect, nullptr, nullptr, -1); + if (strSQL.empty()) { + msSetError(MS_QUERYERR, "Failed to build query SQL.", + "msPostGISLayerWhichShapes()"); return MS_FAILURE; } @@ -2618,28 +2670,34 @@ static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) msDebug("msPostGISLayerWhichShapes query: %s\n", strSQL.c_str()); } - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), RESULTSET_TYPE); + PGresult *pgresult = runPQexecParamsWithBindSubstitution( + layer, strSQL.c_str(), RESULTSET_TYPE); - if ( layer->debug > 1 ) { - msDebug("msPostGISLayerWhichShapes query status: %s (%d)\n", PQresStatus(PQresultStatus(pgresult)), PQresultStatus(pgresult)); + if (layer->debug > 1) { + msDebug("msPostGISLayerWhichShapes query status: %s (%d)\n", + PQresStatus(PQresultStatus(pgresult)), PQresultStatus(pgresult)); } /* Something went wrong. */ if (!pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) { - msDebug("msPostGISLayerWhichShapes(): Error (%s) executing query: %s\n", PQerrorMessage(layerinfo->pgconn), strSQL.c_str()); - msSetError(MS_QUERYERR, "Error executing query. Check server logs","msPostGISLayerWhichShapes()"); + msDebug("msPostGISLayerWhichShapes(): Error (%s) executing query: %s\n", + PQerrorMessage(layerinfo->pgconn), strSQL.c_str()); + msSetError(MS_QUERYERR, "Error executing query. Check server logs", + "msPostGISLayerWhichShapes()"); if (pgresult) { PQclear(pgresult); } return MS_FAILURE; } - if ( layer->debug ) { - msDebug("msPostGISLayerWhichShapes got %d records in result.\n", PQntuples(pgresult)); + if (layer->debug) { + msDebug("msPostGISLayerWhichShapes got %d records in result.\n", + PQntuples(pgresult)); } /* Clean any existing pgresult before storing current one. */ - if(layerinfo->pgresult) PQclear(layerinfo->pgresult); + if (layerinfo->pgresult) + PQclear(layerinfo->pgresult); layerinfo->pgresult = pgresult; layerinfo->sql = strSQL; @@ -2648,9 +2706,8 @@ static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) return MS_SUCCESS; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerWhichShapes()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerWhichShapes()"); return MS_FAILURE; #endif } @@ -2660,8 +2717,7 @@ static int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) ** ** Registered vtable->LayerNextShape function. */ -static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) -{ +static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISLayerNextShape called.\n"); @@ -2670,7 +2726,7 @@ static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) assert(layer != nullptr); assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; shape->type = MS_SHAPE_NULL; @@ -2681,7 +2737,7 @@ static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) if (layerinfo->rownum < PQntuples(layerinfo->pgresult)) { /* Retrieve this shape, cursor access mode. */ msPostGISReadShape(layer, shape); - if( shape->type != MS_SHAPE_NULL ) { + if (shape->type != MS_SHAPE_NULL) { (layerinfo->rownum)++; /* move to next shape */ return MS_SUCCESS; } else { @@ -2697,9 +2753,8 @@ static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) return MS_FAILURE; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerNextShape()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerNextShape()"); return MS_FAILURE; #endif } @@ -2707,10 +2762,10 @@ static int msPostGISLayerNextShape(layerObj *layer, shapeObj *shape) /* ** msPostGISLayerGetShape() ** - */ +*/ // cppcheck-suppress passedByValue -static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, projectionObj *rectProjection) -{ +static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, + projectionObj *rectProjection) { #ifdef USE_POSTGIS int rectSRID = -1; rectObj searchrectInLayerProj = rect; @@ -2722,34 +2777,36 @@ static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, projection msDebug("msPostGISLayerGetShapeCount called.\n"); } - - // Special processing if the specified projection for the rect is different from the layer projection - // We want to issue a WHERE that includes - // ((the_geom && rect_reprojected_in_layer_SRID) AND NOT ST_Disjoint(ST_Transform(the_geom, rect_SRID), rect)) - if( rectProjection != NULL && layer->project && - msProjectionsDiffer(&(layer->projection), rectProjection) ) - { + // Special processing if the specified projection for the rect is different + // from the layer projection We want to issue a WHERE that includes + // ((the_geom && rect_reprojected_in_layer_SRID) AND NOT + // ST_Disjoint(ST_Transform(the_geom, rect_SRID), rect)) + if (rectProjection != NULL && layer->project && + msProjectionsDiffer(&(layer->projection), rectProjection)) { // If we cannot guess the EPSG code of the rectProjection, we cannot // use ST_Transform, so fallback on slow implementation - if( rectProjection->numargs < 1 || - strncasecmp(rectProjection->args[0], "init=epsg:", strlen("init=epsg:")) != 0 ) - { + if (rectProjection->numargs < 1 || + strncasecmp(rectProjection->args[0], + "init=epsg:", strlen("init=epsg:")) != 0) { if (layer->debug) { - msDebug("msPostGISLayerGetShapeCount(): cannot find EPSG code of rectProjection. Falling back on client-side feature count.\n"); + msDebug("msPostGISLayerGetShapeCount(): cannot find EPSG code of " + "rectProjection. Falling back on client-side feature count.\n"); } return LayerDefaultGetShapeCount(layer, rect, rectProjection); } // Reproject the passed rect into the layer projection and get // the SRID from the rectProjection - msProjectRect(rectProjection, &(layer->projection), &searchrectInLayerProj); /* project the searchrect to source coords */ + msProjectRect( + rectProjection, &(layer->projection), + &searchrectInLayerProj); /* project the searchrect to source coords */ rectSRID = atoi(rectProjection->args[0] + strlen("init=epsg:")); } msLayerTranslateFilter(layer, &layer->filter, layer->filteritem); /* Fill out layerinfo with our current DATA state. */ - if ( msPostGISParseData(layer) != MS_SUCCESS) { + if (msPostGISParseData(layer) != MS_SUCCESS) { return -1; } @@ -2757,13 +2814,14 @@ static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, projection ** This comes *after* parsedata, because parsedata fills in ** layer->layerinfo. */ - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* Build a SQL query based on our current state. */ - const std::string strSQL = msPostGISBuildSQL(layer, &searchrectInLayerProj, nullptr, - &rect, rectSRID); - if ( strSQL.empty() ) { - msSetError(MS_QUERYERR, "Failed to build query SQL.", "msPostGISLayerGetShapeCount()"); + const std::string strSQL = msPostGISBuildSQL(layer, &searchrectInLayerProj, + nullptr, &rect, rectSRID); + if (strSQL.empty()) { + msSetError(MS_QUERYERR, "Failed to build query SQL.", + "msPostGISLayerGetShapeCount()"); return -1; } @@ -2775,9 +2833,10 @@ static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, projection msDebug("msPostGISLayerGetShapeCount query: %s\n", strSQLCount.c_str()); } - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, strSQLCount.c_str(), 0); + PGresult *pgresult = + runPQexecParamsWithBindSubstitution(layer, strSQLCount.c_str(), 0); - if ( layer->debug > 1 ) { + if (layer->debug > 1) { msDebug("msPostGISLayerWhichShapes query status: %s (%d)\n", PQresStatus(PQresultStatus(pgresult)), PQresultStatus(pgresult)); } @@ -2793,31 +2852,29 @@ static int msPostGISLayerGetShapeCount(layerObj *layer, rectObj rect, projection return LayerDefaultGetShapeCount(layer, rect, rectProjection); } - const int nCount = atoi(PQgetvalue(pgresult, 0, 0 )); + const int nCount = atoi(PQgetvalue(pgresult, 0, 0)); - if ( layer->debug ) { + if (layer->debug) { msDebug("msPostGISLayerWhichShapes return: %d.\n", nCount); } PQclear(pgresult); return nCount; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerGetShapeCount()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerGetShapeCount()"); return -1; #endif } - /* ** msPostGISLayerGetShape() ** ** Registered vtable->LayerGetShape function. For pulling from a prepared and ** undisposed result set. */ -static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ +static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, + resultObj *record) { #ifdef USE_POSTGIS long shapeindex = record->shapeindex; @@ -2830,35 +2887,36 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r msDebug("msPostGISLayerGetShape called for record = %i\n", resultindex); } - /* If resultindex is set, fetch the shape from the resultcache, otherwise fetch it from the DB */ + /* If resultindex is set, fetch the shape from the resultcache, otherwise + * fetch it from the DB */ if (resultindex >= 0) { - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* Check the validity of the open result. */ - PGresult* pgresult = layerinfo->pgresult; - if ( ! pgresult ) { - msSetError( MS_MISCERR, - "PostgreSQL result set is null.", - "msPostGISLayerGetShape()"); + PGresult *pgresult = layerinfo->pgresult; + if (!pgresult) { + msSetError(MS_MISCERR, "PostgreSQL result set is null.", + "msPostGISLayerGetShape()"); return MS_FAILURE; } ExecStatusType status = PQresultStatus(pgresult); - if ( layer->debug > 1 ) { - msDebug("msPostGISLayerGetShape query status: %s (%d)\n", PQresStatus(status), (int)status); + if (layer->debug > 1) { + msDebug("msPostGISLayerGetShape query status: %s (%d)\n", + PQresStatus(status), (int)status); } - if( ! ( status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) ) { - msSetError( MS_MISCERR, - "PostgreSQL result set is not ready.", - "msPostGISLayerGetShape()"); + if (!(status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK)) { + msSetError(MS_MISCERR, "PostgreSQL result set is not ready.", + "msPostGISLayerGetShape()"); return MS_FAILURE; } /* Check the validity of the requested record number. */ - if( resultindex >= PQntuples(pgresult) ) { - msDebug("msPostGISLayerGetShape got request for (%d) but only has %d tuples.\n", resultindex, PQntuples(pgresult)); - msSetError( MS_MISCERR, - "Got request larger than result set.", - "msPostGISLayerGetShape()"); + if (resultindex >= PQntuples(pgresult)) { + msDebug("msPostGISLayerGetShape got request for (%d) but only has %d " + "tuples.\n", + resultindex, PQntuples(pgresult)); + msSetError(MS_MISCERR, "Got request larger than result set.", + "msPostGISLayerGetShape()"); return MS_FAILURE; } @@ -2875,7 +2933,7 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r int num_tuples; /* Fill out layerinfo with our current DATA state. */ - if ( msPostGISParseData(layer) != MS_SUCCESS) { + if (msPostGISParseData(layer) != MS_SUCCESS) { return MS_FAILURE; } @@ -2883,12 +2941,14 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r ** This comes *after* parsedata, because parsedata fills in ** layer->layerinfo. */ - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* Build a SQL query based on our current state. */ - const std::string strSQL = msPostGISBuildSQL(layer, nullptr, &shapeindex, nullptr, -1); - if ( strSQL.empty() ) { - msSetError(MS_QUERYERR, "Failed to build query SQL.", "msPostGISLayerGetShape()"); + const std::string strSQL = + msPostGISBuildSQL(layer, nullptr, &shapeindex, nullptr, -1); + if (strSQL.empty()) { + msSetError(MS_QUERYERR, "Failed to build query SQL.", + "msPostGISLayerGetShape()"); return MS_FAILURE; } @@ -2896,12 +2956,15 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r msDebug("msPostGISLayerGetShape query: %s\n", strSQL.c_str()); } - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), RESULTSET_TYPE); + PGresult *pgresult = runPQexecParamsWithBindSubstitution( + layer, strSQL.c_str(), RESULTSET_TYPE); /* Something went wrong. */ - if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) { - msDebug("msPostGISLayerGetShape(): Error (%s) executing SQL: %s\n", PQerrorMessage(layerinfo->pgconn), strSQL.c_str() ); - msSetError(MS_QUERYERR, "Error executing SQL. Check server logs.","msPostGISLayerGetShape()"); + if ((!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK)) { + msDebug("msPostGISLayerGetShape(): Error (%s) executing SQL: %s\n", + PQerrorMessage(layerinfo->pgconn), strSQL.c_str()); + msSetError(MS_QUERYERR, "Error executing SQL. Check server logs.", + "msPostGISLayerGetShape()"); if (pgresult) { PQclear(pgresult); @@ -2910,7 +2973,8 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r } /* Clean any existing pgresult before storing current one. */ - if(layerinfo->pgresult) PQclear(layerinfo->pgresult); + if (layerinfo->pgresult) + PQclear(layerinfo->pgresult); layerinfo->pgresult = pgresult; /* Clean any existing SQL before storing current. */ @@ -2931,12 +2995,13 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r msPostGISReadShape(layer, shape); } - return (shape->type == MS_SHAPE_NULL) ? MS_FAILURE : ( (num_tuples > 0) ? MS_SUCCESS : MS_DONE ); + return (shape->type == MS_SHAPE_NULL) + ? MS_FAILURE + : ((num_tuples > 0) ? MS_SUCCESS : MS_DONE); } #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerGetShape()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerGetShape()"); return MS_FAILURE; #endif } @@ -2950,66 +3015,66 @@ static int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *r **********************************************************************/ #ifdef USE_POSTGIS -static void -msPostGISPassThroughFieldDefinitions( layerObj *layer, - PGresult *pgresult ) +static void msPostGISPassThroughFieldDefinitions(layerObj *layer, + PGresult *pgresult) { const int numitems = PQnfields(pgresult); - msPostGISLayerInfo *layerinfo = static_cast(layer->layerinfo); + msPostGISLayerInfo *layerinfo = + static_cast(layer->layerinfo); - for(int i=0; igeomcolumn ) + if (item == layerinfo->geomcolumn) continue; - const int oid = PQftype(pgresult,i); - const int fmod = PQfmod(pgresult,i); + const int oid = PQftype(pgresult, i); + const int fmod = PQfmod(pgresult, i); - if( (oid == BPCHAROID || oid == VARCHAROID) && fmod >= 4 ) { - gml_width = std::to_string( fmod-4 ); + if ((oid == BPCHAROID || oid == VARCHAROID) && fmod >= 4) { + gml_width = std::to_string(fmod - 4); - } else if( oid == BOOLOID ) { + } else if (oid == BOOLOID) { gml_type = "Boolean"; - } else if( oid == INT2OID ) { + } else if (oid == INT2OID) { gml_type = "Integer"; gml_width = '5'; - } else if( oid == INT4OID ) { + } else if (oid == INT4OID) { gml_type = "Integer"; - } else if( oid == INT8OID ) { + } else if (oid == INT8OID) { gml_type = "Long"; - } else if( oid == FLOAT4OID || oid == FLOAT8OID ) { + } else if (oid == FLOAT4OID || oid == FLOAT8OID) { gml_type = "Real"; - } else if( oid == NUMERICOID ) { + } else if (oid == NUMERICOID) { gml_type = "Real"; - if( fmod >= 4 && ((fmod - 4) & 0xFFFF) == 0 ) { + if (fmod >= 4 && ((fmod - 4) & 0xFFFF) == 0) { gml_type = "Integer"; - gml_width = std::to_string( (fmod - 4) >> 16 ); - } else if( fmod >= 4 ) { - gml_width = std::to_string( (fmod - 4) >> 16 ); - gml_precision = std::to_string( (fmod-4) & 0xFFFF ); + gml_width = std::to_string((fmod - 4) >> 16); + } else if (fmod >= 4) { + gml_width = std::to_string((fmod - 4) >> 16); + gml_precision = std::to_string((fmod - 4) & 0xFFFF); } - } else if( oid == DATEOID ) { + } else if (oid == DATEOID) { gml_type = "Date"; - } else if( oid == TIMEOID || oid == TIMETZOID ) { + } else if (oid == TIMEOID || oid == TIMETZOID) { gml_type = "Time"; - } else if( oid == TIMESTAMPOID || oid == TIMESTAMPTZOID ) { + } else if (oid == TIMESTAMPOID || oid == TIMESTAMPTZOID) { gml_type = "DateTime"; } - msUpdateGMLFieldMetadata(layer, item, gml_type, gml_width.c_str(), gml_precision.c_str(), 0); - + msUpdateGMLFieldMetadata(layer, item, gml_type, gml_width.c_str(), + gml_precision.c_str(), 0); } } #endif /* defined(USE_POSTGIS) */ @@ -3022,8 +3087,7 @@ msPostGISPassThroughFieldDefinitions( layerObj *layer, ** system tables, we just run a zero-cost query and read out of the ** result header. */ -static int msPostGISLayerGetItems(layerObj *layer) -{ +static int msPostGISLayerGetItems(layerObj *layer) { #ifdef USE_POSTGIS rectObj rect; @@ -3033,7 +3097,7 @@ static int msPostGISLayerGetItems(layerObj *layer) assert(layer != nullptr); assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; assert(layerinfo->pgconn); @@ -3042,11 +3106,11 @@ static int msPostGISLayerGetItems(layerObj *layer) } /* Fill out layerinfo with our current DATA state. */ - if ( msPostGISParseData(layer) != MS_SUCCESS) { + if (msPostGISParseData(layer) != MS_SUCCESS) { return MS_FAILURE; } - layerinfo = (msPostGISLayerInfo*) layer->layerinfo; + layerinfo = (msPostGISLayerInfo *)layer->layerinfo; /* ** Both the "table" and "(select ...) as sub" cases can be handled with the @@ -3060,26 +3124,33 @@ static int msPostGISLayerGetItems(layerObj *layer) msDebug("msPostGISLayerGetItems executing SQL: %s\n", sql.c_str()); } - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, sql.c_str(), 0); + PGresult *pgresult = + runPQexecParamsWithBindSubstitution(layer, sql.c_str(), 0); - if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) { - msDebug("msPostGISLayerGetItems(): Error (%s) executing SQL: %s\n", PQerrorMessage(layerinfo->pgconn), sql.c_str()); - msSetError(MS_QUERYERR, "Error executing SQL. Check server logs","msPostGISLayerGetItems()"); + if ((!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK)) { + msDebug("msPostGISLayerGetItems(): Error (%s) executing SQL: %s\n", + PQerrorMessage(layerinfo->pgconn), sql.c_str()); + msSetError(MS_QUERYERR, "Error executing SQL. Check server logs", + "msPostGISLayerGetItems()"); if (pgresult) { PQclear(pgresult); } return MS_FAILURE; } - layer->numitems = PQnfields(pgresult) - 1; /* dont include the geometry column (last entry)*/ - layer->items = static_cast(msSmallMalloc(sizeof(char*) * (layer->numitems + 1))); /* +1 in case there is a problem finding geometry column */ + layer->numitems = PQnfields(pgresult) - + 1; /* dont include the geometry column (last entry)*/ + layer->items = static_cast(msSmallMalloc( + sizeof(char *) * + (layer->numitems + + 1))); /* +1 in case there is a problem finding geometry column */ bool found_geom = false; /* havent found the geom field */ int item_num = 0; for (int t = 0; t < PQnfields(pgresult); t++) { - const char* col = PQfname(pgresult, t); - if ( col != layerinfo->geomcolumn) { + const char *col = PQfname(pgresult, t); + if (col != layerinfo->geomcolumn) { /* this isnt the geometry column */ layer->items[item_num] = msStrdup(col); item_num++; @@ -3091,9 +3162,9 @@ static int msPostGISLayerGetItems(layerObj *layer) /* ** consider populating the field definitions in metadata. */ - const char* value = msOWSLookupMetadata(&(layer->metadata), "G", "types"); - if(value != nullptr && strcasecmp(value,"auto") == 0 ) - msPostGISPassThroughFieldDefinitions( layer, pgresult ); + const char *value = msOWSLookupMetadata(&(layer->metadata), "G", "types"); + if (value != nullptr && strcasecmp(value, "auto") == 0) + msPostGISPassThroughFieldDefinitions(layer, pgresult); /* ** Cleanup @@ -3101,52 +3172,54 @@ static int msPostGISLayerGetItems(layerObj *layer) PQclear(pgresult); if (!found_geom) { - msSetError(MS_QUERYERR, "Tried to find the geometry column in the database, but couldn't find it. Is it mis-capitalized? '%s'", "msPostGISLayerGetItems()", layerinfo->geomcolumn.c_str()); + msSetError(MS_QUERYERR, + "Tried to find the geometry column in the database, but " + "couldn't find it. Is it mis-capitalized? '%s'", + "msPostGISLayerGetItems()", layerinfo->geomcolumn.c_str()); return MS_FAILURE; } return msPostGISLayerInitItemInfo(layer); #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISLayerGetItems()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerGetItems()"); return MS_FAILURE; #endif } #ifdef USE_POSTGIS -static std::string addTableNameAndFilterToSelectFrom(layerObj *layer, - const std::string& selectFrom) -{ - auto layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - /* if we have !BOX! substitution then we use just the table name */ - std::string f_table_name; - if (strstr(layerinfo->fromsource.c_str(), BOXTOKEN)) - f_table_name = msPostGISFindTableName(layerinfo->fromsource.c_str()); - else - f_table_name = layerinfo->fromsource; +static std::string +addTableNameAndFilterToSelectFrom(layerObj *layer, + const std::string &selectFrom) { + auto layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + /* if we have !BOX! substitution then we use just the table name */ + std::string f_table_name; + if (strstr(layerinfo->fromsource.c_str(), BOXTOKEN)) + f_table_name = msPostGISFindTableName(layerinfo->fromsource.c_str()); + else + f_table_name = layerinfo->fromsource; - std::string strSQL = selectFrom; - strSQL += f_table_name; + std::string strSQL = selectFrom; + strSQL += f_table_name; - /* Handle a translated filter (RFC91). */ - if (layer->filter.native_string) { - strSQL += " WHERE ("; - strSQL += layer->filter.native_string; - strSQL += ')'; - } + /* Handle a translated filter (RFC91). */ + if (layer->filter.native_string) { + strSQL += " WHERE ("; + strSQL += layer->filter.native_string; + strSQL += ')'; + } - /* Handle a native filter set as a PROCESSING option (#5001). */ - const char* native_filter = msLayerGetProcessingKey(layer, "NATIVE_FILTER"); - if (native_filter) { - if( layer->filter.native_string ) - strSQL += " AND ("; - else - strSQL += " WHERE ("; - strSQL += native_filter; - strSQL += ')'; - } - return strSQL; + /* Handle a native filter set as a PROCESSING option (#5001). */ + const char *native_filter = msLayerGetProcessingKey(layer, "NATIVE_FILTER"); + if (native_filter) { + if (layer->filter.native_string) + strSQL += " AND ("; + else + strSQL += " WHERE ("; + strSQL += native_filter; + strSQL += ')'; + } + return strSQL; } #endif @@ -3156,33 +3229,35 @@ static std::string addTableNameAndFilterToSelectFrom(layerObj *layer, ** Registered vtable->LayerGetExtent function. Query the database for ** the extent of the requested layer. */ -static int msPostGISLayerGetExtent(layerObj *layer, rectObj *extent) -{ +static int msPostGISLayerGetExtent(layerObj *layer, rectObj *extent) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISLayerGetExtent called.\n"); } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - if ( msPostGISParseData(layer) != MS_SUCCESS) { + if (msPostGISParseData(layer) != MS_SUCCESS) { return MS_FAILURE; } auto layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - const std::string strSQL(addTableNameAndFilterToSelectFrom(layer, - "SELECT ST_Extent(" + layerinfo->geomcolumn + ") FROM ")); + const std::string strSQL(addTableNameAndFilterToSelectFrom( + layer, "SELECT ST_Extent(" + layerinfo->geomcolumn + ") FROM ")); if (layer->debug) { msDebug("msPostGISLayerGetExtent executing SQL: %s\n", strSQL.c_str()); } /* executing the query */ - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), 0); - - if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) { - msDebug("Error executing SQL: (%s) in msPostGISLayerGetExtent()", PQerrorMessage(layerinfo->pgconn)); - msSetError(MS_MISCERR, "Error executing SQL. Check server logs.","msPostGISLayerGetExtent()"); + PGresult *pgresult = + runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), 0); + + if ((!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK)) { + msDebug("Error executing SQL: (%s) in msPostGISLayerGetExtent()", + PQerrorMessage(layerinfo->pgconn)); + msSetError(MS_MISCERR, "Error executing SQL. Check server logs.", + "msPostGISLayerGetExtent()"); if (pgresult) PQclear(pgresult); @@ -3191,22 +3266,23 @@ static int msPostGISLayerGetExtent(layerObj *layer, rectObj *extent) /* process results */ if (PQntuples(pgresult) < 1) { - msSetError(MS_MISCERR, "msPostGISLayerGetExtent: No results found.", - "msPostGISLayerGetExtent()"); + msSetError(MS_MISCERR, "msPostGISLayerGetExtent: No results found.", + "msPostGISLayerGetExtent()"); PQclear(pgresult); return MS_FAILURE; } - + if (PQgetisnull(pgresult, 0, 0)) { - msSetError(MS_MISCERR, "msPostGISLayerGetExtent: Null result returned.", - "msPostGISLayerGetExtent()"); + msSetError(MS_MISCERR, "msPostGISLayerGetExtent: Null result returned.", + "msPostGISLayerGetExtent()"); PQclear(pgresult); return MS_FAILURE; } - if (sscanf(PQgetvalue(pgresult, 0, 0), "BOX(%lf %lf,%lf %lf)", - &extent->minx, &extent->miny, &extent->maxx, &extent->maxy) != 4) { - msSetError(MS_MISCERR, "Failed to process result data.", "msPostGISLayerGetExtent()"); + if (sscanf(PQgetvalue(pgresult, 0, 0), "BOX(%lf %lf,%lf %lf)", &extent->minx, + &extent->miny, &extent->maxx, &extent->maxy) != 4) { + msSetError(MS_MISCERR, "Failed to process result data.", + "msPostGISLayerGetExtent()"); PQclear(pgresult); return MS_FAILURE; } @@ -3216,7 +3292,8 @@ static int msPostGISLayerGetExtent(layerObj *layer, rectObj *extent) return MS_SUCCESS; #else - msSetError( MS_MISCERR, "PostGIS support is not available.", "msPostGISLayerGetExtent()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerGetExtent()"); return MS_FAILURE; #endif } @@ -3227,66 +3304,70 @@ static int msPostGISLayerGetExtent(layerObj *layer, rectObj *extent) ** Registered vtable->LayerGetNumFeatures function. Query the database for ** the feature count of the requested layer. */ -static int msPostGISLayerGetNumFeatures(layerObj *layer) -{ +static int msPostGISLayerGetNumFeatures(layerObj *layer) { #ifdef USE_POSTGIS - if (layer->debug) { - msDebug("msPostGISLayerGetNumFeatures called.\n"); - } - - assert(layer->layerinfo != nullptr); + if (layer->debug) { + msDebug("msPostGISLayerGetNumFeatures called.\n"); + } - if (msPostGISParseData(layer) != MS_SUCCESS) { - return -1; - } + assert(layer->layerinfo != nullptr); - auto layerinfo = (msPostGISLayerInfo *)layer->layerinfo; - const std::string strSQL(addTableNameAndFilterToSelectFrom( - layer, "SELECT count(*) FROM ")); - if (layer->debug) { - msDebug("msPostGISLayerGetNumFeatures executing SQL: %s\n", strSQL.c_str()); - } + if (msPostGISParseData(layer) != MS_SUCCESS) { + return -1; + } - /* executing the query */ - PGresult* pgresult = runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), 0); + auto layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + const std::string strSQL( + addTableNameAndFilterToSelectFrom(layer, "SELECT count(*) FROM ")); + if (layer->debug) { + msDebug("msPostGISLayerGetNumFeatures executing SQL: %s\n", strSQL.c_str()); + } - if ((!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK)) { - msDebug("Error executing SQL: (%s) in msPostGISLayerGetNumFeatures()", PQerrorMessage(layerinfo->pgconn)); - msSetError(MS_MISCERR, "Error executing SQL. Check server logs.", "msPostGISLayerGetNumFeatures()"); - if (pgresult) - PQclear(pgresult); + /* executing the query */ + PGresult *pgresult = + runPQexecParamsWithBindSubstitution(layer, strSQL.c_str(), 0); + + if ((!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK)) { + msDebug("Error executing SQL: (%s) in msPostGISLayerGetNumFeatures()", + PQerrorMessage(layerinfo->pgconn)); + msSetError(MS_MISCERR, "Error executing SQL. Check server logs.", + "msPostGISLayerGetNumFeatures()"); + if (pgresult) + PQclear(pgresult); - return -1; - } + return -1; + } - /* process results */ - if (PQntuples(pgresult) < 1) { - msSetError(MS_MISCERR, "msPostGISLayerGetNumFeatures: No results found.", - "msPostGISLayerGetNumFeatures()"); - PQclear(pgresult); - return -1; - } + /* process results */ + if (PQntuples(pgresult) < 1) { + msSetError(MS_MISCERR, "msPostGISLayerGetNumFeatures: No results found.", + "msPostGISLayerGetNumFeatures()"); + PQclear(pgresult); + return -1; + } - if (PQgetisnull(pgresult, 0, 0)) { - msSetError(MS_MISCERR, "msPostGISLayerGetNumFeatures: Null result returned.", - "msPostGISLayerGetNumFeatures()"); - PQclear(pgresult); - return -1; - } + if (PQgetisnull(pgresult, 0, 0)) { + msSetError(MS_MISCERR, + "msPostGISLayerGetNumFeatures: Null result returned.", + "msPostGISLayerGetNumFeatures()"); + PQclear(pgresult); + return -1; + } - const char* tmp = PQgetvalue(pgresult, 0, 0); - int result = 0; - if (tmp) { - result = strtol(tmp, nullptr, 10); - } + const char *tmp = PQgetvalue(pgresult, 0, 0); + int result = 0; + if (tmp) { + result = strtol(tmp, nullptr, 10); + } - /* cleanup */ - PQclear(pgresult); + /* cleanup */ + PQclear(pgresult); - return result; + return result; #else - msSetError(MS_MISCERR, "PostGIS support is not available.", "msPostGISLayerGetNumFeatures()"); - return -1; + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerGetNumFeatures()"); + return -1; #endif } @@ -3299,74 +3380,73 @@ static int msPostGISLayerGetNumFeatures(layerObj *layer) * - if the resolluion is hour or minute (2004-01-01 15), a * complete time is 2004-01-01 15:00:00 */ -static int postgresTimeStampForTimeString(const char *timestring, char *dest, size_t destsize) -{ +static int postgresTimeStampForTimeString(const char *timestring, char *dest, + size_t destsize) { int nlength = strlen(timestring); int timeresolution = msTimeGetResolution(timestring); int bNoDate = (*timestring == 'T'); if (timeresolution < 0) return MS_FALSE; - - switch(timeresolution) { - case TIME_RESOLUTION_YEAR: - if (timestring[nlength-1] != '-') { - snprintf(dest, destsize,"date '%s-01-01'",timestring); - } else { - snprintf(dest, destsize,"date '%s01-01'",timestring); - } - break; - case TIME_RESOLUTION_MONTH: - if (timestring[nlength-1] != '-') { - snprintf(dest, destsize,"date '%s-01'",timestring); - } else { - snprintf(dest, destsize,"date '%s01'",timestring); - } - break; - case TIME_RESOLUTION_DAY: - snprintf(dest, destsize,"date '%s'",timestring); - break; - case TIME_RESOLUTION_HOUR: - if (timestring[nlength-1] != ':') { - if(bNoDate) - snprintf(dest, destsize,"time '%s:00:00'", timestring); - else - snprintf(dest, destsize,"timestamp '%s:00:00'", timestring); - } else { - if(bNoDate) - snprintf(dest, destsize,"time '%s00:00'", timestring); - else - snprintf(dest, destsize,"timestamp '%s00:00'", timestring); - } - break; - case TIME_RESOLUTION_MINUTE: - if (timestring[nlength-1] != ':') { - if(bNoDate) - snprintf(dest, destsize,"time '%s:00'", timestring); - else - snprintf(dest, destsize,"timestamp '%s:00'", timestring); - } else { - if(bNoDate) - snprintf(dest, destsize,"time '%s00'", timestring); - else - snprintf(dest, destsize,"timestamp '%s00'", timestring); - } - break; - case TIME_RESOLUTION_SECOND: - if(bNoDate) - snprintf(dest, destsize,"time '%s'", timestring); + + switch (timeresolution) { + case TIME_RESOLUTION_YEAR: + if (timestring[nlength - 1] != '-') { + snprintf(dest, destsize, "date '%s-01-01'", timestring); + } else { + snprintf(dest, destsize, "date '%s01-01'", timestring); + } + break; + case TIME_RESOLUTION_MONTH: + if (timestring[nlength - 1] != '-') { + snprintf(dest, destsize, "date '%s-01'", timestring); + } else { + snprintf(dest, destsize, "date '%s01'", timestring); + } + break; + case TIME_RESOLUTION_DAY: + snprintf(dest, destsize, "date '%s'", timestring); + break; + case TIME_RESOLUTION_HOUR: + if (timestring[nlength - 1] != ':') { + if (bNoDate) + snprintf(dest, destsize, "time '%s:00:00'", timestring); else - snprintf(dest, destsize,"timestamp '%s'", timestring); - break; - default: - return MS_FAILURE; + snprintf(dest, destsize, "timestamp '%s:00:00'", timestring); + } else { + if (bNoDate) + snprintf(dest, destsize, "time '%s00:00'", timestring); + else + snprintf(dest, destsize, "timestamp '%s00:00'", timestring); + } + break; + case TIME_RESOLUTION_MINUTE: + if (timestring[nlength - 1] != ':') { + if (bNoDate) + snprintf(dest, destsize, "time '%s:00'", timestring); + else + snprintf(dest, destsize, "timestamp '%s:00'", timestring); + } else { + if (bNoDate) + snprintf(dest, destsize, "time '%s00'", timestring); + else + snprintf(dest, destsize, "timestamp '%s00'", timestring); + } + break; + case TIME_RESOLUTION_SECOND: + if (bNoDate) + snprintf(dest, destsize, "time '%s'", timestring); + else + snprintf(dest, destsize, "timestamp '%s'", timestring); + break; + default: + return MS_FAILURE; } return MS_SUCCESS; - } /* - * create a postgresql where clause for the given timestring, taking into account - * the resolution (e.g. second, day, month...) of the given timestring + * create a postgresql where clause for the given timestring, taking into + * account the resolution (e.g. second, day, month...) of the given timestring * we apply the date_trunc function on the given timestring and not on the time * column in order for postgres to take advantage of an eventual index on the * time column @@ -3379,51 +3459,56 @@ static int postgresTimeStampForTimeString(const char *timestring, char *dest, si * timecol < date_trunc(timestring,resolution) + interval '1 resolution' * ) */ -static int createPostgresTimeCompareEquals(const char *timestring, char *dest, size_t destsize) -{ +static int createPostgresTimeCompareEquals(const char *timestring, char *dest, + size_t destsize) { int timeresolution = msTimeGetResolution(timestring); char timeStamp[100]; const char *interval; - if (timeresolution < 0) return MS_FALSE; + if (timeresolution < 0) + return MS_FALSE; - postgresTimeStampForTimeString(timestring,timeStamp,100); + postgresTimeStampForTimeString(timestring, timeStamp, 100); - switch(timeresolution) { - case TIME_RESOLUTION_YEAR: - interval = "year"; - break; - case TIME_RESOLUTION_MONTH: - interval = "month"; - break; - case TIME_RESOLUTION_DAY: - interval = "day"; - break; - case TIME_RESOLUTION_HOUR: - interval = "hour"; - break; - case TIME_RESOLUTION_MINUTE: - interval = "minute"; - break; - case TIME_RESOLUTION_SECOND: - interval = "second"; - break; - default: - return MS_FAILURE; + switch (timeresolution) { + case TIME_RESOLUTION_YEAR: + interval = "year"; + break; + case TIME_RESOLUTION_MONTH: + interval = "month"; + break; + case TIME_RESOLUTION_DAY: + interval = "day"; + break; + case TIME_RESOLUTION_HOUR: + interval = "hour"; + break; + case TIME_RESOLUTION_MINUTE: + interval = "minute"; + break; + case TIME_RESOLUTION_SECOND: + interval = "second"; + break; + default: + return MS_FAILURE; } - snprintf(dest, destsize, " between date_trunc('%s',%s) and date_trunc('%s',%s) + interval '1 %s' - interval '1 second'", interval, timeStamp, interval, timeStamp, interval); + snprintf(dest, destsize, + " between date_trunc('%s',%s) and date_trunc('%s',%s) + interval '1 " + "%s' - interval '1 second'", + interval, timeStamp, interval, timeStamp, interval); return MS_SUCCESS; } -static int createPostgresTimeCompareGreaterThan(const char *timestring, char *dest, size_t destsize) -{ +static int createPostgresTimeCompareGreaterThan(const char *timestring, + char *dest, size_t destsize) { int timeresolution = msTimeGetResolution(timestring); char timestamp[100]; const char *interval; - if (timeresolution < 0) return MS_FALSE; - - postgresTimeStampForTimeString(timestring,timestamp,100); + if (timeresolution < 0) + return MS_FALSE; + + postgresTimeStampForTimeString(timestring, timestamp, 100); - switch(timeresolution) { + switch (timeresolution) { case TIME_RESOLUTION_YEAR: interval = "year"; break; @@ -3446,79 +3531,82 @@ static int createPostgresTimeCompareGreaterThan(const char *timestring, char *de return MS_FAILURE; } - snprintf(dest, destsize,"date_trunc('%s',%s)", interval, timestamp); + snprintf(dest, destsize, "date_trunc('%s',%s)", interval, timestamp); return MS_SUCCESS; } /* - * create a postgresql where clause for the range given by the two input timestring, - * taking into account the resolution (e.g. second, day, month...) of each of the - * given timestrings (both timestrings can have different resolutions, although I don't - * know if that's a valid TIME range - * we apply the date_trunc function on the given timestrings and not on the time - * column in order for postgres to take advantage of an eventual index on the - * time column + * create a postgresql where clause for the range given by the two input + * timestring, taking into account the resolution (e.g. second, day, month...) + * of each of the given timestrings (both timestrings can have different + * resolutions, although I don't know if that's a valid TIME range we apply the + * date_trunc function on the given timestrings and not on the time column in + * order for postgres to take advantage of an eventual index on the time column * * the generated sql is * * ( * timecol >= date_trunc(mintimestring,minresolution) * and - * timecol < date_trunc(maxtimestring,maxresolution) + interval '1 maxresolution' + * timecol < date_trunc(maxtimestring,maxresolution) + interval '1 + * maxresolution' * ) */ -static int createPostgresTimeCompareLessThan(const char *timestring, char *dest, size_t destsize) -{ +static int createPostgresTimeCompareLessThan(const char *timestring, char *dest, + size_t destsize) { int timeresolution = msTimeGetResolution(timestring); char timestamp[100]; const char *interval; - if (timeresolution < 0)return MS_FALSE; + if (timeresolution < 0) + return MS_FALSE; - postgresTimeStampForTimeString(timestring,timestamp,100); + postgresTimeStampForTimeString(timestring, timestamp, 100); - switch(timeresolution) { - case TIME_RESOLUTION_YEAR: - interval = "year"; - break; - case TIME_RESOLUTION_MONTH: - interval = "month"; - break; - case TIME_RESOLUTION_DAY: - interval = "day"; - break; - case TIME_RESOLUTION_HOUR: - interval = "hour"; - break; - case TIME_RESOLUTION_MINUTE: - interval = "minute"; - break; - case TIME_RESOLUTION_SECOND: - interval = "second"; - break; - default: - return MS_FAILURE; + switch (timeresolution) { + case TIME_RESOLUTION_YEAR: + interval = "year"; + break; + case TIME_RESOLUTION_MONTH: + interval = "month"; + break; + case TIME_RESOLUTION_DAY: + interval = "day"; + break; + case TIME_RESOLUTION_HOUR: + interval = "hour"; + break; + case TIME_RESOLUTION_MINUTE: + interval = "minute"; + break; + case TIME_RESOLUTION_SECOND: + interval = "second"; + break; + default: + return MS_FAILURE; } - snprintf(dest, destsize,"(date_trunc('%s',%s) + interval '1 %s' - interval '1 second')", interval, timestamp, interval); + snprintf(dest, destsize, + "(date_trunc('%s',%s) + interval '1 %s' - interval '1 second')", + interval, timestamp, interval); return MS_SUCCESS; } #endif -static char *msPostGISEscapeSQLParam(layerObj *layer, const char *pszString) -{ +static char *msPostGISEscapeSQLParam(layerObj *layer, const char *pszString) { #ifdef USE_POSTGIS - char* pszEscapedStr =nullptr; + char *pszEscapedStr = nullptr; if (layer && pszString) { - if(!msPostGISLayerIsOpen(layer)) + if (!msPostGISLayerIsOpen(layer)) msPostGISLayerOpen(layer); assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *) layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; size_t nSrcLen = strlen(pszString); - pszEscapedStr = (char*) msSmallMalloc( 2 * nSrcLen + 1); + pszEscapedStr = (char *)msSmallMalloc(2 * nSrcLen + 1); int nError = 0; - PQescapeStringConn (layerinfo->pgconn, pszEscapedStr, pszString, nSrcLen, &nError); + PQescapeStringConn(layerinfo->pgconn, pszEscapedStr, pszString, nSrcLen, + &nError); if (nError != 0) { free(pszEscapedStr); pszEscapedStr = nullptr; @@ -3526,59 +3614,52 @@ static char *msPostGISEscapeSQLParam(layerObj *layer, const char *pszString) } return pszEscapedStr; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISEscapeSQLParam()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISEscapeSQLParam()"); return NULL; #endif } -static void msPostGISEnablePaging(layerObj *layer, int value) -{ +static void msPostGISEnablePaging(layerObj *layer, int value) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISEnablePaging called.\n"); } - if(!msPostGISLayerIsOpen(layer)) - { - if(msPostGISLayerOpen(layer) != MS_SUCCESS) - { + if (!msPostGISLayerIsOpen(layer)) { + if (msPostGISLayerOpen(layer) != MS_SUCCESS) { return; } } - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; layerinfo->paging = value; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISEnablePaging()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISEnablePaging()"); #endif return; } -static int msPostGISGetPaging(layerObj *layer) -{ +static int msPostGISGetPaging(layerObj *layer) { #ifdef USE_POSTGIS if (layer->debug) { msDebug("msPostGISGetPaging called.\n"); } - if(!msPostGISLayerIsOpen(layer)) + if (!msPostGISLayerIsOpen(layer)) return MS_TRUE; - assert( layer->layerinfo != nullptr); + assert(layer->layerinfo != nullptr); - msPostGISLayerInfo* layerinfo = (msPostGISLayerInfo *)layer->layerinfo; + msPostGISLayerInfo *layerinfo = (msPostGISLayerInfo *)layer->layerinfo; return layerinfo->paging; #else - msSetError( MS_MISCERR, - "PostGIS support is not available.", - "msPostGISEnablePaging()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISEnablePaging()"); return MS_FAILURE; #endif } @@ -3588,8 +3669,8 @@ static int msPostGISGetPaging(layerObj *layer) ** ** Registered vtable->LayerTranslateFilter function. */ -static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem) -{ +static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, + char *filteritem) { #ifdef USE_POSTGIS tokenListNodeObjPtr node = nullptr; @@ -3598,19 +3679,23 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, int comparisonToken = -1; int bindingToken = -1; - msPostGISLayerInfo *layerinfo = static_cast(layer->layerinfo); + msPostGISLayerInfo *layerinfo = + static_cast(layer->layerinfo); - if(!filter->string) return MS_SUCCESS; /* not an error, just nothing to do */ + if (!filter->string) + return MS_SUCCESS; /* not an error, just nothing to do */ - // fprintf(stderr, "input: %s, %s, %d\n", filter->string, filteritem, filter->type); + // fprintf(stderr, "input: %s, %s, %d\n", filter->string, filteritem, + // filter->type); /* ** FILTERs use MapServer syntax *only* (#5001). */ - if(filter->type == MS_STRING && filter->string && filteritem) { /* item/value pair - add escaping */ + if (filter->type == MS_STRING && filter->string && + filteritem) { /* item/value pair - add escaping */ - char* stresc = msLayerEscapePropertyName(layer, filteritem); - if(filter->flags & MS_EXP_INSENSITIVE) { + char *stresc = msLayerEscapePropertyName(layer, filteritem); + if (filter->flags & MS_EXP_INSENSITIVE) { native_string += "upper("; native_string += stresc; native_string += "::text) = upper("; @@ -3620,19 +3705,22 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, } msFree(stresc); - /* don't have a type for the righthand literal so assume it's a string and we quote */ + /* don't have a type for the righthand literal so assume it's a string and + * we quote */ stresc = msPostGISEscapeSQLParam(layer, filter->string); native_string += '\''; native_string += stresc; native_string += '\''; msFree(stresc); - if(filter->flags & MS_EXP_INSENSITIVE) native_string += ")"; - } else if(filter->type == MS_REGEX && filter->string && filteritem) { /* item/regex pair - add escaping */ + if (filter->flags & MS_EXP_INSENSITIVE) + native_string += ")"; + } else if (filter->type == MS_REGEX && filter->string && + filteritem) { /* item/regex pair - add escaping */ - char* stresc = msLayerEscapePropertyName(layer, filteritem); + char *stresc = msLayerEscapePropertyName(layer, filteritem); native_string += stresc; - if(filter->flags & MS_EXP_INSENSITIVE) { + if (filter->flags & MS_EXP_INSENSITIVE) { native_string += "::text ~* "; } else { native_string += "::text ~ "; @@ -3644,14 +3732,19 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, native_string += stresc; native_string += '\''; msFree(stresc); - } else if(filter->type == MS_EXPRESSION) { + } else if (filter->type == MS_EXPRESSION) { int ieq_expected = MS_FALSE; - if(msPostGISParseData(layer) != MS_SUCCESS) return MS_FAILURE; + if (msPostGISParseData(layer) != MS_SUCCESS) + return MS_FAILURE; - if(layer->debug >= 2) msDebug("msPostGISLayerTranslateFilter. String: %s.\n", filter->string); - if(!filter->tokens) return MS_SUCCESS; - if(layer->debug >= 2) msDebug("msPostGISLayerTranslateFilter. There are tokens to process... \n"); + if (layer->debug >= 2) + msDebug("msPostGISLayerTranslateFilter. String: %s.\n", filter->string); + if (!filter->tokens) + return MS_SUCCESS; + if (layer->debug >= 2) + msDebug( + "msPostGISLayerTranslateFilter. There are tokens to process... \n"); node = filter->tokens; while (node != nullptr) { @@ -3659,243 +3752,248 @@ static int msPostGISLayerTranslateFilter(layerObj *layer, expressionObj *filter, /* ** Do any token caching/tracking here, easier to have it in one place. */ - if(node->token == MS_TOKEN_BINDING_TIME) { + if (node->token == MS_TOKEN_BINDING_TIME) { bindingToken = node->token; - } else if(node->token == MS_TOKEN_COMPARISON_EQ || - node->token == MS_TOKEN_COMPARISON_IEQ || - node->token == MS_TOKEN_COMPARISON_NE || - node->token == MS_TOKEN_COMPARISON_GT || node->token == MS_TOKEN_COMPARISON_GE || - node->token == MS_TOKEN_COMPARISON_LT || node->token == MS_TOKEN_COMPARISON_LE || - node->token == MS_TOKEN_COMPARISON_IN) { + } else if (node->token == MS_TOKEN_COMPARISON_EQ || + node->token == MS_TOKEN_COMPARISON_IEQ || + node->token == MS_TOKEN_COMPARISON_NE || + node->token == MS_TOKEN_COMPARISON_GT || + node->token == MS_TOKEN_COMPARISON_GE || + node->token == MS_TOKEN_COMPARISON_LT || + node->token == MS_TOKEN_COMPARISON_LE || + node->token == MS_TOKEN_COMPARISON_IN) { comparisonToken = node->token; } - switch(node->token) { + switch (node->token) { - /* literal tokens */ - case MS_TOKEN_LITERAL_BOOLEAN: - if(node->tokenval.dblval == MS_TRUE) - native_string += "TRUE"; - else - native_string += "FALSE"; - break; - case MS_TOKEN_LITERAL_NUMBER: - { - if( node->tokenval.dblval >= INT_MIN && - node->tokenval.dblval <= INT_MAX && - node->tokenval.dblval == (int)node->tokenval.dblval ) - native_string += std::to_string((int)node->tokenval.dblval); - else { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.18g", node->tokenval.dblval); - native_string += buffer; - } - break; + /* literal tokens */ + case MS_TOKEN_LITERAL_BOOLEAN: + if (node->tokenval.dblval == MS_TRUE) + native_string += "TRUE"; + else + native_string += "FALSE"; + break; + case MS_TOKEN_LITERAL_NUMBER: { + if (node->tokenval.dblval >= INT_MIN && + node->tokenval.dblval <= INT_MAX && + node->tokenval.dblval == (int)node->tokenval.dblval) + native_string += std::to_string((int)node->tokenval.dblval); + else { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%.18g", node->tokenval.dblval); + native_string += buffer; } - case MS_TOKEN_LITERAL_STRING: - - if(comparisonToken == MS_TOKEN_COMPARISON_IN) { /* issue 5490 */ - int nstrings=0; - char** strings = msStringSplit(node->tokenval.strval, ',', &nstrings); - if(nstrings > 0) { - native_string += "("; - for(int i=0; itokenval.strval, ',', &nstrings); + if (nstrings > 0) { + native_string += "("; + for (int i = 0; i < nstrings; i++) { + if (i != 0) + native_string += ","; + char *stresc = msPostGISEscapeSQLParam(layer, strings[i]); + native_string += '\''; + native_string += stresc; + native_string += '\''; + msFree(stresc); } - char* stresc = msPostGISEscapeSQLParam(layer, node->tokenval.strval); - native_string += strbegin; - native_string += stresc; - native_string += strend; - msFree(stresc); + native_string += ")"; } - break; - case MS_TOKEN_LITERAL_TIME: { - char* snippet = (char *) msSmallMalloc(512); - if(comparisonToken == MS_TOKEN_COMPARISON_EQ) { // TODO: support != - createPostgresTimeCompareEquals(node->tokensrc, snippet, 512); - } else if(comparisonToken == MS_TOKEN_COMPARISON_GT || comparisonToken == MS_TOKEN_COMPARISON_GE) { - createPostgresTimeCompareGreaterThan(node->tokensrc, snippet, 512); - } else if(comparisonToken == MS_TOKEN_COMPARISON_LT || comparisonToken == MS_TOKEN_COMPARISON_LE) { - createPostgresTimeCompareLessThan(node->tokensrc, snippet, 512); + msFreeCharArray(strings, nstrings); + } else { + const char *strbegin; + const char *strend; + if (comparisonToken == MS_TOKEN_COMPARISON_IEQ) { + strbegin = "lower('"; + strend = "')"; } else { - msFree(snippet); - goto cleanup; - } - - comparisonToken = -1; bindingToken = -1; /* reset */ - native_string += snippet; - msFree(snippet); - break; - } - case MS_TOKEN_LITERAL_SHAPE: - { - char* wkt = msShapeToWKT(node->tokenval.shpval); - native_string += "ST_GeomFromText('"; - native_string += wkt; - msFree(wkt); - native_string += "'"; - if( !layerinfo->srid.empty() ) { - native_string += ","; - native_string += layerinfo->srid; - } - native_string += ")"; - break; - } - - /* data binding tokens */ - case MS_TOKEN_BINDING_TIME: - case MS_TOKEN_BINDING_DOUBLE: - case MS_TOKEN_BINDING_INTEGER: - case MS_TOKEN_BINDING_STRING: - { - const char* strbegin = ""; - const char* strend = ""; - if (node->token == MS_TOKEN_BINDING_STRING && node->next->token == MS_TOKEN_COMPARISON_IEQ ) { - strbegin = "lower("; - strend = "::text)"; - ieq_expected = MS_TRUE; + strbegin = "'"; + strend = "'"; } - else if(node->token == MS_TOKEN_BINDING_STRING || node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE) - strend = "::text"; /* explicit cast necessary for certain operators */ - - char* stresc = msLayerEscapePropertyName(layer, node->tokenval.bindval.item); + char *stresc = msPostGISEscapeSQLParam(layer, node->tokenval.strval); native_string += strbegin; native_string += stresc; native_string += strend; msFree(stresc); - break; - } - case MS_TOKEN_BINDING_SHAPE: - native_string += layerinfo->geomcolumn; - break; - case MS_TOKEN_BINDING_MAP_CELLSIZE: - { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.18g", layer->map->cellsize); - native_string += buffer; - break; } - /* spatial comparison tokens */ - case MS_TOKEN_COMPARISON_INTERSECTS: - case MS_TOKEN_COMPARISON_DISJOINT: - case MS_TOKEN_COMPARISON_TOUCHES: - case MS_TOKEN_COMPARISON_OVERLAPS: - case MS_TOKEN_COMPARISON_CROSSES: - case MS_TOKEN_COMPARISON_WITHIN: - case MS_TOKEN_COMPARISON_CONTAINS: - case MS_TOKEN_COMPARISON_EQUALS: - case MS_TOKEN_COMPARISON_DWITHIN: - { - if(node->next->token != '(') goto cleanup; - native_string += "st_"; - const char* str = msExpressionTokenToString(node->token); - if( str == nullptr ) - goto cleanup; - native_string += str; - break; + break; + case MS_TOKEN_LITERAL_TIME: { + char *snippet = (char *)msSmallMalloc(512); + if (comparisonToken == MS_TOKEN_COMPARISON_EQ) { // TODO: support != + createPostgresTimeCompareEquals(node->tokensrc, snippet, 512); + } else if (comparisonToken == MS_TOKEN_COMPARISON_GT || + comparisonToken == MS_TOKEN_COMPARISON_GE) { + createPostgresTimeCompareGreaterThan(node->tokensrc, snippet, 512); + } else if (comparisonToken == MS_TOKEN_COMPARISON_LT || + comparisonToken == MS_TOKEN_COMPARISON_LE) { + createPostgresTimeCompareLessThan(node->tokensrc, snippet, 512); + } else { + msFree(snippet); + goto cleanup; } - /* functions */ - case MS_TOKEN_FUNCTION_LENGTH: - case MS_TOKEN_FUNCTION_AREA: - case MS_TOKEN_FUNCTION_BUFFER: - case MS_TOKEN_FUNCTION_DIFFERENCE: - { - native_string += "st_"; - const char* str = msExpressionTokenToString(node->token); - if( str == nullptr ) - goto cleanup; - native_string += str; - break; + comparisonToken = -1; + bindingToken = -1; /* reset */ + native_string += snippet; + msFree(snippet); + break; + } + case MS_TOKEN_LITERAL_SHAPE: { + char *wkt = msShapeToWKT(node->tokenval.shpval); + native_string += "ST_GeomFromText('"; + native_string += wkt; + msFree(wkt); + native_string += "'"; + if (!layerinfo->srid.empty()) { + native_string += ","; + native_string += layerinfo->srid; } + native_string += ")"; + break; + } - case MS_TOKEN_COMPARISON_IEQ: - if( ieq_expected ) - { - native_string += "="; - ieq_expected = MS_FALSE; - } - else - { - goto cleanup; - } - break; - - /* unsupported tokens */ - case MS_TOKEN_COMPARISON_BEYOND: - case MS_TOKEN_FUNCTION_TOSTRING: - case MS_TOKEN_FUNCTION_ROUND: - case MS_TOKEN_FUNCTION_SIMPLIFY: - case MS_TOKEN_FUNCTION_SIMPLIFYPT: - case MS_TOKEN_FUNCTION_GENERALIZE: + /* data binding tokens */ + case MS_TOKEN_BINDING_TIME: + case MS_TOKEN_BINDING_DOUBLE: + case MS_TOKEN_BINDING_INTEGER: + case MS_TOKEN_BINDING_STRING: { + const char *strbegin = ""; + const char *strend = ""; + if (node->token == MS_TOKEN_BINDING_STRING && + node->next->token == MS_TOKEN_COMPARISON_IEQ) { + strbegin = "lower("; + strend = "::text)"; + ieq_expected = MS_TRUE; + } else if (node->token == MS_TOKEN_BINDING_STRING || + node->next->token == MS_TOKEN_COMPARISON_RE || + node->next->token == MS_TOKEN_COMPARISON_IRE) + strend = "::text"; /* explicit cast necessary for certain operators */ + + char *stresc = + msLayerEscapePropertyName(layer, node->tokenval.bindval.item); + native_string += strbegin; + native_string += stresc; + native_string += strend; + msFree(stresc); + break; + } + case MS_TOKEN_BINDING_SHAPE: + native_string += layerinfo->geomcolumn; + break; + case MS_TOKEN_BINDING_MAP_CELLSIZE: { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%.18g", layer->map->cellsize); + native_string += buffer; + break; + } + + /* spatial comparison tokens */ + case MS_TOKEN_COMPARISON_INTERSECTS: + case MS_TOKEN_COMPARISON_DISJOINT: + case MS_TOKEN_COMPARISON_TOUCHES: + case MS_TOKEN_COMPARISON_OVERLAPS: + case MS_TOKEN_COMPARISON_CROSSES: + case MS_TOKEN_COMPARISON_WITHIN: + case MS_TOKEN_COMPARISON_CONTAINS: + case MS_TOKEN_COMPARISON_EQUALS: + case MS_TOKEN_COMPARISON_DWITHIN: { + if (node->next->token != '(') goto cleanup; - break; + native_string += "st_"; + const char *str = msExpressionTokenToString(node->token); + if (str == nullptr) + goto cleanup; + native_string += str; + break; + } - default: - { - /* by default accept the general token to string conversion */ - - if(node->token == MS_TOKEN_COMPARISON_EQ && node->next != nullptr && node->next->token == MS_TOKEN_LITERAL_TIME) break; /* skip, handled with the next token */ - if(bindingToken == MS_TOKEN_BINDING_TIME && (node->token == MS_TOKEN_COMPARISON_EQ || node->token == MS_TOKEN_COMPARISON_NE)) break; /* skip, handled elsewhere */ - if(node->token == MS_TOKEN_COMPARISON_EQ && node->next != nullptr && node->next->token == MS_TOKEN_LITERAL_STRING && - strcmp(node->next->tokenval.strval, "_MAPSERVER_NULL_") == 0 ) - { - native_string += " IS NULL"; - node = node->next; - break; - } + /* functions */ + case MS_TOKEN_FUNCTION_LENGTH: + case MS_TOKEN_FUNCTION_AREA: + case MS_TOKEN_FUNCTION_BUFFER: + case MS_TOKEN_FUNCTION_DIFFERENCE: { + native_string += "st_"; + const char *str = msExpressionTokenToString(node->token); + if (str == nullptr) + goto cleanup; + native_string += str; + break; + } - const char* str = msExpressionTokenToString(node->token); - if( str == nullptr ) - goto cleanup; - native_string += str; - break; + case MS_TOKEN_COMPARISON_IEQ: + if (ieq_expected) { + native_string += "="; + ieq_expected = MS_FALSE; + } else { + goto cleanup; } + break; + + /* unsupported tokens */ + case MS_TOKEN_COMPARISON_BEYOND: + case MS_TOKEN_FUNCTION_TOSTRING: + case MS_TOKEN_FUNCTION_ROUND: + case MS_TOKEN_FUNCTION_SIMPLIFY: + case MS_TOKEN_FUNCTION_SIMPLIFYPT: + case MS_TOKEN_FUNCTION_GENERALIZE: + goto cleanup; + break; + + default: { + /* by default accept the general token to string conversion */ + + if (node->token == MS_TOKEN_COMPARISON_EQ && node->next != nullptr && + node->next->token == MS_TOKEN_LITERAL_TIME) + break; /* skip, handled with the next token */ + if (bindingToken == MS_TOKEN_BINDING_TIME && + (node->token == MS_TOKEN_COMPARISON_EQ || + node->token == MS_TOKEN_COMPARISON_NE)) + break; /* skip, handled elsewhere */ + if (node->token == MS_TOKEN_COMPARISON_EQ && node->next != nullptr && + node->next->token == MS_TOKEN_LITERAL_STRING && + strcmp(node->next->tokenval.strval, "_MAPSERVER_NULL_") == 0) { + native_string += " IS NULL"; + node = node->next; + break; } + const char *str = msExpressionTokenToString(node->token); + if (str == nullptr) + goto cleanup; + native_string += str; + break; + } + } + node = node->next; } } filter->native_string = msStrdup(native_string.c_str()); - // fprintf(stderr, "output: %s\n", filter->native_string); + // fprintf(stderr, "output: %s\n", filter->native_string); return MS_SUCCESS; cleanup: - msSetError(MS_MISCERR, "Translation to native SQL failed.", "msPostGISLayerTranslateFilter()"); + msSetError(MS_MISCERR, "Translation to native SQL failed.", + "msPostGISLayerTranslateFilter()"); return MS_FAILURE; #else - msSetError(MS_MISCERR, "PostGIS support is not available.", "msPostGISLayerTranslateFilter()"); + msSetError(MS_MISCERR, "PostGIS support is not available.", + "msPostGISLayerTranslateFilter()"); return MS_FAILURE; #endif } -int msPostGISLayerInitializeVirtualTable(layerObj *layer) -{ +int msPostGISLayerInitializeVirtualTable(layerObj *layer) { assert(layer != nullptr); assert(layer->vtable != nullptr); diff --git a/mappostgis.h b/mappostgis.h index 8f5b3e83ec..372607e8be 100644 --- a/mappostgis.h +++ b/mappostgis.h @@ -54,30 +54,31 @@ ** Specific information needed for managing this layer. */ typedef struct { - std::string sql{}; /* SQL query to send to database */ - PGconn *pgconn = nullptr; /* Connection to database */ - long rownum = 0; /* What row is the next to be read (for random access) */ - PGresult *pgresult = nullptr; /* For fetching rows from the database */ - std::string uid{}; /* Name of user-specified unique identifier, if set */ - std::string srid{}; /* Name of user-specified SRID: zero-length => calculate; non-zero => use this value! */ - std::string geomcolumn{}; /* Specified geometry column, eg "THEGEOM from thetable" */ - std::string fromsource{}; /* Specified record source, ed "thegeom from THETABLE" or "thegeom from (SELECT..) AS FOO" */ - int endian = 0; /* Endianness of the mapserver host */ - int version = 0; /* PostGIS version of the database */ - int paging = 0; /* Driver handling of pagination, enabled by default */ - int force2d = 0; /* Pass geometry through ST_Force2D */ -} -msPostGISLayerInfo; - + std::string sql{}; /* SQL query to send to database */ + PGconn *pgconn = nullptr; /* Connection to database */ + long rownum = 0; /* What row is the next to be read (for random access) */ + PGresult *pgresult = nullptr; /* For fetching rows from the database */ + std::string uid{}; /* Name of user-specified unique identifier, if set */ + std::string srid{}; /* Name of user-specified SRID: zero-length => calculate; + non-zero => use this value! */ + std::string + geomcolumn{}; /* Specified geometry column, eg "THEGEOM from thetable" */ + std::string fromsource{}; /* Specified record source, ed "thegeom from + THETABLE" or "thegeom from (SELECT..) AS FOO" */ + int endian = 0; /* Endianness of the mapserver host */ + int version = 0; /* PostGIS version of the database */ + int paging = 0; /* Driver handling of pagination, enabled by default */ + int force2d = 0; /* Pass geometry through ST_Force2D */ +} msPostGISLayerInfo; /* ** Utility structure for handling the WKB returned by the database while ** reading. */ typedef struct { - char *wkb; /* Pointer to front of WKB */ - char *ptr; /* Pointer to current write point */ - size_t size; /* Size of allocated space */ + char *wkb; /* Pointer to front of WKB */ + char *ptr; /* Pointer to current write point */ + size_t size; /* Size of allocated space */ const int *typemap; /* Look-up array to valid OGC types */ } wkbObj; @@ -85,18 +86,18 @@ typedef struct { ** All the WKB type numbers from the OGC */ typedef enum { - WKB_POINT=1, - WKB_LINESTRING=2, - WKB_POLYGON=3, - WKB_MULTIPOINT=4, - WKB_MULTILINESTRING=5, - WKB_MULTIPOLYGON=6, - WKB_GEOMETRYCOLLECTION=7, - WKB_CIRCULARSTRING=8, - WKB_COMPOUNDCURVE=9, - WKB_CURVEPOLYGON=10, - WKB_MULTICURVE=11, - WKB_MULTISURFACE=12 + WKB_POINT = 1, + WKB_LINESTRING = 2, + WKB_POLYGON = 3, + WKB_MULTIPOINT = 4, + WKB_MULTILINESTRING = 5, + WKB_MULTIPOLYGON = 6, + WKB_GEOMETRYCOLLECTION = 7, + WKB_CIRCULARSTRING = 8, + WKB_COMPOUNDCURVE = 9, + WKB_CURVEPOLYGON = 10, + WKB_MULTICURVE = 11, + WKB_MULTISURFACE = 12 } wkb_typenum; /* @@ -108,43 +109,42 @@ typedef enum { ** Map the WKB type numbers returned by PostGIS < 2.0 to the ** valid OGC numbers */ -static const int wkb_postgis15[WKB_TYPE_COUNT] = { - 0, - WKB_POINT, - WKB_LINESTRING, - WKB_POLYGON, - WKB_MULTIPOINT, - WKB_MULTILINESTRING, - WKB_MULTIPOLYGON, - WKB_GEOMETRYCOLLECTION, - WKB_CIRCULARSTRING, - WKB_COMPOUNDCURVE, - 0,0,0, - WKB_CURVEPOLYGON, - WKB_MULTICURVE, - WKB_MULTISURFACE -}; +static const int wkb_postgis15[WKB_TYPE_COUNT] = {0, + WKB_POINT, + WKB_LINESTRING, + WKB_POLYGON, + WKB_MULTIPOINT, + WKB_MULTILINESTRING, + WKB_MULTIPOLYGON, + WKB_GEOMETRYCOLLECTION, + WKB_CIRCULARSTRING, + WKB_COMPOUNDCURVE, + 0, + 0, + 0, + WKB_CURVEPOLYGON, + WKB_MULTICURVE, + WKB_MULTISURFACE}; /* ** Map the WKB type numbers returned by PostGIS >= 2.0 to the ** valid OGC numbers */ -static const int wkb_postgis20[WKB_TYPE_COUNT] = { - 0, - WKB_POINT, - WKB_LINESTRING, - WKB_POLYGON, - WKB_MULTIPOINT, - WKB_MULTILINESTRING, - WKB_MULTIPOLYGON, - WKB_GEOMETRYCOLLECTION, - WKB_CIRCULARSTRING, - WKB_COMPOUNDCURVE, - WKB_CURVEPOLYGON, - WKB_MULTICURVE, - WKB_MULTISURFACE, - 0,0,0 -}; +static const int wkb_postgis20[WKB_TYPE_COUNT] = {0, + WKB_POINT, + WKB_LINESTRING, + WKB_POLYGON, + WKB_MULTIPOINT, + WKB_MULTILINESTRING, + WKB_MULTIPOLYGON, + WKB_GEOMETRYCOLLECTION, + WKB_CIRCULARSTRING, + WKB_COMPOUNDCURVE, + WKB_CURVEPOLYGON, + WKB_MULTICURVE, + WKB_MULTISURFACE, + 0, + 0, + 0}; #endif /* USE_POSTGIS */ - diff --git a/mappostgresql.c b/mappostgresql.c index 69b84925f5..a1668465c1 100644 --- a/mappostgresql.c +++ b/mappostgresql.c @@ -27,7 +27,6 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ - /* $Id$ */ #include #include "mapserver.h" @@ -50,17 +49,14 @@ #include #include /* tolower() */ - - - typedef struct { - PGconn *conn; /* connection to db */ - long row_num; /* what row is the NEXT to be read (for random access) */ - PGresult *query_result; /* for fetching rows from the db */ - int from_index; - char *to_column; - char *from_value; - int layer_debug; /* there's no debug on the join, so use the layer */ + PGconn *conn; /* connection to db */ + long row_num; /* what row is the NEXT to be read (for random access) */ + PGresult *query_result; /* for fetching rows from the db */ + int from_index; + char *to_column; + char *from_value; + int layer_debug; /* there's no debug on the join, so use the layer */ } msPOSTGRESQLJoinInfo; /************************************************************************/ @@ -72,19 +68,18 @@ typedef struct { /* pooled connections with joins. */ /************************************************************************/ -int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) -{ +int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) { char *maskeddata, *temp, *sql, *column; char *conn_decrypted; int i, test; PGresult *query_result; msPOSTGRESQLJoinInfo *joininfo; - if(join->joininfo) + if (join->joininfo) return MS_SUCCESS; joininfo = (msPOSTGRESQLJoinInfo *)malloc(sizeof(msPOSTGRESQLJoinInfo)); - if(!joininfo) { + if (!joininfo) { msSetError(MS_MEMERR, "Error allocating join info struct.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; @@ -102,17 +97,17 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) * We need three things at a minimum, the connection string, a table * name, and a column to join on. */ - if(!join->connection) { + if (!join->connection) { msSetError(MS_QUERYERR, "No connection information provided.", "MSPOSTGRESQLJoinConnect()"); return MS_FAILURE; } - if(!join->table) { + if (!join->table) { msSetError(MS_QUERYERR, "No join table name found.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; } - if(!joininfo->to_column) { + if (!joininfo->to_column) { msSetError(MS_QUERYERR, "No join to column name found.", "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; @@ -124,11 +119,11 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) joininfo->conn = PQconnectdb(conn_decrypted); free(conn_decrypted); } - if(!joininfo->conn || PQstatus(joininfo->conn) == CONNECTION_BAD) { + if (!joininfo->conn || PQstatus(joininfo->conn) == CONNECTION_BAD) { maskeddata = (char *)malloc(strlen(layer->connection) + 1); strcpy(maskeddata, join->connection); temp = strstr(maskeddata, "password="); - if(temp) { + if (temp) { temp = (char *)(temp + 9); while (*temp != '\0' && *temp != ' ') { *temp = '*'; @@ -136,11 +131,12 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) } } msSetError(MS_QUERYERR, - "Unable to connect to PostgreSQL using the string %s.\n Error reported: %s\n", - "msPOSTGRESQLJoinConnect()", - maskeddata, PQerrorMessage(joininfo->conn)); + "Unable to connect to PostgreSQL using the string %s.\n Error " + "reported: %s\n", + "msPOSTGRESQLJoinConnect()", maskeddata, + PQerrorMessage(joininfo->conn)); free(maskeddata); - if(!joininfo->conn) { + if (!joininfo->conn) { free(joininfo->conn); } free(joininfo); @@ -152,15 +148,15 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) sql = (char *)malloc(36 + strlen(join->table) + 1); sprintf(sql, "SELECT * FROM %s WHERE false LIMIT 0", join->table); - if(joininfo->layer_debug) { + if (joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinConnect(): executing %s.\n", sql); } query_result = PQexec(joininfo->conn, sql); - if(!query_result || PQresultStatus(query_result) != PGRES_TUPLES_OK) { + if (!query_result || PQresultStatus(query_result) != PGRES_TUPLES_OK) { msSetError(MS_QUERYERR, "Error determining join items: %s.", "msPOSTGRESQLJoinConnect()", PQerrorMessage(joininfo->conn)); - if(query_result) { + if (query_result) { PQclear(query_result); query_result = NULL; } @@ -173,9 +169,9 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) /* We want the join-to column to be first in the list. */ test = 1; - for(i = 0; i < join->numitems; i++) { + for (i = 0; i < join->numitems; i++) { column = PQfname(query_result, i); - if(strcmp(column, joininfo->to_column) != 0) { + if (strcmp(column, joininfo->to_column) != 0) { join->items[i + test] = (char *)malloc(strlen(column) + 1); strcpy(join->items[i + test], column); } else { @@ -186,27 +182,28 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) } PQclear(query_result); query_result = NULL; - if(test == 1) { + if (test == 1) { msSetError(MS_QUERYERR, "Unable to find join to column: %s", "msPOSTGRESQLJoinConnect()", joininfo->to_column); return MS_FAILURE; } - if(joininfo->layer_debug) { - for(i = 0; i < join->numitems; i++) { - msDebug("msPOSTGRESQLJoinConnect(): Column %d named %s\n", i, join->items[i]); + if (joininfo->layer_debug) { + for (i = 0; i < join->numitems; i++) { + msDebug("msPOSTGRESQLJoinConnect(): Column %d named %s\n", i, + join->items[i]); } } /* Determine the index of the join from column. */ - for(i = 0; i < layer->numitems; i++) { - if(strcasecmp(layer->items[i], join->from) == 0) { + for (i = 0; i < layer->numitems; i++) { + if (strcasecmp(layer->items[i], join->from) == 0) { joininfo->from_index = i; break; } } - if(i == layer->numitems) { + if (i == layer->numitems) { msSetError(MS_JOINERR, "Item %s not found in layer %s.", "msPOSTGRESQLJoinConnect()", join->from, layer->name); return MS_FAILURE; @@ -223,34 +220,37 @@ int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) /* resources, and setting the next value to join to. */ /************************************************************************/ -int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) -{ +int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) { /* We need a connection, and a shape with values to join to. */ msPOSTGRESQLJoinInfo *joininfo = join->joininfo; - if(!joininfo) { - msSetError(MS_JOINERR, "Join has not been connected.", "msPOSTGRESQLJoinPrepare()"); + if (!joininfo) { + msSetError(MS_JOINERR, "Join has not been connected.", + "msPOSTGRESQLJoinPrepare()"); return MS_FAILURE; } - if(!shape) { - msSetError(MS_JOINERR, "Null shape provided for join.", "msPOSTGRESQLJoinPrepare()"); + if (!shape) { + msSetError(MS_JOINERR, "Null shape provided for join.", + "msPOSTGRESQLJoinPrepare()"); return MS_FAILURE; } - if(!shape->values) { - msSetError(MS_JOINERR, "Shape has no attributes. Kinda hard to join against.", "msPOSTGRESQLJoinPrepare()"); + if (!shape->values) { + msSetError(MS_JOINERR, + "Shape has no attributes. Kinda hard to join against.", + "msPOSTGRESQLJoinPrepare()"); return MS_FAILURE; } joininfo->row_num = 0; /* Free the previous join value, if any. */ - if(joininfo->from_value) { + if (joininfo->from_value) { free(joininfo->from_value); } /* Free the previous results, if any. */ - if(joininfo->query_result) { + if (joininfo->query_result) { PQclear(joininfo->query_result); joininfo->query_result = NULL; } @@ -258,7 +258,7 @@ int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) /* Copy the next join value from the shape. */ joininfo->from_value = msStrdup(shape->values[joininfo->from_index]); - if(joininfo->layer_debug) { + if (joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinPrepare() preping for value %s.\n", joininfo->from_value); } @@ -277,52 +277,50 @@ int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) /* we store the next row number and query results in the joininfo and */ /* process the next tuple on each call. */ /************************************************************************/ -int msPOSTGRESQLJoinNext(joinObj *join) -{ +int msPOSTGRESQLJoinNext(joinObj *join) { msPOSTGRESQLJoinInfo *joininfo = join->joininfo; int i, length, row_count; char *sql, *columns; /* We need a connection, and a join value. */ - if(!joininfo || !joininfo->conn) { + if (!joininfo || !joininfo->conn) { msSetError(MS_JOINERR, "Join has not been connected.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } - if(!joininfo->from_value) { + if (!joininfo->from_value) { msSetError(MS_JOINERR, "Join has not been prepared.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } /* Free the previous results. */ - if(join->values) { + if (join->values) { msFreeCharArray(join->values, join->numitems); join->values = NULL; } /* We only need to execute the query if no results exist. */ - if(!joininfo->query_result) { + if (!joininfo->query_result) { /* Write the list of column names. */ length = 0; - for(i = 0; i < join->numitems; i++) { + for (i = 0; i < join->numitems; i++) { length += 8 + strlen(join->items[i]) + 2; } columns = (char *)malloc(length); - if(!columns) { - msSetError(MS_MEMERR, "Failure to malloc.\n", - "msPOSTGRESQLJoinNext()"); + if (!columns) { + msSetError(MS_MEMERR, "Failure to malloc.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } strcpy(columns, ""); - for(i = 0; i < join->numitems; i++) { + for (i = 0; i < join->numitems; i++) { strcat(columns, "\""); strcat(columns, join->items[i]); strcat(columns, "\"::text"); - if(i != join->numitems - 1) { + if (i != join->numitems - 1) { strcat(columns, ", "); } } @@ -330,13 +328,13 @@ int msPOSTGRESQLJoinNext(joinObj *join) /* Create the query string. */ sql = (char *)malloc(26 + strlen(columns) + strlen(join->table) + strlen(join->to) + strlen(joininfo->from_value)); - if(!sql) { - msSetError(MS_MEMERR, "Failure to malloc.\n", - "msPOSTGRESQLJoinNext()"); + if (!sql) { + msSetError(MS_MEMERR, "Failure to malloc.\n", "msPOSTGRESQLJoinNext()"); return MS_FAILURE; } - sprintf(sql, "SELECT %s FROM %s WHERE %s = '%s'", columns, join->table, join->to, joininfo->from_value); - if(joininfo->layer_debug) { + sprintf(sql, "SELECT %s FROM %s WHERE %s = '%s'", columns, join->table, + join->to, joininfo->from_value); + if (joininfo->layer_debug) { msDebug("msPOSTGRESQLJoinNext(): executing %s.\n", sql); } @@ -344,12 +342,11 @@ int msPOSTGRESQLJoinNext(joinObj *join) joininfo->query_result = PQexec(joininfo->conn, sql); - if(!joininfo->query_result || + if (!joininfo->query_result || PQresultStatus(joininfo->query_result) != PGRES_TUPLES_OK) { msSetError(MS_QUERYERR, "Error executing queri %s: %s\n", - "msPOSTGRESQLJoinNext()", sql, - PQerrorMessage(joininfo->conn)); - if(joininfo->query_result) { + "msPOSTGRESQLJoinNext()", sql, PQerrorMessage(joininfo->conn)); + if (joininfo->query_result) { PQclear(joininfo->query_result); joininfo->query_result = NULL; } @@ -361,19 +358,18 @@ int msPOSTGRESQLJoinNext(joinObj *join) row_count = PQntuples(joininfo->query_result); /* see if we're done processing this set */ - if(joininfo->row_num >= row_count) { - return(MS_DONE); + if (joininfo->row_num >= row_count) { + return (MS_DONE); } - if(joininfo->layer_debug) { - msDebug("msPOSTGRESQLJoinNext(): fetching row %ld.\n", - joininfo->row_num); + if (joininfo->layer_debug) { + msDebug("msPOSTGRESQLJoinNext(): fetching row %ld.\n", joininfo->row_num); } /* Copy the resulting values into the joinObj. */ join->values = (char **)malloc(sizeof(char *) * join->numitems); - for(i = 0; i < join->numitems; i++) { - join->values[i] = msStrdup(PQgetvalue( - joininfo->query_result, joininfo->row_num, i)); + for (i = 0; i < join->numitems; i++) { + join->values[i] = + msStrdup(PQgetvalue(joininfo->query_result, joininfo->row_num, i)); } joininfo->row_num++; @@ -387,22 +383,21 @@ int msPOSTGRESQLJoinNext(joinObj *join) /* Closes the connection and frees the resources used by the joininfo. */ /************************************************************************/ -int msPOSTGRESQLJoinClose(joinObj *join) -{ +int msPOSTGRESQLJoinClose(joinObj *join) { msPOSTGRESQLJoinInfo *joininfo = join->joininfo; - if(!joininfo) { + if (!joininfo) { msDebug("msPOSTGRESQLJoinClose() already close or never opened.\n"); return MS_SUCCESS; } - if(joininfo->query_result) { + if (joininfo->query_result) { msDebug("msPOSTGRESQLJoinClose(): clearing query_result.\n"); PQclear(joininfo->query_result); joininfo->query_result = NULL; } - if(joininfo->conn) { + if (joininfo->conn) { msDebug("msPOSTGRESQLJoinClose(): closing connection.\n"); PQfinish(joininfo->conn); joininfo->conn = NULL; @@ -410,7 +405,7 @@ int msPOSTGRESQLJoinClose(joinObj *join) /* removed free(joininfo->to_column), see bug #2936 */ - if(joininfo->from_value) { + if (joininfo->from_value) { free(joininfo->from_value); } @@ -420,31 +415,28 @@ int msPOSTGRESQLJoinClose(joinObj *join) return MS_SUCCESS; } -#else /* not USE_POSTGIS */ -int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) -{ - msSetError(MS_QUERYERR, "PostgreSQL support not available.", "msPOSTGRESQLJoinConnect()"); +#else /* not USE_POSTGIS */ +int msPOSTGRESQLJoinConnect(layerObj *layer, joinObj *join) { + msSetError(MS_QUERYERR, "PostgreSQL support not available.", + "msPOSTGRESQLJoinConnect()"); return MS_FAILURE; } -int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) -{ - msSetError(MS_QUERYERR, "PostgreSQL support not available.", "msPOSTGRESQLJoinPrepare()"); +int msPOSTGRESQLJoinPrepare(joinObj *join, shapeObj *shape) { + msSetError(MS_QUERYERR, "PostgreSQL support not available.", + "msPOSTGRESQLJoinPrepare()"); return MS_FAILURE; - } -int msPOSTGRESQLJoinNext(joinObj *join) -{ - msSetError(MS_QUERYERR, "PostgreSQL support not available.", "msPOSTGRESQLJoinNext()"); +int msPOSTGRESQLJoinNext(joinObj *join) { + msSetError(MS_QUERYERR, "PostgreSQL support not available.", + "msPOSTGRESQLJoinNext()"); return MS_FAILURE; - } -int msPOSTGRESQLJoinClose(joinObj *join) -{ - msSetError(MS_QUERYERR, "PostgreSQL support not available.", "msPOSTGRESQLJoinClose()"); +int msPOSTGRESQLJoinClose(joinObj *join) { + msSetError(MS_QUERYERR, "PostgreSQL support not available.", + "msPOSTGRESQLJoinClose()"); return MS_FAILURE; - } #endif diff --git a/mapprimitive.c b/mapprimitive.c index f398abc1d9..096936a302 100644 --- a/mapprimitive.c +++ b/mapprimitive.c @@ -32,34 +32,36 @@ #include #include "fontcache.h" +typedef enum { CLIP_LEFT, CLIP_MIDDLE, CLIP_RIGHT } CLIP_STATE; -typedef enum {CLIP_LEFT, CLIP_MIDDLE, CLIP_RIGHT} CLIP_STATE; - -#define CLIP_CHECK(min, a, max) ((a) < (min) ? CLIP_LEFT : ((a) > (max) ? CLIP_RIGHT : CLIP_MIDDLE)); -#define ROUND(a) ( (a) + 0.5 ) -#define SWAP( a, b, t) ( (t) = (a), (a) = (b), (b) = (t) ) -#define EDGE_CHECK( x0, x, x1) ((x) < MS_MIN( (x0), (x1)) ? CLIP_LEFT : ((x) > MS_MAX( (x0), (x1)) ? CLIP_RIGHT : CLIP_MIDDLE )) +#define CLIP_CHECK(min, a, max) \ + ((a) < (min) ? CLIP_LEFT : ((a) > (max) ? CLIP_RIGHT : CLIP_MIDDLE)); +#define ROUND(a) ((a) + 0.5) +#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) +#define EDGE_CHECK(x0, x, x1) \ + ((x) < MS_MIN((x0), (x1)) \ + ? CLIP_LEFT \ + : ((x) > MS_MAX((x0), (x1)) ? CLIP_RIGHT : CLIP_MIDDLE)) #ifndef INFINITY #define INFINITY (1.0e+30) #endif #define NEARZERO (1.0e-30) /* 1/INFINITY */ -void msPrintShape(shapeObj *p) -{ - int i,j; +void msPrintShape(shapeObj *p) { + int i, j; - msDebug("Shape contains %d parts.\n", p->numlines); - for (i=0; inumlines; i++) { + msDebug("Shape contains %d parts.\n", p->numlines); + for (i = 0; i < p->numlines; i++) { msDebug("\tPart %d contains %d points.\n", i, p->line[i].numpoints); - for (j=0; jline[i].numpoints; j++) { - msDebug("\t\t%d: (%f, %f)\n", j, p->line[i].point[j].x, p->line[i].point[j].y); + for (j = 0; j < p->line[i].numpoints; j++) { + msDebug("\t\t%d: (%f, %f)\n", j, p->line[i].point[j].x, + p->line[i].point[j].y); } } } -shapeObj *msShapeFromWKT(const char *string) -{ +shapeObj *msShapeFromWKT(const char *string) { #ifdef USE_GEOS return msGEOSShapeFromWKT(string); #else @@ -67,11 +69,10 @@ shapeObj *msShapeFromWKT(const char *string) #endif } -char *msShapeToWKT(shapeObj *shape) -{ +char *msShapeToWKT(shapeObj *shape) { #ifdef USE_GEOS - char* pszGEOSStr; - char* pszStr; + char *pszGEOSStr; + char *pszStr; pszGEOSStr = msGEOSShapeToWKT(shape); pszStr = (pszGEOSStr) ? msStrdup(pszGEOSStr) : NULL; msGEOSFreeWKT(pszGEOSStr); @@ -81,8 +82,7 @@ char *msShapeToWKT(shapeObj *shape) #endif } -void msInitShape(shapeObj *shape) -{ +void msInitShape(shapeObj *shape) { /* spatial component */ shape->line = NULL; shape->numlines = 0; @@ -107,13 +107,13 @@ void msInitShape(shapeObj *shape) shape->scratch = MS_FALSE; /* not a temporary/scratch shape */ } -int msCopyShape(const shapeObj *from, shapeObj *to) -{ +int msCopyShape(const shapeObj *from, shapeObj *to) { int i; - if(!from || !to) return(-1); + if (!from || !to) + return (-1); - for(i=0; inumlines; i++) + for (i = 0; i < from->numlines; i++) msAddLine(to, &(from->line[i])); /* copy each line */ to->type = from->type; @@ -123,17 +123,19 @@ int msCopyShape(const shapeObj *from, shapeObj *to) to->bounds.maxx = from->bounds.maxx; to->bounds.maxy = from->bounds.maxy; - if(from->text) to->text = msStrdup(from->text); + if (from->text) + to->text = msStrdup(from->text); to->classindex = from->classindex; to->index = from->index; to->tileindex = from->tileindex; to->resultindex = from->resultindex; - if(from->values) { - if (to->values) msFreeCharArray(to->values, to->numvalues); - to->values = (char **)msSmallMalloc(sizeof(char *)*from->numvalues); - for(i=0; inumvalues; i++) + if (from->values) { + if (to->values) + msFreeCharArray(to->values, to->numvalues); + to->values = (char **)msSmallMalloc(sizeof(char *) * from->numvalues); + for (i = 0; i < from->numvalues; i++) to->values[i] = msStrdup(from->values[i]); to->numvalues = from->numvalues; } @@ -141,21 +143,24 @@ int msCopyShape(const shapeObj *from, shapeObj *to) to->geometry = NULL; /* GEOS code will build automatically if necessary */ to->scratch = from->scratch; - return(0); + return (0); } -void msFreeShape(shapeObj *shape) -{ +void msFreeShape(shapeObj *shape) { int c; - if(!shape) return; /* for safety */ + if (!shape) + return; /* for safety */ - for (c= 0; c < shape->numlines; c++) + for (c = 0; c < shape->numlines; c++) free(shape->line[c].point); - if (shape->line) free(shape->line); - if(shape->values) msFreeCharArray(shape->values, shape->numvalues); - if(shape->text) free(shape->text); + if (shape->line) + free(shape->line); + if (shape->values) + msFreeCharArray(shape->values, shape->numvalues); + if (shape->text) + free(shape->text); #ifdef USE_GEOS msGEOSFreeGeometry(shape); @@ -164,150 +169,161 @@ void msFreeShape(shapeObj *shape) msInitShape(shape); /* now reset */ } -int msGetShapeRAMSize(shapeObj* shape) -{ - int i; - int size = 0; - size += sizeof(shapeObj); - size += shape->numlines * sizeof(lineObj); - for (i = 0; i < shape->numlines; i++) - { - size += shape->line[i].numpoints * sizeof(pointObj); - } - size += shape->numvalues * sizeof(char*); - for( i = 0; i < shape->numvalues; i++ ) - { - if( shape->values[i] ) - size += strlen( shape->values[i] ) + 1; - } - if( shape->text ) - size += strlen( shape->text ) + 1; - return size; +int msGetShapeRAMSize(shapeObj *shape) { + int i; + int size = 0; + size += sizeof(shapeObj); + size += shape->numlines * sizeof(lineObj); + for (i = 0; i < shape->numlines; i++) { + size += shape->line[i].numpoints * sizeof(pointObj); + } + size += shape->numvalues * sizeof(char *); + for (i = 0; i < shape->numvalues; i++) { + if (shape->values[i]) + size += strlen(shape->values[i]) + 1; + } + if (shape->text) + size += strlen(shape->text) + 1; + return size; } -void msFreeLabelPathObj(labelPathObj *path) -{ +void msFreeLabelPathObj(labelPathObj *path) { msFreeShape(&(path->bounds)); msFree(path->path.point); msFree(path->angles); msFree(path); } -void msShapeDeleteLine( shapeObj *shape, int line ) -{ - if( line < 0 || line >= shape->numlines ) { - assert( 0 ); +void msShapeDeleteLine(shapeObj *shape, int line) { + if (line < 0 || line >= shape->numlines) { + assert(0); return; } - free( shape->line[line].point ); - if( line < shape->numlines - 1 ) { - memmove( shape->line + line, - shape->line + line + 1, - sizeof(lineObj) * (shape->numlines - line - 1) ); + free(shape->line[line].point); + if (line < shape->numlines - 1) { + memmove(shape->line + line, shape->line + line + 1, + sizeof(lineObj) * (shape->numlines - line - 1)); } shape->numlines--; } -void msComputeBounds(shapeObj *shape) -{ +void msComputeBounds(shapeObj *shape) { int i, j; - if(shape->numlines <= 0) return; - for(i=0; inumlines; i++) { - if(shape->line[i].numpoints > 0) { + if (shape->numlines <= 0) + return; + for (i = 0; i < shape->numlines; i++) { + if (shape->line[i].numpoints > 0) { shape->bounds.minx = shape->bounds.maxx = shape->line[i].point[0].x; shape->bounds.miny = shape->bounds.maxy = shape->line[i].point[0].y; break; } } - if(i == shape->numlines) return; + if (i == shape->numlines) + return; - for( i=0; inumlines; i++ ) { - for( j=0; jline[i].numpoints; j++ ) { - shape->bounds.minx = MS_MIN(shape->bounds.minx, shape->line[i].point[j].x); - shape->bounds.maxx = MS_MAX(shape->bounds.maxx, shape->line[i].point[j].x); - shape->bounds.miny = MS_MIN(shape->bounds.miny, shape->line[i].point[j].y); - shape->bounds.maxy = MS_MAX(shape->bounds.maxy, shape->line[i].point[j].y); + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->bounds.minx = + MS_MIN(shape->bounds.minx, shape->line[i].point[j].x); + shape->bounds.maxx = + MS_MAX(shape->bounds.maxx, shape->line[i].point[j].x); + shape->bounds.miny = + MS_MIN(shape->bounds.miny, shape->line[i].point[j].y); + shape->bounds.maxy = + MS_MAX(shape->bounds.maxy, shape->line[i].point[j].y); } } } /* checks to see if ring r is an outer ring of shape */ -int msIsOuterRing(shapeObj *shape, int r) -{ - int i, status=MS_TRUE; +int msIsOuterRing(shapeObj *shape, int r) { + int i, status = MS_TRUE; int result1, result2; - if(!shape) return MS_FALSE ; - if(shape->numlines == 1) return MS_TRUE; - if(r < 0 || r >= shape->numlines) return MS_FALSE; /* bad ring index */ + if (!shape) + return MS_FALSE; + if (shape->numlines == 1) + return MS_TRUE; + if (r < 0 || r >= shape->numlines) + return MS_FALSE; /* bad ring index */ - for(i=0; inumlines; i++) { - if(i == r) continue; + for (i = 0; i < shape->numlines; i++) { + if (i == r) + continue; /* - ** We have to test 2, or perhaps 3 points on the shape against the ring because - ** it is possible that at most one point could touch the ring and the function + ** We have to test 2, or perhaps 3 points on the shape against the ring + *because + ** it is possible that at most one point could touch the ring and the + *function ** msPointInPolygon() is indeterminite in that case. (bug #2434) */ result1 = msPointInPolygon(&(shape->line[r].point[0]), &(shape->line[i])); result2 = msPointInPolygon(&(shape->line[r].point[1]), &(shape->line[i])); - if(result1 == result2) { /* same result twice, neither point was on the edge */ - if(result1 == MS_TRUE) status = !status; - } else { /* one of the first 2 points were on the edge of the ring, the next one isn't */ - if(msPointInPolygon(&(shape->line[r].point[2]), &(shape->line[i])) == MS_TRUE) + if (result1 == + result2) { /* same result twice, neither point was on the edge */ + if (result1 == MS_TRUE) + status = !status; + } else { /* one of the first 2 points were on the edge of the ring, the next + one isn't */ + if (msPointInPolygon(&(shape->line[r].point[2]), &(shape->line[i])) == + MS_TRUE) status = !status; } - } - return(status); + return (status); } /* -** Returns a list of outer rings for shape (the list has one entry for each ring, +** Returns a list of outer rings for shape (the list has one entry for each +*ring, ** MS_TRUE for outer rings). */ -int *msGetOuterList(shapeObj *shape) -{ +int *msGetOuterList(shapeObj *shape) { int i; int *list; - if(!shape) return NULL; + if (!shape) + return NULL; - list = (int *)malloc(sizeof(int)*shape->numlines); - MS_CHECK_ALLOC(list, sizeof(int)*shape->numlines, NULL); + list = (int *)malloc(sizeof(int) * shape->numlines); + MS_CHECK_ALLOC(list, sizeof(int) * shape->numlines, NULL); - for(i=0; inumlines; i++) + for (i = 0; i < shape->numlines; i++) list[i] = msIsOuterRing(shape, i); return list; } /* -** Returns a list of inner rings for ring r in shape (given a list of outer rings). +** Returns a list of inner rings for ring r in shape (given a list of outer +*rings). */ -int *msGetInnerList(shapeObj *shape, int r, int *outerlist) -{ +int *msGetInnerList(shapeObj *shape, int r, int *outerlist) { int i; int *list; - if(!shape || !outerlist) return NULL; - if(r < 0 || r >= shape->numlines) return NULL; /* bad ring index */ + if (!shape || !outerlist) + return NULL; + if (r < 0 || r >= shape->numlines) + return NULL; /* bad ring index */ - list = (int *)malloc(sizeof(int)*shape->numlines); - MS_CHECK_ALLOC(list, sizeof(int)*shape->numlines, NULL); + list = (int *)malloc(sizeof(int) * shape->numlines); + MS_CHECK_ALLOC(list, sizeof(int) * shape->numlines, NULL); - for(i=0; inumlines; i++) { /* test all rings against the ring */ + for (i = 0; i < shape->numlines; i++) { /* test all rings against the ring */ - if(outerlist[i] == MS_TRUE) { /* ring is an outer and can't be an inner */ + if (outerlist[i] == MS_TRUE) { /* ring is an outer and can't be an inner */ list[i] = MS_FALSE; continue; } /* A valid inner ring may touch its outer ring at most one point. */ /* In the case the first point matches a vertex of an outer ring, */ - /* msPointInPolygon() might return 0 or 1 (depending on coordinate values, */ + /* msPointInPolygon() might return 0 or 1 (depending on coordinate values, + */ /* see msGetOuterList()), so test a second point if the first test */ /* returned that the point is not inside the outer ring. */ /* Fixes #5299 */ @@ -318,7 +334,7 @@ int *msGetInnerList(shapeObj *shape, int r, int *outerlist) msPointInPolygon(&(shape->line[i].point[1]), &(shape->line[r])); } - return(list); + return (list); } /* @@ -330,58 +346,58 @@ int *msGetInnerList(shapeObj *shape, int r, int *outerlist) ** then call msAddLine() to add it to a shape. */ -int msAddPointToLine(lineObj *line, pointObj *point ) -{ +int msAddPointToLine(lineObj *line, pointObj *point) { line->numpoints += 1; - line->point = (pointObj *) msSmallRealloc(line->point, sizeof(pointObj) * line->numpoints); - line->point[line->numpoints-1] = *point; + line->point = (pointObj *)msSmallRealloc(line->point, + sizeof(pointObj) * line->numpoints); + line->point[line->numpoints - 1] = *point; return MS_SUCCESS; } -int msAddLine(shapeObj *p, const lineObj *new_line) -{ +int msAddLine(shapeObj *p, const lineObj *new_line) { lineObj lineCopy; lineCopy.numpoints = new_line->numpoints; - lineCopy.point = (pointObj *) malloc(new_line->numpoints*sizeof(pointObj)); - MS_CHECK_ALLOC(lineCopy.point, new_line->numpoints*sizeof(pointObj), MS_FAILURE); + lineCopy.point = (pointObj *)malloc(new_line->numpoints * sizeof(pointObj)); + MS_CHECK_ALLOC(lineCopy.point, new_line->numpoints * sizeof(pointObj), + MS_FAILURE); - if( new_line->point ) - memcpy( lineCopy.point, new_line->point, sizeof(pointObj) * new_line->numpoints ); + if (new_line->point) + memcpy(lineCopy.point, new_line->point, + sizeof(pointObj) * new_line->numpoints); // cppcheck-suppress memleak - return msAddLineDirectly( p, &lineCopy ); + return msAddLineDirectly(p, &lineCopy); } /* ** Same as msAddLine(), except that this version "seizes" the points ** array from the passed in line and uses it instead of copying it. */ -int msAddLineDirectly(shapeObj *p, lineObj *new_line) -{ +int msAddLineDirectly(shapeObj *p, lineObj *new_line) { int c; - if( p->numlines == 0 ) { - p->line = (lineObj *) malloc(sizeof(lineObj)); + if (p->numlines == 0) { + p->line = (lineObj *)malloc(sizeof(lineObj)); } else { - lineObj* newline = (lineObj *) realloc(p->line, (p->numlines+1)*sizeof(lineObj)); - if( !newline ) { - free(p->line); + lineObj *newline = + (lineObj *)realloc(p->line, (p->numlines + 1) * sizeof(lineObj)); + if (!newline) { + free(p->line); } p->line = newline; } - if( !p->line ) - { - free(new_line->point ); + if (!p->line) { + free(new_line->point); new_line->point = NULL; new_line->numpoints = 0; } - MS_CHECK_ALLOC(p->line, (p->numlines+1)*sizeof(lineObj), MS_FAILURE); + MS_CHECK_ALLOC(p->line, (p->numlines + 1) * sizeof(lineObj), MS_FAILURE); /* Copy the new line onto the end of the extended line array */ - c= p->numlines; + c = p->numlines; p->line[c].numpoints = new_line->numpoints; p->line[c].point = new_line->point; @@ -392,22 +408,27 @@ int msAddLineDirectly(shapeObj *p, lineObj *new_line) /* Update the polygon information */ p->numlines++; - return(MS_SUCCESS); + return (MS_SUCCESS); } /* -** Converts a rect array to a shapeObj structure. Note order is CW assuming y origin -** is in the lower left corner (normal cartesian coordinate system). Also polygon is -** is closed (i.e. first=last). This conforms to the shapefile specification. For image -** coordinate systems (i.e. GD) this is back-ass-ward, which is fine cause the function -** that calculates direction assumes min y = lower left, this way it'll still work. Drawing -** functions are independent of direction. Orientation problems can cause some nasty bugs. +** Converts a rect array to a shapeObj structure. Note order is CW assuming y +*origin +** is in the lower left corner (normal cartesian coordinate system). Also +*polygon is +** is closed (i.e. first=last). This conforms to the shapefile specification. +*For image +** coordinate systems (i.e. GD) this is back-ass-ward, which is fine cause the +*function +** that calculates direction assumes min y = lower left, this way it'll still +*work. Drawing +** functions are independent of direction. Orientation problems can cause some +*nasty bugs. */ -void msRectToPolygon(rectObj rect, shapeObj *poly) -{ - lineObj line= {0,NULL}; +void msRectToPolygon(rectObj rect, shapeObj *poly) { + lineObj line = {0, NULL}; - line.point = (pointObj *)msSmallMalloc(sizeof(pointObj)*5); + line.point = (pointObj *)msSmallMalloc(sizeof(pointObj) * 5); line.point[0].x = rect.minx; line.point[0].y = rect.miny; @@ -423,7 +444,7 @@ void msRectToPolygon(rectObj rect, shapeObj *poly) line.numpoints = 5; msAddLine(poly, &line); - if(poly->numlines == 1) { /* poly was empty to begin with */ + if (poly->numlines == 1) { /* poly was empty to begin with */ poly->type = MS_SHAPE_POLYGON; poly->bounds = rect; } else @@ -436,23 +457,23 @@ void msRectToPolygon(rectObj rect, shapeObj *poly) ** "Getting Graphic: Programming Fundamentals in C and C++" by Mark Finlay ** and John Petritis. (pages 179-182) */ -static int clipLine(double *x1, double *y1, double *x2, double *y2, rectObj rect) -{ +static int clipLine(double *x1, double *y1, double *x2, double *y2, + rectObj rect) { double x, y; double slope; CLIP_STATE check1, check2; - if(*x1 < rect.minx && *x2 < rect.minx) - return(MS_FALSE); - if(*x1 > rect.maxx && *x2 > rect.maxx) - return(MS_FALSE); + if (*x1 < rect.minx && *x2 < rect.minx) + return (MS_FALSE); + if (*x1 > rect.maxx && *x2 > rect.maxx) + return (MS_FALSE); check1 = CLIP_CHECK(rect.minx, *x1, rect.maxx); check2 = CLIP_CHECK(rect.minx, *x2, rect.maxx); - if(check1 == CLIP_LEFT || check2 == CLIP_LEFT) { - slope = (*y2 - *y1)/(*x2 - *x1); - y = *y1 + (rect.minx - *x1)*slope; - if(check1 == CLIP_LEFT) { + if (check1 == CLIP_LEFT || check2 == CLIP_LEFT) { + slope = (*y2 - *y1) / (*x2 - *x1); + y = *y1 + (rect.minx - *x1) * slope; + if (check1 == CLIP_LEFT) { *x1 = rect.minx; *y1 = y; } else { @@ -460,10 +481,10 @@ static int clipLine(double *x1, double *y1, double *x2, double *y2, rectObj rect *y2 = y; } } - if(check1 == CLIP_RIGHT || check2 == CLIP_RIGHT) { - slope = (*y2 - *y1)/(*x2 - *x1); - y = *y1 + (rect.maxx - *x1)*slope; - if(check1 == CLIP_RIGHT) { + if (check1 == CLIP_RIGHT || check2 == CLIP_RIGHT) { + slope = (*y2 - *y1) / (*x2 - *x1); + y = *y1 + (rect.maxx - *x1) * slope; + if (check1 == CLIP_RIGHT) { *x1 = rect.maxx; *y1 = y; } else { @@ -472,17 +493,17 @@ static int clipLine(double *x1, double *y1, double *x2, double *y2, rectObj rect } } - if(*y1 < rect.miny && *y2 < rect.miny) - return(MS_FALSE); - if(*y1 > rect.maxy && *y2 > rect.maxy) - return(MS_FALSE); + if (*y1 < rect.miny && *y2 < rect.miny) + return (MS_FALSE); + if (*y1 > rect.maxy && *y2 > rect.maxy) + return (MS_FALSE); check1 = CLIP_CHECK(rect.miny, *y1, rect.maxy); check2 = CLIP_CHECK(rect.miny, *y2, rect.maxy); - if(check1 == CLIP_LEFT || check2 == CLIP_LEFT) { - slope = (*x2 - *x1)/(*y2 - *y1); - x = *x1 + (rect.miny - *y1)*slope; - if(check1 == CLIP_LEFT) { + if (check1 == CLIP_LEFT || check2 == CLIP_LEFT) { + slope = (*x2 - *x1) / (*y2 - *y1); + x = *x1 + (rect.miny - *y1) * slope; + if (check1 == CLIP_LEFT) { *x1 = x; *y1 = rect.miny; } else { @@ -490,10 +511,10 @@ static int clipLine(double *x1, double *y1, double *x2, double *y2, rectObj rect *y2 = rect.miny; } } - if(check1 == CLIP_RIGHT || check2 == CLIP_RIGHT) { - slope = (*x2 - *x1)/(*y2 - *y1); - x = *x1 + (rect.maxy - *y1)*slope; - if(check1 == CLIP_RIGHT) { + if (check1 == CLIP_RIGHT || check2 == CLIP_RIGHT) { + slope = (*x2 - *x1) / (*y2 - *y1); + x = *x1 + (rect.maxy - *y1) * slope; + if (check1 == CLIP_RIGHT) { *x1 = x; *y1 = rect.maxy; } else { @@ -502,24 +523,23 @@ static int clipLine(double *x1, double *y1, double *x2, double *y2, rectObj rect } } - return(MS_TRUE); + return (MS_TRUE); } /* ** Routine for clipping a polyline, stored in a shapeObj struct, to a ** rectangle. Uses clipLine() function to create a new shapeObj. */ -void msClipPolylineRect(shapeObj *shape, rectObj rect) -{ - int i,j; - lineObj line= {0,NULL}; +void msClipPolylineRect(shapeObj *shape, rectObj rect) { + int i, j; + lineObj line = {0, NULL}; double x1, x2, y1, y2; shapeObj tmp; - if(!shape || shape->numlines == 0) /* nothing to clip */ + if (!shape || shape->numlines == 0) /* nothing to clip */ return; - memset( &tmp, 0, sizeof(shapeObj) ); + memset(&tmp, 0, sizeof(shapeObj)); /* ** Don't do any clip processing of shapes completely within the @@ -528,26 +548,25 @@ void msClipPolylineRect(shapeObj *shape, rectObj rect) ** since the spatial query at the layer read level has generally already ** discarded all shapes completely outside the rect. */ - if( shape->bounds.maxx <= rect.maxx - && shape->bounds.minx >= rect.minx - && shape->bounds.maxy <= rect.maxy - && shape->bounds.miny >= rect.miny ) { + if (shape->bounds.maxx <= rect.maxx && shape->bounds.minx >= rect.minx && + shape->bounds.maxy <= rect.maxy && shape->bounds.miny >= rect.miny) { return; } - for(i=0; inumlines; i++) { + for (i = 0; i < shape->numlines; i++) { - line.point = (pointObj *)msSmallMalloc(sizeof(pointObj)*shape->line[i].numpoints); + line.point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * shape->line[i].numpoints); line.numpoints = 0; x1 = shape->line[i].point[0].x; y1 = shape->line[i].point[0].y; - for(j=1; jline[i].numpoints; j++) { + for (j = 1; j < shape->line[i].numpoints; j++) { x2 = shape->line[i].point[j].x; y2 = shape->line[i].point[j].y; - if(clipLine(&x1,&y1,&x2,&y2,rect) == MS_TRUE) { - if(line.numpoints == 0) { /* first segment, add both points */ + if (clipLine(&x1, &y1, &x2, &y2, rect) == MS_TRUE) { + if (line.numpoints == 0) { /* first segment, add both points */ line.point[0].x = x1; line.point[0].y = y1; line.point[1].x = x2; @@ -559,7 +578,8 @@ void msClipPolylineRect(shapeObj *shape, rectObj rect) line.numpoints++; } - if((x2 != shape->line[i].point[j].x) || (y2 != shape->line[i].point[j].y)) { + if ((x2 != shape->line[i].point[j].x) || + (y2 != shape->line[i].point[j].y)) { msAddLine(&tmp, &line); line.numpoints = 0; /* new line */ } @@ -569,7 +589,7 @@ void msClipPolylineRect(shapeObj *shape, rectObj rect) y1 = shape->line[i].point[j].y; } - if(line.numpoints > 0) { + if (line.numpoints > 0) { msAddLineDirectly(&tmp, &line); } else { free(line.point); @@ -577,7 +597,8 @@ void msClipPolylineRect(shapeObj *shape, rectObj rect) } } - for (i=0; inumlines; i++) free(shape->line[i].point); + for (i = 0; i < shape->numlines; i++) + free(shape->line[i].point); free(shape->line); shape->line = tmp.line; @@ -588,17 +609,16 @@ void msClipPolylineRect(shapeObj *shape, rectObj rect) /* ** Slightly modified version of the Liang-Barsky polygon clipping algorithm */ -void msClipPolygonRect(shapeObj *shape, rectObj rect) -{ +void msClipPolygonRect(shapeObj *shape, rectObj rect) { int i, j; - double deltax, deltay, xin,xout, yin,yout; - double tinx,tiny, toutx,touty, tin1, tin2, tout; - double x1,y1, x2,y2; + double deltax, deltay, xin, xout, yin, yout; + double tinx, tiny, toutx, touty, tin1, tin2, tout; + double x1, y1, x2, y2; shapeObj tmp; - lineObj line= {0,NULL}; + lineObj line = {0, NULL}; - if(!shape || shape->numlines == 0) /* nothing to clip */ + if (!shape || shape->numlines == 0) /* nothing to clip */ return; msInitShape(&tmp); @@ -610,32 +630,33 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) ** since the spatial query at the layer read level has generally already ** discarded all shapes completely outside the rect. */ - if( shape->bounds.maxx <= rect.maxx - && shape->bounds.minx >= rect.minx - && shape->bounds.maxy <= rect.maxy - && shape->bounds.miny >= rect.miny ) { + if (shape->bounds.maxx <= rect.maxx && shape->bounds.minx >= rect.minx && + shape->bounds.maxy <= rect.maxy && shape->bounds.miny >= rect.miny) { return; } - for(j=0; jnumlines; j++) { + for (j = 0; j < shape->numlines; j++) { - line.point = (pointObj *)msSmallMalloc(sizeof(pointObj)*2*shape->line[j].numpoints+1); /* worst case scenario, +1 allows us to duplicate the 1st and last point */ + line.point = (pointObj *)msSmallMalloc( + sizeof(pointObj) * 2 * shape->line[j].numpoints + + 1); /* worst case scenario, +1 allows us to duplicate the 1st and last + point */ line.numpoints = 0; - for (i = 0; i < shape->line[j].numpoints-1; i++) { + for (i = 0; i < shape->line[j].numpoints - 1; i++) { x1 = shape->line[j].point[i].x; y1 = shape->line[j].point[i].y; - x2 = shape->line[j].point[i+1].x; - y2 = shape->line[j].point[i+1].y; + x2 = shape->line[j].point[i + 1].x; + y2 = shape->line[j].point[i + 1].y; - deltax = x2-x1; + deltax = x2 - x1; if (deltax == 0) { /* bump off of the vertical */ - deltax = (x1 > rect.minx) ? -NEARZERO : NEARZERO ; + deltax = (x1 > rect.minx) ? -NEARZERO : NEARZERO; } - deltay = y2-y1; + deltay = y2 - y1; if (deltay == 0) { /* bump off of the horizontal */ - deltay = (y1 > rect.miny) ? -NEARZERO : NEARZERO ; + deltay = (y1 > rect.miny) ? -NEARZERO : NEARZERO; } if (deltax > 0) { /* points to right */ @@ -653,13 +674,13 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) yout = rect.miny; } - tinx = (xin - x1)/deltax; - tiny = (yin - y1)/deltay; + tinx = (xin - x1) / deltax; + tiny = (yin - y1) / deltay; if (tinx < tiny) { /* hits x first */ tin1 = tinx; tin2 = tiny; - } else { /* hits y first */ + } else { /* hits y first */ tin1 = tiny; tin2 = tinx; } @@ -671,20 +692,20 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) line.numpoints++; } if (1 >= tin2) { - toutx = (xout - x1)/deltax; - touty = (yout - y1)/deltay; + toutx = (xout - x1) / deltax; + touty = (yout - y1) / deltay; - tout = (toutx < touty) ? toutx : touty ; + tout = (toutx < touty) ? toutx : touty; if (0 < tin2 || 0 < tout) { if (tin2 <= tout) { if (0 < tin2) { if (tinx > tiny) { line.point[line.numpoints].x = xin; - line.point[line.numpoints].y = y1 + tinx*deltay; + line.point[line.numpoints].y = y1 + tinx * deltay; line.numpoints++; } else { - line.point[line.numpoints].x = x1 + tiny*deltax; + line.point[line.numpoints].x = x1 + tiny * deltax; line.point[line.numpoints].y = yin; line.numpoints++; } @@ -692,10 +713,10 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) if (1 > tout) { if (toutx < touty) { line.point[line.numpoints].x = xout; - line.point[line.numpoints].y = y1 + toutx*deltay; + line.point[line.numpoints].y = y1 + toutx * deltay; line.numpoints++; } else { - line.point[line.numpoints].x = x1 + touty*deltax; + line.point[line.numpoints].x = x1 + touty * deltax; line.point[line.numpoints].y = yout; line.numpoints++; } @@ -720,7 +741,7 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) } } - if(line.numpoints > 0) { + if (line.numpoints > 0) { line.point[line.numpoints].x = line.point[0].x; /* force closure */ line.point[line.numpoints].y = line.point[0].y; line.numpoints++; @@ -730,7 +751,8 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) } } /* next line */ - for (i=0; inumlines; i++) free(shape->line[i].point); + for (i = 0; i < shape->numlines; i++) + free(shape->line[i].point); free(shape->line); shape->line = tmp.line; @@ -743,55 +765,55 @@ void msClipPolygonRect(shapeObj *shape, rectObj rect) /* ** offsets a point relative to an image position */ -void msOffsetPointRelativeTo(pointObj *point, layerObj *layer) -{ - double x=0, y=0; - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) +void msOffsetPointRelativeTo(pointObj *point, layerObj *layer) { + double x = 0, y = 0; + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return; + if (layer->transform == MS_TRUE) + return; /* nothing to do */ - if(layer->transform == MS_TRUE) return; /* nothing to do */ - - if(layer->units == MS_PERCENTAGES) { - point->x *= (layer->map->width-1); - point->y *= (layer->map->height-1); + if (layer->units == MS_PERCENTAGES) { + point->x *= (layer->map->width - 1); + point->y *= (layer->map->height - 1); } - if(layer->transform == MS_FALSE || layer->transform == MS_UL) return; /* done */ - - switch(layer->transform) { - case MS_UC: - x = (layer->map->width-1)/2; - y = 0; - break; - case MS_UR: - x = layer->map->width-1; - y = 0; - break; - case MS_CL: - x = 0; - y = layer->map->height/2; - break; - case MS_CC: - x = layer->map->width/2; - y = layer->map->height/2; - break; - case MS_CR: - x = layer->map->width-1; - y = layer->map->height/2; - break; - case MS_LL: - x = 0; - y = layer->map->height-1; - break; - case MS_LC: - x = layer->map->width/2; - y = layer->map->height-1; - break; - case MS_LR: - x = layer->map->width-1; - y = layer->map->height-1; - break; + if (layer->transform == MS_FALSE || layer->transform == MS_UL) + return; /* done */ + + switch (layer->transform) { + case MS_UC: + x = (layer->map->width - 1) / 2; + y = 0; + break; + case MS_UR: + x = layer->map->width - 1; + y = 0; + break; + case MS_CL: + x = 0; + y = layer->map->height / 2; + break; + case MS_CC: + x = layer->map->width / 2; + y = layer->map->height / 2; + break; + case MS_CR: + x = layer->map->width - 1; + y = layer->map->height / 2; + break; + case MS_LL: + x = 0; + y = layer->map->height - 1; + break; + case MS_LC: + x = layer->map->width / 2; + y = layer->map->height - 1; + break; + case MS_LR: + x = layer->map->width - 1; + y = layer->map->height - 1; + break; } point->x += x; @@ -803,64 +825,64 @@ void msOffsetPointRelativeTo(pointObj *point, layerObj *layer) /* ** offsets a shape relative to an image position */ -void msOffsetShapeRelativeTo(shapeObj *shape, layerObj *layer) -{ +void msOffsetShapeRelativeTo(shapeObj *shape, layerObj *layer) { int i, j; - double x=0, y=0; + double x = 0, y = 0; - if(layer->transform == MS_TRUE) return; /* nothing to do */ - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) + if (layer->transform == MS_TRUE) + return; /* nothing to do */ + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return; - - if(layer->units == MS_PERCENTAGES) { - for (i=0; inumlines; i++) { - for (j=0; jline[i].numpoints; j++) { - shape->line[i].point[j].x *= (layer->map->width-1); - shape->line[i].point[j].y *= (layer->map->height-1); + if (layer->units == MS_PERCENTAGES) { + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x *= (layer->map->width - 1); + shape->line[i].point[j].y *= (layer->map->height - 1); } } } - if(layer->transform == MS_FALSE || layer->transform == MS_UL) return; /* done */ - - switch(layer->transform) { - case MS_UC: - x = (layer->map->width-1)/2; - y = 0; - break; - case MS_UR: - x = layer->map->width-1; - y = 0; - break; - case MS_CL: - x = 0; - y = layer->map->height/2; - break; - case MS_CC: - x = layer->map->width/2; - y = layer->map->height/2; - break; - case MS_CR: - x = layer->map->width-1; - y = layer->map->height/2; - break; - case MS_LL: - x = 0; - y = layer->map->height-1; - break; - case MS_LC: - x = layer->map->width/2; - y = layer->map->height-1; - break; - case MS_LR: - x = layer->map->width-1; - y = layer->map->height-1; - break; + if (layer->transform == MS_FALSE || layer->transform == MS_UL) + return; /* done */ + + switch (layer->transform) { + case MS_UC: + x = (layer->map->width - 1) / 2; + y = 0; + break; + case MS_UR: + x = layer->map->width - 1; + y = 0; + break; + case MS_CL: + x = 0; + y = layer->map->height / 2; + break; + case MS_CC: + x = layer->map->width / 2; + y = layer->map->height / 2; + break; + case MS_CR: + x = layer->map->width - 1; + y = layer->map->height / 2; + break; + case MS_LL: + x = 0; + y = layer->map->height - 1; + break; + case MS_LC: + x = layer->map->width / 2; + y = layer->map->height - 1; + break; + case MS_LR: + x = layer->map->width - 1; + y = layer->map->height - 1; + break; } - for (i=0; inumlines; i++) { - for (j=0; jline[i].numpoints; j++) { + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { shape->line[i].point[j].x += x; shape->line[i].point[j].y += y; } @@ -869,16 +891,17 @@ void msOffsetShapeRelativeTo(shapeObj *shape, layerObj *layer) return; } -void msTransformShapeSimplify(shapeObj *shape, rectObj extent, double cellsize) -{ - int i,j,k,beforelast; /* loop counters */ - double dx,dy; +void msTransformShapeSimplify(shapeObj *shape, rectObj extent, + double cellsize) { + int i, j, k, beforelast; /* loop counters */ + double dx, dy; pointObj *point; double inv_cs = 1.0 / cellsize; /* invert and multiply much faster */ int ok = 0; - if(shape->numlines == 0) return; /* nothing to transform */ + if (shape->numlines == 0) + return; /* nothing to transform */ - if(shape->type == MS_SHAPE_LINE) { + if (shape->type == MS_SHAPE_LINE) { /* * loop through the shape's lines, and do naive simplification * to discard the points that are too close to one another. @@ -887,41 +910,42 @@ void msTransformShapeSimplify(shapeObj *shape, rectObj extent, double cellsize) * the simplified line is guaranteed to contain at * least its first and last point */ - for(i=0; inumlines; i++) { /* for each part */ - if(shape->line[i].numpoints<2) { - shape->line[i].numpoints=0; + for (i = 0; i < shape->numlines; i++) { /* for each part */ + if (shape->line[i].numpoints < 2) { + shape->line[i].numpoints = 0; continue; /*skip degenerate lines*/ } - point=shape->line[i].point; + point = shape->line[i].point; /*always keep first point*/ point[0].x = MS_MAP2IMAGE_X_IC_DBL(point[0].x, extent.minx, inv_cs); point[0].y = MS_MAP2IMAGE_Y_IC_DBL(point[0].y, extent.maxy, inv_cs); - beforelast=shape->line[i].numpoints-1; - for(j=1,k=1; j < beforelast; j++ ) { /*loop from second point to first-before-last point*/ + beforelast = shape->line[i].numpoints - 1; + for (j = 1, k = 1; j < beforelast; + j++) { /*loop from second point to first-before-last point*/ point[k].x = MS_MAP2IMAGE_X_IC_DBL(point[j].x, extent.minx, inv_cs); point[k].y = MS_MAP2IMAGE_Y_IC_DBL(point[j].y, extent.maxy, inv_cs); - dx=(point[k].x-point[k-1].x); - dy=(point[k].y-point[k-1].y); - if(dx*dx+dy*dy>1) + dx = (point[k].x - point[k - 1].x); + dy = (point[k].y - point[k - 1].y); + if (dx * dx + dy * dy > 1) k++; } /* try to keep last point */ point[k].x = MS_MAP2IMAGE_X_IC_DBL(point[j].x, extent.minx, inv_cs); point[k].y = MS_MAP2IMAGE_Y_IC_DBL(point[j].y, extent.maxy, inv_cs); /* discard last point if equal to the one before it */ - if(point[k].x!=point[k-1].x || point[k].y!=point[k-1].y) { - shape->line[i].numpoints=k+1; + if (point[k].x != point[k - 1].x || point[k].y != point[k - 1].y) { + shape->line[i].numpoints = k + 1; } else { - shape->line[i].numpoints=k; + shape->line[i].numpoints = k; } /* skip degenerate line once more */ - if(shape->line[i].numpoints<2) { - shape->line[i].numpoints=0; + if (shape->line[i].numpoints < 2) { + shape->line[i].numpoints = 0; } else { ok = 1; /* we have at least one line with more than two points */ } } - } else if(shape->type == MS_SHAPE_POLYGON) { + } else if (shape->type == MS_SHAPE_POLYGON) { /* * loop through the shape's lines, and do naive simplification * to discard the points that are too close to one another. @@ -930,69 +954,74 @@ void msTransformShapeSimplify(shapeObj *shape, rectObj extent, double cellsize) * the simplified polygon is guaranteed to contain at * least its first, second and last point */ - for(i=0; inumlines; i++) { /* for each part */ - if(shape->line[i].numpoints<4) { - shape->line[i].numpoints=0; + for (i = 0; i < shape->numlines; i++) { /* for each part */ + if (shape->line[i].numpoints < 4) { + shape->line[i].numpoints = 0; continue; /*skip degenerate lines*/ } - point=shape->line[i].point; + point = shape->line[i].point; /*always keep first and second point*/ point[0].x = MS_MAP2IMAGE_X_IC_DBL(point[0].x, extent.minx, inv_cs); point[0].y = MS_MAP2IMAGE_Y_IC_DBL(point[0].y, extent.maxy, inv_cs); point[1].x = MS_MAP2IMAGE_X_IC_DBL(point[1].x, extent.minx, inv_cs); point[1].y = MS_MAP2IMAGE_Y_IC_DBL(point[1].y, extent.maxy, inv_cs); - beforelast=shape->line[i].numpoints-2; - for(j=2,k=2; j < beforelast; j++ ) { /*loop from second point to second-before-last point*/ + beforelast = shape->line[i].numpoints - 2; + for (j = 2, k = 2; j < beforelast; + j++) { /*loop from second point to second-before-last point*/ point[k].x = MS_MAP2IMAGE_X_IC_DBL(point[j].x, extent.minx, inv_cs); point[k].y = MS_MAP2IMAGE_Y_IC_DBL(point[j].y, extent.maxy, inv_cs); - dx=(point[k].x-point[k-1].x); - dy=(point[k].y-point[k-1].y); - if(dx*dx+dy*dy>1) + dx = (point[k].x - point[k - 1].x); + dy = (point[k].y - point[k - 1].y); + if (dx * dx + dy * dy > 1) k++; } /*always keep last two points (the last point is the repetition of the * first one */ point[k].x = MS_MAP2IMAGE_X_IC_DBL(point[j].x, extent.minx, inv_cs); point[k].y = MS_MAP2IMAGE_Y_IC_DBL(point[j].y, extent.maxy, inv_cs); - point[k+1].x = MS_MAP2IMAGE_X_IC_DBL(point[j+1].x, extent.minx, inv_cs); - point[k+1].y = MS_MAP2IMAGE_Y_IC_DBL(point[j+1].y, extent.maxy, inv_cs); - shape->line[i].numpoints = k+2; + point[k + 1].x = + MS_MAP2IMAGE_X_IC_DBL(point[j + 1].x, extent.minx, inv_cs); + point[k + 1].y = + MS_MAP2IMAGE_Y_IC_DBL(point[j + 1].y, extent.maxy, inv_cs); + shape->line[i].numpoints = k + 2; ok = 1; } - } else { /* only for untyped shapes, as point layers don't go through this function */ - for(i=0; inumlines; i++) { - point=shape->line[i].point; - for(j=0; jline[i].numpoints; j++) { + } else { /* only for untyped shapes, as point layers don't go through this + function */ + for (i = 0; i < shape->numlines; i++) { + point = shape->line[i].point; + for (j = 0; j < shape->line[i].numpoints; j++) { point[j].x = MS_MAP2IMAGE_X_IC_DBL(point[j].x, extent.minx, inv_cs); point[j].y = MS_MAP2IMAGE_Y_IC_DBL(point[j].y, extent.maxy, inv_cs); } } ok = 1; } - if(!ok) { - for(i=0; inumlines; i++) { + if (!ok) { + for (i = 0; i < shape->numlines; i++) { free(shape->line[i].point); } - shape->numlines = 0 ; + shape->numlines = 0; } } /** * Generic function to transorm the shape coordinates to output coordinates */ -void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, imageObj *image) -{ +void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, + imageObj *image) { if (image != NULL && MS_RENDERER_PLUGIN(image->format)) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image); - if(renderer->transform_mode == MS_TRANSFORM_SNAPTOGRID) { - msTransformShapeToPixelSnapToGrid(shape, extent, cellsize, renderer->approximation_scale); - } else if(renderer->transform_mode == MS_TRANSFORM_SIMPLIFY) { + if (renderer->transform_mode == MS_TRANSFORM_SNAPTOGRID) { + msTransformShapeToPixelSnapToGrid(shape, extent, cellsize, + renderer->approximation_scale); + } else if (renderer->transform_mode == MS_TRANSFORM_SIMPLIFY) { msTransformShapeSimplify(shape, extent, cellsize); - } else if(renderer->transform_mode == MS_TRANSFORM_ROUND) { + } else if (renderer->transform_mode == MS_TRANSFORM_ROUND) { msTransformShapeToPixelRound(shape, extent, cellsize); - } else if(renderer->transform_mode == MS_TRANSFORM_FULLRESOLUTION) { - msTransformShapeToPixelDoublePrecision(shape,extent,cellsize); - } else if(renderer->transform_mode == MS_TRANSFORM_NONE) { + } else if (renderer->transform_mode == MS_TRANSFORM_FULLRESOLUTION) { + msTransformShapeToPixelDoublePrecision(shape, extent, cellsize); + } else if (renderer->transform_mode == MS_TRANSFORM_NONE) { /* nothing to do */ return; } @@ -1002,142 +1031,184 @@ void msTransformShape(shapeObj *shape, rectObj extent, double cellsize, imageOb msTransformShapeToPixelRound(shape, extent, cellsize); } -void msTransformShapeToPixelSnapToGrid(shapeObj *shape, rectObj extent, double cellsize, double grid_resolution) -{ - int i,j,k; /* loop counters */ +void msTransformShapeToPixelSnapToGrid(shapeObj *shape, rectObj extent, + double cellsize, + double grid_resolution) { + int i, j, k; /* loop counters */ double inv_cs; - if(shape->numlines == 0) return; + if (shape->numlines == 0) + return; inv_cs = 1.0 / cellsize; /* invert and multiply much faster */ - - if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */ - for(i=0; inumlines; i++) { /* for each part */ + if (shape->type == MS_SHAPE_LINE || + shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */ + for (i = 0; i < shape->numlines; i++) { /* for each part */ int snap = 1; - const double x0 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[0].x, extent.minx, inv_cs, grid_resolution); - const double y0 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[0].y, extent.maxy, inv_cs, grid_resolution); + const double x0 = MS_MAP2IMAGE_X_IC_SNAP( + shape->line[i].point[0].x, extent.minx, inv_cs, grid_resolution); + const double y0 = MS_MAP2IMAGE_Y_IC_SNAP( + shape->line[i].point[0].y, extent.maxy, inv_cs, grid_resolution); /*do a quick heuristic: will we risk having a degenerate shape*/ - if(shape->type == MS_SHAPE_LINE) { - /*a line is degenerate if it has a single pixel. we check that the first and last pixel are different*/ - const double x1 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints-1].x, extent.minx, inv_cs, grid_resolution); - const double y1 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints-1].y, extent.maxy, inv_cs, grid_resolution); - if(x0 == x1 && y0 == y1) { + if (shape->type == MS_SHAPE_LINE) { + /*a line is degenerate if it has a single pixel. we check that the first + * and last pixel are different*/ + const double x1 = MS_MAP2IMAGE_X_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints - 1].x, extent.minx, + inv_cs, grid_resolution); + const double y1 = MS_MAP2IMAGE_Y_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints - 1].y, extent.maxy, + inv_cs, grid_resolution); + if (x0 == x1 && y0 == y1) { snap = 0; } } else /* if(shape->type == MS_SHAPE_POLYGON) */ { - const double x1 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3].x, extent.minx, inv_cs, grid_resolution); - const double y1 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3].y, extent.maxy, inv_cs, grid_resolution); - const double x2 = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3*2].x, extent.minx, inv_cs, grid_resolution); - const double y2 = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[shape->line[i].numpoints/3*2].y, extent.maxy, inv_cs, grid_resolution); - if((x0 == x1 && y0 == y1) || - (x0 == x2 && y0 == y2) || + const double x1 = MS_MAP2IMAGE_X_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints / 3].x, extent.minx, + inv_cs, grid_resolution); + const double y1 = MS_MAP2IMAGE_Y_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints / 3].y, extent.maxy, + inv_cs, grid_resolution); + const double x2 = MS_MAP2IMAGE_X_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints / 3 * 2].x, + extent.minx, inv_cs, grid_resolution); + const double y2 = MS_MAP2IMAGE_Y_IC_SNAP( + shape->line[i].point[shape->line[i].numpoints / 3 * 2].y, + extent.maxy, inv_cs, grid_resolution); + if ((x0 == x1 && y0 == y1) || (x0 == x2 && y0 == y2) || (x1 == x2 && y1 == y2)) { snap = 0; } } - if(snap) { + if (snap) { shape->line[i].point[0].x = x0; shape->line[i].point[0].y = y0; - for(j=1, k=1; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC_SNAP(shape->line[i].point[j].x, extent.minx, inv_cs, grid_resolution); - shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC_SNAP(shape->line[i].point[j].y, extent.maxy, inv_cs, grid_resolution); - if(shape->line[i].point[k].x!=shape->line[i].point[k-1].x || shape->line[i].point[k].y!=shape->line[i].point[k-1].y) + for (j = 1, k = 1; j < shape->line[i].numpoints; j++) { + shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC_SNAP( + shape->line[i].point[j].x, extent.minx, inv_cs, grid_resolution); + shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC_SNAP( + shape->line[i].point[j].y, extent.maxy, inv_cs, grid_resolution); + if (shape->line[i].point[k].x != shape->line[i].point[k - 1].x || + shape->line[i].point[k].y != shape->line[i].point[k - 1].y) k++; } - shape->line[i].numpoints=k; + shape->line[i].numpoints = k; } else { - if(shape->type == MS_SHAPE_LINE) { - shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[0].x, extent.minx, inv_cs); - shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[0].y, extent.maxy, inv_cs); - shape->line[i].point[1].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[shape->line[i].numpoints-1].x, extent.minx, inv_cs); - shape->line[i].point[1].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[shape->line[i].numpoints-1].y, extent.maxy, inv_cs); + if (shape->type == MS_SHAPE_LINE) { + shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC_DBL( + shape->line[i].point[0].x, extent.minx, inv_cs); + shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC_DBL( + shape->line[i].point[0].y, extent.maxy, inv_cs); + shape->line[i].point[1].x = MS_MAP2IMAGE_X_IC_DBL( + shape->line[i].point[shape->line[i].numpoints - 1].x, extent.minx, + inv_cs); + shape->line[i].point[1].y = MS_MAP2IMAGE_Y_IC_DBL( + shape->line[i].point[shape->line[i].numpoints - 1].y, extent.maxy, + inv_cs); shape->line[i].numpoints = 2; } else { - for(j=0; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs); - shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs); + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL( + shape->line[i].point[j].x, extent.minx, inv_cs); + shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL( + shape->line[i].point[j].y, extent.maxy, inv_cs); } } } } - } else { /* points or untyped shapes */ - for(i=0; inumlines; i++) { /* for each part */ - for(j=1; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs); - shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs); + } else { /* points or untyped shapes */ + for (i = 0; i < shape->numlines; i++) { /* for each part */ + for (j = 1; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL( + shape->line[i].point[j].x, extent.minx, inv_cs); + shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL( + shape->line[i].point[j].y, extent.maxy, inv_cs); } } } - } -void msTransformShapeToPixelRound(shapeObj *shape, rectObj extent, double cellsize) -{ - int i,j,k; /* loop counters */ +void msTransformShapeToPixelRound(shapeObj *shape, rectObj extent, + double cellsize) { + int i, j, k; /* loop counters */ double inv_cs; - if(shape->numlines == 0) return; + if (shape->numlines == 0) + return; inv_cs = 1.0 / cellsize; /* invert and multiply much faster */ - if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */ - for(i=0; inumlines; i++) { /* for each part */ - shape->line[i].point[0].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[0].x, extent.minx, inv_cs);; - shape->line[i].point[0].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[0].y, extent.maxy, inv_cs); - for(j=1, k=1; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[k].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs); - shape->line[i].point[k].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs); - if(shape->line[i].point[k].x!=shape->line[i].point[k-1].x || shape->line[i].point[k].y!=shape->line[i].point[k-1].y) + if (shape->type == MS_SHAPE_LINE || + shape->type == MS_SHAPE_POLYGON) { /* remove duplicate vertices */ + for (i = 0; i < shape->numlines; i++) { /* for each part */ + shape->line[i].point[0].x = + MS_MAP2IMAGE_X_IC(shape->line[i].point[0].x, extent.minx, inv_cs); + ; + shape->line[i].point[0].y = + MS_MAP2IMAGE_Y_IC(shape->line[i].point[0].y, extent.maxy, inv_cs); + for (j = 1, k = 1; j < shape->line[i].numpoints; j++) { + shape->line[i].point[k].x = + MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs); + shape->line[i].point[k].y = + MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs); + if (shape->line[i].point[k].x != shape->line[i].point[k - 1].x || + shape->line[i].point[k].y != shape->line[i].point[k - 1].y) k++; } - shape->line[i].numpoints=k; + shape->line[i].numpoints = k; } - } else { /* points or untyped shapes */ - for(i=0; inumlines; i++) { /* for each part */ - for(j=0; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs); - shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs); + } else { /* points or untyped shapes */ + for (i = 0; i < shape->numlines; i++) { /* for each part */ + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = + MS_MAP2IMAGE_X_IC(shape->line[i].point[j].x, extent.minx, inv_cs); + shape->line[i].point[j].y = + MS_MAP2IMAGE_Y_IC(shape->line[i].point[j].y, extent.maxy, inv_cs); } } } - } -void msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, double cellsize) -{ - int i,j; /* loop counters */ +void msTransformShapeToPixelDoublePrecision(shapeObj *shape, rectObj extent, + double cellsize) { + int i, j; /* loop counters */ double inv_cs = 1.0 / cellsize; /* invert and multiply much faster */ - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - shape->line[i].point[j].x = MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs); - shape->line[i].point[j].y = MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs); + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = + MS_MAP2IMAGE_X_IC_DBL(shape->line[i].point[j].x, extent.minx, inv_cs); + shape->line[i].point[j].y = + MS_MAP2IMAGE_Y_IC_DBL(shape->line[i].point[j].y, extent.maxy, inv_cs); } } } - - /* ** Converts from map coordinates to image coordinates */ -void msTransformPixelToShape(shapeObj *shape, rectObj extent, double cellsize) -{ - int i,j; /* loop counters */ +void msTransformPixelToShape(shapeObj *shape, rectObj extent, double cellsize) { + int i, j; /* loop counters */ - if(shape->numlines == 0) return; /* nothing to transform */ + if (shape->numlines == 0) + return; /* nothing to transform */ - if(shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { /* remove co-linear vertices */ + if (shape->type == MS_SHAPE_LINE || + shape->type == MS_SHAPE_POLYGON) { /* remove co-linear vertices */ - for(i=0; inumlines; i++) { /* for each part */ - for(j=0; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[j].x = MS_IMAGE2MAP_X(shape->line[i].point[j].x, extent.minx, cellsize); - shape->line[i].point[j].y = MS_IMAGE2MAP_Y(shape->line[i].point[j].y, extent.maxy, cellsize); + for (i = 0; i < shape->numlines; i++) { /* for each part */ + for (j = 0; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = + MS_IMAGE2MAP_X(shape->line[i].point[j].x, extent.minx, cellsize); + shape->line[i].point[j].y = + MS_IMAGE2MAP_Y(shape->line[i].point[j].y, extent.maxy, cellsize); } } } else { /* points or untyped shapes */ - for(i=0; inumlines; i++) { /* for each part */ - for(j=1; j < shape->line[i].numpoints; j++ ) { - shape->line[i].point[j].x = MS_IMAGE2MAP_X(shape->line[i].point[j].x, extent.minx, cellsize); - shape->line[i].point[j].y = MS_IMAGE2MAP_Y(shape->line[i].point[j].y, extent.maxy, cellsize); + for (i = 0; i < shape->numlines; i++) { /* for each part */ + for (j = 1; j < shape->line[i].numpoints; j++) { + shape->line[i].point[j].x = + MS_IMAGE2MAP_X(shape->line[i].point[j].x, extent.minx, cellsize); + shape->line[i].point[j].y = + MS_IMAGE2MAP_Y(shape->line[i].point[j].y, extent.maxy, cellsize); } } } @@ -1146,30 +1217,32 @@ void msTransformPixelToShape(shapeObj *shape, rectObj extent, double cellsize) } /* -** Not a generic intersection test, we KNOW the lines aren't parallel or coincident. To be used with the next -** buffering code only. See code in mapsearch.c for a boolean test for intersection. +** Not a generic intersection test, we KNOW the lines aren't parallel or +*coincident. To be used with the next +** buffering code only. See code in mapsearch.c for a boolean test for +*intersection. */ -static pointObj generateLineIntersection(pointObj a, pointObj b, pointObj c, pointObj d) -{ +static pointObj generateLineIntersection(pointObj a, pointObj b, pointObj c, + pointObj d) { pointObj p = {0}; // initialize double r; double denominator, numerator; - if(b.x == c.x && b.y == c.y) return(b); + if (b.x == c.x && b.y == c.y) + return (b); - numerator = ((a.y-c.y)*(d.x-c.x) - (a.x-c.x)*(d.y-c.y)); - denominator = ((b.x-a.x)*(d.y-c.y) - (b.y-a.y)*(d.x-c.x)); + numerator = ((a.y - c.y) * (d.x - c.x) - (a.x - c.x) * (d.y - c.y)); + denominator = ((b.x - a.x) * (d.y - c.y) - (b.y - a.y) * (d.x - c.x)); - r = numerator/denominator; + r = numerator / denominator; - p.x = MS_NINT(a.x + r*(b.x-a.x)); - p.y = MS_NINT(a.y + r*(b.y-a.y)); + p.x = MS_NINT(a.x + r * (b.x - a.x)); + p.y = MS_NINT(a.y + r * (b.y - a.y)); - return(p); + return (p); } -void bufferPolyline(shapeObj *p, shapeObj *op, int w) -{ +void bufferPolyline(shapeObj *p, shapeObj *op, int w) { int i, j; pointObj a = {0}; lineObj inside, outside; @@ -1178,19 +1251,25 @@ void bufferPolyline(shapeObj *p, shapeObj *op, int w) for (i = 0; i < p->numlines; i++) { - inside.point = (pointObj *)msSmallMalloc(sizeof(pointObj)*p->line[i].numpoints); - outside.point = (pointObj *)msSmallMalloc(sizeof(pointObj)*p->line[i].numpoints); + inside.point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * p->line[i].numpoints); + outside.point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * p->line[i].numpoints); inside.numpoints = outside.numpoints = p->line[i].numpoints; - angle = asin(MS_ABS(p->line[i].point[1].x - p->line[i].point[0].x)/sqrt((((p->line[i].point[1].x - p->line[i].point[0].x)*(p->line[i].point[1].x - p->line[i].point[0].x)) + ((p->line[i].point[1].y - p->line[i].point[0].y)*(p->line[i].point[1].y - p->line[i].point[0].y))))); - if(p->line[i].point[0].x < p->line[i].point[1].x) - dy = sin(angle) * (w/2); + angle = asin(MS_ABS(p->line[i].point[1].x - p->line[i].point[0].x) / + sqrt((((p->line[i].point[1].x - p->line[i].point[0].x) * + (p->line[i].point[1].x - p->line[i].point[0].x)) + + ((p->line[i].point[1].y - p->line[i].point[0].y) * + (p->line[i].point[1].y - p->line[i].point[0].y))))); + if (p->line[i].point[0].x < p->line[i].point[1].x) + dy = sin(angle) * (w / 2); else - dy = -sin(angle) * (w/2); - if(p->line[i].point[0].y < p->line[i].point[1].y) - dx = -cos(angle) * (w/2); + dy = -sin(angle) * (w / 2); + if (p->line[i].point[0].y < p->line[i].point[1].y) + dx = -cos(angle) * (w / 2); else - dx = cos(angle) * (w/2); + dx = cos(angle) * (w / 2); inside.point[0].x = p->line[i].point[0].x + dx; inside.point[1].x = p->line[i].point[1].x + dx; @@ -1202,32 +1281,40 @@ void bufferPolyline(shapeObj *p, shapeObj *op, int w) outside.point[0].y = p->line[i].point[0].y - dy; outside.point[1].y = p->line[i].point[1].y - dy; - for(j=2; jline[i].numpoints; j++) { + for (j = 2; j < p->line[i].numpoints; j++) { - angle = asin(MS_ABS(p->line[i].point[j].x - p->line[i].point[j-1].x)/sqrt((((p->line[i].point[j].x - p->line[i].point[j-1].x)*(p->line[i].point[j].x - p->line[i].point[j-1].x)) + ((p->line[i].point[j].y - p->line[i].point[j-1].y)*(p->line[i].point[j].y - p->line[i].point[j-1].y))))); - if(p->line[i].point[j-1].x < p->line[i].point[j].x) - dy = sin(angle) * (w/2); + angle = + asin(MS_ABS(p->line[i].point[j].x - p->line[i].point[j - 1].x) / + sqrt((((p->line[i].point[j].x - p->line[i].point[j - 1].x) * + (p->line[i].point[j].x - p->line[i].point[j - 1].x)) + + ((p->line[i].point[j].y - p->line[i].point[j - 1].y) * + (p->line[i].point[j].y - p->line[i].point[j - 1].y))))); + if (p->line[i].point[j - 1].x < p->line[i].point[j].x) + dy = sin(angle) * (w / 2); else - dy = -sin(angle) * (w/2); - if(p->line[i].point[j-1].y < p->line[i].point[j].y) - dx = -cos(angle) * (w/2); + dy = -sin(angle) * (w / 2); + if (p->line[i].point[j - 1].y < p->line[i].point[j].y) + dx = -cos(angle) * (w / 2); else - dx = cos(angle) * (w/2); + dx = cos(angle) * (w / 2); - a.x = p->line[i].point[j-1].x + dx; + a.x = p->line[i].point[j - 1].x + dx; inside.point[j].x = p->line[i].point[j].x + dx; - a.y = p->line[i].point[j-1].y + dy; + a.y = p->line[i].point[j - 1].y + dy; inside.point[j].y = p->line[i].point[j].y + dy; - inside.point[j-1] = generateLineIntersection(inside.point[j-2], inside.point[j-1], a, inside.point[j]); + inside.point[j - 1] = generateLineIntersection( + inside.point[j - 2], inside.point[j - 1], a, inside.point[j]); - a.x = p->line[i].point[j-1].x - dx; + a.x = p->line[i].point[j - 1].x - dx; outside.point[j].x = p->line[i].point[j].x - dx; - a.y = p->line[i].point[j-1].y - dy; + a.y = p->line[i].point[j - 1].y - dy; outside.point[j].y = p->line[i].point[j].y - dy; - outside.point[j-1] = generateLineIntersection(outside.point[j-2], outside.point[j-1], a, outside.point[j]); + outside.point[j - 1] = generateLineIntersection( + outside.point[j - 2], outside.point[j - 1], a, outside.point[j]); } - /* need a touch of code if 1st point equals last point in p (find intersection) */ + /* need a touch of code if 1st point equals last point in p (find + * intersection) */ msAddLine(op, &inside); msAddLine(op, &outside); @@ -1239,26 +1326,26 @@ void bufferPolyline(shapeObj *p, shapeObj *op, int w) return; } -static double getRingArea(lineObj *ring) -{ +static double getRingArea(lineObj *ring) { int i; - double s=0; + double s = 0; - for(i=0; inumpoints-1; i++) - s += (ring->point[i].x*ring->point[i+1].y - ring->point[i+1].x*ring->point[i].y); + for (i = 0; i < ring->numpoints - 1; i++) + s += (ring->point[i].x * ring->point[i + 1].y - + ring->point[i + 1].x * ring->point[i].y); - return (MS_ABS(s/2)); + return (MS_ABS(s / 2)); } -double msGetPolygonArea(shapeObj *p) -{ +double msGetPolygonArea(shapeObj *p) { int i; - double area=0; + double area = 0; - if(!p) return 0; + if (!p) + return 0; - for(i=0; inumlines; i++) { - if(msIsOuterRing(p, i)) + for (i = 0; i < p->numlines; i++) { + if (msIsOuterRing(p, i)) area += getRingArea(&(p->line[i])); else area -= getRingArea(&(p->line[i])); /* hole */ @@ -1268,79 +1355,82 @@ double msGetPolygonArea(shapeObj *p) } /* -** Computes the center of gravity for a polygon based on it's largest outer ring only. +** Computes the center of gravity for a polygon based on it's largest outer ring +*only. */ -static int getPolygonCenterOfGravity(shapeObj *p, pointObj *lp) -{ - double sx=0, sy=0; /* sums */ - double largestArea=0; +static int getPolygonCenterOfGravity(shapeObj *p, pointObj *lp) { + double sx = 0, sy = 0; /* sums */ + double largestArea = 0; - for(int i=0; inumlines; i++) { + for (int i = 0; i < p->numlines; i++) { double tsx = 0; double tsy = 0; double s = 0; /* reset the ring sums */ - for(int j=0; jline[i].numpoints-1; j++) { - double a = p->line[i].point[j].x*p->line[i].point[j+1].y - p->line[i].point[j+1].x*p->line[i].point[j].y; + for (int j = 0; j < p->line[i].numpoints - 1; j++) { + double a = p->line[i].point[j].x * p->line[i].point[j + 1].y - + p->line[i].point[j + 1].x * p->line[i].point[j].y; s += a; - tsx += (p->line[i].point[j].x + p->line[i].point[j+1].x)*a; - tsy += (p->line[i].point[j].y + p->line[i].point[j+1].y)*a; + tsx += (p->line[i].point[j].x + p->line[i].point[j + 1].x) * a; + tsy += (p->line[i].point[j].y + p->line[i].point[j + 1].y) * a; } - double area = MS_ABS(s/2); + double area = MS_ABS(s / 2); - if(area > largestArea) { + if (area > largestArea) { largestArea = area; - sx = s>0?tsx:-tsx; - sy = s>0?tsy:-tsy; + sx = s > 0 ? tsx : -tsx; + sy = s > 0 ? tsy : -tsy; } } - if(largestArea == 0) /*degenerate polygon*/ + if (largestArea == 0) /*degenerate polygon*/ return MS_FAILURE; - lp->x = sx/(6*largestArea); - lp->y = sy/(6*largestArea); + lp->x = sx / (6 * largestArea); + lp->y = sy / (6 * largestArea); return MS_SUCCESS; } -int msGetPolygonCentroid(shapeObj *p, pointObj *lp, double *miny, double *maxy) -{ - int i,j; - double cent_weight_x=0.0, cent_weight_y=0.0; - double len, total_len=0; +int msGetPolygonCentroid(shapeObj *p, pointObj *lp, double *miny, + double *maxy) { + int i, j; + double cent_weight_x = 0.0, cent_weight_y = 0.0; + double len, total_len = 0; *miny = *maxy = p->line[0].point[0].y; - for(i=0; inumlines; i++) { - for(j=1; jline[i].numpoints; j++) { + for (i = 0; i < p->numlines; i++) { + for (j = 1; j < p->line[i].numpoints; j++) { *miny = MS_MIN(*miny, p->line[i].point[j].y); *maxy = MS_MAX(*maxy, p->line[i].point[j].y); - len = msDistancePointToPoint(&(p->line[i].point[j-1]), &(p->line[i].point[j])); - cent_weight_x += len * ((p->line[i].point[j-1].x + p->line[i].point[j].x)/2); - cent_weight_y += len * ((p->line[i].point[j-1].y + p->line[i].point[j].y)/2); + len = msDistancePointToPoint(&(p->line[i].point[j - 1]), + &(p->line[i].point[j])); + cent_weight_x += + len * ((p->line[i].point[j - 1].x + p->line[i].point[j].x) / 2); + cent_weight_y += + len * ((p->line[i].point[j - 1].y + p->line[i].point[j].y) / 2); total_len += len; } } - if(total_len == 0) - return(MS_FAILURE); + if (total_len == 0) + return (MS_FAILURE); lp->x = cent_weight_x / total_len; lp->y = cent_weight_y / total_len; - return(MS_SUCCESS); + return (MS_SUCCESS); } /* ** Find a label point in a polygon. */ -int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) -{ +int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) { double slope; - pointObj *point1=NULL, *point2=NULL, cp; + pointObj *point1 = NULL, *point2 = NULL, cp; int i, j, nfound; double x, y, *intersect, temp; double min, max; int wrong_order, n; - double len, max_len=0; + double len, max_len = 0; double minx, maxx, maxy, miny; #ifdef notdef @@ -1353,43 +1443,49 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) maxx = p->bounds.maxx; maxy = p->bounds.maxy; - if(min_dimension > 0) - if(MS_MIN(maxx-minx,maxy-miny) < min_dimension) return(MS_FAILURE); + if (min_dimension > 0) + if (MS_MIN(maxx - minx, maxy - miny) < min_dimension) + return (MS_FAILURE); - cp.x = (maxx+minx)/2.0; - cp.y = (maxy+miny)/2.0; + cp.x = (maxx + minx) / 2.0; + cp.y = (maxy + miny) / 2.0; #ifdef notdef switch (method) { - case 0: /* MBR */ - lp->x = cp.x; - lp->y = cp.y; - break; - case 1: /* centroid */ - if(msGetPolygonCentroid(p, lp, &miny, &maxy) != MS_SUCCESS) return(MS_FAILURE); - break; - case 2: /* center of gravity */ - if(getPolygonCenterOfGravity(p, lp) != MS_SUCCESS) return(MS_FAILURE); - break; + case 0: /* MBR */ + lp->x = cp.x; + lp->y = cp.y; + break; + case 1: /* centroid */ + if (msGetPolygonCentroid(p, lp, &miny, &maxy) != MS_SUCCESS) + return (MS_FAILURE); + break; + case 2: /* center of gravity */ + if (getPolygonCenterOfGravity(p, lp) != MS_SUCCESS) + return (MS_FAILURE); + break; } #else - if(getPolygonCenterOfGravity(p, lp) != MS_SUCCESS) return(MS_FAILURE); + if (getPolygonCenterOfGravity(p, lp) != MS_SUCCESS) + return (MS_FAILURE); #endif - if(msIntersectPointPolygon(lp, p) == MS_TRUE) { - double dist, min_dist=-1; + if (msIntersectPointPolygon(lp, p) == MS_TRUE) { + double dist, min_dist = -1; /* compute a distance to the polygon */ - for(j=0; jnumlines; j++) { - for(i=1; iline[j].numpoints; i++) { - dist = msSquareDistancePointToSegment(lp, &(p->line[j].point[i-1]), &(p->line[j].point[i])); - if((dist < min_dist) || (min_dist < 0)) min_dist = dist; + for (j = 0; j < p->numlines; j++) { + for (i = 1; i < p->line[j].numpoints; i++) { + dist = msSquareDistancePointToSegment(lp, &(p->line[j].point[i - 1]), + &(p->line[j].point[i])); + if ((dist < min_dist) || (min_dist < 0)) + min_dist = dist; } } min_dist = sqrt(min_dist); - if(min_dist > .1*MS_MAX(maxx-minx, maxy-miny)) - return(MS_SUCCESS); /* point is not too close to the edge */ + if (min_dist > .1 * MS_MAX(maxx - minx, maxy - miny)) + return (MS_SUCCESS); /* point is not too close to the edge */ } /* printf("label: %s\n", p->text); @@ -1400,63 +1496,67 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) printf(" distance to parent shape: %g\n", min_dist); return MS_SUCCESS; */ - n=0; - for(j=0; jnumlines; j++) /* count total number of points */ + n = 0; + for (j = 0; j < p->numlines; j++) /* count total number of points */ n += p->line[j].numpoints; - intersect = (double *) calloc(n, sizeof(double)); - MS_CHECK_ALLOC(intersect, n*sizeof(double), MS_FAILURE); - + intersect = (double *)calloc(n, sizeof(double)); + MS_CHECK_ALLOC(intersect, n * sizeof(double), MS_FAILURE); - if(MS_ABS((int)lp->x - (int)cp.x) > MS_ABS((int)lp->y - (int)cp.y)) { /* center horizontally, fix y */ + if (MS_ABS((int)lp->x - (int)cp.x) > + MS_ABS((int)lp->y - (int)cp.y)) { /* center horizontally, fix y */ y = lp->y; /* need to find a y that won't intersect any vertices exactly */ - max = y - 1; /* first initializing min, max to be any 2 pnts on either side of y */ + max = y - 1; /* first initializing min, max to be any 2 pnts on either side + of y */ min = y + 1; - for(j=0; jnumlines; j++) { - if((min < y) && (max >= y)) break; - for(i=0; i < p->line[j].numpoints; i++) { - if((min < y) && (max >= y)) break; - if(p->line[j].point[i].y < y) + for (j = 0; j < p->numlines; j++) { + if ((min < y) && (max >= y)) + break; + for (i = 0; i < p->line[j].numpoints; i++) { + if ((min < y) && (max >= y)) + break; + if (p->line[j].point[i].y < y) min = p->line[j].point[i].y; - if(p->line[j].point[i].y >= y) + if (p->line[j].point[i].y >= y) max = p->line[j].point[i].y; } } - n=0; - for(j=0; jnumlines; j++) { - for(i=0; i < p->line[j].numpoints; i++) { - if((p->line[j].point[i].y < y) && ((y - p->line[j].point[i].y) < (y - min))) + n = 0; + for (j = 0; j < p->numlines; j++) { + for (i = 0; i < p->line[j].numpoints; i++) { + if ((p->line[j].point[i].y < y) && + ((y - p->line[j].point[i].y) < (y - min))) min = p->line[j].point[i].y; - if((p->line[j].point[i].y >= y) && ((p->line[j].point[i].y - y) < (max - y))) + if ((p->line[j].point[i].y >= y) && + ((p->line[j].point[i].y - y) < (max - y))) max = p->line[j].point[i].y; } } - if(min == max) { + if (min == max) { msFree(intersect); return (MS_FAILURE); - } - else - y = (max + min)/2.0; + } else + y = (max + min) / 2.0; nfound = 0; - for(j=0; jnumlines; j++) { /* for each line */ + for (j = 0; j < p->numlines; j++) { /* for each line */ - point1 = &( p->line[j].point[p->line[j].numpoints-1] ); - for(i=0; i < p->line[j].numpoints; i++) { - point2 = &( p->line[j].point[i] ); + point1 = &(p->line[j].point[p->line[j].numpoints - 1]); + for (i = 0; i < p->line[j].numpoints; i++) { + point2 = &(p->line[j].point[i]); - if(EDGE_CHECK(point1->y, y, point2->y) == CLIP_MIDDLE) { + if (EDGE_CHECK(point1->y, y, point2->y) == CLIP_MIDDLE) { - if(point1->y == point2->y) + if (point1->y == point2->y) continue; /* ignore horizontal edges */ else slope = (point2->x - point1->x) / (point2->y - point1->y); - x = point1->x + (y - point1->y)*slope; + x = point1->x + (y - point1->y) * slope; intersect[nfound++] = x; } /* end checking this edge */ @@ -1467,20 +1567,20 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) /* sort the intersections */ do { wrong_order = 0; - for(i=0; i < nfound-1; i++) { - if(intersect[i] > intersect[i+1]) { + for (i = 0; i < nfound - 1; i++) { + if (intersect[i] > intersect[i + 1]) { wrong_order = 1; - SWAP(intersect[i], intersect[i+1], temp); + SWAP(intersect[i], intersect[i + 1], temp); } } - } while(wrong_order); + } while (wrong_order); /* find longest span */ - for(i=0; i < nfound; i += 2) { - len = fabs(intersect[i] - intersect[i+1]); - if(len > max_len) { + for (i = 0; i < nfound; i += 2) { + len = fabs(intersect[i] - intersect[i + 1]); + if (len > max_len) { max_len = len; - lp->x = (intersect[i] + intersect[i+1])/2; + lp->x = (intersect[i] + intersect[i + 1]) / 2; lp->y = y; } } @@ -1488,52 +1588,56 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) x = lp->x; /* need to find a x that won't intersect any vertices exactly */ - max = x - 1; /* first initializing min, max to be any 2 pnts on either side of x */ + max = x - 1; /* first initializing min, max to be any 2 pnts on either side + of x */ min = x + 1; - for(j=0; jnumlines; j++) { - if((min < x) && (max >= x)) break; - for(i=0; i < p->line[j].numpoints; i++) { - if((min < x) && (max >= x)) break; - if(p->line[j].point[i].x < x) + for (j = 0; j < p->numlines; j++) { + if ((min < x) && (max >= x)) + break; + for (i = 0; i < p->line[j].numpoints; i++) { + if ((min < x) && (max >= x)) + break; + if (p->line[j].point[i].x < x) min = p->line[j].point[i].x; - if(p->line[j].point[i].x >= x) + if (p->line[j].point[i].x >= x) max = p->line[j].point[i].x; } } - n=0; - for(j=0; jnumlines; j++) { - for(i=0; i < p->line[j].numpoints; i++) { - if((p->line[j].point[i].x < x) && ((x - p->line[j].point[i].x) < (x - min))) + n = 0; + for (j = 0; j < p->numlines; j++) { + for (i = 0; i < p->line[j].numpoints; i++) { + if ((p->line[j].point[i].x < x) && + ((x - p->line[j].point[i].x) < (x - min))) min = p->line[j].point[i].x; - if((p->line[j].point[i].x >= x) && ((p->line[j].point[i].x - x) < (max - x))) + if ((p->line[j].point[i].x >= x) && + ((p->line[j].point[i].x - x) < (max - x))) max = p->line[j].point[i].x; } } - if(min == max) { + if (min == max) { msFree(intersect); return (MS_FAILURE); - } - else - x = (max + min)/2.0; + } else + x = (max + min) / 2.0; nfound = 0; - for(j=0; jnumlines; j++) { /* for each line */ + for (j = 0; j < p->numlines; j++) { /* for each line */ - point1 = &( p->line[j].point[p->line[j].numpoints-1] ); - for(i=0; i < p->line[j].numpoints; i++) { - point2 = &( p->line[j].point[i] ); + point1 = &(p->line[j].point[p->line[j].numpoints - 1]); + for (i = 0; i < p->line[j].numpoints; i++) { + point2 = &(p->line[j].point[i]); - if(EDGE_CHECK(point1->x, x, point2->x) == CLIP_MIDDLE) { + if (EDGE_CHECK(point1->x, x, point2->x) == CLIP_MIDDLE) { - if(point1->x == point2->x) + if (point1->x == point2->x) continue; /* ignore vertical edges */ - else if(point1->y == point2->y) + else if (point1->y == point2->y) y = point1->y; /* for a horizontal edge we know y */ else { slope = (point2->x - point1->x) / (point2->y - point1->y); - y = (x - point1->x)/slope + point1->y; + y = (x - point1->x) / slope + point1->y; } intersect[nfound++] = y; @@ -1546,20 +1650,20 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) /* sort the intersections */ do { wrong_order = 0; - for(i=0; i < nfound-1; i++) { - if(intersect[i] > intersect[i+1]) { + for (i = 0; i < nfound - 1; i++) { + if (intersect[i] > intersect[i + 1]) { wrong_order = 1; - SWAP(intersect[i], intersect[i+1], temp); + SWAP(intersect[i], intersect[i + 1], temp); } } - } while(wrong_order); + } while (wrong_order); /* find longest span */ - for(i=0; i < nfound; i += 2) { - len = fabs(intersect[i] - intersect[i+1]); - if(len > max_len) { + for (i = 0; i < nfound; i += 2) { + len = fabs(intersect[i] - intersect[i + 1]); + if (len > max_len) { max_len = len; - lp->y = (intersect[i] + intersect[i+1])/2; + lp->y = (intersect[i] + intersect[i + 1]) / 2; lp->x = x; } } @@ -1567,46 +1671,51 @@ int msPolygonLabelPoint(shapeObj *p, pointObj *lp, double min_dimension) free(intersect); - if(max_len > 0) - return(MS_SUCCESS); + if (max_len > 0) + return (MS_SUCCESS); else - return(MS_FAILURE); + return (MS_FAILURE); } -/* Compute all the lineString/segment lengths and determine the longest lineString of a multiLineString - * shape: in paramater, the multiLineString to compute. - * struct polyline_lengths pll: out parameter, all line and segment lengths -*/ -void msPolylineComputeLineSegments(shapeObj *shape, struct polyline_lengths *pll) -{ +/* Compute all the lineString/segment lengths and determine the longest + * lineString of a multiLineString shape: in paramater, the multiLineString to + * compute. struct polyline_lengths pll: out parameter, all line and segment + * lengths + */ +void msPolylineComputeLineSegments(shapeObj *shape, + struct polyline_lengths *pll) { int i, j; - double max_line_length=-1, max_segment_length=-1, segment_length; + double max_line_length = -1, max_segment_length = -1, segment_length; pll->ll = msSmallMalloc(shape->numlines * sizeof(struct line_lengths)); pll->total_length = 0; pll->longest_line_index = 0; - - for(i=0; inumlines; i++) { + for (i = 0; i < shape->numlines; i++) { struct line_lengths *ll = &pll->ll[i]; double max_subline_segment_length = -1; - - if(shape->line[i].numpoints > 1) { - ll->segment_lengths = (double*) msSmallMalloc(sizeof(double) * (shape->line[i].numpoints - 1)); + + if (shape->line[i].numpoints > 1) { + ll->segment_lengths = (double *)msSmallMalloc( + sizeof(double) * (shape->line[i].numpoints - 1)); } else { ll->segment_lengths = NULL; } ll->total_length = 0; - - for(j=1; jline[i].numpoints; j++) { - segment_length = sqrt((((shape->line[i].point[j].x-shape->line[i].point[j-1].x)*(shape->line[i].point[j].x-shape->line[i].point[j-1].x)) + ((shape->line[i].point[j].y-shape->line[i].point[j-1].y)*(shape->line[i].point[j].y-shape->line[i].point[j-1].y)))); + + for (j = 1; j < shape->line[i].numpoints; j++) { + segment_length = + sqrt((((shape->line[i].point[j].x - shape->line[i].point[j - 1].x) * + (shape->line[i].point[j].x - shape->line[i].point[j - 1].x)) + + ((shape->line[i].point[j].y - shape->line[i].point[j - 1].y) * + (shape->line[i].point[j].y - shape->line[i].point[j - 1].y)))); ll->total_length += segment_length; - ll->segment_lengths[j-1] = segment_length; - if(segment_length > max_subline_segment_length) { + ll->segment_lengths[j - 1] = segment_length; + if (segment_length > max_subline_segment_length) { max_subline_segment_length = segment_length; ll->longest_segment_index = j; } - if(segment_length > max_segment_length) { + if (segment_length > max_segment_length) { max_segment_length = segment_length; pll->longest_segment_line_index = i; pll->longest_segment_point_index = j; @@ -1614,7 +1723,7 @@ void msPolylineComputeLineSegments(shapeObj *shape, struct polyline_lengths *pll } pll->total_length += ll->total_length; - if(ll->total_length > max_line_length) { + if (ll->total_length > max_line_length) { max_line_length = ll->total_length; pll->longest_line_index = i; } @@ -1622,76 +1731,83 @@ void msPolylineComputeLineSegments(shapeObj *shape, struct polyline_lengths *pll } /* -** If no repeatdistance, find center of longest segment in polyline p. The polyline must have been converted +** If no repeatdistance, find center of longest segment in polyline p. The +*polyline must have been converted ** to image coordinates before calling this function. */ -int msPolylineLabelPoint(mapObj *map, shapeObj *p, textSymbolObj *ts, labelObj *label, struct label_auto_result *lar, double resolutionfactor) -{ +int msPolylineLabelPoint(mapObj *map, shapeObj *p, textSymbolObj *ts, + labelObj *label, struct label_auto_result *lar, + double resolutionfactor) { struct polyline_lengths pll; int i, ret = MS_SUCCESS; double minfeaturesize = -1; assert(ts == NULL || ts->annotext); - - if(label && ts) { - if(label->autominfeaturesize) { - if(!ts->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) + if (label && ts) { + if (label->autominfeaturesize) { + if (!ts->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) return MS_FAILURE; } - if(!ts->textpath) + if (!ts->textpath) return MS_FAILURE; minfeaturesize = ts->textpath->bounds.bbox.maxx; - } else if(label->minfeaturesize) { + } else if (label->minfeaturesize) { minfeaturesize = label->minfeaturesize * resolutionfactor; } } /* compute line lengths, in order to: - extract the longest line if we're not repeating - - check that each line is longer than the text length if using minfeaturesize auto + - check that each line is longer than the text length if using + minfeaturesize auto - check that each line is long enough if using minfeaturesize */ msPolylineComputeLineSegments(p, &pll); - if(label && label->repeatdistance > 0) { - for(i=0; inumlines; i++) { - if(pll.ll[i].total_length > minfeaturesize) { - ret = msLineLabelPoint(map,&p->line[i], ts, &pll.ll[i],lar, label, resolutionfactor); + if (label && label->repeatdistance > 0) { + for (i = 0; i < p->numlines; i++) { + if (pll.ll[i].total_length > minfeaturesize) { + ret = msLineLabelPoint(map, &p->line[i], ts, &pll.ll[i], lar, label, + resolutionfactor); } } } else { i = pll.longest_line_index; - if(pll.ll[i].total_length > minfeaturesize) { - ret = msLineLabelPoint(map,&p->line[i], ts, &pll.ll[i],lar, label, resolutionfactor); + if (pll.ll[i].total_length > minfeaturesize) { + ret = msLineLabelPoint(map, &p->line[i], ts, &pll.ll[i], lar, label, + resolutionfactor); } } /* freeing memory: allocated by msPolylineComputeLineSegments */ - for ( i = 0; i < p->numlines; i++ ) { + for (i = 0; i < p->numlines; i++) { free(pll.ll[i].segment_lengths); } free(pll.ll); - + return ret; } -int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, struct line_lengths *ll, struct label_auto_result *lar, labelObj *label, double resolutionfactor) -{ +int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, + struct line_lengths *ll, struct label_auto_result *lar, + labelObj *label, double resolutionfactor) { (void)map; int j, l, n, point_repeat; double t, theta, fwd_length, point_distance; - double center_point_position, left_point_position, right_point_position, point_position; + double center_point_position, left_point_position, right_point_position, + point_position; double repeat_distance = -1; - if(label) { + if (label) { repeat_distance = label->repeatdistance * resolutionfactor; } - if(MS_UNLIKELY(p->numpoints < 2)) + if (MS_UNLIKELY(p->numpoints < 2)) return MS_FAILURE; point_distance = 0; point_repeat = 1; - left_point_position = right_point_position = center_point_position = ll->total_length / 2.0; + left_point_position = right_point_position = center_point_position = + ll->total_length / 2.0; if (repeat_distance > 0) { point_repeat = ll->total_length / repeat_distance; @@ -1699,19 +1815,21 @@ int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, struct line_len if (point_repeat > 1) { if (point_repeat % 2 == 0) point_repeat -= 1; - point_distance = (ll->total_length / point_repeat); /* buffer allowed per point */ + point_distance = + (ll->total_length / point_repeat); /* buffer allowed per point */ /* initial point position */ - left_point_position -= ((point_repeat-1)/2 * point_distance); - right_point_position += ((point_repeat-1)/2 * point_distance); + left_point_position -= ((point_repeat - 1) / 2 * point_distance); + right_point_position += ((point_repeat - 1) / 2 * point_distance); - point_repeat = (point_repeat-1)/2+1; + point_repeat = (point_repeat - 1) / 2 + 1; } else point_repeat = 1; } - for (l=0; l < point_repeat; ++l) { - if (l == point_repeat-1) { /* last point to place is always the center point */ + for (l = 0; l < point_repeat; ++l) { + if (l == + point_repeat - 1) { /* last point to place is always the center point */ point_position = center_point_position; n = 1; } else { @@ -1720,34 +1838,42 @@ int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, struct line_len } do { - lar->angles = msSmallRealloc(lar->angles, (lar->num_label_points+1)*sizeof(double)); - lar->label_points = msSmallRealloc(lar->label_points, (lar->num_label_points+1)*sizeof(pointObj)); - - /* if there is only 1 label to place... put it in the middle of the current segment (as old behavior) */ - if ( point_repeat == 1 ) { + lar->angles = msSmallRealloc(lar->angles, (lar->num_label_points + 1) * + sizeof(double)); + lar->label_points = msSmallRealloc( + lar->label_points, (lar->num_label_points + 1) * sizeof(pointObj)); + + /* if there is only 1 label to place... put it in the middle of the + * current segment (as old behavior) */ + if (point_repeat == 1) { j = ll->longest_segment_index; - lar->label_points[lar->num_label_points].x = (p->point[j-1].x + p->point[j].x)/2.0; - lar->label_points[lar->num_label_points].y = (p->point[j-1].y + p->point[j].y)/2.0; + lar->label_points[lar->num_label_points].x = + (p->point[j - 1].x + p->point[j].x) / 2.0; + lar->label_points[lar->num_label_points].y = + (p->point[j - 1].y + p->point[j].y) / 2.0; } else { - j=0; + j = 0; fwd_length = 0; while (fwd_length < point_position) { fwd_length += ll->segment_lengths[j++]; } - assert(j>0); + assert(j > 0); - t = 1 - (fwd_length - point_position) / ll->segment_lengths[j-1]; - lar->label_points[lar->num_label_points].x = t * (p->point[j].x - p->point[j-1].x) + p->point[j-1].x; - lar->label_points[lar->num_label_points].y = t * (p->point[j].y - p->point[j-1].y) + p->point[j-1].y; + t = 1 - (fwd_length - point_position) / ll->segment_lengths[j - 1]; + lar->label_points[lar->num_label_points].x = + t * (p->point[j].x - p->point[j - 1].x) + p->point[j - 1].x; + lar->label_points[lar->num_label_points].y = + t * (p->point[j].y - p->point[j - 1].y) + p->point[j - 1].y; } - if(label && ts) { - if(label->anglemode != MS_NONE) { - theta = atan2(p->point[j].x - p->point[j-1].x, p->point[j].y - p->point[j-1].y); - if(label->anglemode == MS_AUTO2) { + if (label && ts) { + if (label->anglemode != MS_NONE) { + theta = atan2(p->point[j].x - p->point[j - 1].x, + p->point[j].y - p->point[j - 1].y); + if (label->anglemode == MS_AUTO2) { theta -= MS_PI2; - } else { /* AUTO, FOLLOW */ - if(p->point[j-1].x < p->point[j].x) { /* i.e. to the left */ + } else { /* AUTO, FOLLOW */ + if (p->point[j - 1].x < p->point[j].x) { /* i.e. to the left */ theta -= MS_PI2; } else { theta += MS_PI2; @@ -1764,7 +1890,7 @@ int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, struct line_len point_position = left_point_position; n++; - } while (n<2); /* we place the right point then the left point. */ + } while (n < 2); /* we place the right point then the left point. */ right_point_position -= point_distance; left_point_position += point_distance; @@ -1773,148 +1899,165 @@ int msLineLabelPoint(mapObj *map, lineObj *p, textSymbolObj *ts, struct line_len return MS_SUCCESS; } - -/* Calculate the labelpath for each line if repeatdistance is enabled, else the labelpath of the longest line segment */ -int msPolylineLabelPath(mapObj *map, imageObj *image, shapeObj *p, textSymbolObj *ts, labelObj *label, struct label_follow_result *lfr) -{ +/* Calculate the labelpath for each line if repeatdistance is enabled, else the + * labelpath of the longest line segment */ +int msPolylineLabelPath(mapObj *map, imageObj *image, shapeObj *p, + textSymbolObj *ts, labelObj *label, + struct label_follow_result *lfr) { struct polyline_lengths pll; - int i,ret = MS_SUCCESS; + int i, ret = MS_SUCCESS; double minfeaturesize = -1; assert(ts->annotext); lfr->num_follow_labels = lfr->lar.num_label_points = 0; /* we first offset the line if we want an offsetted label */ - if(label->offsetx != 0 && IS_PERPENDICULAR_OFFSET(label->offsety)) { + if (label->offsetx != 0 && IS_PERPENDICULAR_OFFSET(label->offsety)) { double offset; - if(label->offsetx > 0) { - offset = label->offsetx + label->size/2; + if (label->offsetx > 0) { + offset = label->offsetx + label->size / 2; } else { - offset = label->offsetx - label->size/2; + offset = label->offsetx - label->size / 2; } - if(label->offsety == MS_LABEL_PERPENDICULAR_TOP_OFFSET && p->numlines>0 && p->line[0].numpoints > 0) { + if (label->offsety == MS_LABEL_PERPENDICULAR_TOP_OFFSET && + p->numlines > 0 && p->line[0].numpoints > 0) { /* is the line mostly left-to-right or right-to-left ? - * FIXME this should be done line by line, by stepping through shape->lines, however - * the OffsetPolyline function works on shapeObjs, not lineObjs - * we only check the first line + * FIXME this should be done line by line, by stepping through + * shape->lines, however the OffsetPolyline function works on shapeObjs, + * not lineObjs we only check the first line */ - if(p->line[0].point[0].x < p->line[0].point[p->line[0].numpoints-1].x) { + if (p->line[0].point[0].x < + p->line[0].point[p->line[0].numpoints - 1].x) { /* line is left to right */ - offset = -offset; + offset = -offset; } } - p = msOffsetPolyline(p,offset, MS_STYLE_SINGLE_SIDED_OFFSET); - if(!p) return MS_FAILURE; + p = msOffsetPolyline(p, offset, MS_STYLE_SINGLE_SIDED_OFFSET); + if (!p) + return MS_FAILURE; } /* compute line lengths, in order to: - extract the longest line if we're not repeating - - check that each line is longer than the text length if using minfeaturesize auto + - check that each line is longer than the text length if using + minfeaturesize auto - check that each line is long enough if using minfeaturesize */ msPolylineComputeLineSegments(p, &pll); - - if(label->autominfeaturesize) { - if(!ts->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) { + + if (label->autominfeaturesize) { + if (!ts->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) { return MS_FAILURE; } } - if(!ts->textpath) + if (!ts->textpath) return MS_FAILURE; minfeaturesize = ts->textpath->bounds.bbox.maxx; - } else if(label->minfeaturesize) { + } else if (label->minfeaturesize) { minfeaturesize = label->minfeaturesize * image->resolutionfactor; } - if(label->repeatdistance > 0) { - for(i=0; inumlines; i++) { - if(pll.ll[i].total_length > minfeaturesize) { - ret = msLineLabelPath(map,image,&p->line[i], ts, &pll.ll[i],lfr, label); + if (label->repeatdistance > 0) { + for (i = 0; i < p->numlines; i++) { + if (pll.ll[i].total_length > minfeaturesize) { + ret = msLineLabelPath(map, image, &p->line[i], ts, &pll.ll[i], lfr, + label); } } } else { i = pll.longest_line_index; - if(pll.ll[i].total_length > minfeaturesize) { - ret = msLineLabelPath(map,image,&p->line[i], ts, &pll.ll[i],lfr, label); + if (pll.ll[i].total_length > minfeaturesize) { + ret = + msLineLabelPath(map, image, &p->line[i], ts, &pll.ll[i], lfr, label); } } /* freeing memory: allocated by msPolylineComputeLineSegments */ - for ( i = 0; i < p->numlines; i++ ) { + for (i = 0; i < p->numlines; i++) { free(pll.ll[i].segment_lengths); } free(pll.ll); - - if(IS_PERPENDICULAR_OFFSET(label->offsety) && label->offsetx != 0) { - msFreeShape(p); - msFree(p); + + if (IS_PERPENDICULAR_OFFSET(label->offsety) && label->offsetx != 0) { + msFreeShape(p); + msFree(p); } return ret; } -static double compute_retry_offset(textSymbolObj *ts, int fail_idx, double retried_offset, double max_dec_offset, double max_inc_offset) { -/* fail_idx: the glyph index in the textpath that originally failed (i.e. before any displacement was tested */ -/* retried_offset: the last offset that was tried and is failing, so we can return the next one (or 0 if none left)*/ - int inc = 1,dec_found=0, inc_found=0; +static double compute_retry_offset(textSymbolObj *ts, int fail_idx, + double retried_offset, double max_dec_offset, + double max_inc_offset) { + /* fail_idx: the glyph index in the textpath that originally failed (i.e. + * before any displacement was tested */ + /* retried_offset: the last offset that was tried and is failing, so we can + * return the next one (or 0 if none left)*/ + int inc = 1, dec_found = 0, inc_found = 0; double inc_offset = 0, dec_offset = 0; retried_offset = fabs(retried_offset); do { - if(fail_idx - inc - 1 >= 0) { + if (fail_idx - inc - 1 >= 0) { dec_offset += ts->textpath->glyphs[fail_idx - inc].glyph->metrics.advance; - if(dec_offset > max_dec_offset) + if (dec_offset > max_dec_offset) break; - if(dec_offset > retried_offset && msIsGlyphASpace(&ts->textpath->glyphs[fail_idx - inc - 1])) { + if (dec_offset > retried_offset && + msIsGlyphASpace(&ts->textpath->glyphs[fail_idx - inc - 1])) { dec_found = 1; - dec_offset += ts->textpath->glyphs[fail_idx - inc -1].glyph->metrics.advance / 2.0; + dec_offset += + ts->textpath->glyphs[fail_idx - inc - 1].glyph->metrics.advance / + 2.0; break; } } inc++; - } while(dec_offset0); - - if(!dec_found) { + } while (dec_offset < max_dec_offset && fail_idx - inc > 0); + + if (!dec_found) { /* try the starting position */ dec_offset += ts->textpath->glyphs[0].glyph->metrics.advance; - if(dec_offset > retried_offset && dec_offset retried_offset && dec_offset < max_dec_offset) { dec_found = 1; } } - + inc = 1; inc_offset = ts->textpath->glyphs[fail_idx].glyph->metrics.advance; - do{ - if(fail_idx + inc < ts->textpath->numglyphs - 1) { - if(inc_offset > retried_offset && msIsGlyphASpace(&ts->textpath->glyphs[fail_idx + inc])) { - inc_offset += ts->textpath->glyphs[fail_idx + inc].glyph->metrics.advance / 2; - if(inc_offset < max_inc_offset) + do { + if (fail_idx + inc < ts->textpath->numglyphs - 1) { + if (inc_offset > retried_offset && + msIsGlyphASpace(&ts->textpath->glyphs[fail_idx + inc])) { + inc_offset += + ts->textpath->glyphs[fail_idx + inc].glyph->metrics.advance / 2; + if (inc_offset < max_inc_offset) inc_found = 1; break; } inc_offset += ts->textpath->glyphs[fail_idx + inc].glyph->metrics.advance; } inc++; - } while(inc_offsettextpath->numglyphs-1); - if(!inc_found) { - inc_offset += ts->textpath->glyphs[ts->textpath->numglyphs-1].glyph->metrics.advance; - if(inc_offset > retried_offset && inc_offsettextpath->numglyphs - 1); + if (!inc_found) { + inc_offset += ts->textpath->glyphs[ts->textpath->numglyphs - 1] + .glyph->metrics.advance; + if (inc_offset > retried_offset && inc_offset < max_inc_offset) { inc_found = 1; } } - - if(!inc_found && !dec_found) + + if (!inc_found && !dec_found) return 0.0; - if(inc_found && dec_found) { - if(inc_offsetrepeatdistance * ts->resolutionfactor; - double segment_length, fwd_line_length, rev_line_length, text_length, text_start_length, label_buffer, text_end_length, cur_label_position, first_label_position; + double segment_length, fwd_line_length, rev_line_length, text_length, + text_start_length, label_buffer, text_end_length, cur_label_position, + first_label_position; double max_retry_offset; - int j,k,l,inc, final_j, label_repeat; + int j, k, l, inc, final_j, label_repeat; double direction; rectObj bbox; lineObj *bounds; @@ -1941,29 +2087,32 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s double dx, dy, w, cos_t, sin_t; const double letterspacing = 1.00; - /* As per RFC 60, if label->maxoverlapangle == 0 then fall back on pre-6.0 behavior - which was to use maxoverlapangle = 0.4*MS_PI ( 40% of 180 degrees ) */ + /* As per RFC 60, if label->maxoverlapangle == 0 then fall back on pre-6.0 + behavior which was to use maxoverlapangle = 0.4*MS_PI ( 40% of 180 degrees + ) */ double maxoverlapangle = 0.4 * MS_PI; - if(p->numpoints < 2) { /* degenerate */ + if (p->numpoints < 2) { /* degenerate */ return MS_FAILURE; } - if(p->numpoints == 2) /* use the regular angled text algorithm */ - return msLineLabelPoint(map,p,ts,ll,&lfr->lar,label, img->resolutionfactor); - - if(!ts->textpath) { - if(MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map,ts))) { + if (p->numpoints == 2) /* use the regular angled text algorithm */ + return msLineLabelPoint(map, p, ts, ll, &lfr->lar, label, + img->resolutionfactor); + + if (!ts->textpath) { + if (MS_UNLIKELY(MS_FAILURE == msComputeTextPath(map, ts))) { return MS_FAILURE; } } - if(!ts->textpath) { + if (!ts->textpath) { return MS_FAILURE; } - - /* skip the label and use the normal algorithm if it has fewer than 2 characters */ - if(ts->textpath->numglyphs < 2) - return msLineLabelPoint(map,p,ts,ll,&lfr->lar,label, img->resolutionfactor); + /* skip the label and use the normal algorithm if it has fewer than 2 + * characters */ + if (ts->textpath->numglyphs < 2) + return msLineLabelPoint(map, p, ts, ll, &lfr->lar, label, + img->resolutionfactor); text_length = letterspacing * ts->textpath->bounds.bbox.maxx; @@ -1971,8 +2120,8 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s ** if the text length is way longer than the line, skip adding the ** label if it isn't forced (long extrapolated labels tend to be ugly) */ - if ( text_length > 1.5 * ll->total_length ) { - if(ts->label->force == MS_FALSE ) { + if (text_length > 1.5 * ll->total_length) { + if (ts->label->force == MS_FALSE) { return MS_SUCCESS; } else { repeat_distance = 0; /* disable repetition */ @@ -1983,8 +2132,10 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s - space occupied by one label - plus N times space occupied by one label + repeat_distance interspacing */ - label_buffer = text_length + repeat_distance; /* distance occupied by one label + inter-repeat spacing */ - if( repeat_distance > 0 && ll->total_length > text_length) { + label_buffer = + text_length + repeat_distance; /* distance occupied by one label + + inter-repeat spacing */ + if (repeat_distance > 0 && ll->total_length > text_length) { label_repeat = 1 + (int)((ll->total_length - text_length) / label_buffer); max_retry_offset = repeat_distance / 2.1; } else { @@ -1992,11 +2143,13 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s max_retry_offset = (ll->total_length - text_length) / 2.1; } /* compute the starting point of where we'll be placing the first label */ - if(label_repeat % 2) { - /* odd number of labels: account for the center label that will be centered on the line + if (label_repeat % 2) { + /* odd number of labels: account for the center label that will be centered + * on the line * ----llll_____llll_____llll---- */ - first_label_position = (ll->total_length - text_length) / 2.0 - (label_repeat / 2) * label_buffer; + first_label_position = (ll->total_length - text_length) / 2.0 - + (label_repeat / 2) * label_buffer; } else { /* even number of labels: * repeat_distance is centered on the line @@ -2005,211 +2158,227 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s * ----llll_____llll---- * --llll_____llll_____llll_____llll-- */ - first_label_position = (ll->total_length - repeat_distance) / 2.0 - text_length - (label_repeat/2 - 1) * label_buffer; + first_label_position = (ll->total_length - repeat_distance) / 2.0 - + text_length - (label_repeat / 2 - 1) * label_buffer; } - if(label->maxoverlapangle > 0) + if (label->maxoverlapangle > 0) maxoverlapangle = label->maxoverlapangle * MS_DEG_TO_RAD; /* radian */ - + cur_label_position = first_label_position; - for (l=0; l < label_repeat; l++) { - + for (l = 0; l < label_repeat; l++) { + double retry_offset = 0.0; int first_retry_idx = 0; - //max_dec_retry_offset = max_inc_retry_offset = max_retry_offset; - textPathObj *tp = msSmallCalloc(1,sizeof(textPathObj)); - /* copy the textPath, we will be overriding the copy's positions and angles */ - msCopyTextPath(tp,ts->textpath); + // max_dec_retry_offset = max_inc_retry_offset = max_retry_offset; + textPathObj *tp = msSmallCalloc(1, sizeof(textPathObj)); + /* copy the textPath, we will be overriding the copy's positions and angles + */ + msCopyTextPath(tp, ts->textpath); tp->bounds.poly = msSmallMalloc(sizeof(lineObj)); bounds = tp->bounds.poly; - /* ** The bounds will have two points for each character plus an endpoint: ** the UL corners of each bbox will be tied together and the LL corners ** will be tied together. */ - bounds->numpoints = 2*tp->numglyphs + 1; - bounds->point = (pointObj *) msSmallMalloc(sizeof(pointObj) * bounds->numpoints); + bounds->numpoints = 2 * tp->numglyphs + 1; + bounds->point = + (pointObj *)msSmallMalloc(sizeof(pointObj) * bounds->numpoints); do { int overlap_collision_detected = 0; text_start_length = cur_label_position + retry_offset; text_end_length = 0; - - for(k=0;knumglyphs;k++) { + + for (k = 0; k < tp->numglyphs; k++) { tp->glyphs[k].pnt.x = 0; tp->glyphs[k].pnt.y = 0; } - - /* the points start at (line_length - text_length) / 2 in order to be centred */ + + /* the points start at (line_length - text_length) / 2 in order to be + * centred */ /* text_start_length = (line_length - text_length) / 2.0; */ - + j = 0; fwd_line_length = 0; - if(text_start_length >= 0.0) { - while ( fwd_line_length < text_start_length ) + if (text_start_length >= 0.0) { + while (fwd_line_length < text_start_length) fwd_line_length += ll->segment_lengths[j++]; - + j--; } final_j = p->numpoints - 1; rev_line_length = 0; - if(text_start_length+text_length <= ll->total_length) { + if (text_start_length + text_length <= ll->total_length) { text_end_length = ll->total_length - (text_start_length + text_length); - while(rev_line_length < text_end_length) { + while (rev_line_length < text_end_length) { rev_line_length += ll->segment_lengths[final_j - 1]; final_j--; } final_j++; } - - if(final_j == 0) + + if (final_j == 0) final_j = 1; - + /* determine if the line is mostly left to right or right to left, see bug 1620 discussion by Steve Woodbridge */ direction = p->point[final_j].x - p->point[j].x; - - if(direction > 0) { + + if (direction > 0) { inc = 1; /* j is already correct */ - + /* length of the segment containing the starting point */ segment_length = ll->segment_lengths[j]; - + /* determine how far along the segment we need to go */ - if(text_start_length < 0.0) + if (text_start_length < 0.0) t = text_start_length / segment_length; else t = 1 - (fwd_line_length - text_start_length) / segment_length; } else { j = final_j; inc = -1; - + /* length of the segment containing the starting point */ - segment_length = ll->segment_lengths[j-1]; - if(text_start_length < 0.0) + segment_length = ll->segment_lengths[j - 1]; + if (text_start_length < 0.0) t = text_start_length / segment_length; else t = 1 - (rev_line_length - text_end_length) / segment_length; } - + distance_along_segment = t * segment_length; /* starting point */ - + theta = 0; k = 0; w = 0; - while ( k < tp->numglyphs ) { - double x,y; - - x = t * (p->point[j+inc].x - p->point[j].x) + p->point[j].x; - y = t * (p->point[j+inc].y - p->point[j].y) + p->point[j].y; + while (k < tp->numglyphs) { + double x, y; + + x = t * (p->point[j + inc].x - p->point[j].x) + p->point[j].x; + y = t * (p->point[j + inc].y - p->point[j].y) + p->point[j].y; tp->glyphs[k].pnt.x = x; tp->glyphs[k].pnt.y = y; - - - w = letterspacing*tp->glyphs[k].glyph->metrics.advance; - + + w = letterspacing * tp->glyphs[k].glyph->metrics.advance; + /* add the character's width to the distance along the line */ distance_along_segment += w; - - /* if we still have segments left and we've past the current segment, move to the next one */ - if(inc == 1 && j < p->numpoints - 2) { - - while ( j < p->numpoints - 2 && distance_along_segment > ll->segment_lengths[j] ) { + + /* if we still have segments left and we've past the current segment, + * move to the next one */ + if (inc == 1 && j < p->numpoints - 2) { + + while (j < p->numpoints - 2 && + distance_along_segment > ll->segment_lengths[j]) { distance_along_segment -= ll->segment_lengths[j]; j += inc; /* move to next segment */ } - + segment_length = ll->segment_lengths[j]; - - } else if( inc == -1 && j > 1 ) { - - while ( j > 1 && distance_along_segment > ll->segment_lengths[j-1] ) { - distance_along_segment -= ll->segment_lengths[j-1]; + + } else if (inc == -1 && j > 1) { + + while (j > 1 && distance_along_segment > ll->segment_lengths[j - 1]) { + distance_along_segment -= ll->segment_lengths[j - 1]; j += inc; /* move to next segment */ } - - segment_length = ll->segment_lengths[j-1]; + + segment_length = ll->segment_lengths[j - 1]; } - + /* Recalculate interpolation parameter */ t = distance_along_segment / segment_length; - + k++; } - - /* pre-calc the character's centre y value. Used for rotation adjustment. */ + + /* pre-calc the character's centre y value. Used for rotation adjustment. + */ cy = -ts->textpath->glyph_size / 2.0; #ifdef USE_KERNEL tp->glyphs[0].pnt.x /= kernel_normal; tp->glyphs[0].pnt.y /= kernel_normal; #endif - + /* Average the points and calculate each angle */ overlap_collision_detected = 0; for (k = 1; k <= tp->numglyphs; k++) { double anglediff; - if ( k < tp->numglyphs ) { + if (k < tp->numglyphs) { #ifdef USE_KERNEL tp->glyphs[k].pnt.x /= kernel_normal; tp->glyphs[k].pnt.y /= kernel_normal; #endif - dx = tp->glyphs[k].pnt.x - tp->glyphs[k-1].pnt.x; - dy = tp->glyphs[k].pnt.y - tp->glyphs[k-1].pnt.y; + dx = tp->glyphs[k].pnt.x - tp->glyphs[k - 1].pnt.x; + dy = tp->glyphs[k].pnt.y - tp->glyphs[k - 1].pnt.y; } else { /* Handle the last character */ - dx = t * (p->point[j+inc].x - p->point[j].x) + p->point[j].x - tp->glyphs[k-1].pnt.x; - dy = t * (p->point[j+inc].y - p->point[j].y) + p->point[j].y - tp->glyphs[k-1].pnt.y; + dx = t * (p->point[j + inc].x - p->point[j].x) + p->point[j].x - + tp->glyphs[k - 1].pnt.x; + dy = t * (p->point[j + inc].y - p->point[j].y) + p->point[j].y - + tp->glyphs[k - 1].pnt.y; } - - - if(dx || dy || k==1) { - - theta = -atan2(dy,dx); - + + if (dx || dy || k == 1) { + + theta = -atan2(dy, dx); + if (maxoverlapangle > 0 && k > 1) { - /* no use testing for overlap if glyph or previous glyph is a space */ - if(!msIsGlyphASpace(&tp->glyphs[k-1]) && !msIsGlyphASpace(&tp->glyphs[k-2])) { - /* If the difference between the last char angle and the current one - is greater than the MAXOVERLAPANGLE value (set at 80% of 180deg by default) - , bail the label */ - anglediff = fabs(theta - tp->glyphs[k-2].rot); + /* no use testing for overlap if glyph or previous glyph is a space + */ + if (!msIsGlyphASpace(&tp->glyphs[k - 1]) && + !msIsGlyphASpace(&tp->glyphs[k - 2])) { + /* If the difference between the last char angle and the current + one is greater than the MAXOVERLAPANGLE value (set at 80% of + 180deg by default) , bail the label */ + anglediff = fabs(theta - tp->glyphs[k - 2].rot); anglediff = MS_MIN(anglediff, MS_2PI - anglediff); - if(anglediff > maxoverlapangle ) { + if (anglediff > maxoverlapangle) { double max_dec_retry_offset; double max_inc_retry_offset; - if(label_repeat == 1) { - max_dec_retry_offset = max_inc_retry_offset = first_label_position; - } else if(l==0) { - if(direction>0) { - max_inc_retry_offset = MS_MIN(first_label_position, max_retry_offset); + if (label_repeat == 1) { + max_dec_retry_offset = max_inc_retry_offset = + first_label_position; + } else if (l == 0) { + if (direction > 0) { + max_inc_retry_offset = + MS_MIN(first_label_position, max_retry_offset); max_dec_retry_offset = max_retry_offset; } else { max_inc_retry_offset = max_retry_offset; - max_dec_retry_offset = MS_MIN(first_label_position, max_retry_offset); + max_dec_retry_offset = + MS_MIN(first_label_position, max_retry_offset); } - } else if(l == label_repeat-1) { - if(direction>0) { - max_dec_retry_offset = MS_MIN(first_label_position, max_retry_offset); + } else if (l == label_repeat - 1) { + if (direction > 0) { + max_dec_retry_offset = + MS_MIN(first_label_position, max_retry_offset); max_inc_retry_offset = max_retry_offset; } else { max_dec_retry_offset = max_retry_offset; - max_inc_retry_offset = MS_MIN(first_label_position, max_retry_offset); + max_inc_retry_offset = + MS_MIN(first_label_position, max_retry_offset); } } else { - max_dec_retry_offset = max_inc_retry_offset = max_retry_offset; + max_dec_retry_offset = max_inc_retry_offset = + max_retry_offset; } overlap_collision_detected = 1; - if(retry_offset == 0.0) { - first_retry_idx = k-1; + if (retry_offset == 0.0) { + first_retry_idx = k - 1; } - retry_offset = compute_retry_offset(ts, first_retry_idx, retry_offset, max_dec_retry_offset, max_inc_retry_offset); - if(retry_offset == 0.0) { /* no offsetted position to try */ + retry_offset = compute_retry_offset( + ts, first_retry_idx, retry_offset, max_dec_retry_offset, + max_inc_retry_offset); + if (retry_offset == 0.0) { /* no offsetted position to try */ freeTextPath(tp); free(tp); } else { - if(direction<0) { + if (direction < 0) { retry_offset = -retry_offset; } } @@ -2219,159 +2388,170 @@ int msLineLabelPath(mapObj *map, imageObj *img, lineObj *p, textSymbolObj *ts, s } } else { /* - * handle the 0-advance case, as the complex text shaping may have placed multiple - * glyphs at the same position + * handle the 0-advance case, as the complex text shaping may have + * placed multiple glyphs at the same position */ - theta = tp->glyphs[k-2].rot; + theta = tp->glyphs[k - 2].rot; } - - /* msDebug("s: %c (x,y): (%0.2f,%0.2f) t: %0.2f\n", string[k-1], labelpath->path.point[k-1].x, labelpath->path.point[k-1].y, theta); */ - - tp->glyphs[k-1].rot = theta; - - + + /* msDebug("s: %c (x,y): (%0.2f,%0.2f) t: %0.2f\n", string[k-1], + * labelpath->path.point[k-1].x, labelpath->path.point[k-1].y, theta); + */ + + tp->glyphs[k - 1].rot = theta; + /* Move the previous point so that when the character is rotated and placed it is centred on the line */ cos_t = cos(theta); sin_t = sin(theta); - - w = letterspacing*tp->glyphs[k-1].glyph->metrics.advance; - + + w = letterspacing * tp->glyphs[k - 1].glyph->metrics.advance; + cx = 0; /* Center the character vertically only */ - - dx = - (cx * cos_t + cy * sin_t); - dy = - (cy * cos_t - cx * sin_t); - - tp->glyphs[k-1].pnt.x += dx; - tp->glyphs[k-1].pnt.y += dy; - + + dx = -(cx * cos_t + cy * sin_t); + dy = -(cy * cos_t - cx * sin_t); + + tp->glyphs[k - 1].pnt.x += dx; + tp->glyphs[k - 1].pnt.y += dy; + /* Calculate the bounds */ bbox.minx = 0; bbox.maxx = w; bbox.maxy = 0; bbox.miny = -ts->textpath->glyph_size; - + /* Add the label buffer to the bounds */ bbox.maxx += ts->label->buffer * ts->resolutionfactor; bbox.maxy += ts->label->buffer * ts->resolutionfactor; bbox.minx -= ts->label->buffer * ts->resolutionfactor; bbox.miny -= ts->label->buffer * ts->resolutionfactor; - - if ( k < tp->numglyphs ) { + + if (k < tp->numglyphs) { /* Transform the bbox too. We take the UL and LL corners and rotate then translate them. */ - bounds->point[k-1].x = (bbox.minx * cos_t + bbox.maxy * sin_t) + tp->glyphs[k-1].pnt.x; - bounds->point[k-1].y = (bbox.maxy * cos_t - bbox.minx * sin_t) + tp->glyphs[k-1].pnt.y; - + bounds->point[k - 1].x = + (bbox.minx * cos_t + bbox.maxy * sin_t) + tp->glyphs[k - 1].pnt.x; + bounds->point[k - 1].y = + (bbox.maxy * cos_t - bbox.minx * sin_t) + tp->glyphs[k - 1].pnt.y; + /* Start at end and work towards the half way point */ - bounds->point[bounds->numpoints - k - 1].x = (bbox.minx * cos_t + bbox.miny * sin_t) + tp->glyphs[k-1].pnt.x; - bounds->point[bounds->numpoints - k - 1].y = (bbox.miny * cos_t - bbox.minx * sin_t) + tp->glyphs[k-1].pnt.y; - + bounds->point[bounds->numpoints - k - 1].x = + (bbox.minx * cos_t + bbox.miny * sin_t) + tp->glyphs[k - 1].pnt.x; + bounds->point[bounds->numpoints - k - 1].y = + (bbox.miny * cos_t - bbox.minx * sin_t) + tp->glyphs[k - 1].pnt.y; + } else { - + /* This is the last character in the string so we take the UR and LR corners of the bbox */ - bounds->point[k-1].x = (bbox.maxx * cos_t + bbox.maxy * sin_t) + tp->glyphs[k-1].pnt.x; - bounds->point[k-1].y = (bbox.maxy * cos_t - bbox.maxx * sin_t) + tp->glyphs[k-1].pnt.y; - - bounds->point[bounds->numpoints - k - 1].x = (bbox.maxx * cos_t + bbox.miny * sin_t) + tp->glyphs[k-1].pnt.x; - bounds->point[bounds->numpoints - k - 1].y = (bbox.miny * cos_t - bbox.maxx * sin_t) + tp->glyphs[k-1].pnt.y; + bounds->point[k - 1].x = + (bbox.maxx * cos_t + bbox.maxy * sin_t) + tp->glyphs[k - 1].pnt.x; + bounds->point[k - 1].y = + (bbox.maxy * cos_t - bbox.maxx * sin_t) + tp->glyphs[k - 1].pnt.y; + + bounds->point[bounds->numpoints - k - 1].x = + (bbox.maxx * cos_t + bbox.miny * sin_t) + tp->glyphs[k - 1].pnt.x; + bounds->point[bounds->numpoints - k - 1].y = + (bbox.miny * cos_t - bbox.maxx * sin_t) + tp->glyphs[k - 1].pnt.y; } } - if(overlap_collision_detected) { + if (overlap_collision_detected) { continue; } - - + /* Close the bounds */ bounds->point[bounds->numpoints - 1].x = bounds->point[0].x; bounds->point[bounds->numpoints - 1].y = bounds->point[0].y; - + /* compute the bounds */ - fastComputeBounds(bounds,&tp->bounds.bbox); - - + fastComputeBounds(bounds, &tp->bounds.bbox); + { textPathObj *tmptp; textSymbolObj *tsnew; lfr->num_follow_labels++; - lfr->follow_labels = msSmallRealloc(lfr->follow_labels,lfr->num_follow_labels * sizeof(textSymbolObj*)); + lfr->follow_labels = + msSmallRealloc(lfr->follow_labels, + lfr->num_follow_labels * sizeof(textSymbolObj *)); tmptp = ts->textpath; ts->textpath = NULL; - lfr->follow_labels[lfr->num_follow_labels - 1] = msSmallMalloc(sizeof(textSymbolObj)); + lfr->follow_labels[lfr->num_follow_labels - 1] = + msSmallMalloc(sizeof(textSymbolObj)); tsnew = lfr->follow_labels[lfr->num_follow_labels - 1]; initTextSymbol(tsnew); - msCopyTextSymbol(tsnew,ts); + msCopyTextSymbol(tsnew, ts); ts->textpath = tmptp; tsnew->textpath = tp; tsnew->textpath->absolute = 1; } - + cur_label_position += label_buffer; retry_offset = 0; - } while(retry_offset); + } while (retry_offset); } return MS_SUCCESS; - - } /* =========================================================================== Pretty printing of primitive objects ======================================================================== */ -void msRectToFormattedString(rectObj *rect, char *format, char *buffer, int buffer_length) -{ - snprintf(buffer, buffer_length, format, rect->minx, rect->miny, rect->maxx, rect->maxy); +void msRectToFormattedString(rectObj *rect, char *format, char *buffer, + int buffer_length) { + snprintf(buffer, buffer_length, format, rect->minx, rect->miny, rect->maxx, + rect->maxy); } -void msPointToFormattedString(pointObj *point, const char *format, char *buffer, int buffer_length) -{ - snprintf(buffer, buffer_length, format, point->x, point->y, point->z, point->m); +void msPointToFormattedString(pointObj *point, const char *format, char *buffer, + int buffer_length) { + snprintf(buffer, buffer_length, format, point->x, point->y, point->z, + point->m); } /* Returns true if a shape contains only degenerate parts */ -int msIsDegenerateShape(shapeObj *shape) -{ +int msIsDegenerateShape(shapeObj *shape) { int i; int non_degenerate_parts = 0; - for(i=0; inumlines; i++) { /* e.g. part */ + for (i = 0; i < shape->numlines; i++) { /* e.g. part */ /* skip degenerate parts, really should only happen with pixel output */ - if((shape->type == MS_SHAPE_LINE && shape->line[i].numpoints < 2) || + if ((shape->type == MS_SHAPE_LINE && shape->line[i].numpoints < 2) || (shape->type == MS_SHAPE_POLYGON && shape->line[i].numpoints < 3)) continue; non_degenerate_parts++; } - return( non_degenerate_parts == 0 ); + return (non_degenerate_parts == 0); } shapeObj *msRings2Shape(shapeObj *shape, int outer) { shapeObj *shape2; - int i, rv, *outerList=NULL; + int i, rv, *outerList = NULL; - if(!shape) return NULL; - if(shape->type != MS_SHAPE_POLYGON) return NULL; + if (!shape) + return NULL; + if (shape->type != MS_SHAPE_POLYGON) + return NULL; - outer = (outer)?1:0; // set explicitly to 1 or 0 + outer = (outer) ? 1 : 0; // set explicitly to 1 or 0 - shape2 = (shapeObj *) malloc(sizeof(shapeObj)); + shape2 = (shapeObj *)malloc(sizeof(shapeObj)); MS_CHECK_ALLOC(shape2, sizeof(shapeObj), NULL); msInitShape(shape2); shape2->type = shape->type; outerList = msGetOuterList(shape); - if(!outerList) { + if (!outerList) { msFreeShape(shape2); free(shape2); return NULL; } - for(i=0; inumlines; i++) { - if(outerList[i] == outer) { // else inner + for (i = 0; i < shape->numlines; i++) { + if (outerList[i] == outer) { // else inner rv = msAddLine(shape2, &(shape->line[i])); - if(rv != MS_SUCCESS) { + if (rv != MS_SUCCESS) { msFreeShape(shape2); free(shape2); free(outerList); @@ -2385,44 +2565,56 @@ shapeObj *msRings2Shape(shapeObj *shape, int outer) { } shapeObj *msDensify(shapeObj *shape, double tolerance) { - int i, j, k, l; // counters + int i, j, k, l; // counters int n; shapeObj *shape2; lineObj line; double distance, length, c; - if(!shape) return NULL; - if(shape->type != MS_SHAPE_POLYGON && shape->type != MS_SHAPE_LINE) return NULL; - if(tolerance <= 0) return NULL; // must be positive + if (!shape) + return NULL; + if (shape->type != MS_SHAPE_POLYGON && shape->type != MS_SHAPE_LINE) + return NULL; + if (tolerance <= 0) + return NULL; // must be positive - shape2 = (shapeObj *) malloc(sizeof(shapeObj)); + shape2 = (shapeObj *)malloc(sizeof(shapeObj)); MS_CHECK_ALLOC(shape2, sizeof(shapeObj), NULL); msInitShape(shape2); shape2->type = shape->type; // POLGYON or LINE - for(i=0; inumlines; i++) { + for (i = 0; i < shape->numlines; i++) { line.numpoints = shape->line[i].numpoints; - line.point = (pointObj *) malloc(sizeof(pointObj)*line.numpoints); // best case we don't have to add any points - MS_CHECK_ALLOC(line.point, sizeof(pointObj)*line.numpoints, NULL); + line.point = (pointObj *)malloc( + sizeof(pointObj) * + line.numpoints); // best case we don't have to add any points + MS_CHECK_ALLOC(line.point, sizeof(pointObj) * line.numpoints, NULL); - for(j=0, l=0; jline[i].numpoints-1; j++, l++) { + for (j = 0, l = 0; j < shape->line[i].numpoints - 1; j++, l++) { line.point[l] = shape->line[i].point[j]; - distance = msDistancePointToPoint(&(shape->line[i].point[j]), &(shape->line[i].point[j+1])); - if(distance > tolerance) { - n = (int) floor(distance/tolerance); // number of new points, n+1 is the number of new segments - length = distance/(n+1); // segment length + distance = msDistancePointToPoint(&(shape->line[i].point[j]), + &(shape->line[i].point[j + 1])); + if (distance > tolerance) { + n = (int)floor(distance / tolerance); // number of new points, n+1 is + // the number of new segments + length = distance / (n + 1); // segment length line.numpoints += n; - line.point = (pointObj *) realloc(line.point, sizeof(pointObj)*line.numpoints); - MS_CHECK_ALLOC(line.point, sizeof(pointObj)*line.numpoints, NULL); + line.point = + (pointObj *)realloc(line.point, sizeof(pointObj) * line.numpoints); + MS_CHECK_ALLOC(line.point, sizeof(pointObj) * line.numpoints, NULL); - for(k=0; kline[i].point[j].x + c*(shape->line[i].point[j+1].x - shape->line[i].point[j].x); - line.point[l].y = shape->line[i].point[j].y + c*(shape->line[i].point[j+1].y - shape->line[i].point[j].y); + line.point[l].x = + shape->line[i].point[j].x + + c * (shape->line[i].point[j + 1].x - shape->line[i].point[j].x); + line.point[l].y = + shape->line[i].point[j].y + + c * (shape->line[i].point[j + 1].y - shape->line[i].point[j].y); } } } diff --git a/mapprimitive.h b/mapprimitive.h index f15104587f..6a52fe862a 100644 --- a/mapprimitive.h +++ b/mapprimitive.h @@ -30,10 +30,11 @@ #ifndef MAPPRIMITIVE_H #define MAPPRIMITIVE_H - /** - A rectObj represents a rectangle or bounding box. - A rectObj may be a lone object or an attribute of another object and has no other associations. - */ +/** +A rectObj represents a rectangle or bounding box. +A rectObj may be a lone object or an attribute of another object and has no +other associations. +*/ typedef struct { double minx; ///< Minimum easting double miny; ///< Minimum northing @@ -76,21 +77,22 @@ typedef struct { } lineObj; /** -Each feature of a layer's data is a :class:`shapeObj`. Each part of the shape is a closed :class:`lineObj`. +Each feature of a layer's data is a :class:`shapeObj`. Each part of the shape is +a closed :class:`lineObj`. */ typedef struct { #ifndef SWIG - lineObj *line; - char **values; - void *geometry; - void *renderer_cache; + lineObj *line; + char **values; + void *geometry; + void *renderer_cache; #endif #ifdef SWIG %immutable; #endif - int numlines; ///< Number of parts + int numlines; ///< Number of parts int numvalues; ///< Number of shape attributes #ifdef SWIG @@ -98,11 +100,12 @@ typedef struct { #endif rectObj bounds; ///< Bounding box of shape - int type; ///< MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON, or MS_SHAPE_NULL - long index; ///< Feature index within the layer - int tileindex; ///< Index of tiled file for tile-indexed layers + int type; ///< MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON, or + ///< MS_SHAPE_NULL + long index; ///< Feature index within the layer + int tileindex; ///< Index of tiled file for tile-indexed layers int classindex; ///< The class index for features of a classified layer - char *text; ///< Shape annotation + char *text; ///< Shape annotation int scratch; int resultindex; ///< Index within a query result set @@ -123,7 +126,7 @@ typedef struct { #ifndef SWIG typedef struct { - int need_geotransform; + int need_geotransform; double rotation_angle; double geotransform[6]; /* Pixel/line to georef. */ double invgeotransform[6]; /* georef to pixel/line */ diff --git a/mapproject.c b/mapproject.c index 215781575a..b355681e5b 100644 --- a/mapproject.c +++ b/mapproject.c @@ -46,20 +46,18 @@ static unsigned ms_proj_data_change_counter = 0; #endif typedef struct LinkedListOfProjContext LinkedListOfProjContext; -struct LinkedListOfProjContext -{ - LinkedListOfProjContext* next; - projectionContext* context; +struct LinkedListOfProjContext { + LinkedListOfProjContext *next; + projectionContext *context; }; -static LinkedListOfProjContext* headOfLinkedListOfProjContext = NULL; - -static int msTestNeedWrap( pointObj pt1, pointObj pt2, pointObj pt2_geo, - reprojectionObj* reprojector ); +static LinkedListOfProjContext *headOfLinkedListOfProjContext = NULL; +static int msTestNeedWrap(pointObj pt1, pointObj pt2, pointObj pt2_geo, + reprojectionObj *reprojector); -static projectionContext* msProjectionContextCreate(void); -static void msProjectionContextUnref(projectionContext* ctx); +static projectionContext *msProjectionContextCreate(void); +static void msProjectionContextUnref(projectionContext *ctx); #if PROJ_VERSION_MAJOR >= 6 @@ -70,20 +68,18 @@ static void msProjectionContextUnref(projectionContext* ctx); /* output SRS */ #define PJ_CACHE_ENTRY_SIZE 32 -typedef struct -{ - char* inStr; - char* outStr; - PJ* pj; +typedef struct { + char *inStr; + char *outStr; + PJ *pj; } pjCacheEntry; -struct projectionContext -{ - PJ_CONTEXT* proj_ctx; - unsigned ms_proj_data_change_counter; - int ref_count; - pjCacheEntry pj_cache[PJ_CACHE_ENTRY_SIZE]; - int pj_cache_size; +struct projectionContext { + PJ_CONTEXT *proj_ctx; + unsigned ms_proj_data_change_counter; + int ref_count; + pjCacheEntry pj_cache[PJ_CACHE_ENTRY_SIZE]; + int pj_cache_size; }; /************************************************************************/ @@ -91,39 +87,33 @@ struct projectionContext /************************************************************************/ static int msProjectHasLonWrapOrOver(projectionObj *in) { - int i; - for( i = 0; i < in->numargs; i++ ) - { - if( strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0 || - strcmp(in->args[i], "+over") == 0 || - strcmp(in->args[i], "over") == 0 ) - { - return MS_TRUE; - } + int i; + for (i = 0; i < in->numargs; i++) { + if (strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0 || + strcmp(in->args[i], "+over") == 0 || strcmp(in->args[i], "over") == 0) { + return MS_TRUE; } - return MS_FALSE; + } + return MS_FALSE; } -static char* getStringFromArgv(int argc, char** args) -{ - int i; - int len = 0; - for( i = 0; i < argc; i++ ) - { - len += strlen(args[i]) + 1; - } - char* str = msSmallMalloc(len + 1); - len = 0; - for( i = 0; i < argc; i++ ) - { - size_t arglen = strlen(args[i]); - memcpy(str + len, args[i], arglen); - len += arglen; - str[len] = ' '; - len ++; - } - str[len] = 0; - return str; +static char *getStringFromArgv(int argc, char **args) { + int i; + int len = 0; + for (i = 0; i < argc; i++) { + len += strlen(args[i]) + 1; + } + char *str = msSmallMalloc(len + 1); + len = 0; + for (i = 0; i < argc; i++) { + size_t arglen = strlen(args[i]); + memcpy(str + len, args[i], arglen); + len += arglen; + str[len] = ' '; + len++; + } + str[len] = 0; + return str; } /************************************************************************/ @@ -131,174 +121,170 @@ static char* getStringFromArgv(int argc, char** args) /************************************************************************/ /* Return to be freed with proj_destroy() if *pbFreePJ = TRUE */ -static PJ* createNormalizedPJ(projectionObj *in, projectionObj *out, int* pbFreePJ) -{ - if( in->proj == out->proj ) - { - /* Special case to avoid out_str below to cause in_str to become invalid */ - *pbFreePJ = TRUE; +static PJ *createNormalizedPJ(projectionObj *in, projectionObj *out, + int *pbFreePJ) { + if (in->proj == out->proj) { + /* Special case to avoid out_str below to cause in_str to become invalid */ + *pbFreePJ = TRUE; #if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR == 0 - /* 6.0 didn't support proj=noop */ - return proj_create(in->proj_ctx->proj_ctx, "+proj=affine"); + /* 6.0 didn't support proj=noop */ + return proj_create(in->proj_ctx->proj_ctx, "+proj=affine"); #else - return proj_create(in->proj_ctx->proj_ctx, "+proj=noop"); + return proj_create(in->proj_ctx->proj_ctx, "+proj=noop"); #endif - } + } - const char* const wkt_options[] = { "MULTILINE=NO", NULL }; - const char* in_str = msProjectHasLonWrapOrOver(in) ? - proj_as_proj_string(in->proj_ctx->proj_ctx, in->proj, PJ_PROJ_4, NULL) : - proj_as_wkt(in->proj_ctx->proj_ctx, in->proj, PJ_WKT2_2018, wkt_options); - const char* out_str = msProjectHasLonWrapOrOver(out) ? - proj_as_proj_string(out->proj_ctx->proj_ctx, out->proj, PJ_PROJ_4, NULL) : - proj_as_wkt(out->proj_ctx->proj_ctx, out->proj, PJ_WKT2_2018, wkt_options); - PJ* pj_raw; - PJ* pj_normalized; - if( !in_str || !out_str ) - return NULL; - char* in_str_for_cache = getStringFromArgv(in->numargs, in->args); - char* out_str_for_cache = getStringFromArgv(out->numargs, out->args); - - if( in->proj_ctx->proj_ctx == out->proj_ctx->proj_ctx ) - { - int i; - pjCacheEntry* pj_cache = in->proj_ctx->pj_cache; - for( i = 0; i < in->proj_ctx->pj_cache_size; i++ ) - { - if (strcmp(pj_cache[i].inStr, in_str_for_cache) == 0 && - strcmp(pj_cache[i].outStr, out_str_for_cache) == 0 ) - { - PJ* ret = pj_cache[i].pj; - if( i != 0 ) - { - /* Move entry to top */ - pjCacheEntry tmp; - memcpy(&tmp, &pj_cache[i], sizeof(pjCacheEntry)); - memmove(&pj_cache[1], &pj_cache[0], i * sizeof(pjCacheEntry)); - memcpy(&pj_cache[0], &tmp, sizeof(pjCacheEntry)); - } + const char *const wkt_options[] = {"MULTILINE=NO", NULL}; + const char *in_str = msProjectHasLonWrapOrOver(in) + ? proj_as_proj_string(in->proj_ctx->proj_ctx, + in->proj, PJ_PROJ_4, NULL) + : proj_as_wkt(in->proj_ctx->proj_ctx, in->proj, + PJ_WKT2_2018, wkt_options); + const char *out_str = msProjectHasLonWrapOrOver(out) + ? proj_as_proj_string(out->proj_ctx->proj_ctx, + out->proj, PJ_PROJ_4, NULL) + : proj_as_wkt(out->proj_ctx->proj_ctx, out->proj, + PJ_WKT2_2018, wkt_options); + PJ *pj_raw; + PJ *pj_normalized; + if (!in_str || !out_str) + return NULL; + char *in_str_for_cache = getStringFromArgv(in->numargs, in->args); + char *out_str_for_cache = getStringFromArgv(out->numargs, out->args); + + if (in->proj_ctx->proj_ctx == out->proj_ctx->proj_ctx) { + int i; + pjCacheEntry *pj_cache = in->proj_ctx->pj_cache; + for (i = 0; i < in->proj_ctx->pj_cache_size; i++) { + if (strcmp(pj_cache[i].inStr, in_str_for_cache) == 0 && + strcmp(pj_cache[i].outStr, out_str_for_cache) == 0) { + PJ *ret = pj_cache[i].pj; + if (i != 0) { + /* Move entry to top */ + pjCacheEntry tmp; + memcpy(&tmp, &pj_cache[i], sizeof(pjCacheEntry)); + memmove(&pj_cache[1], &pj_cache[0], i * sizeof(pjCacheEntry)); + memcpy(&pj_cache[0], &tmp, sizeof(pjCacheEntry)); + } #ifdef notdef - fprintf(stderr, "cache hit!\n"); + fprintf(stderr, "cache hit!\n"); #endif - *pbFreePJ = FALSE; - msFree(in_str_for_cache); - msFree(out_str_for_cache); - return ret; - } - } + *pbFreePJ = FALSE; + msFree(in_str_for_cache); + msFree(out_str_for_cache); + return ret; + } } + } #ifdef notdef - fprintf(stderr, "%s -> %s\n", in_str, out_str); - fprintf(stderr, "%p -> %p\n", in->proj_ctx->proj_ctx, out->proj_ctx->proj_ctx); - fprintf(stderr, "cache miss!\n"); + fprintf(stderr, "%s -> %s\n", in_str, out_str); + fprintf(stderr, "%p -> %p\n", in->proj_ctx->proj_ctx, + out->proj_ctx->proj_ctx); + fprintf(stderr, "cache miss!\n"); #endif #if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR < 2 - if( strstr(in_str, "+proj=") && strstr(in_str, "+over") && - strstr(out_str, "+proj=") && strstr(out_str, "+over") && - strlen(in_str) < 400 && strlen(out_str) < 400 ) + if (strstr(in_str, "+proj=") && strstr(in_str, "+over") && + strstr(out_str, "+proj=") && strstr(out_str, "+over") && + strlen(in_str) < 400 && strlen(out_str) < 400) { + // Fixed per PROJ commit + // https://github.com/OSGeo/PROJ/commit/78302efb70eb4b49610cda6a60bf9ce39b82264f + // and + // https://github.com/OSGeo/PROJ/commit/ae70b26b9cbae85a38d5b26533ba06da0ea13940 + // Fix for wcs_get_capabilities_tileindexmixedsrs_26711.xml and + // wcs_20_getcov_bands_name_new_reproject.dat + char szPipeline[1024]; + strcpy(szPipeline, "+proj=pipeline"); + if (msProjIsGeographicCRS(in)) { + strcat(szPipeline, " +step +proj=unitconvert +xy_in=deg +xy_out=rad"); + } + strcat(szPipeline, " +step +inv "); + strcat(szPipeline, in_str); + strcat(szPipeline, " +step "); + strcat(szPipeline, out_str); + if (msProjIsGeographicCRS(out)) { + strcat(szPipeline, " +step +proj=unitconvert +xy_in=rad +xy_out=deg"); + } + /* We do not want datum=NAD83 to imply a transformation with towgs84=0,0,0 + */ { - // Fixed per PROJ commit - // https://github.com/OSGeo/PROJ/commit/78302efb70eb4b49610cda6a60bf9ce39b82264f - // and - // https://github.com/OSGeo/PROJ/commit/ae70b26b9cbae85a38d5b26533ba06da0ea13940 - // Fix for wcs_get_capabilities_tileindexmixedsrs_26711.xml and wcs_20_getcov_bands_name_new_reproject.dat - char szPipeline[1024]; - strcpy(szPipeline, "+proj=pipeline"); - if( msProjIsGeographicCRS(in) ) - { - strcat(szPipeline, " +step +proj=unitconvert +xy_in=deg +xy_out=rad"); - } - strcat(szPipeline, " +step +inv "); - strcat(szPipeline, in_str); - strcat(szPipeline, " +step "); - strcat(szPipeline, out_str); - if( msProjIsGeographicCRS(out) ) - { - strcat(szPipeline, " +step +proj=unitconvert +xy_in=rad +xy_out=deg"); - } - /* We do not want datum=NAD83 to imply a transformation with towgs84=0,0,0 */ - { - char* ptr = szPipeline; - while(1) - { - ptr = strstr(ptr, " +datum=NAD83"); - if( !ptr ) - break; - memcpy(ptr, " +ellps=GRS80", 13); - } - } - - /* Remove +nadgrids=@null as it doesn't work if going outside of [-180,180] */ - /* Fixed per https://github.com/OSGeo/PROJ/commit/10a30bb539be1afb25952b19af8bbe72e1b13b56 */ - { - char* ptr = strstr(szPipeline, " +nadgrids=@null"); - if( ptr ) - memcpy(ptr, " ", 16); - } + char *ptr = szPipeline; + while (1) { + ptr = strstr(ptr, " +datum=NAD83"); + if (!ptr) + break; + memcpy(ptr, " +ellps=GRS80", 13); + } + } - pj_normalized = proj_create(in->proj_ctx->proj_ctx, szPipeline); + /* Remove +nadgrids=@null as it doesn't work if going outside of [-180,180] + */ + /* Fixed per + * https://github.com/OSGeo/PROJ/commit/10a30bb539be1afb25952b19af8bbe72e1b13b56 + */ + { + char *ptr = strstr(szPipeline, " +nadgrids=@null"); + if (ptr) + memcpy(ptr, " ", 16); } - else + + pj_normalized = proj_create(in->proj_ctx->proj_ctx, szPipeline); + } else #endif - { -#if PROJ_VERSION_MAJOR > 6 || (PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR >= 2) - pj_raw = proj_create_crs_to_crs_from_pj(in->proj_ctx->proj_ctx, in->proj, out->proj, NULL, NULL); + { +#if PROJ_VERSION_MAJOR > 6 || \ + (PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR >= 2) + pj_raw = proj_create_crs_to_crs_from_pj(in->proj_ctx->proj_ctx, in->proj, + out->proj, NULL, NULL); #else - pj_raw = proj_create_crs_to_crs(in->proj_ctx->proj_ctx, in_str, out_str, NULL); + pj_raw = + proj_create_crs_to_crs(in->proj_ctx->proj_ctx, in_str, out_str, NULL); #endif - if( !pj_raw ) - { - msFree(in_str_for_cache); - msFree(out_str_for_cache); - return NULL; - } - pj_normalized = proj_normalize_for_visualization(in->proj_ctx->proj_ctx, pj_raw); - proj_destroy(pj_raw); + if (!pj_raw) { + msFree(in_str_for_cache); + msFree(out_str_for_cache); + return NULL; } - if( !pj_normalized ) - { - msFree(in_str_for_cache); - msFree(out_str_for_cache); - return NULL; - } - - if( in->proj_ctx->proj_ctx == out->proj_ctx->proj_ctx ) - { - /* Insert entry into cache */ - int i; - pjCacheEntry* pj_cache = in->proj_ctx->pj_cache; - if( in->proj_ctx->pj_cache_size < PJ_CACHE_ENTRY_SIZE ) - { - i = in->proj_ctx->pj_cache_size; - assert ( pj_cache[i].inStr == NULL ); - in->proj_ctx->pj_cache_size ++; - } - else - { - i = 0; - /* Evict oldest entry */ - msFree(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].inStr); - msFree(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].outStr); - proj_destroy(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].pj); - memmove(&pj_cache[1], &pj_cache[0], - (PJ_CACHE_ENTRY_SIZE - 1) * sizeof(pjCacheEntry)); - } - pj_cache[i].inStr = msStrdup(in_str_for_cache); - pj_cache[i].outStr = msStrdup(out_str_for_cache); - pj_cache[i].pj = pj_normalized; - *pbFreePJ = FALSE; - } - else - { - *pbFreePJ = TRUE; - } - + pj_normalized = + proj_normalize_for_visualization(in->proj_ctx->proj_ctx, pj_raw); + proj_destroy(pj_raw); + } + if (!pj_normalized) { msFree(in_str_for_cache); msFree(out_str_for_cache); + return NULL; + } - return pj_normalized; + if (in->proj_ctx->proj_ctx == out->proj_ctx->proj_ctx) { + /* Insert entry into cache */ + int i; + pjCacheEntry *pj_cache = in->proj_ctx->pj_cache; + if (in->proj_ctx->pj_cache_size < PJ_CACHE_ENTRY_SIZE) { + i = in->proj_ctx->pj_cache_size; + assert(pj_cache[i].inStr == NULL); + in->proj_ctx->pj_cache_size++; + } else { + i = 0; + /* Evict oldest entry */ + msFree(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].inStr); + msFree(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].outStr); + proj_destroy(pj_cache[PJ_CACHE_ENTRY_SIZE - 1].pj); + memmove(&pj_cache[1], &pj_cache[0], + (PJ_CACHE_ENTRY_SIZE - 1) * sizeof(pjCacheEntry)); + } + pj_cache[i].inStr = msStrdup(in_str_for_cache); + pj_cache[i].outStr = msStrdup(out_str_for_cache); + pj_cache[i].pj = pj_normalized; + *pbFreePJ = FALSE; + } else { + *pbFreePJ = TRUE; + } + + msFree(in_str_for_cache); + msFree(out_str_for_cache); + + return pj_normalized; } /************************************************************************/ @@ -306,108 +292,94 @@ static PJ* createNormalizedPJ(projectionObj *in, projectionObj *out, int* pbFree /************************************************************************/ /* Return to be freed with proj_destroy() */ -static PJ* getBaseGeographicCRS(projectionObj* in) -{ - PJ_CONTEXT* ctxt; - PJ_TYPE type; - assert(in && in->proj); - ctxt = in->proj_ctx->proj_ctx; - type = proj_get_type(in->proj); - if( type == PJ_TYPE_PROJECTED_CRS ) - { - return proj_get_source_crs(ctxt, in->proj); - } - if( type == PJ_TYPE_BOUND_CRS ) - { - /* If it is a boundCRS of a projectedCRS, extract the geographicCRS - * from the projectedCRS, and rewrap it in a boundCRS */ - PJ* source_crs = proj_get_source_crs(ctxt, in->proj); - PJ* geog_source_crs; - PJ* hub_crs; - PJ* transf; - PJ* ret; - if( proj_get_type(source_crs) != PJ_TYPE_PROJECTED_CRS ) - { - proj_destroy(source_crs); - return NULL; - } - geog_source_crs = proj_get_source_crs(ctxt, source_crs); - proj_destroy(source_crs); - hub_crs = proj_get_target_crs(ctxt, in->proj); - transf = proj_crs_get_coordoperation(ctxt, in->proj); - ret = proj_crs_create_bound_crs(ctxt, geog_source_crs, - hub_crs, transf); - proj_destroy(geog_source_crs); - proj_destroy(hub_crs); - proj_destroy(transf); - return ret; - - } - return NULL; +static PJ *getBaseGeographicCRS(projectionObj *in) { + PJ_CONTEXT *ctxt; + PJ_TYPE type; + assert(in && in->proj); + ctxt = in->proj_ctx->proj_ctx; + type = proj_get_type(in->proj); + if (type == PJ_TYPE_PROJECTED_CRS) { + return proj_get_source_crs(ctxt, in->proj); + } + if (type == PJ_TYPE_BOUND_CRS) { + /* If it is a boundCRS of a projectedCRS, extract the geographicCRS + * from the projectedCRS, and rewrap it in a boundCRS */ + PJ *source_crs = proj_get_source_crs(ctxt, in->proj); + PJ *geog_source_crs; + PJ *hub_crs; + PJ *transf; + PJ *ret; + if (proj_get_type(source_crs) != PJ_TYPE_PROJECTED_CRS) { + proj_destroy(source_crs); + return NULL; + } + geog_source_crs = proj_get_source_crs(ctxt, source_crs); + proj_destroy(source_crs); + hub_crs = proj_get_target_crs(ctxt, in->proj); + transf = proj_crs_get_coordoperation(ctxt, in->proj); + ret = proj_crs_create_bound_crs(ctxt, geog_source_crs, hub_crs, transf); + proj_destroy(geog_source_crs); + proj_destroy(hub_crs); + proj_destroy(transf); + return ret; + } + return NULL; } /************************************************************************/ /* msProjErrorLogger() */ /************************************************************************/ -static void msProjErrorLogger(void * user_data, - int level, const char * message) -{ - (void)user_data; -#if PROJ_VERSION_MAJOR >= 6 - if( level == PJ_LOG_ERROR && msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_VV ) +static void msProjErrorLogger(void *user_data, int level, const char *message) { + (void)user_data; +#if PROJ_VERSION_MAJOR >= 6 + if (level == PJ_LOG_ERROR && msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_VV) #else - if( level == PJ_LOG_ERROR ) + if (level == PJ_LOG_ERROR) #endif - { - msDebug( "PROJ: Error: %s\n", message ); - } - else if( level == PJ_LOG_DEBUG ) - { - msDebug( "PROJ: Debug: %s\n", message ); - } + { + msDebug("PROJ: Error: %s\n", message); + } else if (level == PJ_LOG_DEBUG) { + msDebug("PROJ: Debug: %s\n", message); + } } /************************************************************************/ /* msProjectionContextCreate() */ /************************************************************************/ -projectionContext* msProjectionContextCreate(void) -{ - projectionContext* ctx = (projectionContext*)msSmallCalloc(1, sizeof(projectionContext)); - ctx->proj_ctx = proj_context_create(); - if( ctx->proj_ctx == NULL ) - { - msFree(ctx); - return NULL; - } - ctx->ref_count = 1; - proj_context_use_proj4_init_rules(ctx->proj_ctx, TRUE); - proj_log_func (ctx->proj_ctx, NULL, msProjErrorLogger); - return ctx; +projectionContext *msProjectionContextCreate(void) { + projectionContext *ctx = + (projectionContext *)msSmallCalloc(1, sizeof(projectionContext)); + ctx->proj_ctx = proj_context_create(); + if (ctx->proj_ctx == NULL) { + msFree(ctx); + return NULL; + } + ctx->ref_count = 1; + proj_context_use_proj4_init_rules(ctx->proj_ctx, TRUE); + proj_log_func(ctx->proj_ctx, NULL, msProjErrorLogger); + return ctx; } /************************************************************************/ /* msProjectionContextUnref() */ /************************************************************************/ -void msProjectionContextUnref(projectionContext* ctx) -{ - if( !ctx ) - return; - --ctx->ref_count; - if( ctx->ref_count == 0 ) - { - int i; - for( i = 0; i < ctx->pj_cache_size; i++ ) - { - msFree(ctx->pj_cache[i].inStr); - msFree(ctx->pj_cache[i].outStr); - proj_destroy(ctx->pj_cache[i].pj); - } - proj_context_destroy(ctx->proj_ctx); - msFree(ctx); +void msProjectionContextUnref(projectionContext *ctx) { + if (!ctx) + return; + --ctx->ref_count; + if (ctx->ref_count == 0) { + int i; + for (i = 0; i < ctx->pj_cache_size; i++) { + msFree(ctx->pj_cache[i].inStr); + msFree(ctx->pj_cache[i].outStr); + proj_destroy(ctx->pj_cache[i].pj); } + proj_context_destroy(ctx->proj_ctx); + msFree(ctx); + } } /************************************************************************/ @@ -420,113 +392,105 @@ void msProjectionContextUnref(projectionContext* ctx) * If the *content* of in and/or out is changed, then the reprojector is * no longer valid. This can be detected with msProjectIsReprojectorStillValid() */ -reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* out) -{ - reprojectionObj* obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); - obj->in = in; - obj->out = out; - obj->generation_number_in = in ? in->generation_number : 0; - obj->generation_number_out = out ? out->generation_number : 0; - obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; +reprojectionObj *msProjectCreateReprojector(projectionObj *in, + projectionObj *out) { + reprojectionObj *obj = + (reprojectionObj *)msSmallCalloc(1, sizeof(reprojectionObj)); + obj->in = in; + obj->out = out; + obj->generation_number_in = in ? in->generation_number : 0; + obj->generation_number_out = out ? out->generation_number : 0; + obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; - /* -------------------------------------------------------------------- */ - /* If the source and destination are simple and equal, then do */ - /* nothing. */ - /* -------------------------------------------------------------------- */ - if( in && in->numargs == 1 && out && out->numargs == 1 - && strcmp(in->args[0],out->args[0]) == 0 ) { - /* do nothing, no transformation required */ - } - /* -------------------------------------------------------------------- */ - /* If we have a fully defined input coordinate system and */ - /* output coordinate system, then we will use createNormalizedPJ */ - /* -------------------------------------------------------------------- */ - else if( in && in->proj && out && out->proj ) { - PJ* pj = createNormalizedPJ(in, out, &(obj->bFreePJ)); - if( !pj ) - { - msFree(obj); - return NULL; - } - obj->pj = pj; + /* -------------------------------------------------------------------- */ + /* If the source and destination are simple and equal, then do */ + /* nothing. */ + /* -------------------------------------------------------------------- */ + if (in && in->numargs == 1 && out && out->numargs == 1 && + strcmp(in->args[0], out->args[0]) == 0) { + /* do nothing, no transformation required */ + } + /* -------------------------------------------------------------------- */ + /* If we have a fully defined input coordinate system and */ + /* output coordinate system, then we will use createNormalizedPJ */ + /* -------------------------------------------------------------------- */ + else if (in && in->proj && out && out->proj) { + PJ *pj = createNormalizedPJ(in, out, &(obj->bFreePJ)); + if (!pj) { + msFree(obj); + return NULL; } + obj->pj = pj; + } - /* nothing to do if the other coordinate system is also lat/long */ - else if( (in == NULL || in->proj == NULL) && - (out == NULL || out->proj == NULL || msProjIsGeographicCRS(out) )) - { - /* do nothing */ - } - else if( out == NULL && in != NULL && msProjIsGeographicCRS(in) ) - { - /* do nothing */ - } + /* nothing to do if the other coordinate system is also lat/long */ + else if ((in == NULL || in->proj == NULL) && + (out == NULL || out->proj == NULL || msProjIsGeographicCRS(out))) { + /* do nothing */ + } else if (out == NULL && in != NULL && msProjIsGeographicCRS(in)) { + /* do nothing */ + } - /* -------------------------------------------------------------------- */ - /* Otherwise we assume that the NULL projectionObj is supposed to be */ - /* lat/long in the same datum as the other projectionObj. This */ - /* is essentially a backwards compatibility mode. */ - /* -------------------------------------------------------------------- */ - else { - PJ* pj = NULL; - - if( (in==NULL || in->proj==NULL) && out && out->proj) { /* input coordinates are lat/lon */ - PJ* source_crs = getBaseGeographicCRS(out); - projectionObj in_modified; - memset(&in_modified, 0, sizeof(in_modified)); - - in_modified.proj_ctx = out->proj_ctx; - in_modified.proj = source_crs; - pj = createNormalizedPJ(&in_modified, out, &(obj->bFreePJ)); - proj_destroy(source_crs); - } else if( /* (out==NULL || out->proj==NULL) && */ in && in->proj ) { - PJ* target_crs = getBaseGeographicCRS(in); - projectionObj out_modified; - memset(&out_modified, 0, sizeof(out_modified)); - - out_modified.proj_ctx = in->proj_ctx; - out_modified.proj = target_crs; - pj = createNormalizedPJ(in, &out_modified, &(obj->bFreePJ)); - proj_destroy(target_crs); - } - if( !pj ) - { - msFree(obj); - return NULL; - } - obj->pj = pj; + /* -------------------------------------------------------------------- */ + /* Otherwise we assume that the NULL projectionObj is supposed to be */ + /* lat/long in the same datum as the other projectionObj. This */ + /* is essentially a backwards compatibility mode. */ + /* -------------------------------------------------------------------- */ + else { + PJ *pj = NULL; + + if ((in == NULL || in->proj == NULL) && out && + out->proj) { /* input coordinates are lat/lon */ + PJ *source_crs = getBaseGeographicCRS(out); + projectionObj in_modified; + memset(&in_modified, 0, sizeof(in_modified)); + + in_modified.proj_ctx = out->proj_ctx; + in_modified.proj = source_crs; + pj = createNormalizedPJ(&in_modified, out, &(obj->bFreePJ)); + proj_destroy(source_crs); + } else if (/* (out==NULL || out->proj==NULL) && */ in && in->proj) { + PJ *target_crs = getBaseGeographicCRS(in); + projectionObj out_modified; + memset(&out_modified, 0, sizeof(out_modified)); + + out_modified.proj_ctx = in->proj_ctx; + out_modified.proj = target_crs; + pj = createNormalizedPJ(in, &out_modified, &(obj->bFreePJ)); + proj_destroy(target_crs); } + if (!pj) { + msFree(obj); + return NULL; + } + obj->pj = pj; + } - return obj; + return obj; } /************************************************************************/ /* msProjectDestroyReprojector() */ /************************************************************************/ -void msProjectDestroyReprojector(reprojectionObj* reprojector) -{ - if( !reprojector ) - return; - if( reprojector->bFreePJ ) - proj_destroy(reprojector->pj); - msFreeShape(&(reprojector->splitShape)); - msFree(reprojector); +void msProjectDestroyReprojector(reprojectionObj *reprojector) { + if (!reprojector) + return; + if (reprojector->bFreePJ) + proj_destroy(reprojector->pj); + msFreeShape(&(reprojector->splitShape)); + msFree(reprojector); } /************************************************************************/ /* msProjectTransformPoints() */ /************************************************************************/ -int msProjectTransformPoints( reprojectionObj* reprojector, - int npoints, double* x, double* y ) -{ - proj_trans_generic (reprojector->pj, PJ_FWD, - x, sizeof(double), npoints, - y, sizeof(double), npoints, - NULL, 0, 0, - NULL, 0, 0 ); - return MS_SUCCESS; +int msProjectTransformPoints(reprojectionObj *reprojector, int npoints, + double *x, double *y) { + proj_trans_generic(reprojector->pj, PJ_FWD, x, sizeof(double), npoints, y, + sizeof(double), npoints, NULL, 0, 0, NULL, 0, 0); + return MS_SUCCESS; } #else @@ -535,86 +499,72 @@ int msProjectTransformPoints( reprojectionObj* reprojector, /* msProjectionContextCreate() */ /************************************************************************/ -projectionContext* msProjectionContextCreate(void) -{ - return NULL; -} +projectionContext *msProjectionContextCreate(void) { return NULL; } /************************************************************************/ /* msProjectionContextUnref() */ /************************************************************************/ -void msProjectionContextUnref(projectionContext* ctx) -{ - (void)ctx; -} +void msProjectionContextUnref(projectionContext *ctx) { (void)ctx; } /************************************************************************/ /* msProjectCreateReprojector() */ /************************************************************************/ -reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* out) -{ - reprojectionObj* obj; - obj = (reprojectionObj*)msSmallCalloc(1, sizeof(reprojectionObj)); - obj->in = in; - obj->out = out; - obj->generation_number_in = in ? in->generation_number : 0; - obj->generation_number_out = out ? out->generation_number : 0; - obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; +reprojectionObj *msProjectCreateReprojector(projectionObj *in, + projectionObj *out) { + reprojectionObj *obj; + obj = (reprojectionObj *)msSmallCalloc(1, sizeof(reprojectionObj)); + obj->in = in; + obj->out = out; + obj->generation_number_in = in ? in->generation_number : 0; + obj->generation_number_out = out ? out->generation_number : 0; + obj->lineCuttingCase = LINE_CUTTING_UNKNOWN; - /* -------------------------------------------------------------------- */ - /* If the source and destination are equal, then do nothing. */ - /* -------------------------------------------------------------------- */ - if( in && out && in->numargs == out->numargs && in->numargs > 0 - && strcmp(in->args[0],out->args[0]) == 0 ) - { - int i; - obj->no_op = MS_TRUE; - for( i = 1; i < in->numargs; i++ ) - { - if( strcmp(in->args[i],out->args[i]) != 0 ) { - obj->no_op = MS_FALSE; - break; - } - } + /* -------------------------------------------------------------------- */ + /* If the source and destination are equal, then do nothing. */ + /* -------------------------------------------------------------------- */ + if (in && out && in->numargs == out->numargs && in->numargs > 0 && + strcmp(in->args[0], out->args[0]) == 0) { + int i; + obj->no_op = MS_TRUE; + for (i = 1; i < in->numargs; i++) { + if (strcmp(in->args[i], out->args[i]) != 0) { + obj->no_op = MS_FALSE; + break; + } } + } - /* -------------------------------------------------------------------- */ - /* If we have a fully defined input coordinate system and */ - /* output coordinate system, then we will use pj_transform */ - /* -------------------------------------------------------------------- */ - else if( in && in->proj && out && out->proj ) { - /* do nothing for now */ - } - /* nothing to do if the other coordinate system is also lat/long */ - else if( in == NULL && (out == NULL || msProjIsGeographicCRS(out) )) - { - obj->no_op = MS_TRUE; - } - else if( out == NULL && in != NULL && msProjIsGeographicCRS(in) ) - { - obj->no_op = MS_TRUE; - } - else if( (in == NULL || in->proj == NULL) && - (out == NULL || out->proj == NULL) ) - { - msProjectDestroyReprojector(obj); - return NULL; - } - return obj; + /* -------------------------------------------------------------------- */ + /* If we have a fully defined input coordinate system and */ + /* output coordinate system, then we will use pj_transform */ + /* -------------------------------------------------------------------- */ + else if (in && in->proj && out && out->proj) { + /* do nothing for now */ + } + /* nothing to do if the other coordinate system is also lat/long */ + else if (in == NULL && (out == NULL || msProjIsGeographicCRS(out))) { + obj->no_op = MS_TRUE; + } else if (out == NULL && in != NULL && msProjIsGeographicCRS(in)) { + obj->no_op = MS_TRUE; + } else if ((in == NULL || in->proj == NULL) && + (out == NULL || out->proj == NULL)) { + msProjectDestroyReprojector(obj); + return NULL; + } + return obj; } /************************************************************************/ /* msProjectDestroyReprojector() */ /************************************************************************/ -void msProjectDestroyReprojector(reprojectionObj* reprojector) -{ - if( !reprojector ) - return; - msFreeShape(&(reprojector->splitShape)); - msFree(reprojector); +void msProjectDestroyReprojector(reprojectionObj *reprojector) { + if (!reprojector) + return; + msFreeShape(&(reprojector->splitShape)); + msFree(reprojector); } #endif @@ -622,38 +572,36 @@ void msProjectDestroyReprojector(reprojectionObj* reprojector) /* ** Initialize, load and free a projectionObj structure */ -int msInitProjection(projectionObj *p) -{ +int msInitProjection(projectionObj *p) { p->gt.need_geotransform = MS_FALSE; p->numargs = 0; p->args = NULL; p->wellknownprojection = wkp_none; p->proj = NULL; - p->args = (char **)malloc(MS_MAXPROJARGS*sizeof(char *)); - MS_CHECK_ALLOC(p->args, MS_MAXPROJARGS*sizeof(char *), -1); + p->args = (char **)malloc(MS_MAXPROJARGS * sizeof(char *)); + MS_CHECK_ALLOC(p->args, MS_MAXPROJARGS * sizeof(char *), -1); #if PROJ_VERSION_MAJOR >= 6 p->proj_ctx = NULL; #elif PJ_VERSION >= 480 p->proj_ctx = NULL; #endif p->generation_number = 0; - return(0); + return (0); } -void msFreeProjection(projectionObj *p) -{ +void msFreeProjection(projectionObj *p) { #if PROJ_VERSION_MAJOR >= 6 proj_destroy(p->proj); p->proj = NULL; msProjectionContextUnref(p->proj_ctx); p->proj_ctx = NULL; #else - if(p->proj) { + if (p->proj) { pj_free(p->proj); p->proj = NULL; } #if PJ_VERSION >= 480 - if(p->proj_ctx) { + if (p->proj_ctx) { pj_ctx_free(p->proj_ctx); p->proj_ctx = NULL; } @@ -665,13 +613,12 @@ void msFreeProjection(projectionObj *p) msFreeCharArray(p->args, p->numargs); p->args = NULL; p->numargs = 0; - p->generation_number ++; + p->generation_number++; } -void msFreeProjectionExceptContext(projectionObj *p) -{ +void msFreeProjectionExceptContext(projectionObj *p) { #if PROJ_VERSION_MAJOR >= 6 - projectionContext* ctx = p->proj_ctx; + projectionContext *ctx = p->proj_ctx; p->proj_ctx = NULL; msFreeProjection(p); p->proj_ctx = ctx; @@ -684,17 +631,16 @@ void msFreeProjectionExceptContext(projectionObj *p) /* msProjectionInheritContextFrom() */ /************************************************************************/ -void msProjectionInheritContextFrom(projectionObj *pDst, const projectionObj* pSrc) -{ +void msProjectionInheritContextFrom(projectionObj *pDst, + const projectionObj *pSrc) { #if PROJ_VERSION_MAJOR >= 6 - if( pDst->proj_ctx == NULL && pSrc->proj_ctx != NULL) - { - pDst->proj_ctx = pSrc->proj_ctx; - pDst->proj_ctx->ref_count ++; - } + if (pDst->proj_ctx == NULL && pSrc->proj_ctx != NULL) { + pDst->proj_ctx = pSrc->proj_ctx; + pDst->proj_ctx->ref_count++; + } #else - (void)pDst; - (void)pSrc; + (void)pDst; + (void)pSrc; #endif } @@ -702,17 +648,15 @@ void msProjectionInheritContextFrom(projectionObj *pDst, const projectionObj* pS /* msProjectionSetContext() */ /************************************************************************/ -void msProjectionSetContext(projectionObj *p, projectionContext* ctx) -{ +void msProjectionSetContext(projectionObj *p, projectionContext *ctx) { #if PROJ_VERSION_MAJOR >= 6 - if( p->proj_ctx == NULL && ctx != NULL) - { - p->proj_ctx = ctx; - p->proj_ctx->ref_count ++; - } + if (p->proj_ctx == NULL && ctx != NULL) { + p->proj_ctx = ctx; + p->proj_ctx->ref_count++; + } #else - (void)p; - (void)ctx; + (void)p; + (void)ctx; #endif } @@ -721,37 +665,35 @@ void msProjectionSetContext(projectionObj *p, projectionContext* ctx) ** "AUTO:proj_id,units_id,lon0,lat0" */ -static int _msProcessAutoProjection(projectionObj *p) -{ +static int _msProcessAutoProjection(projectionObj *p) { char **args; int numargs, nProjId, nUnitsId, nZone; double dLat0, dLon0; const char *pszUnits = "m"; - char szProjBuf[512]=""; + char szProjBuf[512] = ""; /* WMS/WFS AUTO projection: "AUTO:proj_id,units_id,lon0,lat0" */ args = msStringSplit(p->args[0], ',', &numargs); - if (numargs != 4 || - (strncasecmp(args[0], "AUTO:", 5) != 0 && - strncasecmp(args[0], "AUTO2:", 6) != 0)) { + if (numargs != 4 || (strncasecmp(args[0], "AUTO:", 5) != 0 && + strncasecmp(args[0], "AUTO2:", 6) != 0)) { msSetError(MS_PROJERR, "WMS/WFS AUTO/AUTO2 PROJECTION must be in the format " - "'AUTO:proj_id,units_id,lon0,lat0' or 'AUTO2:crs_id,factor,lon0,lat0'(got '%s').\n", + "'AUTO:proj_id,units_id,lon0,lat0' or " + "'AUTO2:crs_id,factor,lon0,lat0'(got '%s').\n", "_msProcessAutoProjection()", p->args[0]); msFreeCharArray(args, numargs); return -1; } - if (strncasecmp(args[0], "AUTO:", 5)==0) - nProjId = atoi(args[0]+5); + if (strncasecmp(args[0], "AUTO:", 5) == 0) + nProjId = atoi(args[0] + 5); else - nProjId = atoi(args[0]+6); + nProjId = atoi(args[0] + 6); nUnitsId = atoi(args[1]); dLon0 = atof(args[2]); dLat0 = atof(args[3]); - /*There is no unit parameter for AUTO2. The 2nd parameter is factor. Set the units to always be meter*/ if (strncasecmp(args[0], "AUTO2:", 6) == 0) @@ -760,15 +702,15 @@ static int _msProcessAutoProjection(projectionObj *p) msFreeCharArray(args, numargs); /* Handle EPSG Units. Only meters for now. */ - switch(nUnitsId) { - case 9001: /* Meters */ - pszUnits = "m"; - break; - default: - msSetError(MS_PROJERR, - "WMS/WFS AUTO PROJECTION: EPSG Units %d not supported.\n", - "_msProcessAutoProjection()", nUnitsId); - return -1; + switch (nUnitsId) { + case 9001: /* Meters */ + pszUnits = "m"; + break; + default: + msSetError(MS_PROJERR, + "WMS/WFS AUTO PROJECTION: EPSG Units %d not supported.\n", + "_msProcessAutoProjection()", nUnitsId); + return -1; } /* Build PROJ4 definition. @@ -777,49 +719,44 @@ static int _msProcessAutoProjection(projectionObj *p) * The conversion from the original WKT definitions to PROJ4 format was * done using the MapScript setWKTProjection() function (based on OGR). */ - switch(nProjId) { - case 42001: /** WGS 84 / Auto UTM **/ - nZone = (int) floor( (dLon0 + 180.0) / 6.0 ) + 1; - sprintf( szProjBuf, - "+proj=tmerc+lat_0=0+lon_0=%.16g+k=0.999600+x_0=500000" - "+y_0=%.16g+ellps=WGS84+datum=WGS84+units=%s+type=crs", - -183.0 + nZone * 6.0, - (dLat0 >= 0.0) ? 0.0 : 10000000.0, - pszUnits); - break; - case 42002: /** WGS 84 / Auto Tr. Mercator **/ - sprintf( szProjBuf, - "+proj=tmerc+lat_0=0+lon_0=%.16g+k=0.999600+x_0=500000" - "+y_0=%.16g+ellps=WGS84+datum=WGS84+units=%s+type=crs", - dLon0, - (dLat0 >= 0.0) ? 0.0 : 10000000.0, - pszUnits); - break; - case 42003: /** WGS 84 / Auto Orthographic **/ - sprintf( szProjBuf, - "+proj=ortho+lon_0=%.16g+lat_0=%.16g+x_0=0+y_0=0" - "+ellps=WGS84+datum=WGS84+units=%s+type=crs", - dLon0, dLat0, pszUnits ); - break; - case 42004: /** WGS 84 / Auto Equirectangular **/ - /* Note that we have to pass lon_0 as lon_ts for this one to */ - /* work. Either a PROJ4 bug or a PROJ4 documentation issue. */ - sprintf( szProjBuf, - "+proj=eqc+lon_ts=%.16g+lat_ts=%.16g+x_0=0+y_0=0" - "+ellps=WGS84+datum=WGS84+units=%s+type=crs", - dLon0, dLat0, pszUnits); - break; - case 42005: /** WGS 84 / Auto Mollweide **/ - sprintf( szProjBuf, - "+proj=moll+lon_0=%.16g+x_0=0+y_0=0+ellps=WGS84" - "+datum=WGS84+units=%s+type=crs", - dLon0, pszUnits); - break; - default: - msSetError(MS_PROJERR, - "WMS/WFS AUTO PROJECTION %d not supported.\n", - "_msProcessAutoProjection()", nProjId); - return -1; + switch (nProjId) { + case 42001: /** WGS 84 / Auto UTM **/ + nZone = (int)floor((dLon0 + 180.0) / 6.0) + 1; + sprintf(szProjBuf, + "+proj=tmerc+lat_0=0+lon_0=%.16g+k=0.999600+x_0=500000" + "+y_0=%.16g+ellps=WGS84+datum=WGS84+units=%s+type=crs", + -183.0 + nZone * 6.0, (dLat0 >= 0.0) ? 0.0 : 10000000.0, pszUnits); + break; + case 42002: /** WGS 84 / Auto Tr. Mercator **/ + sprintf(szProjBuf, + "+proj=tmerc+lat_0=0+lon_0=%.16g+k=0.999600+x_0=500000" + "+y_0=%.16g+ellps=WGS84+datum=WGS84+units=%s+type=crs", + dLon0, (dLat0 >= 0.0) ? 0.0 : 10000000.0, pszUnits); + break; + case 42003: /** WGS 84 / Auto Orthographic **/ + sprintf(szProjBuf, + "+proj=ortho+lon_0=%.16g+lat_0=%.16g+x_0=0+y_0=0" + "+ellps=WGS84+datum=WGS84+units=%s+type=crs", + dLon0, dLat0, pszUnits); + break; + case 42004: /** WGS 84 / Auto Equirectangular **/ + /* Note that we have to pass lon_0 as lon_ts for this one to */ + /* work. Either a PROJ4 bug or a PROJ4 documentation issue. */ + sprintf(szProjBuf, + "+proj=eqc+lon_ts=%.16g+lat_ts=%.16g+x_0=0+y_0=0" + "+ellps=WGS84+datum=WGS84+units=%s+type=crs", + dLon0, dLat0, pszUnits); + break; + case 42005: /** WGS 84 / Auto Mollweide **/ + sprintf(szProjBuf, + "+proj=moll+lon_0=%.16g+x_0=0+y_0=0+ellps=WGS84" + "+datum=WGS84+units=%s+type=crs", + dLon0, pszUnits); + break; + default: + msSetError(MS_PROJERR, "WMS/WFS AUTO PROJECTION %d not supported.\n", + "_msProcessAutoProjection()", nProjId); + return -1; } /* msDebug("%s = %s\n", p->args[0], szProjBuf); */ @@ -828,45 +765,45 @@ static int _msProcessAutoProjection(projectionObj *p) args = msStringSplit(szProjBuf, '+', &numargs); #if PROJ_VERSION_MAJOR >= 6 - if( !(p->proj = proj_create_argv(p->proj_ctx->proj_ctx, numargs, args)) ) { - int l_pj_errno = proj_context_errno (p->proj_ctx->proj_ctx); + if (!(p->proj = proj_create_argv(p->proj_ctx->proj_ctx, numargs, args))) { + int l_pj_errno = proj_context_errno(p->proj_ctx->proj_ctx); msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", - "msProcessProjection()", proj_errno_string(l_pj_errno), szProjBuf) ; + "msProcessProjection()", proj_errno_string(l_pj_errno), + szProjBuf); msFreeCharArray(args, numargs); - return(-1); + return (-1); } #else - msAcquireLock( TLOCK_PROJ ); - if( !(p->proj = pj_init(numargs, args)) ) { + msAcquireLock(TLOCK_PROJ); + if (!(p->proj = pj_init(numargs, args))) { int *pj_errno_ref = pj_get_errno_ref(); - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", - "msProcessProjection()", pj_strerrno(*pj_errno_ref), szProjBuf) ; + "msProcessProjection()", pj_strerrno(*pj_errno_ref), szProjBuf); msFreeCharArray(args, numargs); - return(-1); + return (-1); } - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); #endif msFreeCharArray(args, numargs); - return(0); + return (0); } -int msProcessProjection(projectionObj *p) -{ - assert( p->proj == NULL ); +int msProcessProjection(projectionObj *p) { + assert(p->proj == NULL); - p->generation_number ++; + p->generation_number++; - if( strcasecmp(p->args[0],"GEOGRAPHIC") == 0 ) { + if (strcasecmp(p->args[0], "GEOGRAPHIC") == 0) { msSetError(MS_PROJERR, "PROJECTION 'GEOGRAPHIC' no longer supported.\n" "Provide explicit definition.\n" "ie. proj=latlong\n" " ellps=clrk66\n", "msProcessProjection()"); - return(-1); + return (-1); } if (strcasecmp(p->args[0], "AUTO") == 0) { @@ -875,38 +812,32 @@ int msProcessProjection(projectionObj *p) } #if PROJ_VERSION_MAJOR >= 6 - if( p->proj_ctx == NULL ) - { + if (p->proj_ctx == NULL) { p->proj_ctx = msProjectionContextCreate(); - if( p->proj_ctx == NULL ) - { - return -1; + if (p->proj_ctx == NULL) { + return -1; } } - if( p->proj_ctx->ms_proj_data_change_counter != ms_proj_data_change_counter ) - { - msAcquireLock( TLOCK_PROJ ); + if (p->proj_ctx->ms_proj_data_change_counter != ms_proj_data_change_counter) { + msAcquireLock(TLOCK_PROJ); p->proj_ctx->ms_proj_data_change_counter = ms_proj_data_change_counter; { - if( ms_proj_data ) - { - int num_tokens = 0; + if (ms_proj_data) { + int num_tokens = 0; #ifdef _WIN32 - char sep = ';'; + char sep = ';'; #else - char sep = ':'; + char sep = ':'; #endif - char** paths = msStringSplit(ms_proj_data, sep, &num_tokens); - proj_context_set_search_paths(p->proj_ctx->proj_ctx, num_tokens, - (const char* const*)paths); - msFreeCharArray(paths, num_tokens); - } - else - { - proj_context_set_search_paths(p->proj_ctx->proj_ctx, 0, NULL); - } + char **paths = msStringSplit(ms_proj_data, sep, &num_tokens); + proj_context_set_search_paths(p->proj_ctx->proj_ctx, num_tokens, + (const char *const *)paths); + msFreeCharArray(paths, num_tokens); + } else { + proj_context_set_search_paths(p->proj_ctx->proj_ctx, 0, NULL); + } } - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); } #endif @@ -918,91 +849,94 @@ int msProcessProjection(projectionObj *p) } #if PROJ_VERSION_MAJOR >= 6 - if( p->numargs == 1 && strncmp(p->args[0], "init=", 5) != 0 ) - { - /* Deal e.g. with EPSG:XXXX or ESRI:XXXX */ - if( !(p->proj = proj_create_argv(p->proj_ctx->proj_ctx, p->numargs, p->args)) ) { - int l_pj_errno = proj_context_errno (p->proj_ctx->proj_ctx); - msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", - "msProcessProjection()", proj_errno_string(l_pj_errno), p->args[0]) ; - return(-1); - } - } - else - { - char** args = (char**)msSmallMalloc(sizeof(char*) * (p->numargs+1)); - memcpy(args, p->args, sizeof(char*) * p->numargs); + if (p->numargs == 1 && strncmp(p->args[0], "init=", 5) != 0) { + /* Deal e.g. with EPSG:XXXX or ESRI:XXXX */ + if (!(p->proj = + proj_create_argv(p->proj_ctx->proj_ctx, p->numargs, p->args))) { + int l_pj_errno = proj_context_errno(p->proj_ctx->proj_ctx); + msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", + "msProcessProjection()", proj_errno_string(l_pj_errno), + p->args[0]); + return (-1); + } + } else { + char **args = (char **)msSmallMalloc(sizeof(char *) * (p->numargs + 1)); + memcpy(args, p->args, sizeof(char *) * p->numargs); #if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR < 2 - /* PROJ lookups are faster with EPSG in uppercase. Fixed in PROJ 6.2 */ - /* Do that only for those versions, as it can create confusion if using */ - /* a real old-style 'epsg' file... */ - char szTemp[24]; - if( p->numargs && strncmp(args[0], "init=epsg:", strlen("init=epsg:")) == 0 && - strlen(args[0]) < 24) - { - strcpy(szTemp, "init=EPSG:"); - strcat(szTemp, args[0] + strlen("init=epsg:")); - args[0] = szTemp; - } + /* PROJ lookups are faster with EPSG in uppercase. Fixed in PROJ 6.2 */ + /* Do that only for those versions, as it can create confusion if using */ + /* a real old-style 'epsg' file... */ + char szTemp[24]; + if (p->numargs && + strncmp(args[0], "init=epsg:", strlen("init=epsg:")) == 0 && + strlen(args[0]) < 24) { + strcpy(szTemp, "init=EPSG:"); + strcat(szTemp, args[0] + strlen("init=epsg:")); + args[0] = szTemp; + } #endif - args[p->numargs] = (char*) "type=crs"; + args[p->numargs] = (char *)"type=crs"; #if 0 for( int i = 0; i < p->numargs + 1; i++ ) fprintf(stderr, "%s ", args[i]); fprintf(stderr, "\n"); #endif - if( !(p->proj = proj_create_argv(p->proj_ctx->proj_ctx, p->numargs + 1, args)) ) { - int l_pj_errno = proj_context_errno (p->proj_ctx->proj_ctx); - if(p->numargs>1) { - msSetError(MS_PROJERR, "proj error \"%s\" for \"%s:%s\"", - "msProcessProjection()", proj_errno_string(l_pj_errno), p->args[0],p->args[1]) ; - } else { - msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", - "msProcessProjection()", proj_errno_string(l_pj_errno), p->args[0]) ; - } - free(args); - return(-1); + if (!(p->proj = + proj_create_argv(p->proj_ctx->proj_ctx, p->numargs + 1, args))) { + int l_pj_errno = proj_context_errno(p->proj_ctx->proj_ctx); + if (p->numargs > 1) { + msSetError(MS_PROJERR, "proj error \"%s\" for \"%s:%s\"", + "msProcessProjection()", proj_errno_string(l_pj_errno), + p->args[0], p->args[1]); + } else { + msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", + "msProcessProjection()", proj_errno_string(l_pj_errno), + p->args[0]); } free(args); + return (-1); + } + free(args); } #else - msAcquireLock( TLOCK_PROJ ); + msAcquireLock(TLOCK_PROJ); #if PJ_VERSION < 480 - if( !(p->proj = pj_init(p->numargs, p->args)) ) { + if (!(p->proj = pj_init(p->numargs, p->args))) { #else p->proj_ctx = pj_ctx_alloc(); - if( !(p->proj=pj_init_ctx(p->proj_ctx, p->numargs, p->args)) ) { + if (!(p->proj = pj_init_ctx(p->proj_ctx, p->numargs, p->args))) { #endif int *pj_errno_ref = pj_get_errno_ref(); - msReleaseLock( TLOCK_PROJ ); - if(p->numargs>1) { + msReleaseLock(TLOCK_PROJ); + if (p->numargs > 1) { msSetError(MS_PROJERR, "proj error \"%s\" for \"%s:%s\"", - "msProcessProjection()", pj_strerrno(*pj_errno_ref), p->args[0],p->args[1]) ; + "msProcessProjection()", pj_strerrno(*pj_errno_ref), + p->args[0], p->args[1]); } else { msSetError(MS_PROJERR, "proj error \"%s\" for \"%s\"", - "msProcessProjection()", pj_strerrno(*pj_errno_ref), p->args[0]) ; + "msProcessProjection()", pj_strerrno(*pj_errno_ref), + p->args[0]); } - return(-1); + return (-1); } - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); #endif #ifdef USE_PROJ_FASTPATHS - if(strcasestr(p->args[0],"epsg:4326")) { + if (strcasestr(p->args[0], "epsg:4326")) { p->wellknownprojection = wkp_lonlat; - } else if(strcasestr(p->args[0],"epsg:3857")) { + } else if (strcasestr(p->args[0], "epsg:3857")) { p->wellknownprojection = wkp_gmerc; } else { p->wellknownprojection = wkp_none; } #endif - - return(0); + return (0); } /************************************************************************/ @@ -1010,15 +944,15 @@ int msProcessProjection(projectionObj *p) /* Check to see if we should invert the axis. */ /* */ /************************************************************************/ -int msIsAxisInverted(int epsg_code) -{ - if( epsg_code < 0 ) +int msIsAxisInverted(int epsg_code) { + if (epsg_code < 0) return MS_FALSE; const unsigned int row = epsg_code / 8; const unsigned char index = epsg_code % 8; /*check the static table*/ - if ((row < sizeof(axisOrientationEpsgCodes)) && (axisOrientationEpsgCodes[row] & (1 << index))) + if ((row < sizeof(axisOrientationEpsgCodes)) && + (axisOrientationEpsgCodes[row] & (1 << index))) return MS_TRUE; else return MS_FALSE; @@ -1027,55 +961,51 @@ int msIsAxisInverted(int epsg_code) /************************************************************************/ /* msProjectPoint() */ /************************************************************************/ -int msProjectPoint(projectionObj *in, projectionObj *out, pointObj *point) -{ - int ret; - reprojectionObj* reprojector = msProjectCreateReprojector(in, out); - if( !reprojector ) - return MS_FAILURE; - ret = msProjectPointEx(reprojector, point); - msProjectDestroyReprojector(reprojector); - return ret; +int msProjectPoint(projectionObj *in, projectionObj *out, pointObj *point) { + int ret; + reprojectionObj *reprojector = msProjectCreateReprojector(in, out); + if (!reprojector) + return MS_FAILURE; + ret = msProjectPointEx(reprojector, point); + msProjectDestroyReprojector(reprojector); + return ret; } /************************************************************************/ /* msProjectPointEx() */ /************************************************************************/ -int msProjectPointEx(reprojectionObj* reprojector, pointObj *point) -{ - projectionObj* in = reprojector->in; - projectionObj* out = reprojector->out; +int msProjectPointEx(reprojectionObj *reprojector, pointObj *point) { + projectionObj *in = reprojector->in; + projectionObj *out = reprojector->out; - if( in && in->gt.need_geotransform ) { + if (in && in->gt.need_geotransform) { double x_out, y_out; - x_out = in->gt.geotransform[0] - + in->gt.geotransform[1] * point->x - + in->gt.geotransform[2] * point->y; - y_out = in->gt.geotransform[3] - + in->gt.geotransform[4] * point->x - + in->gt.geotransform[5] * point->y; + x_out = in->gt.geotransform[0] + in->gt.geotransform[1] * point->x + + in->gt.geotransform[2] * point->y; + y_out = in->gt.geotransform[3] + in->gt.geotransform[4] * point->x + + in->gt.geotransform[5] * point->y; point->x = x_out; point->y = y_out; } #if PROJ_VERSION_MAJOR >= 6 - if( reprojector->pj ) { + if (reprojector->pj) { PJ_COORD c; c.xyzt.x = point->x; c.xyzt.y = point->y; c.xyzt.z = 0; c.xyzt.t = 0; - c = proj_trans (reprojector->pj, PJ_FWD, c); - if( c.xyzt.x == HUGE_VAL || c.xyzt.y == HUGE_VAL ) { + c = proj_trans(reprojector->pj, PJ_FWD, c); + if (c.xyzt.x == HUGE_VAL || c.xyzt.y == HUGE_VAL) { return MS_FAILURE; } point->x = c.xyzt.x; point->y = c.xyzt.y; } #else - if( reprojector->no_op ) { + if (reprojector->no_op) { /* do nothing, no transformation required */ } @@ -1083,30 +1013,31 @@ int msProjectPointEx(reprojectionObj* reprojector, pointObj *point) /* If we have a fully defined input coordinate system and */ /* output coordinate system, then we will use pj_transform. */ /* -------------------------------------------------------------------- */ - else if( in && in->proj && out && out->proj ) { + else if (in && in->proj && out && out->proj) { int error; - double z = 0.0; + double z = 0.0; - if( pj_is_latlong(in->proj) ) { + if (pj_is_latlong(in->proj)) { point->x *= DEG_TO_RAD; point->y *= DEG_TO_RAD; } #if PJ_VERSION < 480 - msAcquireLock( TLOCK_PROJ ); + msAcquireLock(TLOCK_PROJ); #endif - error = pj_transform( in->proj, out->proj, 1, 0, - &(point->x), &(point->y), &z ); + error = + pj_transform(in->proj, out->proj, 1, 0, &(point->x), &(point->y), &z); #if PJ_VERSION < 480 - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); #endif - if( error || point->x == HUGE_VAL || point->y == HUGE_VAL ) { -// msSetError(MS_PROJERR,"proj says: %s","msProjectPoint()",pj_strerrno(error)); + if (error || point->x == HUGE_VAL || point->y == HUGE_VAL) { + // msSetError(MS_PROJERR,"proj says: + // %s","msProjectPoint()",pj_strerrno(error)); return MS_FAILURE; } - if( pj_is_latlong(out->proj) ) { + if (pj_is_latlong(out->proj)) { point->x *= RAD_TO_DEG; point->y *= RAD_TO_DEG; } @@ -1124,11 +1055,12 @@ int msProjectPointEx(reprojectionObj* reprojector, pointObj *point) p.u = point->x; p.v = point->y; - if(in==NULL || in->proj==NULL) { /* input coordinates are lat/lon */ - p.u *= DEG_TO_RAD; /* convert to radians */ + if (in == NULL || in->proj == NULL) { /* input coordinates are lat/lon */ + p.u *= DEG_TO_RAD; /* convert to radians */ p.v *= DEG_TO_RAD; p = pj_fwd(p, out->proj); - } else /* if(out==NULL || out->proj==NULL) */ { /* output coordinates are lat/lon */ + } else /* if(out==NULL || out->proj==NULL) */ { /* output coordinates are + lat/lon */ p = pj_inv(p, in->proj); p.u *= RAD_TO_DEG; /* convert to decimal degrees */ p.v *= RAD_TO_DEG; @@ -1136,42 +1068,39 @@ int msProjectPointEx(reprojectionObj* reprojector, pointObj *point) point->x = p.u; point->y = p.v; - if( point->x == HUGE_VAL || point->y == HUGE_VAL ) { + if (point->x == HUGE_VAL || point->y == HUGE_VAL) { return MS_FAILURE; } } #endif - if( out && out->gt.need_geotransform ) { + if (out && out->gt.need_geotransform) { double x_out, y_out; - x_out = out->gt.invgeotransform[0] - + out->gt.invgeotransform[1] * point->x - + out->gt.invgeotransform[2] * point->y; - y_out = out->gt.invgeotransform[3] - + out->gt.invgeotransform[4] * point->x - + out->gt.invgeotransform[5] * point->y; + x_out = out->gt.invgeotransform[0] + out->gt.invgeotransform[1] * point->x + + out->gt.invgeotransform[2] * point->y; + y_out = out->gt.invgeotransform[3] + out->gt.invgeotransform[4] * point->x + + out->gt.invgeotransform[5] * point->y; point->x = x_out; point->y = y_out; } - return(MS_SUCCESS); + return (MS_SUCCESS); } /************************************************************************/ /* msProjectGrowRect() */ /************************************************************************/ -static void msProjectGrowRect(reprojectionObj* reprojector, - rectObj *prj_rect, - pointObj *prj_point, int *failure ) +static void msProjectGrowRect(reprojectionObj *reprojector, rectObj *prj_rect, + pointObj *prj_point, int *failure) { - if( msProjectPointEx(reprojector, prj_point) == MS_SUCCESS ) { - prj_rect->miny = MS_MIN(prj_rect->miny, prj_point->y); - prj_rect->maxy = MS_MAX(prj_rect->maxy, prj_point->y); - prj_rect->minx = MS_MIN(prj_rect->minx, prj_point->x); - prj_rect->maxx = MS_MAX(prj_rect->maxx, prj_point->x); + if (msProjectPointEx(reprojector, prj_point) == MS_SUCCESS) { + prj_rect->miny = MS_MIN(prj_rect->miny, prj_point->y); + prj_rect->maxy = MS_MAX(prj_rect->maxy, prj_point->y); + prj_rect->minx = MS_MIN(prj_rect->minx, prj_point->x); + prj_rect->maxx = MS_MAX(prj_rect->maxx, prj_point->x); } else (*failure)++; } @@ -1182,8 +1111,8 @@ static void msProjectGrowRect(reprojectionObj* reprojector, /* Interpolate along a line segment for which one end */ /* reprojects and the other end does not. Finds the horizon. */ /************************************************************************/ -static int msProjectSegment( reprojectionObj* reprojector, - pointObj *start, pointObj *end ) +static int msProjectSegment(reprojectionObj *reprojector, pointObj *start, + pointObj *end) { pointObj testPoint, subStart, subEnd; @@ -1194,12 +1123,12 @@ static int msProjectSegment( reprojectionObj* reprojector, /* then re-call with the points reversed. */ /* -------------------------------------------------------------------- */ testPoint = *start; - if( msProjectPointEx( reprojector, &testPoint ) == MS_FAILURE ) { + if (msProjectPointEx(reprojector, &testPoint) == MS_FAILURE) { testPoint = *end; - if( msProjectPointEx( reprojector, &testPoint ) == MS_FAILURE ) + if (msProjectPointEx(reprojector, &testPoint) == MS_FAILURE) return MS_FAILURE; else - return msProjectSegment( reprojector, end, start ); + return msProjectSegment(reprojector, end, start); } /* -------------------------------------------------------------------- */ @@ -1211,8 +1140,8 @@ static int msProjectSegment( reprojectionObj* reprojector, #define TOLERANCE 0.01 - while( fabs(subStart.x - subEnd.x) - + fabs(subStart.y - subEnd.y) > TOLERANCE ) { + while (fabs(subStart.x - subEnd.x) + fabs(subStart.y - subEnd.y) > + TOLERANCE) { pointObj midPoint = {0}; midPoint.x = (subStart.x + subEnd.x) * 0.5; @@ -1220,13 +1149,12 @@ static int msProjectSegment( reprojectionObj* reprojector, testPoint = midPoint; - if( msProjectPointEx( reprojector, &testPoint ) == MS_FAILURE ) { + if (msProjectPointEx(reprojector, &testPoint) == MS_FAILURE) { if (midPoint.x == subEnd.x && midPoint.y == subEnd.y) return MS_FAILURE; /* break infinite loop */ subEnd = midPoint; - } - else { + } else { if (midPoint.x == subStart.x && midPoint.y == subStart.y) return MS_FAILURE; /* break infinite loop */ @@ -1239,8 +1167,8 @@ static int msProjectSegment( reprojectionObj* reprojector, /* -------------------------------------------------------------------- */ *end = subStart; - if( msProjectPointEx( reprojector, end ) == MS_FAILURE - || msProjectPointEx( reprojector, start ) == MS_FAILURE ) + if (msProjectPointEx(reprojector, end) == MS_FAILURE || + msProjectPointEx(reprojector, start) == MS_FAILURE) return MS_FAILURE; else return MS_SUCCESS; @@ -1253,131 +1181,122 @@ static int msProjectSegment( reprojectionObj* reprojector, /* Detect projecting from north polar stereographic to longlat or EPSG:3857 */ /* or from lonlat lon_wrap = 0 */ #ifdef USE_GEOS -static msLineCuttingCase msProjectGetLineCuttingCase(reprojectionObj* reprojector) -{ - if( reprojector->lineCuttingCase != LINE_CUTTING_UNKNOWN) - return reprojector->lineCuttingCase; +static msLineCuttingCase +msProjectGetLineCuttingCase(reprojectionObj *reprojector) { + if (reprojector->lineCuttingCase != LINE_CUTTING_UNKNOWN) + return reprojector->lineCuttingCase; - projectionObj *in = reprojector->in; - projectionObj *out = reprojector->out; - const double EPS = 1e-10; + projectionObj *in = reprojector->in; + projectionObj *out = reprojector->out; + const double EPS = 1e-10; - if( !in->gt.need_geotransform && msProjIsGeographicCRS(in) ) - { - int i; - for( i = 0; i < in->numargs; i++ ) - { - if( strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0 && - atof(in->args[i] + strlen("lon_wrap=")) == 0.0 ) - { - reprojector->lineCuttingCase = LINE_CUTTING_FROM_LONGLAT_WRAP0; - - msInitShape(&(reprojector->splitShape)); - reprojector->splitShape.type = MS_SHAPE_POLYGON; - int j; - for( j = -1; j <= 1; j += 2 ) - { - const double x = j * 180; - pointObj p = {0}; // initialize - lineObj newLine = {0,NULL}; - p.x = x - EPS; - p.y = 90; - msAddPointToLine(&newLine, &p ); - p.x = x + EPS; - p.y = 90; - msAddPointToLine(&newLine, &p ); - p.x = x + EPS; - p.y = -90; - msAddPointToLine(&newLine, &p ); - p.x = x - EPS; - p.y = -90; - msAddPointToLine(&newLine, &p ); - p.x = x - EPS; - p.y = 90; - msAddPointToLine(&newLine, &p ); - msAddLineDirectly(&(reprojector->splitShape), &newLine); - } - - return reprojector->lineCuttingCase; - } + if (!in->gt.need_geotransform && msProjIsGeographicCRS(in)) { + int i; + for (i = 0; i < in->numargs; i++) { + if (strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0 && + atof(in->args[i] + strlen("lon_wrap=")) == 0.0) { + reprojector->lineCuttingCase = LINE_CUTTING_FROM_LONGLAT_WRAP0; + + msInitShape(&(reprojector->splitShape)); + reprojector->splitShape.type = MS_SHAPE_POLYGON; + int j; + for (j = -1; j <= 1; j += 2) { + const double x = j * 180; + pointObj p = {0}; // initialize + lineObj newLine = {0, NULL}; + p.x = x - EPS; + p.y = 90; + msAddPointToLine(&newLine, &p); + p.x = x + EPS; + p.y = 90; + msAddPointToLine(&newLine, &p); + p.x = x + EPS; + p.y = -90; + msAddPointToLine(&newLine, &p); + p.x = x - EPS; + p.y = -90; + msAddPointToLine(&newLine, &p); + p.x = x - EPS; + p.y = 90; + msAddPointToLine(&newLine, &p); + msAddLineDirectly(&(reprojector->splitShape), &newLine); } - } - if( !(!in->gt.need_geotransform && !msProjIsGeographicCRS(in) && - (msProjIsGeographicCRS(out) || - (out->numargs == 1 && strcmp(out->args[0], "init=epsg:3857") == 0))) ) - { - reprojector->lineCuttingCase = LINE_CUTTING_NONE; return reprojector->lineCuttingCase; + } } + } - int srcIsPolar; - double extremeLongEasting; - if( msProjIsGeographicCRS(out) ) - { - pointObj p; - double gt3 = out->gt.need_geotransform ? out->gt.geotransform[3] : 0.0; - double gt4 = out->gt.need_geotransform ? out->gt.geotransform[4] : 0.0; - double gt5 = out->gt.need_geotransform ? out->gt.geotransform[5] : 1.0; - p.x = 0.0; - p.y = 0.0; - srcIsPolar = msProjectPointEx(reprojector, &p) == MS_SUCCESS && - fabs(gt3 + p.x * gt4 + p.y * gt5 - 90) < 1e-8; - extremeLongEasting = 180; - } - else - { - pointObj p1; - pointObj p2; - double gt1 = out->gt.need_geotransform ? out->gt.geotransform[1] : 1.0; - p1.x = 0.0; - p1.y = -0.1; - p2.x = 0.0; - p2.y = 0.1; - srcIsPolar = msProjectPointEx(reprojector, &p1) == MS_SUCCESS && - msProjectPointEx(reprojector, &p2) == MS_SUCCESS && - fabs((p1.x - p2.x) * gt1) > 20e6; - extremeLongEasting = 20037508.3427892; - } - if( !srcIsPolar ) - { - reprojector->lineCuttingCase = LINE_CUTTING_NONE; - return reprojector->lineCuttingCase; - } + if (!(!in->gt.need_geotransform && !msProjIsGeographicCRS(in) && + (msProjIsGeographicCRS(out) || + (out->numargs == 1 && strcmp(out->args[0], "init=epsg:3857") == 0)))) { + reprojector->lineCuttingCase = LINE_CUTTING_NONE; + return reprojector->lineCuttingCase; + } + + int srcIsPolar; + double extremeLongEasting; + if (msProjIsGeographicCRS(out)) { + pointObj p; + double gt3 = out->gt.need_geotransform ? out->gt.geotransform[3] : 0.0; + double gt4 = out->gt.need_geotransform ? out->gt.geotransform[4] : 0.0; + double gt5 = out->gt.need_geotransform ? out->gt.geotransform[5] : 1.0; + p.x = 0.0; + p.y = 0.0; + srcIsPolar = msProjectPointEx(reprojector, &p) == MS_SUCCESS && + fabs(gt3 + p.x * gt4 + p.y * gt5 - 90) < 1e-8; + extremeLongEasting = 180; + } else { + pointObj p1; + pointObj p2; + double gt1 = out->gt.need_geotransform ? out->gt.geotransform[1] : 1.0; + p1.x = 0.0; + p1.y = -0.1; + p2.x = 0.0; + p2.y = 0.1; + srcIsPolar = msProjectPointEx(reprojector, &p1) == MS_SUCCESS && + msProjectPointEx(reprojector, &p2) == MS_SUCCESS && + fabs((p1.x - p2.x) * gt1) > 20e6; + extremeLongEasting = 20037508.3427892; + } + if (!srcIsPolar) { + reprojector->lineCuttingCase = LINE_CUTTING_NONE; + return reprojector->lineCuttingCase; + } - pointObj p = {0}; // initialize - double invgt0 = out->gt.need_geotransform ? out->gt.invgeotransform[0] : 0.0; - double invgt1 = out->gt.need_geotransform ? out->gt.invgeotransform[1] : 1.0; - double invgt3 = out->gt.need_geotransform ? out->gt.invgeotransform[3] : 0.0; - double invgt4 = out->gt.need_geotransform ? out->gt.invgeotransform[4] : 0.0; + pointObj p = {0}; // initialize + double invgt0 = out->gt.need_geotransform ? out->gt.invgeotransform[0] : 0.0; + double invgt1 = out->gt.need_geotransform ? out->gt.invgeotransform[1] : 1.0; + double invgt3 = out->gt.need_geotransform ? out->gt.invgeotransform[3] : 0.0; + double invgt4 = out->gt.need_geotransform ? out->gt.invgeotransform[4] : 0.0; - lineObj newLine = {0,NULL}; + lineObj newLine = {0, NULL}; - p.x = invgt0 + -extremeLongEasting * (1 - EPS) * invgt1; - p.y = invgt3 + -extremeLongEasting * (1 - EPS) * invgt4; - /* coverity[swapped_arguments] */ - msProjectPoint(out, in, &p); - pointObj first = p; - msAddPointToLine(&newLine, &p ); + p.x = invgt0 + -extremeLongEasting * (1 - EPS) * invgt1; + p.y = invgt3 + -extremeLongEasting * (1 - EPS) * invgt4; + /* coverity[swapped_arguments] */ + msProjectPoint(out, in, &p); + pointObj first = p; + msAddPointToLine(&newLine, &p); - p.x = invgt0 + extremeLongEasting * (1 - EPS) * invgt1; - p.y = invgt3 + extremeLongEasting * (1 - EPS) * invgt4; - /* coverity[swapped_arguments] */ - msProjectPoint(out, in, &p); - msAddPointToLine(&newLine, &p ); + p.x = invgt0 + extremeLongEasting * (1 - EPS) * invgt1; + p.y = invgt3 + extremeLongEasting * (1 - EPS) * invgt4; + /* coverity[swapped_arguments] */ + msProjectPoint(out, in, &p); + msAddPointToLine(&newLine, &p); - p.x = 0; - p.y = 0; - msAddPointToLine(&newLine, &p ); + p.x = 0; + p.y = 0; + msAddPointToLine(&newLine, &p); - msAddPointToLine(&newLine, &first ); + msAddPointToLine(&newLine, &first); - msInitShape(&(reprojector->splitShape)); - reprojector->splitShape.type = MS_SHAPE_POLYGON; - msAddLineDirectly(&(reprojector->splitShape), &newLine); + msInitShape(&(reprojector->splitShape)); + reprojector->splitShape.type = MS_SHAPE_POLYGON; + msAddLineDirectly(&(reprojector->splitShape), &newLine); - reprojector->lineCuttingCase = LINE_CUTTING_FROM_POLAR; - return reprojector->lineCuttingCase; + reprojector->lineCuttingCase = LINE_CUTTING_FROM_POLAR; + return reprojector->lineCuttingCase; } #endif @@ -1385,13 +1304,14 @@ static msLineCuttingCase msProjectGetLineCuttingCase(reprojectionObj* reprojecto /* msProjectIsReprojectorStillValid() */ /************************************************************************/ -int msProjectIsReprojectorStillValid(reprojectionObj* reprojector) -{ - if( reprojector->in && reprojector->in->generation_number != reprojector->generation_number_in ) - return MS_FALSE; - if( reprojector->out && reprojector->out->generation_number != reprojector->generation_number_out ) - return MS_FALSE; - return MS_TRUE; +int msProjectIsReprojectorStillValid(reprojectionObj *reprojector) { + if (reprojector->in && + reprojector->in->generation_number != reprojector->generation_number_in) + return MS_FALSE; + if (reprojector->out && + reprojector->out->generation_number != reprojector->generation_number_out) + return MS_FALSE; + return MS_TRUE; } /************************************************************************/ @@ -1406,13 +1326,12 @@ int msProjectIsReprojectorStillValid(reprojectionObj* reprojector) /* over the horizon point to the come back over the horizon point. */ /************************************************************************/ -static int -msProjectShapeLine(reprojectionObj* reprojector, - shapeObj *shape, int line_index) +static int msProjectShapeLine(reprojectionObj *reprojector, shapeObj *shape, + int line_index) { int i; - pointObj lastPoint, thisPoint, wrkPoint; + pointObj lastPoint, thisPoint, wrkPoint; lineObj *line = shape->line + line_index; lineObj *line_out = line; int valid_flag = 0; /* 1=true, -1=false, 0=unknown */ @@ -1428,29 +1347,39 @@ msProjectShapeLine(reprojectionObj* reprojector, #define MAXEXTENTby180 111319.4907777777777777777 #define p_x line->point[i].x #define p_y line->point[i].y - if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { - for( i = line->numpoints-1; i >= 0; i-- ) { + if (in->wellknownprojection == wkp_lonlat && + out->wellknownprojection == wkp_gmerc) { + for (i = line->numpoints - 1; i >= 0; i--) { p_x *= MAXEXTENTby180; p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; p_y *= MAXEXTENTby180; - if (p_x > MAXEXTENT) p_x = MAXEXTENT; - if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; - if (p_y > MAXEXTENT) p_y = MAXEXTENT; - if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; + if (p_x > MAXEXTENT) + p_x = MAXEXTENT; + if (p_x < -MAXEXTENT) + p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) + p_y = MAXEXTENT; + if (p_y < -MAXEXTENT) + p_y = -MAXEXTENT; } return MS_SUCCESS; } - if(in->wellknownprojection == wkp_gmerc && out->wellknownprojection == wkp_lonlat) { - for( i = line->numpoints-1; i >= 0; i-- ) { - if (p_x > MAXEXTENT) p_x = MAXEXTENT; - else if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; - if (p_y > MAXEXTENT) p_y = MAXEXTENT; - else if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; + if (in->wellknownprojection == wkp_gmerc && + out->wellknownprojection == wkp_lonlat) { + for (i = line->numpoints - 1; i >= 0; i--) { + if (p_x > MAXEXTENT) + p_x = MAXEXTENT; + else if (p_x < -MAXEXTENT) + p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) + p_y = MAXEXTENT; + else if (p_y < -MAXEXTENT) + p_y = -MAXEXTENT; p_x = (p_x / MAXEXTENT) * 180; p_y = (p_y / MAXEXTENT) * 180; p_y = MS_RAD_TO_DEG * (2 * atan(exp(p_y * MS_DEG_TO_RAD)) - MS_PI2); } - msComputeBounds( shape ); /* fixes bug 1586 */ + msComputeBounds(shape); /* fixes bug 1586 */ return MS_SUCCESS; } #undef p_x @@ -1460,115 +1389,103 @@ msProjectShapeLine(reprojectionObj* reprojector, #ifdef USE_GEOS int use_splitShape = MS_FALSE; int use_splitShape_check_intersects = MS_FALSE; - if( shape->type == MS_SHAPE_LINE && - msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_POLAR ) - { + if (shape->type == MS_SHAPE_LINE && + msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_POLAR) { use_splitShape = MS_TRUE; use_splitShape_check_intersects = MS_TRUE; - } - else if( shape->type == MS_SHAPE_LINE && - msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_LONGLAT_WRAP0 ) - { - for( i=0; i < numpoints_in; i++ ) - { - if( fabs(line->point[i].x) > 180 ) - { - use_splitShape = MS_TRUE; - break; - } + } else if (shape->type == MS_SHAPE_LINE && + msProjectGetLineCuttingCase(reprojector) == + LINE_CUTTING_FROM_LONGLAT_WRAP0) { + for (i = 0; i < numpoints_in; i++) { + if (fabs(line->point[i].x) > 180) { + use_splitShape = MS_TRUE; + break; } + } } - if( use_splitShape ) - { + if (use_splitShape) { shapeObj tmpShapeInputLine; msInitShape(&tmpShapeInputLine); tmpShapeInputLine.type = MS_SHAPE_LINE; tmpShapeInputLine.numlines = 1; tmpShapeInputLine.line = line; - shapeObj* diff = NULL; - if( use_splitShape_check_intersects == MS_FALSE || - msGEOSIntersects(&tmpShapeInputLine, &(reprojector->splitShape)) ) - { - diff = msGEOSDifference(&tmpShapeInputLine, &(reprojector->splitShape)); + shapeObj *diff = NULL; + if (use_splitShape_check_intersects == MS_FALSE || + msGEOSIntersects(&tmpShapeInputLine, &(reprojector->splitShape))) { + diff = msGEOSDifference(&tmpShapeInputLine, &(reprojector->splitShape)); } tmpShapeInputLine.numlines = 0; tmpShapeInputLine.line = NULL; msFreeShape(&tmpShapeInputLine); - if( diff ) - { - for(int j = 0; j < diff->numlines; j++ ) - { - for( i=0; i < diff->line[j].numpoints; i++ ) { - msProjectPointEx(reprojector, &(diff->line[j].point[i])); - } - if( j == 0 ) - { - line_out->numpoints = diff->line[j].numpoints; - memcpy(line_out->point, diff->line[0].point, sizeof(pointObj) * line_out->numpoints); - } - else - { - msAddLineDirectly(shape, &(diff->line[j])); - } + if (diff) { + for (int j = 0; j < diff->numlines; j++) { + for (i = 0; i < diff->line[j].numpoints; i++) { + msProjectPointEx(reprojector, &(diff->line[j].point[i])); + } + if (j == 0) { + line_out->numpoints = diff->line[j].numpoints; + memcpy(line_out->point, diff->line[0].point, + sizeof(pointObj) * line_out->numpoints); + } else { + msAddLineDirectly(shape, &(diff->line[j])); } - msFreeShape(diff); - msFree(diff); - return MS_SUCCESS; + } + msFreeShape(diff); + msFree(diff); + return MS_SUCCESS; } } #endif - wrap_test = out != NULL && out->proj != NULL && msProjIsGeographicCRS(out) - && !msProjIsGeographicCRS(in); + wrap_test = out != NULL && out->proj != NULL && msProjIsGeographicCRS(out) && + !msProjIsGeographicCRS(in); line->numpoints = 0; - memset( &lastPoint, 0, sizeof(lastPoint) ); + memset(&lastPoint, 0, sizeof(lastPoint)); /* -------------------------------------------------------------------- */ /* Loop over all input points in linestring. */ /* -------------------------------------------------------------------- */ - for( i=0; i < numpoints_in; i++ ) { + for (i = 0; i < numpoints_in; i++) { int ms_err; wrkPoint = thisPoint = line->point[i]; - ms_err = msProjectPointEx(reprojector, &wrkPoint ); + ms_err = msProjectPointEx(reprojector, &wrkPoint); /* -------------------------------------------------------------------- */ /* Apply wrap logic. */ /* -------------------------------------------------------------------- */ - if( wrap_test && i > 0 && ms_err != MS_FAILURE ) { + if (wrap_test && i > 0 && ms_err != MS_FAILURE) { double dist; pointObj pt1Geo; - if( line_out->numpoints > 0 ) - pt1Geo = line_out->point[line_out->numpoints-1]; + if (line_out->numpoints > 0) + pt1Geo = line_out->point[line_out->numpoints - 1]; else pt1Geo = wrkPoint; /* this is a cop out */ - if( out->gt.need_geotransform && out->gt.geotransform[2] == 0 ) { + if (out->gt.need_geotransform && out->gt.geotransform[2] == 0) { dist = out->gt.geotransform[1] * (wrkPoint.x - pt1Geo.x); } else { dist = wrkPoint.x - pt1Geo.x; } - if( fabs(dist) > 180.0 - && msTestNeedWrap( thisPoint, lastPoint, - pt1Geo, reprojector ) ) { - if( out->gt.need_geotransform && out->gt.geotransform[2] == 0 ) { - if( dist > 0.0 ) + if (fabs(dist) > 180.0 && + msTestNeedWrap(thisPoint, lastPoint, pt1Geo, reprojector)) { + if (out->gt.need_geotransform && out->gt.geotransform[2] == 0) { + if (dist > 0.0) wrkPoint.x -= 360.0 * out->gt.invgeotransform[1]; - else if( dist < 0.0 ) + else if (dist < 0.0) wrkPoint.x += 360.0 * out->gt.invgeotransform[1]; - } - else { - if( dist > 0.0 ) + } else { + if (dist > 0.0) wrkPoint.x -= 360.0; - else if( dist < 0.0 ) + else if (dist < 0.0) wrkPoint.x += 360.0; } } @@ -1578,40 +1495,40 @@ msProjectShapeLine(reprojectionObj* reprojector, /* Put result into output line with appropriate logic for */ /* failure breaking lines, etc. */ /* -------------------------------------------------------------------- */ - if( ms_err == MS_FAILURE ) { + if (ms_err == MS_FAILURE) { /* We have started out invalid */ - if( i == 0 ) { + if (i == 0) { valid_flag = -1; } /* valid data has ended, we need to work out the horizon */ - else if( valid_flag == 1 ) { + else if (valid_flag == 1) { pointObj startPoint, endPoint; startPoint = lastPoint; endPoint = thisPoint; - if( msProjectSegment( reprojector, &startPoint, &endPoint ) - == MS_SUCCESS ) { + if (msProjectSegment(reprojector, &startPoint, &endPoint) == + MS_SUCCESS) { line_out->point[line_out->numpoints++] = endPoint; } valid_flag = -1; } /* Still invalid ... */ - else if( valid_flag == -1 ) { + else if (valid_flag == -1) { /* do nothing */ } } else { /* starting out valid. */ - if( i == 0 ) { + if (i == 0) { line_out->point[line_out->numpoints++] = wrkPoint; valid_flag = 1; } /* Still valid, nothing special */ - else if( valid_flag == 1 ) { + else if (valid_flag == 1) { line_out->point[line_out->numpoints++] = wrkPoint; } @@ -1621,33 +1538,31 @@ msProjectShapeLine(reprojectionObj* reprojector, startPoint = lastPoint; endPoint = thisPoint; - if( msProjectSegment( reprojector, &endPoint, &startPoint ) - == MS_SUCCESS ) { + if (msProjectSegment(reprojector, &endPoint, &startPoint) == + MS_SUCCESS) { lineObj newLine; /* force pre-allocation of lots of points room */ - if( line_out->numpoints > 0 - && shape->type == MS_SHAPE_LINE ) { + if (line_out->numpoints > 0 && shape->type == MS_SHAPE_LINE) { newLine.numpoints = numpoints_in - i + 1; newLine.point = line->point; - msAddLine( shape, &newLine ); + msAddLine(shape, &newLine); /* new line is now lineout, but start without any points */ - line_out = shape->line + shape->numlines-1; + line_out = shape->line + shape->numlines - 1; line_out->numpoints = 0; /* the shape->line array is realloc, refetch "line" */ line = shape->line + line_index; - } else if( line_out == line - && line->numpoints >= i-2 ) { + } else if (line_out == line && line->numpoints >= i - 2) { newLine.numpoints = numpoints_in; newLine.point = line->point; - msAddLine( shape, &newLine ); + msAddLine(shape, &newLine); line = shape->line + line_index; - line_out = shape->line + shape->numlines-1; + line_out = shape->line + shape->numlines - 1; line_out->numpoints = line->numpoints; line->numpoints = 0; @@ -1657,9 +1572,8 @@ msProjectShapeLine(reprojectionObj* reprojector, */ line_alloc = line_alloc * 2; - line_out->point = (pointObj *) - realloc(line_out->point, - sizeof(pointObj) * line_alloc); + line_out->point = (pointObj *)realloc( + line_out->point, sizeof(pointObj) * line_alloc); } line_out->point[line_out->numpoints++] = startPoint; @@ -1676,71 +1590,78 @@ msProjectShapeLine(reprojectionObj* reprojector, /* Make sure that polygons are closed, even if the trip over */ /* the horizon left them unclosed. */ /* -------------------------------------------------------------------- */ - if( shape->type == MS_SHAPE_POLYGON - && line_out->numpoints > 2 - && (line_out->point[0].x != line_out->point[line_out->numpoints-1].x - || line_out->point[0].y != line_out->point[line_out->numpoints-1].y) ) { + if (shape->type == MS_SHAPE_POLYGON && line_out->numpoints > 2 && + (line_out->point[0].x != line_out->point[line_out->numpoints - 1].x || + line_out->point[0].y != line_out->point[line_out->numpoints - 1].y)) { /* make a copy because msAddPointToLine can realloc the array */ pointObj sFirstPoint = line_out->point[0]; - msAddPointToLine( line_out, &sFirstPoint ); + msAddPointToLine(line_out, &sFirstPoint); } - return(MS_SUCCESS); + return (MS_SUCCESS); } /************************************************************************/ /* msProjectShape() */ /************************************************************************/ -int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape) -{ - int ret; - reprojectionObj* reprojector = msProjectCreateReprojector(in, out); - if( !reprojector ) - return MS_FAILURE; - ret = msProjectShapeEx(reprojector, shape); - msProjectDestroyReprojector(reprojector); - return ret; +int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape) { + int ret; + reprojectionObj *reprojector = msProjectCreateReprojector(in, out); + if (!reprojector) + return MS_FAILURE; + ret = msProjectShapeEx(reprojector, shape); + msProjectDestroyReprojector(reprojector); + return ret; } /************************************************************************/ /* msProjectShapeEx() */ /************************************************************************/ -int msProjectShapeEx(reprojectionObj* reprojector, shapeObj *shape) -{ +int msProjectShapeEx(reprojectionObj *reprojector, shapeObj *shape) { int i; #ifdef USE_PROJ_FASTPATHS int j; #define p_x shape->line[i].point[j].x #define p_y shape->line[i].point[j].y - if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { - for( i = shape->numlines-1; i >= 0; i-- ) { - for( j = shape->line[i].numpoints-1; j >= 0; j-- ) { + if (in->wellknownprojection == wkp_lonlat && + out->wellknownprojection == wkp_gmerc) { + for (i = shape->numlines - 1; i >= 0; i--) { + for (j = shape->line[i].numpoints - 1; j >= 0; j--) { p_x *= MAXEXTENTby180; p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; p_y *= MAXEXTENTby180; - if (p_x > MAXEXTENT) p_x = MAXEXTENT; - else if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; - if (p_y > MAXEXTENT) p_y = MAXEXTENT; - else if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; + if (p_x > MAXEXTENT) + p_x = MAXEXTENT; + else if (p_x < -MAXEXTENT) + p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) + p_y = MAXEXTENT; + else if (p_y < -MAXEXTENT) + p_y = -MAXEXTENT; } } - msComputeBounds( shape ); /* fixes bug 1586 */ + msComputeBounds(shape); /* fixes bug 1586 */ return MS_SUCCESS; } - if(in->wellknownprojection == wkp_gmerc && out->wellknownprojection == wkp_lonlat) { - for( i = shape->numlines-1; i >= 0; i-- ) { - for( j = shape->line[i].numpoints-1; j >= 0; j-- ) { - if (p_x > MAXEXTENT) p_x = MAXEXTENT; - else if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; - if (p_y > MAXEXTENT) p_y = MAXEXTENT; - else if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; + if (in->wellknownprojection == wkp_gmerc && + out->wellknownprojection == wkp_lonlat) { + for (i = shape->numlines - 1; i >= 0; i--) { + for (j = shape->line[i].numpoints - 1; j >= 0; j--) { + if (p_x > MAXEXTENT) + p_x = MAXEXTENT; + else if (p_x < -MAXEXTENT) + p_x = -MAXEXTENT; + if (p_y > MAXEXTENT) + p_y = MAXEXTENT; + else if (p_y < -MAXEXTENT) + p_y = -MAXEXTENT; p_x = (p_x / MAXEXTENT) * 180; p_y = (p_y / MAXEXTENT) * 180; p_y = MS_RAD_TO_DEG * (2 * atan(exp(p_y * MS_DEG_TO_RAD)) - MS_PI2); } } - msComputeBounds( shape ); /* fixes bug 1586 */ + msComputeBounds(shape); /* fixes bug 1586 */ return MS_SUCCESS; } #undef p_x @@ -1748,28 +1669,27 @@ int msProjectShapeEx(reprojectionObj* reprojector, shapeObj *shape) #endif if (shape->numlines == 0) { - // don't attempt to project any NULL geometries - // but if we want to return the record's attributes we won't free the shape - // and throw an error - shape->type = MS_SHAPE_NULL; - return MS_SUCCESS; + // don't attempt to project any NULL geometries + // but if we want to return the record's attributes we won't free the shape + // and throw an error + shape->type = MS_SHAPE_NULL; + return MS_SUCCESS; } else { - for( i = shape->numlines-1; i >= 0; i-- ) { - if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) { - if( msProjectShapeLine( reprojector, shape, i ) == MS_FAILURE ) - msShapeDeleteLine( shape, i ); - } else if( msProjectLineEx(reprojector, shape->line+i ) == MS_FAILURE ) { - msShapeDeleteLine( shape, i ); + for (i = shape->numlines - 1; i >= 0; i--) { + if (shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON) { + if (msProjectShapeLine(reprojector, shape, i) == MS_FAILURE) + msShapeDeleteLine(shape, i); + } else if (msProjectLineEx(reprojector, shape->line + i) == MS_FAILURE) { + msShapeDeleteLine(shape, i); } } - if ( shape->numlines == 0 ) { - msFreeShape(shape); - return MS_FAILURE; - } - else { - msComputeBounds(shape); /* fixes bug 1586 */ - return(MS_SUCCESS); + if (shape->numlines == 0) { + msFreeShape(shape); + return MS_FAILURE; + } else { + msComputeBounds(shape); /* fixes bug 1586 */ + return (MS_SUCCESS); } } } @@ -1777,15 +1697,14 @@ int msProjectShapeEx(reprojectionObj* reprojector, shapeObj *shape) /************************************************************************/ /* msProjectLine() */ /************************************************************************/ -int msProjectLine(projectionObj *in, projectionObj *out, lineObj *line) -{ - int ret; - reprojectionObj* reprojector = msProjectCreateReprojector(in, out); - if( !reprojector ) - return MS_FAILURE; - ret = msProjectLineEx(reprojector, line); - msProjectDestroyReprojector(reprojector); - return ret; +int msProjectLine(projectionObj *in, projectionObj *out, lineObj *line) { + int ret; + reprojectionObj *reprojector = msProjectCreateReprojector(in, out); + if (!reprojector) + return MS_FAILURE; + ret = msProjectLineEx(reprojector, line); + msProjectDestroyReprojector(reprojector); + return ret; } /************************************************************************/ @@ -1796,19 +1715,18 @@ int msProjectLine(projectionObj *in, projectionObj *out, lineObj *line) /* lots of logic to handle horizon crossing. */ /************************************************************************/ -int msProjectLineEx(reprojectionObj* reprojector, lineObj *line) -{ +int msProjectLineEx(reprojectionObj *reprojector, lineObj *line) { int be_careful = reprojector->out->proj != NULL && - msProjIsGeographicCRS(reprojector->out) - && !msProjIsGeographicCRS(reprojector->in); + msProjIsGeographicCRS(reprojector->out) && + !msProjIsGeographicCRS(reprojector->in); - if( be_careful ) { - pointObj startPoint, thisPoint; /* locations in projected space */ + if (be_careful) { + pointObj startPoint, thisPoint; /* locations in projected space */ startPoint = line->point[0]; - for(int i=0; inumpoints; i++) { - double dist; + for (int i = 0; i < line->numpoints; i++) { + double dist; thisPoint = line->point[i]; @@ -1817,29 +1735,28 @@ int msProjectLineEx(reprojectionObj* reprojector, lineObj *line) ** this dateline wrapping logic. */ msProjectPointEx(reprojector, &(line->point[i])); - if( i > 0 ) { + if (i > 0) { dist = line->point[i].x - line->point[0].x; - if( fabs(dist) > 180.0 ) { - if( msTestNeedWrap( thisPoint, startPoint, - line->point[0], reprojector ) ) { - if( dist > 0.0 ) { + if (fabs(dist) > 180.0) { + if (msTestNeedWrap(thisPoint, startPoint, line->point[0], + reprojector)) { + if (dist > 0.0) { line->point[i].x -= 360.0; - } else if( dist < 0.0 ) { + } else if (dist < 0.0) { line->point[i].x += 360.0; } } } - } } } else { - for(int i=0; inumpoints; i++) { - if( msProjectPointEx(reprojector, &(line->point[i])) == MS_FAILURE ) + for (int i = 0; i < line->numpoints; i++) { + if (msProjectPointEx(reprojector, &(line->point[i])) == MS_FAILURE) return MS_FAILURE; } } - return(MS_SUCCESS); + return (MS_SUCCESS); } /************************************************************************/ @@ -1848,13 +1765,11 @@ int msProjectLineEx(reprojectionObj* reprojector, lineObj *line) #define NUMBER_OF_SAMPLE_POINTS 100 -static -int msProjectRectGrid(reprojectionObj* reprojector, rectObj *rect) -{ +static int msProjectRectGrid(reprojectionObj *reprojector, rectObj *rect) { pointObj prj_point; rectObj prj_rect; - int failure=0; - int ix, iy; + int failure = 0; + int ix, iy; double dx, dy; double x, y; @@ -1864,8 +1779,8 @@ int msProjectRectGrid(reprojectionObj* reprojector, rectObj *rect) prj_rect.maxx = -DBL_MAX; prj_rect.maxy = -DBL_MAX; - dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS; - dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS; + dx = (rect->maxx - rect->minx) / NUMBER_OF_SAMPLE_POINTS; + dy = (rect->maxy - rect->miny) / NUMBER_OF_SAMPLE_POINTS; /* first ensure the top left corner is processed, even if the rect turns out to be degenerate. */ @@ -1875,35 +1790,35 @@ int msProjectRectGrid(reprojectionObj* reprojector, rectObj *rect) prj_point.z = 0.0; prj_point.m = 0.0; - msProjectGrowRect(reprojector,&prj_rect,&prj_point, - &failure); + msProjectGrowRect(reprojector, &prj_rect, &prj_point, &failure); failure = 0; - for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) { + for (ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++) { x = rect->minx + ix * dx; - for(iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) { + for (iy = 0; iy <= NUMBER_OF_SAMPLE_POINTS; iy++) { y = rect->miny + iy * dy; prj_point.x = x; prj_point.y = y; - msProjectGrowRect(reprojector,&prj_rect,&prj_point, - &failure); + msProjectGrowRect(reprojector, &prj_rect, &prj_point, &failure); } } - if( prj_rect.minx > prj_rect.maxx ) { + if (prj_rect.minx > prj_rect.maxx) { rect->minx = 0; rect->maxx = 0; rect->miny = 0; rect->maxy = 0; - msSetError(MS_PROJERR, "All points failed to reproject.", "msProjectRect()"); + msSetError(MS_PROJERR, "All points failed to reproject.", + "msProjectRect()"); return MS_FAILURE; } - if( failure ) { - msDebug( "msProjectRect(): some points failed to reproject, doing internal sampling.\n" ); + if (failure) { + msDebug("msProjectRect(): some points failed to reproject, doing internal " + "sampling.\n"); } rect->minx = prj_rect.minx; @@ -1911,27 +1826,26 @@ int msProjectRectGrid(reprojectionObj* reprojector, rectObj *rect) rect->maxx = prj_rect.maxx; rect->maxy = prj_rect.maxy; - return(MS_SUCCESS); + return (MS_SUCCESS); } /************************************************************************/ /* msProjectRectAsPolygon() */ /************************************************************************/ -int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) -{ +int msProjectRectAsPolygon(reprojectionObj *reprojector, rectObj *rect) { shapeObj polygonObj; - lineObj ring; + lineObj ring; /* pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4]; */ pointObj *ringPoints; - int ix, iy, ixy; + int ix, iy, ixy; double dx, dy; /* If projecting from longlat to projected */ /* This hack was introduced for WFS 2.0 compliance testing, but is far */ /* from being perfect */ - if( reprojector->out && !msProjIsGeographicCRS(reprojector->out) && + if (reprojector->out && !msProjIsGeographicCRS(reprojector->out) && reprojector->in && msProjIsGeographicCRS(reprojector->in) && fabs(rect->minx - -180.0) < 1e-5 && fabs(rect->miny - -90.0) < 1e-5 && fabs(rect->maxx - 180.0) < 1e-5 && fabs(rect->maxy - 90.0) < 1e-5) { @@ -1942,19 +1856,17 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) /* Detect if we are reprojecting from EPSG:4326 to EPSG:3857 */ /* and if so use more plausible bounds to avoid issues with computed */ /* resolution for WCS */ - if (fabs(pointTest.x - -20037508.3427892) < 1e-5 && fabs(pointTest.y - 19971868.8804086) ) - { - rect->minx = -20037508.3427892; - rect->miny = -20037508.3427892; - rect->maxx = 20037508.3427892; - rect->maxy = 20037508.3427892; - } - else - { - rect->minx = -1e15; - rect->miny = -1e15; - rect->maxx = 1e15; - rect->maxy = 1e15; + if (fabs(pointTest.x - -20037508.3427892) < 1e-5 && + fabs(pointTest.y - 19971868.8804086)) { + rect->minx = -20037508.3427892; + rect->miny = -20037508.3427892; + rect->maxx = 20037508.3427892; + rect->maxy = 20037508.3427892; + } else { + rect->minx = -1e15; + rect->miny = -1e15; + rect->maxx = 1e15; + rect->maxy = 1e15; } return MS_SUCCESS; } @@ -1963,77 +1875,82 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) /* Build polygon as steps around the source rectangle */ /* and possibly its diagonal. */ /* -------------------------------------------------------------------- */ - dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS; - dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS; + dx = (rect->maxx - rect->minx) / NUMBER_OF_SAMPLE_POINTS; + dy = (rect->maxy - rect->miny) / NUMBER_OF_SAMPLE_POINTS; - if(dx==0 && dy==0) { + if (dx == 0 && dy == 0) { pointObj foo; - msDebug( "msProjectRect(): Warning: degenerate rect {%f,%f,%f,%f}\n",rect->minx,rect->miny,rect->minx,rect->miny ); + msDebug("msProjectRect(): Warning: degenerate rect {%f,%f,%f,%f}\n", + rect->minx, rect->miny, rect->minx, rect->miny); foo.x = rect->minx; foo.y = rect->miny; - msProjectPointEx(reprojector,&foo); - rect->minx=rect->maxx=foo.x; - rect->miny=rect->maxy=foo.y; + msProjectPointEx(reprojector, &foo); + rect->minx = rect->maxx = foo.x; + rect->miny = rect->maxy = foo.y; return MS_SUCCESS; } - - /* If there is more than two sample points we will also get samples from the diagonal line */ - ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*5+3); + + /* If there is more than two sample points we will also get samples from the + * diagonal line */ + ringPoints = + (pointObj *)calloc(sizeof(pointObj), NUMBER_OF_SAMPLE_POINTS * 5 + 3); ring.point = ringPoints; ring.numpoints = 0; - msInitShape( &polygonObj ); + msInitShape(&polygonObj); polygonObj.type = MS_SHAPE_POLYGON; /* sample along top */ - if(dx != 0) { - for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) { + if (dx != 0) { + for (ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->miny; } } /* sample along right side */ - if(dy != 0) { - for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) { + if (dy != 0) { + for (iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++) { ringPoints[ring.numpoints].x = rect->maxx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } /* sample along bottom */ - if(dx != 0) { - for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- ) { + if (dx != 0) { + for (ix = NUMBER_OF_SAMPLE_POINTS - 1; ix >= 0; ix--) { ringPoints[ring.numpoints].x = rect->minx + ix * dx; ringPoints[ring.numpoints++].y = rect->maxy; } } /* sample along left side */ - if(dy != 0) { - for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- ) { + if (dy != 0) { + for (iy = NUMBER_OF_SAMPLE_POINTS - 1; iy >= 0; iy--) { ringPoints[ring.numpoints].x = rect->minx; ringPoints[ring.numpoints++].y = rect->miny + iy * dy; } } /* sample along diagonal line */ - /* This is done to handle cases where reprojection from world covering projection to one */ - /* which isn't could cause min and max values of the projected rectangle to be invalid */ - if(dy != 0 && dx != 0) { + /* This is done to handle cases where reprojection from world covering + * projection to one */ + /* which isn't could cause min and max values of the projected rectangle to be + * invalid */ + if (dy != 0 && dx != 0) { /* No need to compute corners as they've already been computed */ - for(ixy = NUMBER_OF_SAMPLE_POINTS-2; ixy >= 1; ixy-- ) { + for (ixy = NUMBER_OF_SAMPLE_POINTS - 2; ixy >= 1; ixy--) { ringPoints[ring.numpoints].x = rect->minx + ixy * dx; ringPoints[ring.numpoints++].y = rect->miny + ixy * dy; } } - msAddLineDirectly( &polygonObj, &ring ); + msAddLineDirectly(&polygonObj, &ring); #ifdef notdef - FILE *wkt = fopen("/tmp/www-before.wkt","w"); + FILE *wkt = fopen("/tmp/www-before.wkt", "w"); char *tmp = msShapeToWKT(&polygonObj); - fprintf(wkt,"%s\n", tmp); + fprintf(wkt, "%s\n", tmp); free(tmp); fclose(wkt); #endif @@ -2041,18 +1958,18 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) /* -------------------------------------------------------------------- */ /* Attempt to reproject. */ /* -------------------------------------------------------------------- */ - msProjectShapeLine( reprojector, &polygonObj, 0 ); + msProjectShapeLine(reprojector, &polygonObj, 0); /* If no points reprojected, try a grid sampling */ - if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 ) { - msFreeShape( &polygonObj ); - return msProjectRectGrid( reprojector, rect ); + if (polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0) { + msFreeShape(&polygonObj); + return msProjectRectGrid(reprojector, rect); } #ifdef notdef - wkt = fopen("/tmp/www-after.wkt","w"); + wkt = fopen("/tmp/www-after.wkt", "w"); tmp = msShapeToWKT(&polygonObj); - fprintf(wkt,"%s\n", tmp); + fprintf(wkt, "%s\n", tmp); free(tmp); fclose(wkt); #endif @@ -2063,16 +1980,16 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) rect->minx = rect->maxx = polygonObj.line[0].point[0].x; rect->miny = rect->maxy = polygonObj.line[0].point[0].y; - for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ ) { - pointObj *pnt = polygonObj.line[0].point + ix; + for (ix = 1; ix < polygonObj.line[0].numpoints; ix++) { + pointObj *pnt = polygonObj.line[0].point + ix; - rect->minx = MS_MIN(rect->minx,pnt->x); - rect->maxx = MS_MAX(rect->maxx,pnt->x); - rect->miny = MS_MIN(rect->miny,pnt->y); - rect->maxy = MS_MAX(rect->maxy,pnt->y); + rect->minx = MS_MIN(rect->minx, pnt->x); + rect->maxx = MS_MAX(rect->maxx, pnt->x); + rect->miny = MS_MIN(rect->miny, pnt->y); + rect->maxy = MS_MAX(rect->maxy, pnt->y); } - msFreeShape( &polygonObj ); + msFreeShape(&polygonObj); /* -------------------------------------------------------------------- */ /* Special case to handle reprojection from "more than the */ @@ -2080,10 +1997,10 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) /* region greater than 360 degrees wide due to various wrapping */ /* logic. */ /* -------------------------------------------------------------------- */ - if( reprojector->out && msProjIsGeographicCRS(reprojector->out) && - reprojector->in && !msProjIsGeographicCRS(reprojector->in) - && rect->maxx - rect->minx > 360.0 && - !reprojector->out->gt.need_geotransform ) { + if (reprojector->out && msProjIsGeographicCRS(reprojector->out) && + reprojector->in && !msProjIsGeographicCRS(reprojector->in) && + rect->maxx - rect->minx > 360.0 && + !reprojector->out->gt.need_geotransform) { rect->maxx = 180; rect->minx = -180; } @@ -2095,264 +2012,239 @@ int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect) /* msProjectHasLonWrap() */ /************************************************************************/ -int msProjectHasLonWrap(projectionObj *in, double* pdfLonWrap) -{ - int i; - if( pdfLonWrap ) - *pdfLonWrap = 0; +int msProjectHasLonWrap(projectionObj *in, double *pdfLonWrap) { + int i; + if (pdfLonWrap) + *pdfLonWrap = 0; - if( !msProjIsGeographicCRS(in) ) - return MS_FALSE; + if (!msProjIsGeographicCRS(in)) + return MS_FALSE; - for( i = 0; i < in->numargs; i++ ) - { - if( strncmp(in->args[i], "lon_wrap=", - strlen("lon_wrap=")) == 0 ) - { - if( pdfLonWrap ) - *pdfLonWrap = atof(in->args[i] + strlen("lon_wrap=")); - return MS_TRUE; - } + for (i = 0; i < in->numargs; i++) { + if (strncmp(in->args[i], "lon_wrap=", strlen("lon_wrap=")) == 0) { + if (pdfLonWrap) + *pdfLonWrap = atof(in->args[i] + strlen("lon_wrap=")); + return MS_TRUE; } - return MS_FALSE; + } + return MS_FALSE; } /************************************************************************/ /* msProjectRect() */ /************************************************************************/ -int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect) -{ +int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect) { char *over = "+over"; int ret; int bFreeInOver = MS_FALSE; int bFreeOutOver = MS_FALSE; - projectionObj in_over,out_over,*inp,*outp; + projectionObj in_over, out_over, *inp, *outp; double dfLonWrap = 0.0; - reprojectionObj* reprojector = NULL; + reprojectionObj *reprojector = NULL; /* Detect projecting from polar stereographic to longlat */ - if( in && !in->gt.need_geotransform && - out && !out->gt.need_geotransform && - !msProjIsGeographicCRS(in) && msProjIsGeographicCRS(out) ) - { - reprojector = msProjectCreateReprojector(in, out); - for( int sign = 1; sign >= -1; sign -= 2 ) - { - pointObj p; - p.x = 0.0; - p.y = 0.0; - if( reprojector && - msProjectPointEx(reprojector, &p) == MS_SUCCESS && - fabs(p.y - sign * 90) < 1e-8 ) - { - /* Is the pole in the rectangle ? */ - if( 0 >= rect->minx && 0 >= rect->miny && - 0 <= rect->maxx && 0 <= rect->maxy ) - { - if( msProjectRectAsPolygon(reprojector, rect ) == MS_SUCCESS ) - { - rect->minx = -180.0; - rect->maxx = 180.0; - rect->maxy = sign * 90.0; - msProjectDestroyReprojector(reprojector); - return MS_SUCCESS; - } - } - /* Are we sure the dateline is not enclosed ? */ - else if( rect->maxy < 0 || rect->maxx < 0 || rect->minx > 0 ) - { - ret = msProjectRectAsPolygon(reprojector, rect ); - msProjectDestroyReprojector(reprojector); - return ret; - } + if (in && !in->gt.need_geotransform && out && !out->gt.need_geotransform && + !msProjIsGeographicCRS(in) && msProjIsGeographicCRS(out)) { + reprojector = msProjectCreateReprojector(in, out); + for (int sign = 1; sign >= -1; sign -= 2) { + pointObj p; + p.x = 0.0; + p.y = 0.0; + if (reprojector && msProjectPointEx(reprojector, &p) == MS_SUCCESS && + fabs(p.y - sign * 90) < 1e-8) { + /* Is the pole in the rectangle ? */ + if (0 >= rect->minx && 0 >= rect->miny && 0 <= rect->maxx && + 0 <= rect->maxy) { + if (msProjectRectAsPolygon(reprojector, rect) == MS_SUCCESS) { + rect->minx = -180.0; + rect->maxx = 180.0; + rect->maxy = sign * 90.0; + msProjectDestroyReprojector(reprojector); + return MS_SUCCESS; } + } + /* Are we sure the dateline is not enclosed ? */ + else if (rect->maxy < 0 || rect->maxx < 0 || rect->minx > 0) { + ret = msProjectRectAsPolygon(reprojector, rect); + msProjectDestroyReprojector(reprojector); + return ret; + } } + } } /* Detect projecting from polar stereographic to another projected system */ - else if( in && !in->gt.need_geotransform && - out && !out->gt.need_geotransform && - !msProjIsGeographicCRS(in) && !msProjIsGeographicCRS(out) ) - { - reprojectionObj* reprojectorToLongLat = msProjectCreateReprojector(in, NULL); - for( int sign = 1; sign >= -1; sign -= 2 ) - { - pointObj p; - p.x = 0.0; - p.y = 0.0; - if( reprojectorToLongLat && - msProjectPointEx(reprojectorToLongLat, &p) == MS_SUCCESS && - fabs(p.y - 90) < 1e-8 ) - { - reprojector = msProjectCreateReprojector(in, out); - /* Is the pole in the rectangle ? */ - if( 0 >= rect->minx && 0 >= rect->miny && - 0 <= rect->maxx && 0 <= rect->maxy ) - { - if( msProjectRectAsPolygon(reprojector, rect ) == MS_SUCCESS ) - { - msProjectDestroyReprojector(reprojector); - msProjectDestroyReprojector(reprojectorToLongLat); - return MS_SUCCESS; - } - } - /* Are we sure the dateline is not enclosed ? */ - else if( rect->maxy < 0 || rect->maxx < 0 || rect->minx > 0 ) - { - ret = msProjectRectAsPolygon(reprojector, rect ); - msProjectDestroyReprojector(reprojector); - msProjectDestroyReprojector(reprojectorToLongLat); - return ret; - } + else if (in && !in->gt.need_geotransform && out && + !out->gt.need_geotransform && !msProjIsGeographicCRS(in) && + !msProjIsGeographicCRS(out)) { + reprojectionObj *reprojectorToLongLat = + msProjectCreateReprojector(in, NULL); + for (int sign = 1; sign >= -1; sign -= 2) { + pointObj p; + p.x = 0.0; + p.y = 0.0; + if (reprojectorToLongLat && + msProjectPointEx(reprojectorToLongLat, &p) == MS_SUCCESS && + fabs(p.y - 90) < 1e-8) { + reprojector = msProjectCreateReprojector(in, out); + /* Is the pole in the rectangle ? */ + if (0 >= rect->minx && 0 >= rect->miny && 0 <= rect->maxx && + 0 <= rect->maxy) { + if (msProjectRectAsPolygon(reprojector, rect) == MS_SUCCESS) { + msProjectDestroyReprojector(reprojector); + msProjectDestroyReprojector(reprojectorToLongLat); + return MS_SUCCESS; } + } + /* Are we sure the dateline is not enclosed ? */ + else if (rect->maxy < 0 || rect->maxx < 0 || rect->minx > 0) { + ret = msProjectRectAsPolygon(reprojector, rect); + msProjectDestroyReprojector(reprojector); + msProjectDestroyReprojector(reprojectorToLongLat); + return ret; + } } - msProjectDestroyReprojector(reprojectorToLongLat); + } + msProjectDestroyReprojector(reprojectorToLongLat); } - - if(in && msProjectHasLonWrap(in, &dfLonWrap) && dfLonWrap == 180.0) { + if (in && msProjectHasLonWrap(in, &dfLonWrap) && dfLonWrap == 180.0) { inp = in; outp = out; - if( rect->maxx > 180.0 ) { + if (rect->maxx > 180.0) { rect->minx = -180.0; rect->maxx = 180.0; } } - /* - * Issue #4892: When projecting a rectangle we do not want proj to wrap resulting - * coordinates around the dateline, as in practice a requested bounding box of - * -22.000.000, -YYY, 22.000.000, YYY should be projected as - * -190,-YYY,190,YYY rather than 170,-YYY,-170,YYY as would happen when wrapping (and - * vice-versa when projecting from lonlat to metric). - * To enforce this, we clone the input projections and add the "+over" proj - * parameter in order to disable dateline wrapping. - */ + /* + * Issue #4892: When projecting a rectangle we do not want proj to wrap + * resulting coordinates around the dateline, as in practice a requested + * bounding box of -22.000.000, -YYY, 22.000.000, YYY should be projected as + * -190,-YYY,190,YYY rather than 170,-YYY,-170,YYY as would happen when + * wrapping (and vice-versa when projecting from lonlat to metric). To enforce + * this, we clone the input projections and add the "+over" proj parameter in + * order to disable dateline wrapping. + */ else { int apply_over = MS_TRUE; #if PROJ_VERSION_MAJOR >= 6 && PROJ_VERSION_MAJOR < 9 - // Workaround PROJ [6,9[ bug (fixed per https://github.com/OSGeo/PROJ/pull/3055) - // that prevents datum shifts from being applied when +over is added to +init=epsg:XXXX - // This is far from being bullet proof but it should work for most common use cases - if(in && in->proj) - { - if( in->numargs == 1 && EQUAL(in->args[0], "init=epsg:4326") && - rect->minx >= -180 && rect->maxx <= 180 ) - { - apply_over = MS_FALSE; - } - else if( in->numargs == 1 && EQUAL(in->args[0], "init=epsg:3857") && - rect->minx >= -20037508.3427892 && rect->maxx <= 20037508.3427892 ) - { - apply_over = MS_FALSE; - } + // Workaround PROJ [6,9[ bug (fixed per + // https://github.com/OSGeo/PROJ/pull/3055) that prevents datum shifts from + // being applied when +over is added to +init=epsg:XXXX This is far from + // being bullet proof but it should work for most common use cases + if (in && in->proj) { + if (in->numargs == 1 && EQUAL(in->args[0], "init=epsg:4326") && + rect->minx >= -180 && rect->maxx <= 180) { + apply_over = MS_FALSE; + } else if (in->numargs == 1 && EQUAL(in->args[0], "init=epsg:3857") && + rect->minx >= -20037508.3427892 && + rect->maxx <= 20037508.3427892) { + apply_over = MS_FALSE; + } } #endif - if(out && apply_over && out->numargs > 0 && - (strncmp(out->args[0], "init=", 5) == 0 || strncmp(out->args[0], "proj=", 5) == 0)) { + if (out && apply_over && out->numargs > 0 && + (strncmp(out->args[0], "init=", 5) == 0 || + strncmp(out->args[0], "proj=", 5) == 0)) { bFreeOutOver = MS_TRUE; msInitProjection(&out_over); - msCopyProjectionExtended(&out_over,out,&over,1); + msCopyProjectionExtended(&out_over, out, &over, 1); outp = &out_over; - if( reprojector ) { - msProjectDestroyReprojector(reprojector); - reprojector = NULL; + if (reprojector) { + msProjectDestroyReprojector(reprojector); + reprojector = NULL; } } else { outp = out; } - if(in && apply_over && in->numargs > 0 && - (strncmp(in->args[0], "init=", 5) == 0 || strncmp(in->args[0], "proj=", 5) == 0)) { + if (in && apply_over && in->numargs > 0 && + (strncmp(in->args[0], "init=", 5) == 0 || + strncmp(in->args[0], "proj=", 5) == 0)) { bFreeInOver = MS_TRUE; msInitProjection(&in_over); - msCopyProjectionExtended(&in_over,in,&over,1); + msCopyProjectionExtended(&in_over, in, &over, 1); inp = &in_over; /* coverity[dead_error_begin] */ - if( reprojector ) { - msProjectDestroyReprojector(reprojector); - reprojector = NULL; + if (reprojector) { + msProjectDestroyReprojector(reprojector); + reprojector = NULL; } } else { inp = in; } } - if( reprojector == NULL ) - { - reprojector = msProjectCreateReprojector(inp, outp); + if (reprojector == NULL) { + reprojector = msProjectCreateReprojector(inp, outp); } - ret = reprojector ? msProjectRectAsPolygon(reprojector, rect ) : MS_FAILURE; + ret = reprojector ? msProjectRectAsPolygon(reprojector, rect) : MS_FAILURE; msProjectDestroyReprojector(reprojector); - if(bFreeInOver) + if (bFreeInOver) msFreeProjection(&in_over); - if(bFreeOutOver) + if (bFreeOutOver) msFreeProjection(&out_over); return ret; } #if PROJ_VERSION_MAJOR < 6 -static int msProjectSortString(const void* firstelt, const void* secondelt) -{ - char* firststr = *(char**)firstelt; - char* secondstr = *(char**)secondelt; - return strcmp(firststr, secondstr); +static int msProjectSortString(const void *firstelt, const void *secondelt) { + char *firststr = *(char **)firstelt; + char *secondstr = *(char **)secondelt; + return strcmp(firststr, secondstr); } /************************************************************************/ /* msGetProjectNormalized() */ /************************************************************************/ -static projectionObj* msGetProjectNormalized( const projectionObj* p ) -{ +static projectionObj *msGetProjectNormalized(const projectionObj *p) { int i; #if PROJ_VERSION_MAJOR >= 6 - const char* pszNewProj4Def; + const char *pszNewProj4Def; #else - char* pszNewProj4Def; + char *pszNewProj4Def; #endif - projectionObj* pnew; + projectionObj *pnew; - pnew = (projectionObj*)msSmallMalloc(sizeof(projectionObj)); + pnew = (projectionObj *)msSmallMalloc(sizeof(projectionObj)); msInitProjection(pnew); - msCopyProjection(pnew, (projectionObj*)p); + msCopyProjection(pnew, (projectionObj *)p); - if(p->proj == NULL ) - return pnew; + if (p->proj == NULL) + return pnew; - /* Normalize definition so that msProjectDiffers() works better */ + /* Normalize definition so that msProjectDiffers() works better */ #if PROJ_VERSION_MAJOR >= 6 - pszNewProj4Def = proj_as_proj_string(p->proj_ctx->proj_ctx, p->proj, PJ_PROJ_4, NULL); + pszNewProj4Def = + proj_as_proj_string(p->proj_ctx->proj_ctx, p->proj, PJ_PROJ_4, NULL); #else - pszNewProj4Def = pj_get_def( p->proj, 0 ); + pszNewProj4Def = pj_get_def(p->proj, 0); #endif msFreeCharArray(pnew->args, pnew->numargs); - pnew->args = msStringSplit(pszNewProj4Def,'+', &pnew->numargs); - for(i = 0; i < pnew->numargs; i++) - { - /* Remove trailing space */ - if( strlen(pnew->args[i]) > 0 && pnew->args[i][strlen(pnew->args[i])-1] == ' ' ) - pnew->args[i][strlen(pnew->args[i])-1] = '\0'; - /* Remove spurious no_defs or init= */ - if( strcmp(pnew->args[i], "no_defs") == 0 || - strncmp(pnew->args[i], "init=", 5) == 0 ) - { - if( i < pnew->numargs - 1 ) - { - msFree(pnew->args[i]); - memmove(pnew->args + i, pnew->args + i + 1, - sizeof(char*) * (pnew->numargs - 1 -i )); - } - else - { - msFree(pnew->args[i]); - } - pnew->numargs --; - i --; - continue; + pnew->args = msStringSplit(pszNewProj4Def, '+', &pnew->numargs); + for (i = 0; i < pnew->numargs; i++) { + /* Remove trailing space */ + if (strlen(pnew->args[i]) > 0 && + pnew->args[i][strlen(pnew->args[i]) - 1] == ' ') + pnew->args[i][strlen(pnew->args[i]) - 1] = '\0'; + /* Remove spurious no_defs or init= */ + if (strcmp(pnew->args[i], "no_defs") == 0 || + strncmp(pnew->args[i], "init=", 5) == 0) { + if (i < pnew->numargs - 1) { + msFree(pnew->args[i]); + memmove(pnew->args + i, pnew->args + i + 1, + sizeof(char *) * (pnew->numargs - 1 - i)); + } else { + msFree(pnew->args[i]); } + pnew->numargs--; + i--; + continue; + } } /* Sort the strings so they can be compared */ - qsort(pnew->args, pnew->numargs, sizeof(char*), msProjectSortString); + qsort(pnew->args, pnew->numargs, sizeof(char *), msProjectSortString); /*{ fprintf(stderr, "'%s' =\n", pszNewProj4Def); for(i = 0; i < p->numargs; i++) @@ -2382,55 +2274,53 @@ static projectionObj* msGetProjectNormalized( const projectionObj* p ) ** has no arguments, since reprojection won't work anyways. */ -static int msProjectionsDifferInternal( projectionObj *proj1, projectionObj *proj2 ) +static int msProjectionsDifferInternal(projectionObj *proj1, + projectionObj *proj2) { - int i; + int i; - if( proj1->numargs == 0 || proj2->numargs == 0 ) + if (proj1->numargs == 0 || proj2->numargs == 0) return MS_FALSE; - if( proj1->numargs != proj2->numargs ) + if (proj1->numargs != proj2->numargs) return MS_TRUE; /* This test should be more rigerous. */ - if( proj1->gt.need_geotransform - || proj2->gt.need_geotransform ) + if (proj1->gt.need_geotransform || proj2->gt.need_geotransform) return MS_TRUE; - for( i = 0; i < proj1->numargs; i++ ) { - if( strcmp(proj1->args[i],proj2->args[i]) != 0 ) + for (i = 0; i < proj1->numargs; i++) { + if (strcmp(proj1->args[i], proj2->args[i]) != 0) return MS_TRUE; } return MS_FALSE; } -int msProjectionsDiffer( projectionObj *proj1, projectionObj *proj2 ) -{ - int ret; +int msProjectionsDiffer(projectionObj *proj1, projectionObj *proj2) { + int ret; - ret = msProjectionsDifferInternal(proj1, proj2); + ret = msProjectionsDifferInternal(proj1, proj2); #if PROJ_VERSION_MAJOR < 6 - if( ret && - /* to speed up things, do normalization only if one proj is */ - /* likely of the form init=epsg:XXX and the other proj=XXX datum=YYY... */ - ( (proj1->numargs == 1 && proj2->numargs > 1) || - (proj1->numargs > 1 && proj2->numargs == 1) ) ) - { - projectionObj* p1normalized; - projectionObj* p2normalized; - - p1normalized = msGetProjectNormalized( proj1 ); - p2normalized = msGetProjectNormalized( proj2 ); - ret = msProjectionsDifferInternal(p1normalized, p2normalized); - msFreeProjection(p1normalized); - msFree(p1normalized); - msFreeProjection(p2normalized); - msFree(p2normalized); - } + if (ret && + /* to speed up things, do normalization only if one proj is */ + /* likely of the form init=epsg:XXX and the other proj=XXX datum=YYY... */ + ((proj1->numargs == 1 && proj2->numargs > 1) || + (proj1->numargs > 1 && proj2->numargs == 1))) { + projectionObj *p1normalized; + projectionObj *p2normalized; + + p1normalized = msGetProjectNormalized(proj1); + p2normalized = msGetProjectNormalized(proj2); + ret = msProjectionsDifferInternal(p1normalized, p2normalized); + msFreeProjection(p1normalized); + msFree(p1normalized); + msFreeProjection(p2normalized); + msFree(p2normalized); + } #endif - return ret; + return ret; } /************************************************************************/ @@ -2503,30 +2393,30 @@ reprojected to geographic space. However, it does not: */ -static int msTestNeedWrap( pointObj pt1, pointObj pt2, pointObj pt2_geo, - reprojectionObj* reprojector ) +static int msTestNeedWrap(pointObj pt1, pointObj pt2, pointObj pt2_geo, + reprojectionObj *reprojector) { - pointObj middle; - projectionObj* out = reprojector->out; + pointObj middle; + projectionObj *out = reprojector->out; middle.x = (pt1.x + pt2.x) * 0.5; middle.y = (pt1.y + pt2.y) * 0.5; - if( msProjectPointEx( reprojector, &pt1 ) == MS_FAILURE - || msProjectPointEx( reprojector, &pt2 ) == MS_FAILURE - || msProjectPointEx( reprojector, &middle ) == MS_FAILURE ) + if (msProjectPointEx(reprojector, &pt1) == MS_FAILURE || + msProjectPointEx(reprojector, &pt2) == MS_FAILURE || + msProjectPointEx(reprojector, &middle) == MS_FAILURE) return 0; /* * If the last point was moved, then we are considered due for a * move to. */ - if( out->gt.need_geotransform && out->gt.geotransform[2] == 0 ) { - if( fabs( (pt2_geo.x-pt2.x) * out->gt.geotransform[1] ) > 180.0 ) + if (out->gt.need_geotransform && out->gt.geotransform[2] == 0) { + if (fabs((pt2_geo.x - pt2.x) * out->gt.geotransform[1]) > 180.0) return 1; } else { - if( fabs(pt2_geo.x-pt2.x) > 180.0 ) + if (fabs(pt2_geo.x - pt2.x) > 180.0) return 1; } @@ -2535,8 +2425,8 @@ static int msTestNeedWrap( pointObj pt1, pointObj pt2, pointObj pt2_geo, * to be between the end points. If yes, no wrapping is needed. * Otherwise wrapping is needed. */ - if( (middle.x < pt1.x && middle.x < pt2_geo.x) - || (middle.x > pt1.x && middle.x > pt2_geo.x) ) + if ((middle.x < pt1.x && middle.x < pt2_geo.x) || + (middle.x > pt1.x && middle.x > pt2_geo.x)) return 1; else return 0; @@ -2549,20 +2439,20 @@ static int msTestNeedWrap( pointObj pt1, pointObj pt2, pointObj pt2_geo, #if PROJ_VERSION_MAJOR < 6 static char *last_filename = NULL; -static const char *msProjFinder( const char *filename) +static const char *msProjFinder(const char *filename) { - if( last_filename != NULL ) - free( last_filename ); + if (last_filename != NULL) + free(last_filename); - if( filename == NULL ) + if (filename == NULL) return NULL; - if( ms_proj_data == NULL ) + if (ms_proj_data == NULL) return filename; - last_filename = (char *) malloc(strlen(filename)+strlen(ms_proj_data)+2); - sprintf( last_filename, "%s/%s", ms_proj_data, filename ); + last_filename = (char *)malloc(strlen(filename) + strlen(ms_proj_data) + 2); + sprintf(last_filename, "%s/%s", ms_proj_data, filename); return last_filename; } @@ -2571,12 +2461,11 @@ static const char *msProjFinder( const char *filename) /************************************************************************/ /* msProjDataInitFromEnv() */ /************************************************************************/ -void msProjDataInitFromEnv() -{ +void msProjDataInitFromEnv() { const char *val; - if( (val=CPLGetConfigOption( "PROJ_DATA", NULL )) != NULL || - (val=CPLGetConfigOption( "PROJ_LIB", NULL )) != NULL ) { + if ((val = CPLGetConfigOption("PROJ_DATA", NULL)) != NULL || + (val = CPLGetConfigOption("PROJ_LIB", NULL)) != NULL) { msSetPROJ_DATA(val, NULL); } } @@ -2584,90 +2473,81 @@ void msProjDataInitFromEnv() /************************************************************************/ /* msSetPROJ_DATA() */ /************************************************************************/ -void msSetPROJ_DATA( const char *proj_data, const char *pszRelToPath ) +void msSetPROJ_DATA(const char *proj_data, const char *pszRelToPath) { char *extended_path = NULL; /* Handle relative path if applicable */ - if( proj_data && pszRelToPath - && proj_data[0] != '/' - && proj_data[0] != '\\' - && !(proj_data[0] != '\0' && proj_data[1] == ':') ) { + if (proj_data && pszRelToPath && proj_data[0] != '/' && + proj_data[0] != '\\' && !(proj_data[0] != '\0' && proj_data[1] == ':')) { struct stat stat_buf; - extended_path = (char*) msSmallMalloc(strlen(pszRelToPath) - + strlen(proj_data) + 10); - sprintf( extended_path, "%s/%s", pszRelToPath, proj_data ); + extended_path = + (char *)msSmallMalloc(strlen(pszRelToPath) + strlen(proj_data) + 10); + sprintf(extended_path, "%s/%s", pszRelToPath, proj_data); #ifndef S_ISDIR -# define S_ISDIR(x) ((x) & S_IFDIR) +#define S_ISDIR(x) ((x)&S_IFDIR) #endif - if( stat( extended_path, &stat_buf ) == 0 - && S_ISDIR(stat_buf.st_mode) ) + if (stat(extended_path, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) proj_data = extended_path; } - - msAcquireLock( TLOCK_PROJ ); + msAcquireLock(TLOCK_PROJ); #if PROJ_VERSION_MAJOR >= 6 - if( proj_data == NULL && ms_proj_data == NULL ) - { - /* do nothing */ - } - else if( proj_data != NULL && ms_proj_data != NULL && - strcmp(proj_data, ms_proj_data) == 0 ) - { + if (proj_data == NULL && ms_proj_data == NULL) { /* do nothing */ - } - else - { + } else if (proj_data != NULL && ms_proj_data != NULL && + strcmp(proj_data, ms_proj_data) == 0) { + /* do nothing */ + } else { ms_proj_data_change_counter++; - free( ms_proj_data ); + free(ms_proj_data); ms_proj_data = proj_data ? msStrdup(proj_data) : NULL; } #else { static int finder_installed = 0; - if( finder_installed == 0 && proj_data != NULL) { + if (finder_installed == 0 && proj_data != NULL) { finder_installed = 1; - pj_set_finder( msProjFinder ); + pj_set_finder(msProjFinder); } } - if (proj_data == NULL) pj_set_finder(NULL); + if (proj_data == NULL) + pj_set_finder(NULL); - if( ms_proj_data != NULL ) { - free( ms_proj_data ); + if (ms_proj_data != NULL) { + free(ms_proj_data); ms_proj_data = NULL; } - if( last_filename != NULL ) { - free( last_filename ); + if (last_filename != NULL) { + free(last_filename); last_filename = NULL; } - if( proj_data != NULL ) - ms_proj_data = msStrdup( proj_data ); + if (proj_data != NULL) + ms_proj_data = msStrdup(proj_data); #endif - msReleaseLock( TLOCK_PROJ ); + msReleaseLock(TLOCK_PROJ); #if GDAL_VERSION_MAJOR >= 3 - if( ms_proj_data != NULL ) - { + if (ms_proj_data != NULL) { #ifdef _WIN32 - const char* sep = ";"; + const char *sep = ";"; #else - const char* sep = ":"; + const char *sep = ":"; #endif - char** papszPaths = CSLTokenizeString2(ms_proj_data, sep, 0); - OSRSetPROJSearchPaths((const char* const *)papszPaths); + char **papszPaths = CSLTokenizeString2(ms_proj_data, sep, 0); + OSRSetPROJSearchPaths((const char *const *)papszPaths); CSLDestroy(papszPaths); } #endif - if ( extended_path ) - msFree( extended_path ); + if (extended_path) + msFree(extended_path); } /************************************************************************/ @@ -2676,27 +2556,26 @@ void msSetPROJ_DATA( const char *proj_data, const char *pszRelToPath ) /* Return the projection string. */ /************************************************************************/ -char *msGetProjectionString(projectionObj *proj) -{ - char *pszProjString = NULL; - int nLen = 0; +char *msGetProjectionString(projectionObj *proj) { + char *pszProjString = NULL; + int nLen = 0; if (proj) { /* -------------------------------------------------------------------- */ /* Alloc buffer large enough to hold the whole projection defn */ /* -------------------------------------------------------------------- */ - for (int i=0; inumargs; i++) { + for (int i = 0; i < proj->numargs; i++) { if (proj->args[i]) nLen += (strlen(proj->args[i]) + 2); } - pszProjString = (char*)malloc(sizeof(char) * nLen+1); + pszProjString = (char *)malloc(sizeof(char) * nLen + 1); pszProjString[0] = '\0'; /* -------------------------------------------------------------------- */ /* Plug each arg into the string with a '+' prefix */ /* -------------------------------------------------------------------- */ - for (int i=0; inumargs; i++) { + for (int i = 0; i < proj->numargs; i++) { if (!proj->args[i] || strlen(proj->args[i]) == 0) continue; if (pszProjString[0] == '\0') { @@ -2722,30 +2601,28 @@ char *msGetProjectionString(projectionObj *proj) /* Return MS_TRUE is the proj object has epgsaxis=ne */ /************************************************************************/ -int msIsAxisInvertedProj( projectionObj *proj ) -{ +int msIsAxisInvertedProj(projectionObj *proj) { int i; const char *axis = NULL; - for( i = 0; i < proj->numargs; i++ ) { - if( strstr(proj->args[i],"epsgaxis=") != NULL ) { - axis = strstr(proj->args[i],"=") + 1; + for (i = 0; i < proj->numargs; i++) { + if (strstr(proj->args[i], "epsgaxis=") != NULL) { + axis = strstr(proj->args[i], "=") + 1; break; } } - if( axis == NULL ) + if (axis == NULL) return MS_FALSE; - if( strcasecmp(axis,"en") == 0 ) + if (strcasecmp(axis, "en") == 0) return MS_FALSE; - if( strcasecmp(axis,"ne") != 0 ) { - msDebug( "msIsAxisInvertedProj(): odd +epsgaxis= value: '%s'.", - axis ); + if (strcasecmp(axis, "ne") != 0) { + msDebug("msIsAxisInvertedProj(): odd +epsgaxis= value: '%s'.", axis); return MS_FALSE; } - + return MS_TRUE; } @@ -2756,16 +2633,15 @@ int msIsAxisInvertedProj( projectionObj *proj ) /* orientation if they are not already. */ /************************************************************************/ -void msAxisNormalizePoints( projectionObj *proj, int count, - double *x, double *y ) +void msAxisNormalizePoints(projectionObj *proj, int count, double *x, double *y) { int i; - if( !msIsAxisInvertedProj(proj ) ) - return; + if (!msIsAxisInvertedProj(proj)) + return; /* Switch axes */ - for( i = 0; i < count; i++ ) { + for (i = 0; i < count; i++) { double tmp; tmp = x[i]; @@ -2774,22 +2650,19 @@ void msAxisNormalizePoints( projectionObj *proj, int count, } } - - /************************************************************************/ /* msAxisSwapShape */ /* */ /* Utility function to swap x and y coordiatesn Use for now for */ /* WFS 1.1.x */ /************************************************************************/ -void msAxisSwapShape(shapeObj *shape) -{ +void msAxisSwapShape(shapeObj *shape) { double tmp; - int i,j; + int i, j; if (shape) { - for(i=0; inumlines; i++) { - for( j=0; jline[i].numpoints; j++ ) { + for (i = 0; i < shape->numlines; i++) { + for (j = 0; j < shape->line[i].numpoints; j++) { tmp = shape->line[i].point[j].x; shape->line[i].point[j].x = shape->line[i].point[j].y; shape->line[i].point[j].y = tmp; @@ -2814,12 +2687,12 @@ void msAxisSwapShape(shapeObj *shape) /* preferred epsg orientation of this projectionObj. */ /************************************************************************/ -void msAxisDenormalizePoints( projectionObj *proj, int count, - double *x, double *y ) +void msAxisDenormalizePoints(projectionObj *proj, int count, double *x, + double *y) { /* For how this is essentially identical to normalizing */ - msAxisNormalizePoints( proj, count, x, y ); + msAxisNormalizePoints(proj, count, x, y); } /************************************************************************/ @@ -2828,25 +2701,24 @@ void msAxisDenormalizePoints( projectionObj *proj, int count, /* Returns whether a CRS is a geographic one. */ /************************************************************************/ -int msProjIsGeographicCRS(projectionObj* proj) -{ +int msProjIsGeographicCRS(projectionObj *proj) { #if PROJ_VERSION_MAJOR >= 6 - PJ_TYPE type; - if( !proj->proj ) - return FALSE; - type = proj_get_type(proj->proj); - if( type == PJ_TYPE_GEOGRAPHIC_2D_CRS || type == PJ_TYPE_GEOGRAPHIC_3D_CRS ) - return TRUE; - if( type == PJ_TYPE_BOUND_CRS ) - { - PJ* base_crs = proj_get_source_crs(proj->proj_ctx->proj_ctx, proj->proj); - type = proj_get_type(base_crs); - proj_destroy(base_crs); - return type == PJ_TYPE_GEOGRAPHIC_2D_CRS || type == PJ_TYPE_GEOGRAPHIC_3D_CRS; - } + PJ_TYPE type; + if (!proj->proj) return FALSE; + type = proj_get_type(proj->proj); + if (type == PJ_TYPE_GEOGRAPHIC_2D_CRS || type == PJ_TYPE_GEOGRAPHIC_3D_CRS) + return TRUE; + if (type == PJ_TYPE_BOUND_CRS) { + PJ *base_crs = proj_get_source_crs(proj->proj_ctx->proj_ctx, proj->proj); + type = proj_get_type(base_crs); + proj_destroy(base_crs); + return type == PJ_TYPE_GEOGRAPHIC_2D_CRS || + type == PJ_TYPE_GEOGRAPHIC_3D_CRS; + } + return FALSE; #else - return proj->proj != NULL && pj_is_latlong(proj->proj); + return proj->proj != NULL && pj_is_latlong(proj->proj); #endif } @@ -2857,17 +2729,19 @@ int msProjIsGeographicCRS(projectionObj* proj) /* unit passed as argument. */ /* Please refer to ./src/pj_units.c file in the Proj.4 module. */ /************************************************************************/ -static int ConvertProjUnitStringToMS(const char *pszProjUnit) -{ - if (strcmp(pszProjUnit, "m") ==0) { +static int ConvertProjUnitStringToMS(const char *pszProjUnit) { + if (strcmp(pszProjUnit, "m") == 0) { return MS_METERS; - } else if (strcmp(pszProjUnit, "km") ==0) { + } else if (strcmp(pszProjUnit, "km") == 0) { return MS_KILOMETERS; - } else if (strcmp(pszProjUnit, "mi") ==0 || strcmp(pszProjUnit, "us-mi") ==0) { + } else if (strcmp(pszProjUnit, "mi") == 0 || + strcmp(pszProjUnit, "us-mi") == 0) { return MS_MILES; - } else if (strcmp(pszProjUnit, "in") ==0 || strcmp(pszProjUnit, "us-in") ==0 ) { + } else if (strcmp(pszProjUnit, "in") == 0 || + strcmp(pszProjUnit, "us-in") == 0) { return MS_INCHES; - } else if (strcmp(pszProjUnit, "ft") ==0 || strcmp(pszProjUnit, "us-ft") ==0) { + } else if (strcmp(pszProjUnit, "ft") == 0 || + strcmp(pszProjUnit, "us-ft") == 0) { return MS_FEET; } else if (strcmp(pszProjUnit, "kmi") == 0) { return MS_NAUTICALMILES; @@ -2882,82 +2756,82 @@ static int ConvertProjUnitStringToMS(const char *pszProjUnit) /* Return a mapserver unit corresponding to the projection */ /* passed. Retunr -1 on failure */ /************************************************************************/ -int GetMapserverUnitUsingProj(projectionObj *psProj) -{ +int GetMapserverUnitUsingProj(projectionObj *psProj) { #if PROJ_VERSION_MAJOR >= 6 const char *proj_str; #else char *proj_str; #endif - if( msProjIsGeographicCRS( psProj ) ) + if (msProjIsGeographicCRS(psProj)) return MS_DD; #if PROJ_VERSION_MAJOR >= 6 - proj_str = proj_as_proj_string(psProj->proj_ctx->proj_ctx, psProj->proj, PJ_PROJ_4, NULL); + proj_str = proj_as_proj_string(psProj->proj_ctx->proj_ctx, psProj->proj, + PJ_PROJ_4, NULL); #else - proj_str = pj_get_def( psProj->proj, 0 ); + proj_str = pj_get_def(psProj->proj, 0); #endif - if( proj_str == NULL ) + if (proj_str == NULL) return -1; /* -------------------------------------------------------------------- */ /* Handle case of named units. */ /* -------------------------------------------------------------------- */ - if( strstr(proj_str,"units=") != NULL ) { + if (strstr(proj_str, "units=") != NULL) { char units[32]; char *blank; - strlcpy( units, (strstr(proj_str,"units=")+6), sizeof(units) ); + strlcpy(units, (strstr(proj_str, "units=") + 6), sizeof(units)); #if PROJ_VERSION_MAJOR < 6 - pj_dalloc( proj_str ); + pj_dalloc(proj_str); #endif blank = strchr(units, ' '); - if( blank != NULL ) + if (blank != NULL) *blank = '\0'; - return ConvertProjUnitStringToMS( units ); + return ConvertProjUnitStringToMS(units); } /* -------------------------------------------------------------------- */ /* Handle case of to_meter value. */ /* -------------------------------------------------------------------- */ - if( strstr(proj_str,"to_meter=") != NULL ) { + if (strstr(proj_str, "to_meter=") != NULL) { char to_meter_str[32]; char *blank; double to_meter; - strlcpy(to_meter_str,(strstr(proj_str,"to_meter=")+9), + strlcpy(to_meter_str, (strstr(proj_str, "to_meter=") + 9), sizeof(to_meter_str)); #if PROJ_VERSION_MAJOR < 6 - pj_dalloc( proj_str ); + pj_dalloc(proj_str); #endif blank = strchr(to_meter_str, ' '); - if( blank != NULL ) + if (blank != NULL) *blank = '\0'; to_meter = atof(to_meter_str); - if( fabs(to_meter-1.0) < 0.0000001 ) + if (fabs(to_meter - 1.0) < 0.0000001) return MS_METERS; - else if( fabs(to_meter-1000.0) < 0.00001 ) + else if (fabs(to_meter - 1000.0) < 0.00001) return MS_KILOMETERS; - else if( fabs(to_meter-0.3048) < 0.0001 ) + else if (fabs(to_meter - 0.3048) < 0.0001) return MS_FEET; - else if( fabs(to_meter-0.0254) < 0.0001 ) + else if (fabs(to_meter - 0.0254) < 0.0001) return MS_INCHES; - else if( fabs(to_meter-1609.344) < 0.001 ) + else if (fabs(to_meter - 1609.344) < 0.001) return MS_MILES; - else if( fabs(to_meter-1852.0) < 0.1 ) + else if (fabs(to_meter - 1852.0) < 0.1) return MS_NAUTICALMILES; else return -1; } #if PROJ_VERSION_MAJOR < 6 - pj_dalloc( proj_str ); + pj_dalloc(proj_str); #endif return -1; } @@ -2971,58 +2845,51 @@ int GetMapserverUnitUsingProj(projectionObj *psProj) /* msProjectionContextReleaseToPool() */ /************************************************************************/ -projectionContext* msProjectionContextGetFromPool() -{ - projectionContext* context; - msAcquireLock( TLOCK_PROJ ); +projectionContext *msProjectionContextGetFromPool() { + projectionContext *context; + msAcquireLock(TLOCK_PROJ); - if( headOfLinkedListOfProjContext ) - { - LinkedListOfProjContext* next = headOfLinkedListOfProjContext->next; - context = headOfLinkedListOfProjContext->context; - msFree(headOfLinkedListOfProjContext); - headOfLinkedListOfProjContext = next; - } - else - { - context = msProjectionContextCreate(); - } + if (headOfLinkedListOfProjContext) { + LinkedListOfProjContext *next = headOfLinkedListOfProjContext->next; + context = headOfLinkedListOfProjContext->context; + msFree(headOfLinkedListOfProjContext); + headOfLinkedListOfProjContext = next; + } else { + context = msProjectionContextCreate(); + } - msReleaseLock( TLOCK_PROJ ); - return context; + msReleaseLock(TLOCK_PROJ); + return context; } /************************************************************************/ /* msProjectionContextReleaseToPool() */ /************************************************************************/ -void msProjectionContextReleaseToPool(projectionContext* ctx) -{ - LinkedListOfProjContext* link = - (LinkedListOfProjContext*)msSmallMalloc(sizeof(LinkedListOfProjContext)); - link->context = ctx; - msAcquireLock( TLOCK_PROJ ); - link->next = headOfLinkedListOfProjContext; - headOfLinkedListOfProjContext = link; - msReleaseLock( TLOCK_PROJ ); +void msProjectionContextReleaseToPool(projectionContext *ctx) { + LinkedListOfProjContext *link = + (LinkedListOfProjContext *)msSmallMalloc(sizeof(LinkedListOfProjContext)); + link->context = ctx; + msAcquireLock(TLOCK_PROJ); + link->next = headOfLinkedListOfProjContext; + headOfLinkedListOfProjContext = link; + msReleaseLock(TLOCK_PROJ); } /************************************************************************/ /* msProjectionContextPoolCleanup() */ /************************************************************************/ -void msProjectionContextPoolCleanup() -{ - LinkedListOfProjContext* link; - msAcquireLock( TLOCK_PROJ ); - link = headOfLinkedListOfProjContext; - while( link ) - { - LinkedListOfProjContext* next = link->next; - msProjectionContextUnref(link->context); - msFree(link); - link = next; - } - headOfLinkedListOfProjContext = NULL; - msReleaseLock( TLOCK_PROJ ); +void msProjectionContextPoolCleanup() { + LinkedListOfProjContext *link; + msAcquireLock(TLOCK_PROJ); + link = headOfLinkedListOfProjContext; + while (link) { + LinkedListOfProjContext *next = link->next; + msProjectionContextUnref(link->context); + msFree(link); + link = next; + } + headOfLinkedListOfProjContext = NULL; + msReleaseLock(TLOCK_PROJ); } diff --git a/mapproject.h b/mapproject.h index 82a1235616..1e4128c56c 100644 --- a/mapproject.h +++ b/mapproject.h @@ -38,14 +38,14 @@ extern "C" { #endif #if PROJ_VERSION_MAJOR >= 6 -# include +#include #if PROJ_VERSION_MAJOR == 6 && PROJ_VERSION_MINOR == 0 #error "PROJ 6.0 is not supported. Use PROJ 6.1 or later" #endif #else -# include +#include #if PJ_VERSION >= 470 && PJ_VERSION < 480 - void pj_clear_initcache(); +void pj_clear_initcache(); #endif #endif @@ -56,127 +56,144 @@ extern "C" { typedef struct projectionContext projectionContext; #ifndef SWIG -typedef enum -{ - LINE_CUTTING_UNKNOWN = -1, - LINE_CUTTING_NONE = 0, - LINE_CUTTING_FROM_POLAR = 1, - LINE_CUTTING_FROM_LONGLAT_WRAP0 = 2 +typedef enum { + LINE_CUTTING_UNKNOWN = -1, + LINE_CUTTING_NONE = 0, + LINE_CUTTING_FROM_POLAR = 1, + LINE_CUTTING_FROM_LONGLAT_WRAP0 = 2 } msLineCuttingCase; #endif /** The :ref:`PROJECTION ` object -MapServer's Maps and Layers have Projection attributes, and these are C projectionObj structures, -but are not directly exposed by the mapscript module +MapServer's Maps and Layers have Projection attributes, and these are C +projectionObj structures, but are not directly exposed by the mapscript module */ - typedef struct { +typedef struct { #ifndef SWIG - char **args; /* variable number of projection args */ + char **args; /* variable number of projection args */ #if PROJ_VERSION_MAJOR >= 6 - PJ* proj; - projectionContext* proj_ctx; + PJ *proj; + projectionContext *proj_ctx; #else - projPJ proj; /* a projection structure for the PROJ package */ + projPJ proj; /* a projection structure for the PROJ package */ #if PJ_VERSION >= 480 - projCtx proj_ctx; + projCtx proj_ctx; #endif #endif - geotransformObj gt; /* extra transformation to apply */ + geotransformObj gt; /* extra transformation to apply */ #endif #ifdef SWIG %immutable; #endif - int numargs; ///< Actual number of projection args - short automatic; ///< Projection object was to fetched from the layer - unsigned short generation_number; ///< To be incremented when the content of the object changes, so that a reprojector can be invalidated + int numargs; ///< Actual number of projection args + short automatic; ///< Projection object was to fetched from the layer + unsigned short + generation_number; ///< To be incremented when the content of the object + ///< changes, so that a reprojector can be invalidated #ifdef SWIG %mutable; #endif - int wellknownprojection; ///< One of ``wkp_none 0``, ``wkp_lonlat 1``, or ``wkp_gmerc 2`` - } projectionObj; + int wellknownprojection; ///< One of ``wkp_none 0``, ``wkp_lonlat 1``, or + ///< ``wkp_gmerc 2`` +} projectionObj; /** -A holder object for projection coordinate transformations, introduced in RFC 126. -This allows caching of reprojections improving performance. +A holder object for projection coordinate transformations, introduced in RFC +126. This allows caching of reprojections improving performance. */ - typedef struct { +typedef struct { #if PROJ_VERSION_MAJOR >= 6 #ifndef SWIG - projectionObj* in; - projectionObj* out; - PJ* pj; - msLineCuttingCase lineCuttingCase; - shapeObj splitShape; - int bFreePJ; + projectionObj *in; + projectionObj *out; + PJ *pj; + msLineCuttingCase lineCuttingCase; + shapeObj splitShape; + int bFreePJ; #endif #else #ifndef SWIG - projectionObj* in; - projectionObj* out; - msLineCuttingCase lineCuttingCase; - shapeObj splitShape; - int no_op; + projectionObj *in; + projectionObj *out; + msLineCuttingCase lineCuttingCase; + shapeObj splitShape; + int no_op; #endif #endif - unsigned short generation_number_in; ///< A counter that is incremented when the input projectionObj changes - unsigned short generation_number_out; ///< A counter that is incremented when the output projectionObj changes - } reprojectionObj; + unsigned short generation_number_in; ///< A counter that is incremented when + ///< the input projectionObj changes + unsigned short generation_number_out; ///< A counter that is incremented when + ///< the output projectionObj changes +} reprojectionObj; #ifndef SWIG - MS_DLL_EXPORT reprojectionObj* msProjectCreateReprojector(projectionObj* in, projectionObj* out); - MS_DLL_EXPORT void msProjectDestroyReprojector(reprojectionObj* reprojector); - MS_DLL_EXPORT int msProjectIsReprojectorStillValid(reprojectionObj* reprojector); - - MS_DLL_EXPORT projectionContext* msProjectionContextGetFromPool(void); - MS_DLL_EXPORT void msProjectionContextReleaseToPool(projectionContext* ctx); - MS_DLL_EXPORT void msProjectionContextPoolCleanup(void); - - MS_DLL_EXPORT int msIsAxisInverted(int epsg_code); - MS_DLL_EXPORT int msProjectPoint(projectionObj *in, projectionObj *out, pointObj *point); /* legacy interface */ - MS_DLL_EXPORT int msProjectPointEx(reprojectionObj* reprojector, pointObj *point); - MS_DLL_EXPORT int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape); /* legacy interface */ - MS_DLL_EXPORT int msProjectShapeEx(reprojectionObj* reprojector, shapeObj *shape); - MS_DLL_EXPORT int msProjectLine(projectionObj *in, projectionObj *out, lineObj *line); /* legacy interface */ - MS_DLL_EXPORT int msProjectLineEx(reprojectionObj* reprojector, lineObj *line); - MS_DLL_EXPORT int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect); /* legacy interface */ - MS_DLL_EXPORT int msProjectRectAsPolygon(reprojectionObj* reprojector, rectObj *rect); - MS_DLL_EXPORT int msProjectionsDiffer(projectionObj *, projectionObj *); - MS_DLL_EXPORT int msOGCWKT2ProjectionObj( const char *pszWKT, projectionObj *proj, int debug_flag ); - MS_DLL_EXPORT char *msProjectionObj2OGCWKT( projectionObj *proj ); - - MS_DLL_EXPORT void msFreeProjection(projectionObj *p); - MS_DLL_EXPORT void msFreeProjectionExceptContext(projectionObj *p); - MS_DLL_EXPORT int msInitProjection(projectionObj *p); - MS_DLL_EXPORT void msProjectionInheritContextFrom(projectionObj *pDst, const projectionObj* pSrc); - MS_DLL_EXPORT void msProjectionSetContext(projectionObj *p, projectionContext* ctx); - MS_DLL_EXPORT int msProcessProjection(projectionObj *p); - MS_DLL_EXPORT int msLoadProjectionString(projectionObj *p, const char *value); - MS_DLL_EXPORT int msLoadProjectionStringEPSG(projectionObj *p, const char *value); - MS_DLL_EXPORT char *msGetProjectionString(projectionObj *proj); - int msIsAxisInvertedProj( projectionObj *proj ); - void msAxisSwapShape(shapeObj *shape); - MS_DLL_EXPORT void msAxisNormalizePoints( projectionObj *proj, int count, - double *x, double *y ); - MS_DLL_EXPORT void msAxisDenormalizePoints( projectionObj *proj, int count, - double *x, double *y ); - - MS_DLL_EXPORT void msSetPROJ_DATA( const char *, const char * ); - MS_DLL_EXPORT void msProjDataInitFromEnv(); - - int msProjIsGeographicCRS(projectionObj* proj); +MS_DLL_EXPORT reprojectionObj *msProjectCreateReprojector(projectionObj *in, + projectionObj *out); +MS_DLL_EXPORT void msProjectDestroyReprojector(reprojectionObj *reprojector); +MS_DLL_EXPORT int +msProjectIsReprojectorStillValid(reprojectionObj *reprojector); + +MS_DLL_EXPORT projectionContext *msProjectionContextGetFromPool(void); +MS_DLL_EXPORT void msProjectionContextReleaseToPool(projectionContext *ctx); +MS_DLL_EXPORT void msProjectionContextPoolCleanup(void); + +MS_DLL_EXPORT int msIsAxisInverted(int epsg_code); +MS_DLL_EXPORT int msProjectPoint(projectionObj *in, projectionObj *out, + pointObj *point); /* legacy interface */ +MS_DLL_EXPORT int msProjectPointEx(reprojectionObj *reprojector, + pointObj *point); +MS_DLL_EXPORT int msProjectShape(projectionObj *in, projectionObj *out, + shapeObj *shape); /* legacy interface */ +MS_DLL_EXPORT int msProjectShapeEx(reprojectionObj *reprojector, + shapeObj *shape); +MS_DLL_EXPORT int msProjectLine(projectionObj *in, projectionObj *out, + lineObj *line); /* legacy interface */ +MS_DLL_EXPORT int msProjectLineEx(reprojectionObj *reprojector, lineObj *line); +MS_DLL_EXPORT int msProjectRect(projectionObj *in, projectionObj *out, + rectObj *rect); /* legacy interface */ +MS_DLL_EXPORT int msProjectRectAsPolygon(reprojectionObj *reprojector, + rectObj *rect); +MS_DLL_EXPORT int msProjectionsDiffer(projectionObj *, projectionObj *); +MS_DLL_EXPORT int msOGCWKT2ProjectionObj(const char *pszWKT, + projectionObj *proj, int debug_flag); +MS_DLL_EXPORT char *msProjectionObj2OGCWKT(projectionObj *proj); + +MS_DLL_EXPORT void msFreeProjection(projectionObj *p); +MS_DLL_EXPORT void msFreeProjectionExceptContext(projectionObj *p); +MS_DLL_EXPORT int msInitProjection(projectionObj *p); +MS_DLL_EXPORT void msProjectionInheritContextFrom(projectionObj *pDst, + const projectionObj *pSrc); +MS_DLL_EXPORT void msProjectionSetContext(projectionObj *p, + projectionContext *ctx); +MS_DLL_EXPORT int msProcessProjection(projectionObj *p); +MS_DLL_EXPORT int msLoadProjectionString(projectionObj *p, const char *value); +MS_DLL_EXPORT int msLoadProjectionStringEPSG(projectionObj *p, + const char *value); +MS_DLL_EXPORT char *msGetProjectionString(projectionObj *proj); +int msIsAxisInvertedProj(projectionObj *proj); +void msAxisSwapShape(shapeObj *shape); +MS_DLL_EXPORT void msAxisNormalizePoints(projectionObj *proj, int count, + double *x, double *y); +MS_DLL_EXPORT void msAxisDenormalizePoints(projectionObj *proj, int count, + double *x, double *y); + +MS_DLL_EXPORT void msSetPROJ_DATA(const char *, const char *); +MS_DLL_EXPORT void msProjDataInitFromEnv(); + +int msProjIsGeographicCRS(projectionObj *proj); #if PROJ_VERSION_MAJOR >= 6 - int msProjectTransformPoints( reprojectionObj* reprojector, - int npoints, double* x, double* y ); +int msProjectTransformPoints(reprojectionObj *reprojector, int npoints, + double *x, double *y); #endif - /*utility functions */ - MS_DLL_EXPORT int GetMapserverUnitUsingProj(projectionObj *psProj); +/*utility functions */ +MS_DLL_EXPORT int GetMapserverUnitUsingProj(projectionObj *psProj); - int msProjectHasLonWrap(projectionObj *in, double* pdfLonWrap); +int msProjectHasLonWrap(projectionObj *in, double *pdfLonWrap); #endif #ifdef __cplusplus diff --git a/mapquantization.c b/mapquantization.c index 407a641eb5..3055ec8403 100644 --- a/mapquantization.c +++ b/mapquantization.c @@ -51,17 +51,21 @@ #define PAM_GETG(p) ((p).g) #define PAM_GETB(p) ((p).b) #define PAM_GETA(p) ((p).a) -#define PAM_ASSIGN(p,red,grn,blu,alf) \ - do { (p).r = (red); (p).g = (grn); (p).b = (blu); (p).a = (alf); } while (0) -#define PAM_EQUAL(p,q) \ - ((p).r == (q).r && (p).g == (q).g && (p).b == (q).b && (p).a == (q).a) -#define PAM_DEPTH(newp,p,oldmaxval,newmaxval) \ - PAM_ASSIGN( (newp), \ - ( (int) PAM_GETR(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \ - ( (int) PAM_GETG(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \ - ( (int) PAM_GETB(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \ - ( (int) PAM_GETA(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval) ) - +#define PAM_ASSIGN(p, red, grn, blu, alf) \ + do { \ + (p).r = (red); \ + (p).g = (grn); \ + (p).b = (blu); \ + (p).a = (alf); \ + } while (0) +#define PAM_EQUAL(p, q) \ + ((p).r == (q).r && (p).g == (q).g && (p).b == (q).b && (p).a == (q).a) +#define PAM_DEPTH(newp, p, oldmaxval, newmaxval) \ + PAM_ASSIGN((newp), \ + ((int)PAM_GETR(p) * (newmaxval) + (oldmaxval) / 2) / (oldmaxval), \ + ((int)PAM_GETG(p) * (newmaxval) + (oldmaxval) / 2) / (oldmaxval), \ + ((int)PAM_GETB(p) * (newmaxval) + (oldmaxval) / 2) / (oldmaxval), \ + ((int)PAM_GETA(p) * (newmaxval) + (oldmaxval) / 2) / (oldmaxval)) /* from pamcmap.h */ @@ -79,7 +83,7 @@ struct acolorhist_list_item { typedef acolorhist_list *acolorhash_table; -#define MAXCOLORS 32767 +#define MAXCOLORS 32767 #define LARGE_NORM #define REP_AVERAGE_PIXELS @@ -91,54 +95,58 @@ struct box { int sum; }; -static acolorhist_vector mediancut -(acolorhist_vector achv, int colors, int sum, unsigned char maxval, int newcolors); -static int redcompare (const void *ch1, const void *ch2); -static int greencompare (const void *ch1, const void *ch2); -static int bluecompare (const void *ch1, const void *ch2); -static int alphacompare (const void *ch1, const void *ch2); -static int sumcompare (const void *b1, const void *b2); - -static acolorhist_vector pam_acolorhashtoacolorhist -(acolorhash_table acht, int maxacolors); -static acolorhist_vector pam_computeacolorhist -(rgbaPixel **apixels, int cols, int rows, int maxacolors, int* acolorsP); -static acolorhash_table pam_computeacolorhash -(rgbaPixel** apixels, int cols, int rows, int maxacolors, int* acolorsP); -static acolorhash_table pam_allocacolorhash (void); -static int pam_addtoacolorhash -(acolorhash_table acht, rgbaPixel *acolorP, int value); -static int pam_lookupacolor (acolorhash_table acht, rgbaPixel* acolorP); -static void pam_freeacolorhist (acolorhist_vector achv); -static void pam_freeacolorhash (acolorhash_table acht); - +static acolorhist_vector mediancut(acolorhist_vector achv, int colors, int sum, + unsigned char maxval, int newcolors); +static int redcompare(const void *ch1, const void *ch2); +static int greencompare(const void *ch1, const void *ch2); +static int bluecompare(const void *ch1, const void *ch2); +static int alphacompare(const void *ch1, const void *ch2); +static int sumcompare(const void *b1, const void *b2); + +static acolorhist_vector pam_acolorhashtoacolorhist(acolorhash_table acht, + int maxacolors); +static acolorhist_vector pam_computeacolorhist(rgbaPixel **apixels, int cols, + int rows, int maxacolors, + int *acolorsP); +static acolorhash_table pam_computeacolorhash(rgbaPixel **apixels, int cols, + int rows, int maxacolors, + int *acolorsP); +static acolorhash_table pam_allocacolorhash(void); +static int pam_addtoacolorhash(acolorhash_table acht, rgbaPixel *acolorP, + int value); +static int pam_lookupacolor(acolorhash_table acht, rgbaPixel *acolorP); +static void pam_freeacolorhist(acolorhist_vector achv); +static void pam_freeacolorhash(acolorhash_table acht); /** - * Compute a palette for the given RGBA rasterBuffer using a median cut quantization. + * Compute a palette for the given RGBA rasterBuffer using a median cut + * quantization. * - rb: the rasterBuffer to quantize - * - reqcolors: the desired number of colors the palette should contain. will be set - * with the actual number of entries in the computed palette + * - reqcolors: the desired number of colors the palette should contain. will be + * set with the actual number of entries in the computed palette * - forced_palette: entries that should appear in the computed palette - * - num_forced_palette_entries: number of entries contained in "force_palette". if 0, - * "force_palette" can be NULL - * - palette_scaling_maxval: the quantization process may have to reduce the image depth - * by iteratively dividing the pixels by 2. In case palette_scaling_maxval is set to - * something different than 255, the returned palette colors have to be scaled back up to - * 255, and rb's pixels will have been scaled down to maxsize (see bug #3848) + * - num_forced_palette_entries: number of entries contained in "force_palette". + * if 0, "force_palette" can be NULL + * - palette_scaling_maxval: the quantization process may have to reduce the + * image depth by iteratively dividing the pixels by 2. In case + * palette_scaling_maxval is set to something different than 255, the returned + * palette colors have to be scaled back up to 255, and rb's pixels will have + * been scaled down to maxsize (see bug #3848) */ -int msQuantizeRasterBuffer(rasterBufferObj *rb, - unsigned int *reqcolors, rgbaPixel *palette, - rgbaPixel *forced_palette_ignored, int num_forced_palette_entries_ignored, - unsigned int *palette_scaling_maxval) -{ +int msQuantizeRasterBuffer(rasterBufferObj *rb, unsigned int *reqcolors, + rgbaPixel *palette, + rgbaPixel *forced_palette_ignored, + int num_forced_palette_entries_ignored, + unsigned int *palette_scaling_maxval) { (void)forced_palette_ignored; (void)num_forced_palette_entries_ignored; - rgbaPixel **apixels=NULL; /* pointer to the start rows of truecolor pixels */ + rgbaPixel **apixels = + NULL; /* pointer to the start rows of truecolor pixels */ register rgbaPixel *pP; unsigned char newmaxval; - acolorhist_vector achv, acolormap=NULL; + acolorhist_vector achv, acolormap = NULL; int colors; int newcolors = 0; @@ -150,10 +158,11 @@ int msQuantizeRasterBuffer(rasterBufferObj *rb, *palette_scaling_maxval = 255; - apixels=(rgbaPixel**)msSmallMalloc(rb->height*sizeof(rgbaPixel*)); + apixels = (rgbaPixel **)msSmallMalloc(rb->height * sizeof(rgbaPixel *)); - for(unsigned row=0; rowheight; row++) { - apixels[row]=(rgbaPixel*)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step])); + for (unsigned row = 0; row < rb->height; row++) { + apixels[row] = + (rgbaPixel *)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step])); } /* @@ -163,28 +172,26 @@ int msQuantizeRasterBuffer(rasterBufferObj *rb, ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. [GRR POSSIBLE BUG: what about 32^4 ?] */ - for ( ; ; ) { - achv = pam_computeacolorhist( - apixels, rb->width, rb->height, MAXCOLORS, &colors ); - if ( achv != (acolorhist_vector) 0 ) + for (;;) { + achv = pam_computeacolorhist(apixels, rb->width, rb->height, MAXCOLORS, + &colors); + if (achv != (acolorhist_vector)0) break; newmaxval = *palette_scaling_maxval / 2; - for ( unsigned row = 0; row < rb->height; ++row ) - { + for (unsigned row = 0; row < rb->height; ++row) { pP = apixels[row]; - for (unsigned col = 0 ; col < rb->width; ++col, ++pP ) - PAM_DEPTH( *pP, *pP, *palette_scaling_maxval, newmaxval ); + for (unsigned col = 0; col < rb->width; ++col, ++pP) + PAM_DEPTH(*pP, *pP, *palette_scaling_maxval, newmaxval); } *palette_scaling_maxval = newmaxval; } newcolors = MS_MIN(colors, (int)*reqcolors); - acolormap = mediancut(achv, colors, rb->width*rb->height, *palette_scaling_maxval, newcolors); + acolormap = mediancut(achv, colors, rb->width * rb->height, + *palette_scaling_maxval, newcolors); pam_freeacolorhist(achv); - *reqcolors = newcolors; - for (x = 0; x < newcolors; ++x) { palette[x].r = acolormap[x].acolor.r; palette[x].g = acolormap[x].acolor.g; @@ -197,11 +204,9 @@ int msQuantizeRasterBuffer(rasterBufferObj *rb, return MS_SUCCESS; } - -int msClassifyRasterBuffer(rasterBufferObj *rb, rasterBufferObj *qrb) -{ +int msClassifyRasterBuffer(rasterBufferObj *rb, rasterBufferObj *qrb) { register int ind; - unsigned char *outrow,*pQ; + unsigned char *outrow, *pQ; register rgbaPixel *pP; acolorhash_table acht; int usehash; @@ -209,44 +214,44 @@ int msClassifyRasterBuffer(rasterBufferObj *rb, rasterBufferObj *qrb) ** Step 4: map the colors in the image to their closest match in the ** new colormap, and write 'em out. */ - acht = pam_allocacolorhash( ); + acht = pam_allocacolorhash(); usehash = 1; - for ( unsigned row = 0; row < qrb->height; ++row ) { - outrow = &(qrb->data.palette.pixels[row*qrb->width]); + for (unsigned row = 0; row < qrb->height; ++row) { + outrow = &(qrb->data.palette.pixels[row * qrb->width]); unsigned col = 0; - pP = (rgbaPixel*)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step]));; + pP = (rgbaPixel *)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step])); + ; pQ = outrow; do { /* Check hash table to see if we have already matched this color. */ - ind = pam_lookupacolor( acht, pP ); - if ( ind == -1 ) { + ind = pam_lookupacolor(acht, pP); + if (ind == -1) { /* No; search acolormap for closest match. */ register int r1, g1, b1, a1, r2, g2, b2, a2; register long dist, newdist; - r1 = PAM_GETR( *pP ); - g1 = PAM_GETG( *pP ); - b1 = PAM_GETB( *pP ); - a1 = PAM_GETA( *pP ); + r1 = PAM_GETR(*pP); + g1 = PAM_GETG(*pP); + b1 = PAM_GETB(*pP); + a1 = PAM_GETA(*pP); dist = 2000000000; - for ( unsigned i = 0; i < qrb->data.palette.num_entries; ++i ) { - r2 = PAM_GETR( qrb->data.palette.palette[i] ); - g2 = PAM_GETG( qrb->data.palette.palette[i] ); - b2 = PAM_GETB( qrb->data.palette.palette[i] ); - a2 = PAM_GETA( qrb->data.palette.palette[i] ); + for (unsigned i = 0; i < qrb->data.palette.num_entries; ++i) { + r2 = PAM_GETR(qrb->data.palette.palette[i]); + g2 = PAM_GETG(qrb->data.palette.palette[i]); + b2 = PAM_GETB(qrb->data.palette.palette[i]); + a2 = PAM_GETA(qrb->data.palette.palette[i]); /* GRR POSSIBLE BUG */ - newdist = ( r1 - r2 ) * ( r1 - r2 ) + /* may overflow? */ - ( g1 - g2 ) * ( g1 - g2 ) + - ( b1 - b2 ) * ( b1 - b2 ) + - ( a1 - a2 ) * ( a1 - a2 ); - if ( newdist < dist ) { + newdist = (r1 - r2) * (r1 - r2) + /* may overflow? */ + (g1 - g2) * (g1 - g2) + (b1 - b2) * (b1 - b2) + + (a1 - a2) * (a1 - a2); + if (newdist < dist) { ind = i; dist = newdist; } } - if ( usehash ) { - if ( pam_addtoacolorhash( acht, pP, ind ) < 0 ) { + if (usehash) { + if (pam_addtoacolorhash(acht, pP, ind) < 0) { usehash = 0; } } @@ -259,39 +264,36 @@ int msClassifyRasterBuffer(rasterBufferObj *rb, rasterBufferObj *qrb) ++pP; ++pQ; - } while ( col != rb->width ); + } while (col != rb->width); } pam_freeacolorhash(acht); return MS_SUCCESS; } - - /* ** Here is the fun part, the median-cut colormap generator. This is based ** on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer ** Display," SIGGRAPH 1982 Proceedings, page 297. */ -static acolorhist_vector -mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, int newcolors ) -{ +static acolorhist_vector mediancut(acolorhist_vector achv, int colors, int sum, + unsigned char maxval, int newcolors) { acolorhist_vector acolormap; box_vector bv; register int bi, i; int boxes; - bv = (box_vector) malloc( sizeof(struct box) * newcolors ); + bv = (box_vector)malloc(sizeof(struct box) * newcolors); acolormap = - (acolorhist_vector) malloc( sizeof(struct acolorhist_item) * newcolors); - if ( bv == (box_vector) 0 || acolormap == (acolorhist_vector) 0 ) { - fprintf( stderr, " out of memory allocating box vector\n" ); + (acolorhist_vector)malloc(sizeof(struct acolorhist_item) * newcolors); + if (bv == (box_vector)0 || acolormap == (acolorhist_vector)0) { + fprintf(stderr, " out of memory allocating box vector\n"); fflush(stderr); exit(6); } - for ( i = 0; i < newcolors; ++i ) - PAM_ASSIGN( acolormap[i].acolor, 0, 0, 0, 0 ); + for (i = 0; i < newcolors; ++i) + PAM_ASSIGN(acolormap[i].acolor, 0, 0, 0, 0); /* ** Set up the initial box. @@ -304,7 +306,7 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in /* ** Main loop: split boxes until we have enough. */ - while ( boxes < newcolors ) { + while (boxes < newcolors) { register int indx, clrs; int sm; register int minr, maxr, ming, mina, maxg, minb, maxb, maxa, v; @@ -313,11 +315,11 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in /* ** Find the first splittable box. */ - for ( bi = 0; bi < boxes; ++bi ) - if ( bv[bi].colors >= 2 ) + for (bi = 0; bi < boxes; ++bi) + if (bv[bi].colors >= 2) break; - if ( bi == boxes ) - break; /* ran out of colors! */ + if (bi == boxes) + break; /* ran out of colors! */ indx = bv[bi].ind; clrs = bv[bi].colors; sm = bv[bi].sum; @@ -326,23 +328,31 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in ** Go through the box finding the minimum and maximum of each ** component - the boundaries of the box. */ - minr = maxr = PAM_GETR( achv[indx].acolor ); - ming = maxg = PAM_GETG( achv[indx].acolor ); - minb = maxb = PAM_GETB( achv[indx].acolor ); - mina = maxa = PAM_GETA( achv[indx].acolor ); - for ( i = 1; i < clrs; ++i ) { - v = PAM_GETR( achv[indx + i].acolor ); - if ( v < minr ) minr = v; - if ( v > maxr ) maxr = v; - v = PAM_GETG( achv[indx + i].acolor ); - if ( v < ming ) ming = v; - if ( v > maxg ) maxg = v; - v = PAM_GETB( achv[indx + i].acolor ); - if ( v < minb ) minb = v; - if ( v > maxb ) maxb = v; - v = PAM_GETA( achv[indx + i].acolor ); - if ( v < mina ) mina = v; - if ( v > maxa ) maxa = v; + minr = maxr = PAM_GETR(achv[indx].acolor); + ming = maxg = PAM_GETG(achv[indx].acolor); + minb = maxb = PAM_GETB(achv[indx].acolor); + mina = maxa = PAM_GETA(achv[indx].acolor); + for (i = 1; i < clrs; ++i) { + v = PAM_GETR(achv[indx + i].acolor); + if (v < minr) + minr = v; + if (v > maxr) + maxr = v; + v = PAM_GETG(achv[indx + i].acolor); + if (v < ming) + ming = v; + if (v > maxg) + maxg = v; + v = PAM_GETB(achv[indx + i].acolor); + if (v < minb) + minb = v; + if (v > maxb) + maxb = v; + v = PAM_GETA(achv[indx + i].acolor); + if (v < mina) + mina = v; + if (v > maxa) + maxa = v; } /* @@ -354,22 +364,19 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in ** the LARGE_ defines at the beginning of this source file. */ #ifdef LARGE_NORM - if ( maxa - mina >= maxr - minr && maxa - mina >= maxg - ming && maxa - mina >= maxb - minb ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - alphacompare ); - else if ( maxr - minr >= maxg - ming && maxr - minr >= maxb - minb ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - redcompare ); - else if ( maxg - ming >= maxb - minb ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - greencompare ); + if (maxa - mina >= maxr - minr && maxa - mina >= maxg - ming && + maxa - mina >= maxb - minb) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + alphacompare); + else if (maxr - minr >= maxg - ming && maxr - minr >= maxb - minb) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + redcompare); + else if (maxg - ming >= maxb - minb) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + greencompare); else - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - bluecompare ); + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + bluecompare); #endif /*LARGE_NORM*/ #ifdef LARGE_LUM { @@ -391,22 +398,18 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in [probably should read Heckbert's paper to decide] */ - if ( al >= rl && al >= gl && al >= bl ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - alphacompare ); - else if ( rl >= gl && rl >= bl ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - redcompare ); - else if ( gl >= bl ) - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - greencompare ); + if (al >= rl && al >= gl && al >= bl) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + alphacompare); + else if (rl >= gl && rl >= bl) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + redcompare); + else if (gl >= bl) + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + greencompare); else - qsort( - (char*) &(achv[indx]), clrs, sizeof(struct acolorhist_item), - bluecompare ); + qsort((char *)&(achv[indx]), clrs, sizeof(struct acolorhist_item), + bluecompare); } #endif /*LARGE_LUM*/ @@ -416,8 +419,8 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in */ lowersum = achv[indx].value; halfsum = sm / 2; - for ( i = 1; i < clrs - 1; ++i ) { - if ( lowersum >= halfsum ) + for (i = 1; i < clrs - 1; ++i) { + if (lowersum >= halfsum) break; lowersum += achv[indx + i].value; } @@ -431,7 +434,7 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in bv[boxes].colors = clrs - i; bv[boxes].sum = sm - lowersum; ++boxes; - qsort( (char*) bv, boxes, sizeof(struct box), sumcompare ); + qsort((char *)bv, boxes, sizeof(struct box), sumcompare); } /* @@ -444,77 +447,81 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in ** method is used by switching the commenting on the REP_ defines at ** the beginning of this source file. */ - for ( bi = 0; bi < boxes; ++bi ) { + for (bi = 0; bi < boxes; ++bi) { #ifdef REP_CENTER_BOX register int indx = bv[bi].ind; register int clrs = bv[bi].colors; register int minr, maxr, ming, maxg, minb, maxb, mina, maxa, v; - minr = maxr = PAM_GETR( achv[indx].acolor ); - ming = maxg = PAM_GETG( achv[indx].acolor ); - minb = maxb = PAM_GETB( achv[indx].acolor ); - mina = maxa = PAM_GETA( achv[indx].acolor ); - for ( i = 1; i < clrs; ++i ) { - v = PAM_GETR( achv[indx + i].acolor ); - minr = min( minr, v ); - maxr = max( maxr, v ); - v = PAM_GETG( achv[indx + i].acolor ); - ming = min( ming, v ); - maxg = max( maxg, v ); - v = PAM_GETB( achv[indx + i].acolor ); - minb = min( minb, v ); - maxb = max( maxb, v ); - v = PAM_GETA( achv[indx + i].acolor ); - mina = min( mina, v ); - maxa = max( maxa, v ); + minr = maxr = PAM_GETR(achv[indx].acolor); + ming = maxg = PAM_GETG(achv[indx].acolor); + minb = maxb = PAM_GETB(achv[indx].acolor); + mina = maxa = PAM_GETA(achv[indx].acolor); + for (i = 1; i < clrs; ++i) { + v = PAM_GETR(achv[indx + i].acolor); + minr = min(minr, v); + maxr = max(maxr, v); + v = PAM_GETG(achv[indx + i].acolor); + ming = min(ming, v); + maxg = max(maxg, v); + v = PAM_GETB(achv[indx + i].acolor); + minb = min(minb, v); + maxb = max(maxb, v); + v = PAM_GETA(achv[indx + i].acolor); + mina = min(mina, v); + maxa = max(maxa, v); } - PAM_ASSIGN( - acolormap[bi].acolor, ( minr + maxr ) / 2, ( ming + maxg ) / 2, - ( minb + maxb ) / 2, ( mina + maxa ) / 2 ); + PAM_ASSIGN(acolormap[bi].acolor, (minr + maxr) / 2, (ming + maxg) / 2, + (minb + maxb) / 2, (mina + maxa) / 2); #endif /*REP_CENTER_BOX*/ #ifdef REP_AVERAGE_COLORS register int indx = bv[bi].ind; register int clrs = bv[bi].colors; register long r = 0, g = 0, b = 0, a = 0; - for ( i = 0; i < clrs; ++i ) { - r += PAM_GETR( achv[indx + i].acolor ); - g += PAM_GETG( achv[indx + i].acolor ); - b += PAM_GETB( achv[indx + i].acolor ); - a += PAM_GETA( achv[indx + i].acolor ); + for (i = 0; i < clrs; ++i) { + r += PAM_GETR(achv[indx + i].acolor); + g += PAM_GETG(achv[indx + i].acolor); + b += PAM_GETB(achv[indx + i].acolor); + a += PAM_GETA(achv[indx + i].acolor); } r = r / clrs; g = g / clrs; b = b / clrs; a = a / clrs; - PAM_ASSIGN( acolormap[bi].acolor, r, g, b, a ); + PAM_ASSIGN(acolormap[bi].acolor, r, g, b, a); #endif /*REP_AVERAGE_COLORS*/ #ifdef REP_AVERAGE_PIXELS register int indx = bv[bi].ind; register int clrs = bv[bi].colors; register long r = 0, g = 0, b = 0, a = 0, sum = 0; - for ( i = 0; i < clrs; ++i ) { - r += (long)PAM_GETR( achv[indx + i].acolor ) * achv[indx + i].value; - g += (long)PAM_GETG( achv[indx + i].acolor ) * achv[indx + i].value; - b += (long)PAM_GETB( achv[indx + i].acolor ) * achv[indx + i].value; - a += (long)PAM_GETA( achv[indx + i].acolor ) * achv[indx + i].value; + for (i = 0; i < clrs; ++i) { + r += (long)PAM_GETR(achv[indx + i].acolor) * achv[indx + i].value; + g += (long)PAM_GETG(achv[indx + i].acolor) * achv[indx + i].value; + b += (long)PAM_GETB(achv[indx + i].acolor) * achv[indx + i].value; + a += (long)PAM_GETA(achv[indx + i].acolor) * achv[indx + i].value; sum += achv[indx + i].value; } - if(sum>0) { + if (sum > 0) { r = r / sum; - if ( r > maxval ) r = maxval; /* avoid math errors */ + if (r > maxval) + r = maxval; /* avoid math errors */ g = g / sum; - if ( g > maxval ) g = maxval; + if (g > maxval) + g = maxval; b = b / sum; - if ( b > maxval ) b = maxval; + if (b > maxval) + b = maxval; a = a / sum; - if ( a > maxval ) a = maxval; + if (a > maxval) + a = maxval; } else { r = g = b = a = maxval; } /* GRR 20001228: added casts to quiet warnings; 255 DEPENDENCY */ - PAM_ASSIGN( acolormap[bi].acolor, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a ); + PAM_ASSIGN(acolormap[bi].acolor, (unsigned char)r, (unsigned char)g, + (unsigned char)b, (unsigned char)a); #endif /*REP_AVERAGE_PIXELS*/ } @@ -525,45 +532,32 @@ mediancut( acolorhist_vector achv, int colors, int sum, unsigned char maxval, in return acolormap; } -static int -redcompare( const void *ch1, const void *ch2 ) -{ - return (int) PAM_GETR( ((acolorhist_vector)ch1)->acolor ) - - (int) PAM_GETR( ((acolorhist_vector)ch2)->acolor ); +static int redcompare(const void *ch1, const void *ch2) { + return (int)PAM_GETR(((acolorhist_vector)ch1)->acolor) - + (int)PAM_GETR(((acolorhist_vector)ch2)->acolor); } -static int -greencompare( const void *ch1, const void *ch2 ) -{ - return (int) PAM_GETG( ((acolorhist_vector)ch1)->acolor ) - - (int) PAM_GETG( ((acolorhist_vector)ch2)->acolor ); +static int greencompare(const void *ch1, const void *ch2) { + return (int)PAM_GETG(((acolorhist_vector)ch1)->acolor) - + (int)PAM_GETG(((acolorhist_vector)ch2)->acolor); } -static int -bluecompare( const void *ch1, const void *ch2 ) -{ - return (int) PAM_GETB( ((acolorhist_vector)ch1)->acolor ) - - (int) PAM_GETB( ((acolorhist_vector)ch2)->acolor ); +static int bluecompare(const void *ch1, const void *ch2) { + return (int)PAM_GETB(((acolorhist_vector)ch1)->acolor) - + (int)PAM_GETB(((acolorhist_vector)ch2)->acolor); } -static int -alphacompare( const void *ch1, const void *ch2 ) -{ - return (int) PAM_GETA( ((acolorhist_vector)ch1)->acolor ) - - (int) PAM_GETA( ((acolorhist_vector)ch2)->acolor ); +static int alphacompare(const void *ch1, const void *ch2) { + return (int)PAM_GETA(((acolorhist_vector)ch1)->acolor) - + (int)PAM_GETA(((acolorhist_vector)ch2)->acolor); } -static int -sumcompare( const void *b1, const void *b2 ) -{ - return ((box_vector)b2)->sum - - ((box_vector)b1)->sum; +static int sumcompare(const void *b1, const void *b2) { + return ((box_vector)b2)->sum - ((box_vector)b1)->sum; } - /*===========================================================================*/ - /* libpam3.c - pam (portable alpha map) utility library part 3 ** ** Colormap routines. @@ -586,62 +580,60 @@ sumcompare( const void *b1, const void *b2 ) #define HASH_SIZE 20023 -#define pam_hashapixel(p) ( ( ( (long) PAM_GETR(p) * 33023 + \ - (long) PAM_GETG(p) * 30013 + \ - (long) PAM_GETB(p) * 27011 + \ - (long) PAM_GETA(p) * 24007 ) \ - & 0x7fffffff ) % HASH_SIZE ) +#define pam_hashapixel(p) \ + ((((long)PAM_GETR(p) * 33023 + (long)PAM_GETG(p) * 30013 + \ + (long)PAM_GETB(p) * 27011 + (long)PAM_GETA(p) * 24007) & \ + 0x7fffffff) % \ + HASH_SIZE) -static acolorhist_vector -pam_computeacolorhist( apixels, cols, rows, maxacolors, acolorsP ) -rgbaPixel** apixels; +static acolorhist_vector pam_computeacolorhist(apixels, cols, rows, maxacolors, + acolorsP) +rgbaPixel **apixels; int cols, rows, maxacolors; -int* acolorsP; +int *acolorsP; { acolorhash_table acht; acolorhist_vector achv; - acht = pam_computeacolorhash( apixels, cols, rows, maxacolors, acolorsP ); - if ( acht == (acolorhash_table) 0 ) - return (acolorhist_vector) 0; - achv = pam_acolorhashtoacolorhist( acht, maxacolors ); - pam_freeacolorhash( acht ); + acht = pam_computeacolorhash(apixels, cols, rows, maxacolors, acolorsP); + if (acht == (acolorhash_table)0) + return (acolorhist_vector)0; + achv = pam_acolorhashtoacolorhist(acht, maxacolors); + pam_freeacolorhash(acht); return achv; } - - -static acolorhash_table -pam_computeacolorhash( apixels, cols, rows, maxacolors, acolorsP ) -rgbaPixel** apixels; +static acolorhash_table pam_computeacolorhash(apixels, cols, rows, maxacolors, + acolorsP) +rgbaPixel **apixels; int cols, rows, maxacolors; -int* acolorsP; +int *acolorsP; { acolorhash_table acht; - register rgbaPixel* pP; + register rgbaPixel *pP; acolorhist_list achl; int col, row, hash; - acht = pam_allocacolorhash( ); + acht = pam_allocacolorhash(); *acolorsP = 0; /* Go through the entire image, building a hash table of colors. */ - for ( row = 0; row < rows; ++row ) - for ( col = 0, pP = apixels[row]; col < cols; ++col, ++pP ) { - hash = pam_hashapixel( *pP ); - for ( achl = acht[hash]; achl != (acolorhist_list) 0; achl = achl->next ) - if ( PAM_EQUAL( achl->ch.acolor, *pP ) ) + for (row = 0; row < rows; ++row) + for (col = 0, pP = apixels[row]; col < cols; ++col, ++pP) { + hash = pam_hashapixel(*pP); + for (achl = acht[hash]; achl != (acolorhist_list)0; achl = achl->next) + if (PAM_EQUAL(achl->ch.acolor, *pP)) break; - if ( achl != (acolorhist_list) 0 ) + if (achl != (acolorhist_list)0) ++(achl->ch.value); else { - if ( ++(*acolorsP) > maxacolors ) { - pam_freeacolorhash( acht ); - return (acolorhash_table) 0; + if (++(*acolorsP) > maxacolors) { + pam_freeacolorhash(acht); + return (acolorhash_table)0; } - achl = (acolorhist_list) malloc( sizeof(struct acolorhist_list_item) ); - if ( achl == 0 ) { - fprintf( stderr, " out of memory computing hash table\n" ); + achl = (acolorhist_list)malloc(sizeof(struct acolorhist_list_item)); + if (achl == 0) { + fprintf(stderr, " out of memory computing hash table\n"); exit(7); } achl->ch.acolor = *pP; @@ -654,40 +646,33 @@ int* acolorsP; return acht; } - - -static acolorhash_table -pam_allocacolorhash( ) -{ +static acolorhash_table pam_allocacolorhash() { acolorhash_table acht; int i; - acht = (acolorhash_table) malloc( HASH_SIZE * sizeof(acolorhist_list) ); - if ( acht == 0 ) { - fprintf( stderr, " out of memory allocating hash table\n" ); + acht = (acolorhash_table)malloc(HASH_SIZE * sizeof(acolorhist_list)); + if (acht == 0) { + fprintf(stderr, " out of memory allocating hash table\n"); exit(8); } - for ( i = 0; i < HASH_SIZE; ++i ) - acht[i] = (acolorhist_list) 0; + for (i = 0; i < HASH_SIZE; ++i) + acht[i] = (acolorhist_list)0; return acht; } - - -static int -pam_addtoacolorhash( acht, acolorP, value ) +static int pam_addtoacolorhash(acht, acolorP, value) acolorhash_table acht; -rgbaPixel* acolorP; +rgbaPixel *acolorP; int value; { register int hash; register acolorhist_list achl; - achl = (acolorhist_list) msSmallMalloc( sizeof(struct acolorhist_list_item) ); + achl = (acolorhist_list)msSmallMalloc(sizeof(struct acolorhist_list_item)); - hash = pam_hashapixel( *acolorP ); + hash = pam_hashapixel(*acolorP); achl->ch.acolor = *acolorP; achl->ch.value = value; achl->next = acht[hash]; @@ -695,10 +680,7 @@ int value; return 0; } - - -static acolorhist_vector -pam_acolorhashtoacolorhist( acht, maxacolors ) +static acolorhist_vector pam_acolorhashtoacolorhist(acht, maxacolors) acolorhash_table acht; int maxacolors; { @@ -707,17 +689,17 @@ int maxacolors; int i, j; /* Now collate the hash table into a simple acolorhist array. */ - achv = (acolorhist_vector) malloc( maxacolors * sizeof(struct acolorhist_item) ); + achv = (acolorhist_vector)malloc(maxacolors * sizeof(struct acolorhist_item)); /* (Leave room for expansion by caller.) */ - if ( achv == (acolorhist_vector) 0 ) { - fprintf( stderr, " out of memory generating histogram\n" ); + if (achv == (acolorhist_vector)0) { + fprintf(stderr, " out of memory generating histogram\n"); exit(9); } /* Loop through the hash table. */ j = 0; - for ( i = 0; i < HASH_SIZE; ++i ) - for ( achl = acht[i]; achl != (acolorhist_list) 0; achl = achl->next ) { + for (i = 0; i < HASH_SIZE; ++i) + for (achl = acht[i]; achl != (acolorhist_list)0; achl = achl->next) { /* Add the new entry. */ achv[j] = achl->ch; ++j; @@ -727,49 +709,33 @@ int maxacolors; return achv; } - - -static int -pam_lookupacolor( acht, acolorP ) +static int pam_lookupacolor(acht, acolorP) acolorhash_table acht; -rgbaPixel* acolorP; +rgbaPixel *acolorP; { int hash; acolorhist_list achl; - hash = pam_hashapixel( *acolorP ); - for ( achl = acht[hash]; achl != (acolorhist_list) 0; achl = achl->next ) - if ( PAM_EQUAL( achl->ch.acolor, *acolorP ) ) + hash = pam_hashapixel(*acolorP); + for (achl = acht[hash]; achl != (acolorhist_list)0; achl = achl->next) + if (PAM_EQUAL(achl->ch.acolor, *acolorP)) return achl->ch.value; return -1; } +static void pam_freeacolorhist(achv) acolorhist_vector achv; +{ free((char *)achv); } - -static void -pam_freeacolorhist( achv ) -acolorhist_vector achv; -{ - free( (char*) achv ); -} - - - -static void -pam_freeacolorhash( acht ) -acolorhash_table acht; +static void pam_freeacolorhash(acht) acolorhash_table acht; { int i; acolorhist_list achl, achlnext; - for ( i = 0; i < HASH_SIZE; ++i ) - for ( achl = acht[i]; achl != (acolorhist_list) 0; achl = achlnext ) { + for (i = 0; i < HASH_SIZE; ++i) + for (achl = acht[i]; achl != (acolorhist_list)0; achl = achlnext) { achlnext = achl->next; - free( (char*) achl ); + free((char *)achl); } - free( (char*) acht ); + free((char *)acht); } - - - diff --git a/mapquery.c b/mapquery.c index ae08cbb837..6d6d14b09f 100644 --- a/mapquery.c +++ b/mapquery.c @@ -34,21 +34,21 @@ /* This object is used by the various mapQueryXXXXX() functions. It stores * the total amount of shapes and their RAM footprint, when they are cached - * in the resultCacheObj* of layers. This is the total number accross all queried - * layers. However this is isn't persistant accross several calls to + * in the resultCacheObj* of layers. This is the total number accross all + * queried layers. However this is isn't persistant accross several calls to * mapQueryXXXXX(), if the resultCacheObj* objects weren't cleaned up. This * is not needed in the context of WFS, for which this is used for now. */ -typedef struct -{ - int cachedShapeCountWarningEmitted; - int cachedShapeCount; - int cachedShapeRAMWarningEmitted; - int cachedShapeRAM; +typedef struct { + int cachedShapeCountWarningEmitted; + int cachedShapeCount; + int cachedShapeRAMWarningEmitted; + int cachedShapeRAM; } queryCacheObj; int msInitQuery(queryObj *query) { - if(!query) return MS_FAILURE; + if (!query) + return MS_FAILURE; msFreeQuery(query); /* clean up anything previously allocated */ @@ -61,19 +61,21 @@ int msInitQuery(queryObj *query) { query->buffer = 0.0; query->maxresults = 0; /* only used by msQueryByPoint() apparently */ - query->rect.minx = query->rect.miny = query->rect.maxx = query->rect.maxy = -1; + query->rect.minx = query->rect.miny = query->rect.maxx = query->rect.maxy = + -1; query->shape = NULL; query->shapeindex = query->tileindex = -1; - query->clear_resultcache = MS_TRUE; /* index queries allow the old results to persist */ + query->clear_resultcache = + MS_TRUE; /* index queries allow the old results to persist */ query->maxfeatures = -1; query->startindex = -1; query->only_cache_result_count = 0; - + query->filteritem = NULL; msInitExpression(&query->filter); - + query->cache_shapes = MS_FALSE; query->max_cached_shape_count = 0; query->max_cached_shape_ram_amount = 0; @@ -81,54 +83,55 @@ int msInitQuery(queryObj *query) { return MS_SUCCESS; } -void msFreeQuery(queryObj *query) -{ - if(query->shape) { +void msFreeQuery(queryObj *query) { + if (query->shape) { msFreeShape(query->shape); free(query->shape); } - if(query->filteritem) free(query->filteritem); + if (query->filteritem) + free(query->filteritem); msFreeExpression(&query->filter); } /* -** Wrapper for all query functions, just feed is a mapObj with a populated queryObj... +** Wrapper for all query functions, just feed is a mapObj with a populated +*queryObj... */ -int msExecuteQuery(mapObj *map) -{ - int tmp=-1, status; +int msExecuteQuery(mapObj *map) { + int tmp = -1, status; /* handle slayer/qlayer management for feature queries */ - if(map->query.slayer >= 0) { + if (map->query.slayer >= 0) { tmp = map->query.layer; map->query.layer = map->query.slayer; } - switch(map->query.type) { - case MS_QUERY_BY_POINT: - status = msQueryByPoint(map); - break; - case MS_QUERY_BY_RECT: - status = msQueryByRect(map); - break; - case MS_QUERY_BY_FILTER: - status = msQueryByFilter(map); - break; - case MS_QUERY_BY_SHAPE: - status = msQueryByShape(map); - break; - case MS_QUERY_BY_INDEX: - status = msQueryByIndex(map); - break; - default: - msSetError(MS_QUERYERR, "Malformed queryObj.", "msExecuteQuery()"); - return(MS_FAILURE); + switch (map->query.type) { + case MS_QUERY_BY_POINT: + status = msQueryByPoint(map); + break; + case MS_QUERY_BY_RECT: + status = msQueryByRect(map); + break; + case MS_QUERY_BY_FILTER: + status = msQueryByFilter(map); + break; + case MS_QUERY_BY_SHAPE: + status = msQueryByShape(map); + break; + case MS_QUERY_BY_INDEX: + status = msQueryByIndex(map); + break; + default: + msSetError(MS_QUERYERR, "Malformed queryObj.", "msExecuteQuery()"); + return (MS_FAILURE); } - if(map->query.slayer >= 0) { + if (map->query.slayer >= 0) { map->query.layer = tmp; /* restore layer */ - if(status == MS_SUCCESS) status = msQueryByFeatures(map); + if (status == MS_SUCCESS) + status = msQueryByFeatures(map); } return status; @@ -137,89 +140,89 @@ int msExecuteQuery(mapObj *map) /* ** msIsLayerQueryable() returns MS_TRUE/MS_FALSE */ -int msIsLayerQueryable(layerObj *lp) -{ +int msIsLayerQueryable(layerObj *lp) { int i; - if ( lp->type == MS_LAYER_TILEINDEX ) + if (lp->type == MS_LAYER_TILEINDEX) return MS_FALSE; - if(lp->template && strlen(lp->template) > 0) return MS_TRUE; + if (lp->template && strlen(lp->template) > 0) + return MS_TRUE; - for(i=0; inumclasses; i++) { - if(lp->class[i]->template && strlen(lp->class[i]->template) > 0) + for (i = 0; i < lp->numclasses; i++) { + if (lp->class[i] -> template &&strlen(lp->class[i] -> template) > 0) return MS_TRUE; } return MS_FALSE; } -static void initQueryCache(queryCacheObj* queryCache) -{ - queryCache->cachedShapeCountWarningEmitted = MS_FALSE; - queryCache->cachedShapeCount = 0; - queryCache->cachedShapeRAMWarningEmitted = MS_FALSE; - queryCache->cachedShapeRAM = 0; +static void initQueryCache(queryCacheObj *queryCache) { + queryCache->cachedShapeCountWarningEmitted = MS_FALSE; + queryCache->cachedShapeCount = 0; + queryCache->cachedShapeRAMWarningEmitted = MS_FALSE; + queryCache->cachedShapeRAM = 0; } /** Check whether we should store the shape in resultCacheObj* given the * limits allowed in map->query.max_cached_shape_count and * map->query.max_cached_shape_ram_amount. */ -static int canCacheShape(mapObj* map, queryCacheObj *queryCache, int shape_ram_size) -{ - if( !map->query.cache_shapes ) - return MS_FALSE; - if( queryCache->cachedShapeCountWarningEmitted || +static int canCacheShape(mapObj *map, queryCacheObj *queryCache, + int shape_ram_size) { + if (!map->query.cache_shapes) + return MS_FALSE; + if (queryCache->cachedShapeCountWarningEmitted || (map->query.max_cached_shape_count > 0 && - queryCache->cachedShapeCount >= map->query.max_cached_shape_count) ) - { - if( !queryCache->cachedShapeCountWarningEmitted ) - { - queryCache->cachedShapeCountWarningEmitted = MS_TRUE; - if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("map->query.max_cached_shape_count = %d reached. " - "Next features will not be cached.\n", - map->query.max_cached_shape_count); - } + queryCache->cachedShapeCount >= map->query.max_cached_shape_count)) { + if (!queryCache->cachedShapeCountWarningEmitted) { + queryCache->cachedShapeCountWarningEmitted = MS_TRUE; + if (map->debug >= MS_DEBUGLEVEL_V) { + msDebug("map->query.max_cached_shape_count = %d reached. " + "Next features will not be cached.\n", + map->query.max_cached_shape_count); } - return MS_FALSE; + } + return MS_FALSE; } - if( queryCache->cachedShapeRAMWarningEmitted || + if (queryCache->cachedShapeRAMWarningEmitted || (map->query.max_cached_shape_ram_amount > 0 && - queryCache->cachedShapeRAM + shape_ram_size > map->query.max_cached_shape_ram_amount) ) - { - if( !queryCache->cachedShapeRAMWarningEmitted ) - { - queryCache->cachedShapeRAMWarningEmitted = MS_TRUE; - if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("map->query.max_cached_shape_ram_amount = %d reached after %d cached features. " - "Next features will not be cached.\n", - map->query.max_cached_shape_ram_amount, - queryCache->cachedShapeCount); - } + queryCache->cachedShapeRAM + shape_ram_size > + map->query.max_cached_shape_ram_amount)) { + if (!queryCache->cachedShapeRAMWarningEmitted) { + queryCache->cachedShapeRAMWarningEmitted = MS_TRUE; + if (map->debug >= MS_DEBUGLEVEL_V) { + msDebug("map->query.max_cached_shape_ram_amount = %d reached after %d " + "cached features. " + "Next features will not be cached.\n", + map->query.max_cached_shape_ram_amount, + queryCache->cachedShapeCount); } - return MS_FALSE; + } + return MS_FALSE; } return MS_TRUE; } -static int addResult(mapObj* map, resultCacheObj *cache, - queryCacheObj* queryCache, shapeObj *shape) -{ +static int addResult(mapObj *map, resultCacheObj *cache, + queryCacheObj *queryCache, shapeObj *shape) { int i; - int shape_ram_size = (map->query.max_cached_shape_ram_amount > 0) ? - msGetShapeRAMSize( shape ) : 0; - int store_shape = canCacheShape (map, queryCache, shape_ram_size); - - if(cache->numresults == cache->cachesize) { /* just add it to the end */ - if(cache->cachesize == 0) - cache->results = (resultObj *) malloc(sizeof(resultObj)*MS_RESULTCACHEINCREMENT); + int shape_ram_size = (map->query.max_cached_shape_ram_amount > 0) + ? msGetShapeRAMSize(shape) + : 0; + int store_shape = canCacheShape(map, queryCache, shape_ram_size); + + if (cache->numresults == cache->cachesize) { /* just add it to the end */ + if (cache->cachesize == 0) + cache->results = + (resultObj *)malloc(sizeof(resultObj) * MS_RESULTCACHEINCREMENT); else - cache->results = (resultObj *) realloc(cache->results, sizeof(resultObj)*(cache->cachesize+MS_RESULTCACHEINCREMENT)); - if(!cache->results) { + cache->results = (resultObj *)realloc( + cache->results, + sizeof(resultObj) * (cache->cachesize + MS_RESULTCACHEINCREMENT)); + if (!cache->results) { msSetError(MS_MEMERR, "Realloc() error.", "addResult()"); - return(MS_FAILURE); + return (MS_FAILURE); } cache->cachesize += MS_RESULTCACHEINCREMENT; } @@ -230,61 +233,64 @@ static int addResult(mapObj* map, resultCacheObj *cache, cache->results[i].tileindex = shape->tileindex; cache->results[i].shapeindex = shape->index; cache->results[i].resultindex = shape->resultindex; - if( store_shape ) - { - cache->results[i].shape = (shapeObj*)msSmallMalloc(sizeof(shapeObj)); - msInitShape(cache->results[i].shape); - msCopyShape(shape, cache->results[i].shape); - queryCache->cachedShapeCount ++; - queryCache->cachedShapeRAM += shape_ram_size; - } - else - cache->results[i].shape = NULL; + if (store_shape) { + cache->results[i].shape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); + msInitShape(cache->results[i].shape); + msCopyShape(shape, cache->results[i].shape); + queryCache->cachedShapeCount++; + queryCache->cachedShapeRAM += shape_ram_size; + } else + cache->results[i].shape = NULL; cache->numresults++; cache->previousBounds = cache->bounds; - if(cache->numresults == 1) + if (cache->numresults == 1) cache->bounds = shape->bounds; else msMergeRect(&(cache->bounds), &(shape->bounds)); - return(MS_SUCCESS); + return (MS_SUCCESS); } /* ** Serialize a query result set to disk. */ -static int saveQueryResults(mapObj *map, char *filename) -{ +static int saveQueryResults(mapObj *map, char *filename) { FILE *stream; - int i, j, n=0; + int i, j, n = 0; - if(!filename) { - msSetError(MS_MISCERR, "No filename provided to save query results to.", "saveQueryResults()"); + if (!filename) { + msSetError(MS_MISCERR, "No filename provided to save query results to.", + "saveQueryResults()"); return MS_FAILURE; } stream = fopen(filename, "w"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "saveQueryResults()", filename); return MS_FAILURE; } - fprintf(stream, "%s - Generated by msSaveQuery()\n", MS_QUERY_RESULTS_MAGIC_STRING); + fprintf(stream, "%s - Generated by msSaveQuery()\n", + MS_QUERY_RESULTS_MAGIC_STRING); /* count the number of layers with results */ - for(i=0; inumlayers; i++) - if(GET_LAYER(map, i)->resultcache) n++; + for (i = 0; i < map->numlayers; i++) + if (GET_LAYER(map, i)->resultcache) + n++; fwrite(&n, sizeof(int), 1, stream); /* now write the result set for each layer */ - for(i=0; inumlayers; i++) { - if(GET_LAYER(map, i)->resultcache) { + for (i = 0; i < map->numlayers; i++) { + if (GET_LAYER(map, i)->resultcache) { fwrite(&i, sizeof(int), 1, stream); /* layer index */ - fwrite(&(GET_LAYER(map, i)->resultcache->numresults), sizeof(int), 1, stream); /* number of results */ - fwrite(&(GET_LAYER(map, i)->resultcache->bounds), sizeof(rectObj), 1, stream); /* bounding box */ - for(j=0; jresultcache->numresults; j++) - fwrite(&(GET_LAYER(map, i)->resultcache->results[j]), sizeof(resultObj), 1, stream); /* each result */ + fwrite(&(GET_LAYER(map, i)->resultcache->numresults), sizeof(int), 1, + stream); /* number of results */ + fwrite(&(GET_LAYER(map, i)->resultcache->bounds), sizeof(rectObj), 1, + stream); /* bounding box */ + for (j = 0; j < GET_LAYER(map, i)->resultcache->numresults; j++) + fwrite(&(GET_LAYER(map, i)->resultcache->results[j]), sizeof(resultObj), + 1, stream); /* each result */ } } @@ -292,65 +298,87 @@ static int saveQueryResults(mapObj *map, char *filename) return MS_SUCCESS; } -static int loadQueryResults(mapObj *map, FILE *stream) -{ - int i, j, k, n=0; +static int loadQueryResults(mapObj *map, FILE *stream) { + int i, j, k, n = 0; - if(1 != fread(&n, sizeof(int), 1, stream) || n > INT_MAX - 1) { - msSetError(MS_MISCERR,"failed to read query count from query file stream", "loadQueryResults()"); + if (1 != fread(&n, sizeof(int), 1, stream) || n > INT_MAX - 1) { + msSetError(MS_MISCERR, "failed to read query count from query file stream", + "loadQueryResults()"); return MS_FAILURE; } /* now load the result set for each layer found in the query file */ - for(i=0; imap->numlayers) { - msSetError(MS_MISCERR, "Invalid layer index loaded from query file.", "loadQueryResults()"); + if (j < 0 || j > map->numlayers) { + msSetError(MS_MISCERR, "Invalid layer index loaded from query file.", + "loadQueryResults()"); return MS_FAILURE; } /* inialize the results for this layer */ - GET_LAYER(map, j)->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ - MS_CHECK_ALLOC(GET_LAYER(map, j)->resultcache, sizeof(resultCacheObj), MS_FAILURE); - - if(1 != fread(&(GET_LAYER(map, j)->resultcache->numresults), sizeof(int), 1, stream) || (GET_LAYER(map, j)->resultcache->numresults < 0)) { /* number of results */ - msSetError(MS_MISCERR,"failed to read number of results from query file stream", "loadQueryResults()"); + GET_LAYER(map, j)->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + MS_CHECK_ALLOC(GET_LAYER(map, j)->resultcache, sizeof(resultCacheObj), + MS_FAILURE); + + if (1 != fread(&(GET_LAYER(map, j)->resultcache->numresults), sizeof(int), + 1, stream) || + (GET_LAYER(map, j)->resultcache->numresults < + 0)) { /* number of results */ + msSetError(MS_MISCERR, + "failed to read number of results from query file stream", + "loadQueryResults()"); free(GET_LAYER(map, j)->resultcache); GET_LAYER(map, j)->resultcache = NULL; return MS_FAILURE; } - GET_LAYER(map, j)->resultcache->cachesize = GET_LAYER(map, j)->resultcache->numresults; + GET_LAYER(map, j)->resultcache->cachesize = + GET_LAYER(map, j)->resultcache->numresults; - if(1 != fread(&(GET_LAYER(map, j)->resultcache->bounds), sizeof(rectObj), 1, stream)) { /* bounding box */ - msSetError(MS_MISCERR,"failed to read bounds from query file stream", "loadQueryResults()"); + if (1 != fread(&(GET_LAYER(map, j)->resultcache->bounds), sizeof(rectObj), + 1, stream)) { /* bounding box */ + msSetError(MS_MISCERR, "failed to read bounds from query file stream", + "loadQueryResults()"); free(GET_LAYER(map, j)->resultcache); GET_LAYER(map, j)->resultcache = NULL; return MS_FAILURE; } - GET_LAYER(map, j)->resultcache->results = (resultObj *) malloc(sizeof(resultObj)*GET_LAYER(map, j)->resultcache->numresults); + GET_LAYER(map, j)->resultcache->results = (resultObj *)malloc( + sizeof(resultObj) * GET_LAYER(map, j)->resultcache->numresults); if (GET_LAYER(map, j)->resultcache->results == NULL) { - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "loadQueryResults()", - __FILE__, __LINE__, (unsigned int)(sizeof(resultObj)*GET_LAYER(map, j)->resultcache->numresults)); + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", + "loadQueryResults()", __FILE__, __LINE__, + (unsigned int)(sizeof(resultObj) * + GET_LAYER(map, j)->resultcache->numresults)); free(GET_LAYER(map, j)->resultcache); GET_LAYER(map, j)->resultcache = NULL; return MS_FAILURE; } - for(k=0; kresultcache->numresults; k++) { - if(1 != fread(&(GET_LAYER(map, j)->resultcache->results[k]), sizeof(resultObj), 1, stream)) { /* each result */ - msSetError(MS_MISCERR,"failed to read result %d from query file stream", "loadQueryResults()", k); + for (k = 0; k < GET_LAYER(map, j)->resultcache->numresults; k++) { + if (1 != fread(&(GET_LAYER(map, j)->resultcache->results[k]), + sizeof(resultObj), 1, stream)) { /* each result */ + msSetError(MS_MISCERR, + "failed to read result %d from query file stream", + "loadQueryResults()", k); free(GET_LAYER(map, j)->resultcache->results); free(GET_LAYER(map, j)->resultcache); GET_LAYER(map, j)->resultcache = NULL; return MS_FAILURE; } - if(!GET_LAYER(map, j)->tileindex) GET_LAYER(map, j)->resultcache->results[k].tileindex = -1; /* reset the tile index for non-tiled layers */ - GET_LAYER(map, j)->resultcache->results[k].resultindex = -1; /* all results loaded this way have a -1 result (set) index */ + if (!GET_LAYER(map, j)->tileindex) + GET_LAYER(map, j)->resultcache->results[k].tileindex = + -1; /* reset the tile index for non-tiled layers */ + GET_LAYER(map, j)->resultcache->results[k].resultindex = + -1; /* all results loaded this way have a -1 result (set) index */ } } @@ -358,43 +386,54 @@ static int loadQueryResults(mapObj *map, FILE *stream) } /* -** Serialize the parameters necessary to duplicate a query to disk. (TODO: add filter query...) +** Serialize the parameters necessary to duplicate a query to disk. (TODO: add +*filter query...) */ -static int saveQueryParams(mapObj *map, char *filename) -{ +static int saveQueryParams(mapObj *map, char *filename) { FILE *stream; - if(!filename) { - msSetError(MS_MISCERR, "No filename provided to save query to.", "saveQueryParams()"); + if (!filename) { + msSetError(MS_MISCERR, "No filename provided to save query to.", + "saveQueryParams()"); return MS_FAILURE; } stream = fopen(filename, "w"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "saveQueryParams()", filename); return MS_FAILURE; } - fprintf(stream, "%s - Generated by msSaveQuery()\n", MS_QUERY_PARAMS_MAGIC_STRING); - - fprintf(stream, "%d %d %d %d\n", map->query.mode, map->query.type, map->query.layer, map->query.slayer); /* all queries */ - fprintf(stream, "%.15g %.15g %g %d\n", map->query.point.x, map->query.point.y, map->query.buffer, map->query.maxresults); /* by point */ - fprintf(stream, "%.15g %.15g %.15g %.15g\n", map->query.rect.minx, map->query.rect.miny, map->query.rect.maxx, map->query.rect.maxy); /* by rect */ - fprintf(stream, "%ld %ld %d\n", map->query.shapeindex, map->query.tileindex, map->query.clear_resultcache); /* by index */ - - fprintf(stream, "%s\n", (map->query.filteritem)?map->query.filteritem:"NULL"); /* by filter */ - fprintf(stream, "%s\n", (map->query.filter.string)?map->query.filter.string:"NULL"); - - if(map->query.shape) { /* by shape */ + fprintf(stream, "%s - Generated by msSaveQuery()\n", + MS_QUERY_PARAMS_MAGIC_STRING); + + fprintf(stream, "%d %d %d %d\n", map->query.mode, map->query.type, + map->query.layer, map->query.slayer); /* all queries */ + fprintf(stream, "%.15g %.15g %g %d\n", map->query.point.x, map->query.point.y, + map->query.buffer, map->query.maxresults); /* by point */ + fprintf(stream, "%.15g %.15g %.15g %.15g\n", map->query.rect.minx, + map->query.rect.miny, map->query.rect.maxx, + map->query.rect.maxy); /* by rect */ + fprintf(stream, "%ld %ld %d\n", map->query.shapeindex, map->query.tileindex, + map->query.clear_resultcache); /* by index */ + + fprintf(stream, "%s\n", + (map->query.filteritem) ? map->query.filteritem + : "NULL"); /* by filter */ + fprintf(stream, "%s\n", + (map->query.filter.string) ? map->query.filter.string : "NULL"); + + if (map->query.shape) { /* by shape */ int i, j; shapeObj *s = map->query.shape; fprintf(stream, "%d\n", s->type); fprintf(stream, "%d\n", s->numlines); - for(i=0; inumlines; i++) { + for (i = 0; i < s->numlines; i++) { fprintf(stream, "%d\n", s->line[i].numpoints); - for(j=0; jline[i].numpoints; j++) - fprintf(stream, "%.15g %.15g\n", s->line[i].point[j].x, s->line[i].point[j].y); + for (j = 0; j < s->line[i].numpoints; j++) + fprintf(stream, "%.15g %.15g\n", s->line[i].point[j].x, + s->line[i].point[j].y); } } else { fprintf(stream, "%d\n", MS_SHAPE_NULL); /* NULL shape */ @@ -404,8 +443,7 @@ static int saveQueryParams(mapObj *map, char *filename) return MS_SUCCESS; } -static int loadQueryParams(mapObj *map, FILE *stream) -{ +static int loadQueryParams(mapObj *map, FILE *stream) { char buffer[MS_BUFFER_LENGTH]; int lineno; @@ -414,60 +452,78 @@ static int loadQueryParams(mapObj *map, FILE *stream) msInitQuery(&(map->query)); /* this will free any previous query as well */ lineno = 2; /* line 1 is the magic string */ - while(fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { - switch(lineno) { - case 2: - if(sscanf(buffer, "%d %d %d %d\n", &(map->query.mode), &(map->query.type), &(map->query.layer), &(map->query.slayer)) != 4) goto parse_error; - break; - case 3: - if(sscanf(buffer, "%lf %lf %lf %d\n", &map->query.point.x, &map->query.point.y, &map->query.buffer, &map->query.maxresults) != 4) goto parse_error; - break; - case 4: - if(sscanf(buffer, "%lf %lf %lf %lf\n", &map->query.rect.minx, &map->query.rect.miny, &map->query.rect.maxx, &map->query.rect.maxy) != 4) goto parse_error; - break; - case 5: - if(sscanf(buffer, "%ld %ld %d\n", &map->query.shapeindex, &map->query.tileindex, &map->query.clear_resultcache) != 3) goto parse_error; - break; - case 6: - if(strncmp(buffer, "NULL", 4) != 0) { - map->query.filteritem = msStrdup(buffer); - msStringChop(map->query.filteritem); - } - break; - case 7: - if(strncmp(buffer, "NULL", 4) != 0) - msLoadExpressionString(&map->query.filter, buffer); /* chop buffer */ - break; - case 8: - if(sscanf(buffer, "%d\n", &shapetype) != 1) goto parse_error; - - if(shapetype != MS_SHAPE_NULL) { /* load the rest of the shape */ - int i, j; - lineObj line; - - map->query.shape = (shapeObj *) msSmallMalloc(sizeof(shapeObj)); - msInitShape(map->query.shape); - map->query.shape->type = shapetype; - - if(fscanf(stream, "%d\n", &numlines) != 1) goto parse_error; - if( numlines > INT_MAX - 1 ) goto parse_error; - for(i=0; i INT_MAX / (int)sizeof(pointObj)) goto parse_error; - - line.numpoints = numpoints; - line.point = (pointObj *) msSmallMalloc(line.numpoints*sizeof(pointObj)); - - for(j=0; jquery.shape, &line); - free(line.point); - } + while (fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { + switch (lineno) { + case 2: + if (sscanf(buffer, "%d %d %d %d\n", &(map->query.mode), + &(map->query.type), &(map->query.layer), + &(map->query.slayer)) != 4) + goto parse_error; + break; + case 3: + if (sscanf(buffer, "%lf %lf %lf %d\n", &map->query.point.x, + &map->query.point.y, &map->query.buffer, + &map->query.maxresults) != 4) + goto parse_error; + break; + case 4: + if (sscanf(buffer, "%lf %lf %lf %lf\n", &map->query.rect.minx, + &map->query.rect.miny, &map->query.rect.maxx, + &map->query.rect.maxy) != 4) + goto parse_error; + break; + case 5: + if (sscanf(buffer, "%ld %ld %d\n", &map->query.shapeindex, + &map->query.tileindex, &map->query.clear_resultcache) != 3) + goto parse_error; + break; + case 6: + if (strncmp(buffer, "NULL", 4) != 0) { + map->query.filteritem = msStrdup(buffer); + msStringChop(map->query.filteritem); + } + break; + case 7: + if (strncmp(buffer, "NULL", 4) != 0) + msLoadExpressionString(&map->query.filter, buffer); /* chop buffer */ + break; + case 8: + if (sscanf(buffer, "%d\n", &shapetype) != 1) + goto parse_error; + + if (shapetype != MS_SHAPE_NULL) { /* load the rest of the shape */ + int i, j; + lineObj line; + + map->query.shape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); + msInitShape(map->query.shape); + map->query.shape->type = shapetype; + + if (fscanf(stream, "%d\n", &numlines) != 1) + goto parse_error; + if (numlines > INT_MAX - 1) + goto parse_error; + for (i = 0; i < numlines; i++) { + if (fscanf(stream, "%d\n", &numpoints) != 1 || numpoints < 0 || + numpoints > INT_MAX / (int)sizeof(pointObj)) + goto parse_error; + + line.numpoints = numpoints; + line.point = + (pointObj *)msSmallMalloc(line.numpoints * sizeof(pointObj)); + + for (j = 0; j < numpoints; j++) + if (fscanf(stream, "%lf %lf\n", &line.point[j].x, + &line.point[j].y) != 2) + goto parse_error; + + msAddLine(map->query.shape, &line); + free(line.point); } - break; - default: - break; + } + break; + default: + break; } lineno++; @@ -476,49 +532,55 @@ static int loadQueryParams(mapObj *map, FILE *stream) /* TODO: should we throw an error if lineno != 10? */ /* force layer and slayer on */ - if(map->query.layer >= 0 && map->query.layer < map->numlayers) GET_LAYER(map, map->query.layer)->status = MS_ON; - if(map->query.slayer >= 0 && map->query.slayer < map->numlayers) GET_LAYER(map, map->query.slayer)->status = MS_ON; + if (map->query.layer >= 0 && map->query.layer < map->numlayers) + GET_LAYER(map, map->query.layer)->status = MS_ON; + if (map->query.slayer >= 0 && map->query.slayer < map->numlayers) + GET_LAYER(map, map->query.slayer)->status = MS_ON; /* now execute the query */ return msExecuteQuery(map); parse_error: - msSetError(MS_MISCERR, "Parse error line %d.", "loadQueryParameters()", lineno); + msSetError(MS_MISCERR, "Parse error line %d.", "loadQueryParameters()", + lineno); return MS_FAILURE; } /* -** Save (serialize) a query to disk. There are two methods, one saves the query parameters and the other saves -** all the shape indexes. Note the latter can be very slow against certain data sources but has a certain usefulness +** Save (serialize) a query to disk. There are two methods, one saves the query +*parameters and the other saves +** all the shape indexes. Note the latter can be very slow against certain data +*sources but has a certain usefulness ** on occation. */ -int msSaveQuery(mapObj *map, char *filename, int results) -{ - if(results) +int msSaveQuery(mapObj *map, char *filename, int results) { + if (results) return saveQueryResults(map, filename); else return saveQueryParams(map, filename); } /* -** Loads a query file contained either serialized 1) query parameters or 2) query results (e.g. indexes). +** Loads a query file contained either serialized 1) query parameters or 2) +*query results (e.g. indexes). */ -int msLoadQuery(mapObj *map, char *filename) -{ +int msLoadQuery(mapObj *map, char *filename) { FILE *stream; char buffer[MS_BUFFER_LENGTH]; - int retval=MS_FAILURE; + int retval = MS_FAILURE; - if(!filename) { - msSetError(MS_MISCERR, "No filename provided to load query from.", "msLoadQuery()"); + if (!filename) { + msSetError(MS_MISCERR, "No filename provided to load query from.", + "msLoadQuery()"); return MS_FAILURE; } /* ** Make sure the file at least has the right extension. */ - if(msEvalRegex("\\.qy$", filename) != MS_TRUE) { - msSetError(MS_MISCERR, "Queryfile %s has incorrect file extension.", "msLoadQuery()", filename); + if (msEvalRegex("\\.qy$", filename) != MS_TRUE) { + msSetError(MS_MISCERR, "Queryfile %s has incorrect file extension.", + "msLoadQuery()", filename); return MS_FAILURE; } @@ -526,25 +588,31 @@ int msLoadQuery(mapObj *map, char *filename) ** Open the file and inspect the first line. */ stream = fopen(filename, "r"); - if(!stream) { + if (!stream) { msSetError(MS_IOERR, "(%s)", "msLoadQuery()", filename); return MS_FAILURE; } - if(fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { + if (fgets(buffer, MS_BUFFER_LENGTH, stream) != NULL) { /* ** Call correct reader based on the magic string. */ - if(strncasecmp(buffer, MS_QUERY_RESULTS_MAGIC_STRING, strlen(MS_QUERY_RESULTS_MAGIC_STRING)) == 0) { + if (strncasecmp(buffer, MS_QUERY_RESULTS_MAGIC_STRING, + strlen(MS_QUERY_RESULTS_MAGIC_STRING)) == 0) { retval = loadQueryResults(map, stream); - } else if(strncasecmp(buffer, MS_QUERY_PARAMS_MAGIC_STRING, strlen(MS_QUERY_PARAMS_MAGIC_STRING)) == 0) { + } else if (strncasecmp(buffer, MS_QUERY_PARAMS_MAGIC_STRING, + strlen(MS_QUERY_PARAMS_MAGIC_STRING)) == 0) { retval = loadQueryParams(map, stream); } else { - msSetError(MS_WEBERR, "Missing magic string, %s doesn't look like a MapServer query file.", "msLoadQuery()", filename); + msSetError( + MS_WEBERR, + "Missing magic string, %s doesn't look like a MapServer query file.", + "msLoadQuery()", filename); retval = MS_FAILURE; } } else { - msSetError(MS_WEBERR, "Empty file or failed read for %s.", "msLoadQuery()", filename); + msSetError(MS_WEBERR, "Empty file or failed read for %s.", "msLoadQuery()", + filename); retval = MS_FAILURE; } @@ -552,8 +620,7 @@ int msLoadQuery(mapObj *map, char *filename) return retval; } -int msQueryByIndex(mapObj *map) -{ +int msQueryByIndex(mapObj *map) { layerObj *lp; int status; @@ -565,25 +632,27 @@ int msQueryByIndex(mapObj *map) initQueryCache(&queryCache); - if(map->query.type != MS_QUERY_BY_INDEX) { - msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByIndex()"); - return(MS_FAILURE); + if (map->query.type != MS_QUERY_BY_INDEX) { + msSetError(MS_QUERYERR, "The query is not properly defined.", + "msQueryByIndex()"); + return (MS_FAILURE); } - if(map->query.layer < 0 || map->query.layer >= map->numlayers) { + if (map->query.layer < 0 || map->query.layer >= map->numlayers) { msSetError(MS_QUERYERR, "No query layer defined.", "msQueryByIndex()"); - return(MS_FAILURE); + return (MS_FAILURE); } lp = (GET_LAYER(map, map->query.layer)); - if(!msIsLayerQueryable(lp)) { - msSetError(MS_QUERYERR, "Requested layer has no templates defined.", "msQueryByIndex()"); - return(MS_FAILURE); + if (!msIsLayerQueryable(lp)) { + msSetError(MS_QUERYERR, "Requested layer has no templates defined.", + "msQueryByIndex()"); + return (MS_FAILURE); } - if(map->query.clear_resultcache) { - if(lp->resultcache) { + if (map->query.clear_resultcache) { + if (lp->resultcache) { cleanupResultCache(lp->resultcache); free(lp->resultcache); lp->resultcache = NULL; @@ -592,18 +661,21 @@ int msQueryByIndex(mapObj *map) msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); /* disable driver paging */ msLayerEnablePaging(lp, MS_FALSE); /* build item list, we want *all* items */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); - if(map->query.clear_resultcache || lp->resultcache == NULL) { - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + if (map->query.clear_resultcache || lp->resultcache == NULL) { + lp->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); } msInitShape(&shape); @@ -613,9 +685,9 @@ int msQueryByIndex(mapObj *map) record.tileindex = map->query.tileindex; status = msLayerGetShape(lp, &shape, &record); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msSetError(MS_NOTFOUND, "Not valid record request.", "msQueryByIndex()"); - return(MS_FAILURE); + return (MS_FAILURE); } /* @@ -625,7 +697,9 @@ int msQueryByIndex(mapObj *map) * thus useless as the index in the result cache. See #4926 #4076. Only shape * files and flatgeobuf are considered to have consistent row numbers. */ - if ( !(lp->connectiontype == MS_SHAPEFILE || lp->connectiontype == MS_TILED_SHAPEFILE || lp->connectiontype == MS_FLATGEOBUF) ) { + if (!(lp->connectiontype == MS_SHAPEFILE || + lp->connectiontype == MS_TILED_SHAPEFILE || + lp->connectiontype == MS_FLATGEOBUF)) { shape.resultindex = -1; } @@ -633,63 +707,75 @@ int msQueryByIndex(mapObj *map) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - msSetError(MS_NOTFOUND, "Requested shape not valid against layer minfeaturesize.", "msQueryByIndex()"); + msSetError(MS_NOTFOUND, + "Requested shape not valid against layer minfeaturesize.", + "msQueryByIndex()"); msFreeShape(&shape); msLayerClose(lp); - return(MS_FAILURE); + return (MS_FAILURE); } } shape.classindex = msShapeGetClass(lp, map, &shape, NULL, 0); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ - msSetError(MS_NOTFOUND, "Requested shape not valid against layer classification scheme.", "msQueryByIndex()"); + if (!(lp->template) && + ((shape.classindex == -1) || + (lp->class[shape.classindex] -> status == + MS_OFF))) { /* not a valid shape */ + msSetError(MS_NOTFOUND, + "Requested shape not valid against layer classification scheme.", + "msQueryByIndex()"); msFreeShape(&shape); msLayerClose(lp); - return(MS_FAILURE); + return (MS_FAILURE); } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ - msSetError(MS_NOTFOUND, "Requested shape does not have a valid template, no way to present results.", "msQueryByIndex()"); + if (!(lp->template) && + !(lp->class[shape.classindex] -> template)) { /* no valid template */ + msSetError(MS_NOTFOUND, + "Requested shape does not have a valid template, no way to " + "present results.", + "msQueryByIndex()"); msFreeShape(&shape); msLayerClose(lp); - return(MS_FAILURE); + return (MS_FAILURE); } - + addResult(map, lp->resultcache, &queryCache, &shape); msFreeShape(&shape); /* msLayerClose(lp); */ - return(MS_SUCCESS); + return (MS_SUCCESS); } static char *filterTranslateToLogical(expressionObj *filter, char *filteritem) { char *string = NULL; - if(filter->type == MS_STRING && filteritem) { + if (filter->type == MS_STRING && filteritem) { string = msStrdup("'["); string = msStringConcatenate(string, filteritem); string = msStringConcatenate(string, "]'"); - if(filter->flags & MS_EXP_INSENSITIVE) + if (filter->flags & MS_EXP_INSENSITIVE) string = msStringConcatenate(string, " =* '"); else string = msStringConcatenate(string, " = '"); string = msStringConcatenate(string, filter->string); string = msStringConcatenate(string, "'"); - } else if(filter->type == MS_REGEX && filteritem) { + } else if (filter->type == MS_REGEX && filteritem) { string = msStrdup("'["); string = msStringConcatenate(string, filteritem); string = msStringConcatenate(string, "]'"); - if(filter->flags & MS_EXP_INSENSITIVE) + if (filter->flags & MS_EXP_INSENSITIVE) string = msStringConcatenate(string, " ~* '"); else string = msStringConcatenate(string, " ~ '"); string = msStringConcatenate(string, filter->string); string = msStringConcatenate(string, "'"); - } else if(filter->type == MS_EXPRESSION) { + } else if (filter->type == MS_EXPRESSION) { string = msStrdup(filter->string); } else { /* native expression, nothing we can do - sigh */ @@ -698,20 +784,22 @@ static char *filterTranslateToLogical(expressionObj *filter, char *filteritem) { return string; } -static expressionObj mergeFilters(expressionObj *filter1, char *filteritem1, expressionObj *filter2, char *filteritem2) { +static expressionObj mergeFilters(expressionObj *filter1, char *filteritem1, + expressionObj *filter2, char *filteritem2) { expressionObj filter; - char *tmpstr1=NULL; - char *tmpstr2=NULL; + char *tmpstr1 = NULL; + char *tmpstr2 = NULL; msInitExpression(&filter); filter.type = MS_EXPRESSION; /* we're building a logical expression */ tmpstr1 = filterTranslateToLogical(filter1, filteritem1); - if(!tmpstr1) return filter; /* should only happen if the filter was a native filter */ + if (!tmpstr1) + return filter; /* should only happen if the filter was a native filter */ tmpstr2 = filterTranslateToLogical(filter2, filteritem2); - if(!tmpstr2) { + if (!tmpstr2) { msFree(tmpstr1); return filter; /* should only happen if the filter was a native filter */ } @@ -729,16 +817,15 @@ static expressionObj mergeFilters(expressionObj *filter1, char *filteritem1, exp /* ** Query using common expression syntax. */ -int msQueryByFilter(mapObj *map) -{ +int msQueryByFilter(mapObj *map) { int l; - int start, stop=0; + int start, stop = 0; layerObj *lp; char status; - char *old_filteritem=NULL; + char *old_filteritem = NULL; expressionObj old_filter; rectObj search_rect; @@ -754,26 +841,28 @@ int msQueryByFilter(mapObj *map) initQueryCache(&queryCache); - if(map->query.type != MS_QUERY_BY_FILTER) { - msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByFilter()"); - return(MS_FAILURE); + if (map->query.type != MS_QUERY_BY_FILTER) { + msSetError(MS_QUERYERR, "The query is not properly defined.", + "msQueryByFilter()"); + return (MS_FAILURE); } - if(!map->query.filter.string) { + if (!map->query.filter.string) { msSetError(MS_QUERYERR, "Filter is not set.", "msQueryByFilter()"); - return(MS_FAILURE); + return (MS_FAILURE); } - // fprintf(stderr, "in msQueryByFilter: filter=%s, filteritem=%s\n", map->query.filter.string, map->query.filteritem); + // fprintf(stderr, "in msQueryByFilter: filter=%s, filteritem=%s\n", + // map->query.filter.string, map->query.filteritem); msInitShape(&shape); - if(map->query.layer < 0 || map->query.layer >= map->numlayers) - start = map->numlayers-1; + if (map->query.layer < 0 || map->query.layer >= map->numlayers) + start = map->numlayers - 1; else start = stop = map->query.layer; - for(l=start; l>=stop; l--) { - reprojectionObj* reprojector = NULL; + for (l = start; l >= stop; l--) { + reprojectionObj *reprojector = NULL; lp = (GET_LAYER(map, l)); if (map->query.maxfeatures == 0) @@ -784,114 +873,132 @@ int msQueryByFilter(mapObj *map) /* using mapscript, the map->query.startindex will be unset... */ if (lp->startindex > 1 && map->query.startindex < 0) map->query.startindex = lp->startindex; - + /* conditions may have changed since this layer last drawn, so set layer->project true to recheck projection needs (Bug #673) */ lp->project = MS_TRUE; - /* free any previous search results, do it now in case one of the next few tests fail */ - if(lp->resultcache) { - if(lp->resultcache->results) free(lp->resultcache->results); + /* free any previous search results, do it now in case one of the next few + * tests fail */ + if (lp->resultcache) { + if (lp->resultcache->results) + free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; } - if(!msIsLayerQueryable(lp)) continue; - if(lp->status == MS_OFF) continue; - if(lp->type == MS_LAYER_RASTER) continue; /* ok to skip? */ + if (!msIsLayerQueryable(lp)) + continue; + if (lp->status == MS_OFF) + continue; + if (lp->type == MS_LAYER_RASTER) + continue; /* ok to skip? */ - if(map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } paging = msLayerGetPaging(lp); msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) return MS_FAILURE; + if (status != MS_SUCCESS) + return MS_FAILURE; msLayerEnablePaging(lp, paging); /* disable driver paging */ // msLayerEnablePaging(lp, MS_FALSE); - + old_filteritem = lp->filteritem; /* cache the existing filter/filteritem */ msInitExpression(&old_filter); msCopyExpression(&old_filter, &lp->filter); - + /* - ** Set the lp->filter and lp->filteritem (may need to merge). Remember filters are *always* MapServer syntax. + ** Set the lp->filter and lp->filteritem (may need to merge). Remember + *filters are *always* MapServer syntax. */ lp->filteritem = map->query.filteritem; /* re-point lp->filteritem */ - if(old_filter.string != NULL) { /* need to merge filters to create one logical expression */ + if (old_filter.string != + NULL) { /* need to merge filters to create one logical expression */ msFreeExpression(&lp->filter); - lp->filter = mergeFilters(&map->query.filter, map->query.filteritem, &old_filter, old_filteritem); - if(!lp->filter.string) { - msSetError(MS_MISCERR, "Filter merge failed, able to process query.", "msQueryByFilter()"); + lp->filter = mergeFilters(&map->query.filter, map->query.filteritem, + &old_filter, old_filteritem); + if (!lp->filter.string) { + msSetError(MS_MISCERR, "Filter merge failed, able to process query.", + "msQueryByFilter()"); goto restore_old_filter; - } + } } else { msCopyExpression(&lp->filter, &map->query.filter); /* apply new filter */ } - /* build item list, we want *all* items, note this *also* build tokens for the layer filter */ + /* build item list, we want *all* items, note this *also* build tokens for + * the layer filter */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) goto restore_old_filter; + if (status != MS_SUCCESS) + goto restore_old_filter; search_rect = map->query.rect; /* If only result count is needed, we can use msLayerGetShapeCount() */ /* that has optimizations to avoid retrieving individual features */ - if( map->query.only_cache_result_count && + if (map->query.only_cache_result_count && lp->template != NULL && /* always TRUE for WFS case */ - lp->minfeaturesize <= 0 ) - { + lp->minfeaturesize <= 0) { int bUseLayerSRS = MS_FALSE; int numFeatures = -1; -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Optimization to detect the case where a WFS query uses in fact the */ - /* whole layer extent, but expressed in a map SRS different from the layer SRS */ - /* In the case, we can directly request against the layer extent in its native SRS */ - if( lp->project && - memcmp( &search_rect, &invalid_rect, sizeof(search_rect) ) != 0 && - msProjectionsDiffer(&(lp->projection), &(map->projection)) ) - { + /* whole layer extent, but expressed in a map SRS different from the layer + * SRS */ + /* In the case, we can directly request against the layer extent in its + * native SRS */ + if (lp->project && + memcmp(&search_rect, &invalid_rect, sizeof(search_rect)) != 0 && + msProjectionsDiffer(&(lp->projection), &(map->projection))) { rectObj layerExtent; - if ( msOWSGetLayerExtent(map, lp, "FO", &layerExtent) == MS_SUCCESS) - { - rectObj ext = layerExtent; - ext.minx -= 1e-5; - ext.miny -= 1e-5; - ext.maxx += 1e-5; - ext.maxy += 1e-5; - msProjectRect(&(lp->projection), &(map->projection), &ext); - if( fabs(ext.minx - search_rect.minx) <= 2e-5 && - fabs(ext.miny - search_rect.miny) <= 2e-5 && - fabs(ext.maxx - search_rect.maxx) <= 2e-5 && - fabs(ext.maxy - search_rect.maxy) <= 2e-5 ) - { - bUseLayerSRS = MS_TRUE; - numFeatures = msLayerGetShapeCount(lp, layerExtent, &(lp->projection)); - } + if (msOWSGetLayerExtent(map, lp, "FO", &layerExtent) == MS_SUCCESS) { + rectObj ext = layerExtent; + ext.minx -= 1e-5; + ext.miny -= 1e-5; + ext.maxx += 1e-5; + ext.maxy += 1e-5; + msProjectRect(&(lp->projection), &(map->projection), &ext); + if (fabs(ext.minx - search_rect.minx) <= 2e-5 && + fabs(ext.miny - search_rect.miny) <= 2e-5 && + fabs(ext.maxx - search_rect.maxx) <= 2e-5 && + fabs(ext.maxy - search_rect.maxy) <= 2e-5) { + bUseLayerSRS = MS_TRUE; + numFeatures = + msLayerGetShapeCount(lp, layerExtent, &(lp->projection)); + } } } #endif - if( !bUseLayerSRS ) - numFeatures = msLayerGetShapeCount(lp, search_rect, &(map->projection)); - if( numFeatures >= 0 ) - { - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + if (!bUseLayerSRS) + numFeatures = msLayerGetShapeCount(lp, search_rect, &(map->projection)); + if (numFeatures >= 0) { + lp->resultcache = (resultCacheObj *)malloc(sizeof( + resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); lp->resultcache->numresults = numFeatures; if (!msLayerGetPaging(lp) && map->query.startindex > 1) { - lp->resultcache->numresults -= (map->query.startindex-1); + lp->resultcache->numresults -= (map->query.startindex - 1); } lp->filteritem = old_filteritem; /* point back to original value */ @@ -904,20 +1011,24 @@ int msQueryByFilter(mapObj *map) } lp->project = msProjectionsDiffer(&(lp->projection), &(map->projection)); - if(lp->project && memcmp( &search_rect, &invalid_rect, sizeof(search_rect) ) != 0 ) - msProjectRect(&(map->projection), &(lp->projection), &search_rect); /* project the searchrect to source coords */ + if (lp->project && + memcmp(&search_rect, &invalid_rect, sizeof(search_rect)) != 0) + msProjectRect(&(map->projection), &(lp->projection), + &search_rect); /* project the searchrect to source coords */ status = msLayerWhichShapes(lp, search_rect, MS_TRUE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ lp->filteritem = old_filteritem; /* point back to original value */ msCopyExpression(&lp->filter, &old_filter); /* restore old filter */ msFreeExpression(&old_filter); msLayerClose(lp); continue; - } else if(status != MS_SUCCESS) goto restore_old_filter; + } else if (status != MS_SUCCESS) + goto restore_old_filter; - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ - initResultCache( lp->resultcache); + lp->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + initResultCache(lp->resultcache); nclasses = 0; classgroup = NULL; @@ -927,37 +1038,46 @@ int msQueryByFilter(mapObj *map) if (lp->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); - while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes - if necessary the filter is applied in msLayerNextShape(...) */ + while ((status = msLayerNextShape(lp, &shape)) == + MS_SUCCESS) { /* step through the shapes - if necessary the filter is + applied in msLayerNextShape(...) */ - /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + /* Check if the shape size is ok to be drawn */ + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - if( lp->debug >= MS_DEBUGLEVEL_V ) - msDebug("msQueryByFilter(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if (lp->debug >= MS_DEBUGLEVEL_V) + msDebug("msQueryByFilter(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); msFreeShape(&shape); continue; } } shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ + if (!(lp->template) && ((shape.classindex == -1) || + (lp->class[shape.classindex] + -> status == MS_OFF))) { /* not a valid shape */ msFreeShape(&shape); continue; } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ + if (!(lp->template) && + !(lp->class[shape.classindex] -> template)) { /* no valid template */ msFreeShape(&shape); continue; } - if(lp->project) { - if( reprojector == NULL ) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msFreeShape(&shape); - status = MS_FAILURE; - break; - } + if (lp->project) { + if (reprojector == NULL) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { + msFreeShape(&shape); + status = MS_FAILURE; + break; + } } msProjectShapeEx(reprojector, &shape); } @@ -968,26 +1088,29 @@ int msQueryByFilter(mapObj *map) msFreeShape(&shape); continue; } - - if( map->query.only_cache_result_count ) - lp->resultcache->numresults ++; + + if (map->query.only_cache_result_count) + lp->resultcache->numresults++; else addResult(map, lp->resultcache, &queryCache, &shape); msFreeShape(&shape); - if(map->query.mode == MS_QUERY_SINGLE) { /* no need to look any further */ - status = MS_DONE; - break; + if (map->query.mode == + MS_QUERY_SINGLE) { /* no need to look any further */ + status = MS_DONE; + break; } /* check shape count */ - if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) { + if (lp->maxfeatures > 0 && + lp->maxfeatures == lp->resultcache->numresults) { status = MS_DONE; break; } } /* next shape */ - if(classgroup) msFree(classgroup); + if (classgroup) + msFree(classgroup); lp->filteritem = old_filteritem; /* point back to original value */ msCopyExpression(&lp->filter, &old_filter); /* restore old filter */ @@ -995,21 +1118,23 @@ int msQueryByFilter(mapObj *map) msProjectDestroyReprojector(reprojector); - if(status != MS_DONE) return MS_FAILURE; - if(!map->query.only_cache_result_count && lp->resultcache->numresults == 0) + if (status != MS_DONE) + return MS_FAILURE; + if (!map->query.only_cache_result_count && lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */ - } /* next layer */ + } /* next layer */ /* was anything found? */ - for(l=start; l>=stop; l--) { - if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0) + for (l = start; l >= stop; l--) { + if (GET_LAYER(map, l)->resultcache && + GET_LAYER(map, l)->resultcache->numresults > 0) return MS_SUCCESS; } if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("msQueryByFilter(): No matching record(s) found."); + msDebug("msQueryByFilter(): No matching record(s) found."); } - return(MS_SUCCESS); + return (MS_SUCCESS); restore_old_filter: lp->filteritem = old_filteritem; @@ -1019,10 +1144,9 @@ int msQueryByFilter(mapObj *map) return MS_FAILURE; } -int msQueryByRect(mapObj *map) -{ +int msQueryByRect(mapObj *map) { int l; /* counters */ - int start, stop=0; + int start, stop = 0; layerObj *lp; @@ -1040,21 +1164,22 @@ int msQueryByRect(mapObj *map) initQueryCache(&queryCache); - if(map->query.type != MS_QUERY_BY_RECT) { - msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByRect()"); - return(MS_FAILURE); + if (map->query.type != MS_QUERY_BY_RECT) { + msSetError(MS_QUERYERR, "The query is not properly defined.", + "msQueryByRect()"); + return (MS_FAILURE); } msInitShape(&shape); msInitShape(&searchshape); - if(map->query.layer < 0 || map->query.layer >= map->numlayers) - start = map->numlayers-1; + if (map->query.layer < 0 || map->query.layer >= map->numlayers) + start = map->numlayers - 1; else start = stop = map->query.layer; - for(l=start; l>=stop; l--) { - reprojectionObj* reprojector = NULL; + for (l = start; l >= stop; l--) { + reprojectionObj *reprojector = NULL; lp = (GET_LAYER(map, l)); /* Set the global maxfeatures */ if (map->query.maxfeatures == 0) @@ -1065,39 +1190,51 @@ int msQueryByRect(mapObj *map) /* using mapscript, the map->query.startindex will be unset... */ if (lp->startindex > 1 && map->query.startindex < 0) map->query.startindex = lp->startindex; - + /* conditions may have changed since this layer last drawn, so set layer->project true to recheck projection needs (Bug #673) */ lp->project = MS_TRUE; - /* free any previous search results, do it now in case one of the next few tests fail */ - if(lp->resultcache) { - if(lp->resultcache->results) free(lp->resultcache->results); + /* free any previous search results, do it now in case one of the next few + * tests fail */ + if (lp->resultcache) { + if (lp->resultcache->results) + free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; } - if(!msIsLayerQueryable(lp)) continue; - if(lp->status == MS_OFF) continue; + if (!msIsLayerQueryable(lp)) + continue; + if (lp->status == MS_OFF) + continue; - if(map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } searchrect = map->query.rect; - if(lp->tolerance > 0) { + if (lp->tolerance > 0) { layer_tolerance = lp->tolerance; - if(lp->toleranceunits == MS_PIXELS) - tolerance = layer_tolerance * msAdjustExtent(&(map->extent), map->width, map->height); + if (lp->toleranceunits == MS_PIXELS) + tolerance = layer_tolerance * + msAdjustExtent(&(map->extent), map->width, map->height); else - tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits,0)/msInchesPerUnit(map->units,0)); + tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); searchrect.minx -= tolerance; searchrect.maxx += tolerance; @@ -1109,8 +1246,8 @@ int msQueryByRect(mapObj *map) msRectToPolygon(searchrect, &searchshape); /* Raster layers are handled specially. */ - if( lp->type == MS_LAYER_RASTER ) { - if( msRasterQueryByRect( map, lp, searchrect ) == MS_FAILURE) + if (lp->type == MS_LAYER_RASTER) { + if (msRasterQueryByRect(map, lp, searchrect) == MS_FAILURE) return MS_FAILURE; continue; @@ -1120,68 +1257,68 @@ int msQueryByRect(mapObj *map) paging = msLayerGetPaging(lp); msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msFreeShape(&searchshape); - return(MS_FAILURE); + return (MS_FAILURE); } msLayerEnablePaging(lp, paging); /* build item list, we want *all* items */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) { + if (status != MS_SUCCESS) { msFreeShape(&searchshape); - return(MS_FAILURE); + return (MS_FAILURE); } /* If only result count is needed, we can use msLayerGetShapeCount() */ /* that has optimizations to avoid retrieving individual features */ - if( map->query.only_cache_result_count && + if (map->query.only_cache_result_count && lp->template != NULL && /* always TRUE for WFS case */ - lp->minfeaturesize <= 0 ) - { + lp->minfeaturesize <= 0) { int bUseLayerSRS = MS_FALSE; int numFeatures = -1; -#if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) +#if defined(USE_WMS_SVR) || defined(USE_WFS_SVR) || defined(USE_WCS_SVR) || \ + defined(USE_SOS_SVR) || defined(USE_WMS_LYR) || defined(USE_WFS_LYR) /* Optimization to detect the case where a WFS query uses in fact the */ - /* whole layer extent, but expressed in a map SRS different from the layer SRS */ - /* In the case, we can directly request against the layer extent in its native SRS */ - if( lp->project && - memcmp( &searchrect, &invalid_rect, sizeof(searchrect) ) != 0 && - msProjectionsDiffer(&(lp->projection), &(map->projection)) ) - { + /* whole layer extent, but expressed in a map SRS different from the layer + * SRS */ + /* In the case, we can directly request against the layer extent in its + * native SRS */ + if (lp->project && + memcmp(&searchrect, &invalid_rect, sizeof(searchrect)) != 0 && + msProjectionsDiffer(&(lp->projection), &(map->projection))) { rectObj layerExtent; - if ( msOWSGetLayerExtent(map, lp, "FO", &layerExtent) == MS_SUCCESS) - { - rectObj ext = layerExtent; - ext.minx -= 1e-5; - ext.miny -= 1e-5; - ext.maxx += 1e-5; - ext.maxy += 1e-5; - msProjectRect(&(lp->projection), &(map->projection), &ext); - if( fabs(ext.minx - searchrect.minx) <= 2e-5 && - fabs(ext.miny - searchrect.miny) <= 2e-5 && - fabs(ext.maxx - searchrect.maxx) <= 2e-5 && - fabs(ext.maxy - searchrect.maxy) <= 2e-5 ) - { - bUseLayerSRS = MS_TRUE; - numFeatures = msLayerGetShapeCount(lp, layerExtent, &(lp->projection)); - } + if (msOWSGetLayerExtent(map, lp, "FO", &layerExtent) == MS_SUCCESS) { + rectObj ext = layerExtent; + ext.minx -= 1e-5; + ext.miny -= 1e-5; + ext.maxx += 1e-5; + ext.maxy += 1e-5; + msProjectRect(&(lp->projection), &(map->projection), &ext); + if (fabs(ext.minx - searchrect.minx) <= 2e-5 && + fabs(ext.miny - searchrect.miny) <= 2e-5 && + fabs(ext.maxx - searchrect.maxx) <= 2e-5 && + fabs(ext.maxy - searchrect.maxy) <= 2e-5) { + bUseLayerSRS = MS_TRUE; + numFeatures = + msLayerGetShapeCount(lp, layerExtent, &(lp->projection)); + } } } #endif - if( !bUseLayerSRS ) - numFeatures = msLayerGetShapeCount(lp, searchrect, &(map->projection)); - if( numFeatures >= 0 ) - { - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + if (!bUseLayerSRS) + numFeatures = msLayerGetShapeCount(lp, searchrect, &(map->projection)); + if (numFeatures >= 0) { + lp->resultcache = (resultCacheObj *)malloc(sizeof( + resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); lp->resultcache->numresults = numFeatures; if (!paging && map->query.startindex > 1) { - lp->resultcache->numresults -= (map->query.startindex-1); + lp->resultcache->numresults -= (map->query.startindex - 1); } msFreeShape(&searchshape); continue; @@ -1190,23 +1327,25 @@ int msQueryByRect(mapObj *map) } lp->project = msProjectionsDiffer(&(lp->projection), &(map->projection)); - if(lp->project && - memcmp( &searchrect, &invalid_rect, sizeof(searchrect) ) != 0 ) - msProjectRect(&(map->projection), &(lp->projection), &searchrect); /* project the searchrect to source coords */ + if (lp->project && + memcmp(&searchrect, &invalid_rect, sizeof(searchrect)) != 0) + msProjectRect(&(map->projection), &(lp->projection), + &searchrect); /* project the searchrect to source coords */ status = msLayerWhichShapes(lp, searchrect, MS_TRUE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(lp); continue; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(lp); msFreeShape(&searchshape); - return(MS_FAILURE); + return (MS_FAILURE); } - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + lp->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); nclasses = 0; classgroup = NULL; @@ -1216,86 +1355,97 @@ int msQueryByRect(mapObj *map) if (lp->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); - while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */ + while ((status = msLayerNextShape(lp, &shape)) == + MS_SUCCESS) { /* step through the shapes */ /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - if( lp->debug >= MS_DEBUGLEVEL_V ) - msDebug("msQueryByRect(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if (lp->debug >= MS_DEBUGLEVEL_V) + msDebug("msQueryByRect(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); msFreeShape(&shape); continue; } } shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ + if (!(lp->template) && ((shape.classindex == -1) || + (lp->class[shape.classindex] + -> status == MS_OFF))) { /* not a valid shape */ msFreeShape(&shape); continue; } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ + if (!(lp->template) && + !(lp->class[shape.classindex] -> template)) { /* no valid template */ msFreeShape(&shape); continue; } - if(lp->project) { - if( reprojector == NULL ) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msFreeShape(&shape); - status = MS_FAILURE; - break; - } + if (lp->project) { + if (reprojector == NULL) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { + msFreeShape(&shape); + status = MS_FAILURE; + break; + } } - if( msProjectShapeEx(reprojector, &shape) != MS_SUCCESS ) { - // msProjectShapeEx() calls msFreeShape() on error - continue; + if (msProjectShapeEx(reprojector, &shape) != MS_SUCCESS) { + // msProjectShapeEx() calls msFreeShape() on error + continue; } } - if(msRectContained(&shape.bounds, &searchrectInMapProj) == MS_TRUE) { /* if the whole shape is in, don't intersect */ + if (msRectContained(&shape.bounds, &searchrectInMapProj) == + MS_TRUE) { /* if the whole shape is in, don't intersect */ status = MS_TRUE; } else { - switch(shape.type) { /* make sure shape actually intersects the qrect (ADD FUNCTIONS SPECIFIC TO RECTOBJ) */ - case MS_SHAPE_POINT: - status = msIntersectMultipointPolygon(&shape, &searchshape); - break; - case MS_SHAPE_LINE: - status = msIntersectPolylinePolygon(&shape, &searchshape); - break; - case MS_SHAPE_POLYGON: - status = msIntersectPolygons(&shape, &searchshape); - break; - case MS_SHAPE_NULL: - status = MS_TRUE; - break; - default: - break; + switch (shape.type) { /* make sure shape actually intersects the qrect + (ADD FUNCTIONS SPECIFIC TO RECTOBJ) */ + case MS_SHAPE_POINT: + status = msIntersectMultipointPolygon(&shape, &searchshape); + break; + case MS_SHAPE_LINE: + status = msIntersectPolylinePolygon(&shape, &searchshape); + break; + case MS_SHAPE_POLYGON: + status = msIntersectPolygons(&shape, &searchshape); + break; + case MS_SHAPE_NULL: + status = MS_TRUE; + break; + default: + break; } } - if(status == MS_TRUE) { + if (status == MS_TRUE) { /* Should we skip this feature? */ if (!paging && map->query.startindex > 1) { --map->query.startindex; msFreeShape(&shape); continue; } - if( map->query.only_cache_result_count ) - lp->resultcache->numresults ++; + if (map->query.only_cache_result_count) + lp->resultcache->numresults++; else - addResult(map, lp->resultcache, &queryCache, &shape); + addResult(map, lp->resultcache, &queryCache, &shape); --map->query.maxfeatures; } msFreeShape(&shape); /* check shape count */ - if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) { + if (lp->maxfeatures > 0 && + lp->maxfeatures == lp->resultcache->numresults) { status = MS_DONE; break; } - + } /* next shape */ if (classgroup) @@ -1303,43 +1453,45 @@ int msQueryByRect(mapObj *map) msProjectDestroyReprojector(reprojector); - if(status != MS_DONE) { - msFreeShape(&searchshape); - return(MS_FAILURE); + if (status != MS_DONE) { + msFreeShape(&searchshape); + return (MS_FAILURE); } - if( !map->query.only_cache_result_count && - lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */ - } /* next layer */ + if (!map->query.only_cache_result_count && lp->resultcache->numresults == 0) + msLayerClose(lp); /* no need to keep the layer open */ + } /* next layer */ msFreeShape(&searchshape); /* was anything found? */ - for(l=start; l>=stop; l--) { - if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0) - return(MS_SUCCESS); + for (l = start; l >= stop; l--) { + if (GET_LAYER(map, l)->resultcache && + GET_LAYER(map, l)->resultcache->numresults > 0) + return (MS_SUCCESS); } if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("msQueryByRect(): No matching record(s) found."); + msDebug("msQueryByRect(): No matching record(s) found."); } - return(MS_SUCCESS); + return (MS_SUCCESS); } -static int is_duplicate(resultCacheObj *resultcache, int shapeindex, int tileindex) -{ +static int is_duplicate(resultCacheObj *resultcache, int shapeindex, + int tileindex) { int i; - for(i=0; inumresults; i++) - if(resultcache->results[i].shapeindex == shapeindex && resultcache->results[i].tileindex == tileindex) return(MS_TRUE); + for (i = 0; i < resultcache->numresults; i++) + if (resultcache->results[i].shapeindex == shapeindex && + resultcache->results[i].tileindex == tileindex) + return (MS_TRUE); - return(MS_FALSE); + return (MS_FALSE); } -int msQueryByFeatures(mapObj *map) -{ +int msQueryByFeatures(mapObj *map) { int i, l; - int start, stop=0; + int start, stop = 0; layerObj *lp, *slp; char status; @@ -1355,25 +1507,28 @@ int msQueryByFeatures(mapObj *map) initQueryCache(&queryCache); - if(map->debug) msDebug("in msQueryByFeatures()\n"); + if (map->debug) + msDebug("in msQueryByFeatures()\n"); /* is the selection layer valid and has it been queried */ - if(map->query.slayer < 0 || map->query.slayer >= map->numlayers) { - msSetError(MS_QUERYERR, "Invalid selection layer index.", "msQueryByFeatures()"); - return(MS_FAILURE); + if (map->query.slayer < 0 || map->query.slayer >= map->numlayers) { + msSetError(MS_QUERYERR, "Invalid selection layer index.", + "msQueryByFeatures()"); + return (MS_FAILURE); } slp = (GET_LAYER(map, map->query.slayer)); - if(!slp->resultcache) { - msSetError(MS_QUERYERR, "Selection layer has not been queried.", "msQueryByFeatures()"); - return(MS_FAILURE); + if (!slp->resultcache) { + msSetError(MS_QUERYERR, "Selection layer has not been queried.", + "msQueryByFeatures()"); + return (MS_FAILURE); } /* conditions may have changed since this layer last drawn, so set layer->project true to recheck projection needs (Bug #673) */ slp->project = msProjectionsDiffer(&(slp->projection), &(map->projection)); - if(map->query.layer < 0 || map->query.layer >= map->numlayers) - start = map->numlayers-1; + if (map->query.layer < 0 || map->query.layer >= map->numlayers) + start = map->numlayers - 1; else start = stop = map->query.layer; @@ -1384,9 +1539,10 @@ int msQueryByFeatures(mapObj *map) msInitShape(&shape); /* initialize a few things */ msInitShape(&selectshape); - for(l=start; l>=stop; l--) { - reprojectionObj* reprojector = NULL; - if(l == map->query.slayer) continue; /* skip the selection layer */ + for (l = start; l >= stop; l--) { + reprojectionObj *reprojector = NULL; + if (l == map->query.slayer) + continue; /* skip the selection layer */ lp = (GET_LAYER(map, l)); if (map->query.maxfeatures == 0) @@ -1402,95 +1558,117 @@ int msQueryByFeatures(mapObj *map) layer->project true to recheck projection needs (Bug #673) */ lp->project = msProjectionsDiffer(&(lp->projection), &(map->projection)); - /* free any previous search results, do it now in case one of the next few tests fail */ - if(lp->resultcache) { - if(lp->resultcache->results) free(lp->resultcache->results); + /* free any previous search results, do it now in case one of the next few + * tests fail */ + if (lp->resultcache) { + if (lp->resultcache->results) + free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; } - if(!msIsLayerQueryable(lp)) continue; - if(lp->status == MS_OFF) continue; + if (!msIsLayerQueryable(lp)) + continue; + if (lp->status == MS_OFF) + continue; - if(map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } - /* Get the layer tolerance default is 3 for point and line layers, 0 for others */ - if(lp->tolerance == -1) { - if(lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) + /* Get the layer tolerance default is 3 for point and line layers, 0 for + * others */ + if (lp->tolerance == -1) { + if (lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) layer_tolerance = 3; else layer_tolerance = 0; } else layer_tolerance = lp->tolerance; - if(lp->toleranceunits == MS_PIXELS) - tolerance = layer_tolerance * msAdjustExtent(&(map->extent), map->width, map->height); + if (lp->toleranceunits == MS_PIXELS) + tolerance = layer_tolerance * + msAdjustExtent(&(map->extent), map->width, map->height); else - tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits,0)/msInchesPerUnit(map->units,0)); + tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); msLayerEnablePaging(lp, MS_FALSE); /* build item list, we want *all* items */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); /* for each selection shape */ - for(i=0; iresultcache->numresults; i++) { + for (i = 0; i < slp->resultcache->numresults; i++) { - status = msLayerGetShape(slp, &selectshape, &(slp->resultcache->results[i])); - if(status != MS_SUCCESS) { + status = + msLayerGetShape(slp, &selectshape, &(slp->resultcache->results[i])); + if (status != MS_SUCCESS) { msLayerClose(lp); msLayerClose(slp); - return(MS_FAILURE); + return (MS_FAILURE); } - if(selectshape.type != MS_SHAPE_POLYGON && selectshape.type != MS_SHAPE_LINE) { + if (selectshape.type != MS_SHAPE_POLYGON && + selectshape.type != MS_SHAPE_LINE) { msLayerClose(lp); msLayerClose(slp); - msSetError(MS_QUERYERR, "Selection features MUST be polygons or lines.", "msQueryByFeatures()"); - return(MS_FAILURE); + msSetError(MS_QUERYERR, "Selection features MUST be polygons or lines.", + "msQueryByFeatures()"); + return (MS_FAILURE); } - if(slp->project) + if (slp->project) msProjectShape(&(slp->projection), &(map->projection), &selectshape); /* identify target shapes */ searchrect = selectshape.bounds; - searchrect.minx -= tolerance; /* expand the search box to account for layer tolerances (e.g. buffered searches) */ + searchrect.minx -= + tolerance; /* expand the search box to account for layer tolerances + (e.g. buffered searches) */ searchrect.maxx += tolerance; searchrect.miny -= tolerance; searchrect.maxy += tolerance; - if(lp->project) - msProjectRect(&(map->projection), &(lp->projection), &searchrect); /* project the searchrect to source coords */ + if (lp->project) + msProjectRect( + &(map->projection), &(lp->projection), + &searchrect); /* project the searchrect to source coords */ status = msLayerWhichShapes(lp, searchrect, MS_TRUE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(lp); break; /* next layer */ - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(lp); msLayerClose(slp); - return(MS_FAILURE); + return (MS_FAILURE); } - if(i == 0) { - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + if (i == 0) { + lp->resultcache = (resultCacheObj *)malloc(sizeof( + resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); - + initResultCache(lp->resultcache); } nclasses = 0; @@ -1501,114 +1679,136 @@ int msQueryByFeatures(mapObj *map) if (lp->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); - while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */ + while ((status = msLayerNextShape(lp, &shape)) == + MS_SUCCESS) { /* step through the shapes */ /* check for dups when there are multiple selection shapes */ - if(i > 0 && is_duplicate(lp->resultcache, shape.index, shape.tileindex)) continue; - + if (i > 0 && + is_duplicate(lp->resultcache, shape.index, shape.tileindex)) + continue; /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - if( lp->debug >= MS_DEBUGLEVEL_V ) - msDebug("msQueryByFeature(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if (lp->debug >= MS_DEBUGLEVEL_V) + msDebug("msQueryByFeature(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); msFreeShape(&shape); continue; } } - shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ + shape.classindex = + msShapeGetClass(lp, map, &shape, classgroup, nclasses); + if (!(lp->template) && + ((shape.classindex == -1) || + (lp->class[shape.classindex] + -> status == MS_OFF))) { /* not a valid shape */ msFreeShape(&shape); continue; } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ + if (!(lp->template) && !(lp->class[shape.classindex] + -> template)) { /* no valid template */ msFreeShape(&shape); continue; } - if(lp->project) { - if( reprojector == NULL ) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msFreeShape(&shape); - status = MS_FAILURE; - break; - } + if (lp->project) { + if (reprojector == NULL) { + reprojector = msProjectCreateReprojector(&(lp->projection), + &(map->projection)); + if (reprojector == NULL) { + msFreeShape(&shape); + status = MS_FAILURE; + break; } - msProjectShapeEx(reprojector, &shape); + } + msProjectShapeEx(reprojector, &shape); } - switch(selectshape.type) { /* may eventually support types other than polygon on line */ + switch (selectshape.type) { /* may eventually support types other than + polygon on line */ + case MS_SHAPE_POLYGON: + switch (shape.type) { /* make sure shape actually intersects the + selectshape */ + case MS_SHAPE_POINT: + if (tolerance == 0) /* just test for intersection */ + status = msIntersectMultipointPolygon(&shape, &selectshape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + case MS_SHAPE_LINE: + if (tolerance == 0) { /* just test for intersection */ + status = msIntersectPolylinePolygon(&shape, &selectshape); + } else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; case MS_SHAPE_POLYGON: - switch(shape.type) { /* make sure shape actually intersects the selectshape */ - case MS_SHAPE_POINT: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectMultipointPolygon(&shape, &selectshape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_LINE: - if(tolerance == 0) { /* just test for intersection */ - status = msIntersectPolylinePolygon(&shape, &selectshape); - } else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_POLYGON: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectPolygons(&shape, &selectshape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - default: - status = MS_FALSE; - break; + if (tolerance == 0) /* just test for intersection */ + status = msIntersectPolygons(&shape, &selectshape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + default: + status = MS_FALSE; + break; + } + break; + case MS_SHAPE_LINE: + switch (shape.type) { /* make sure shape actually intersects the + selectshape */ + case MS_SHAPE_POINT: + if (tolerance == 0) { /* just test for intersection */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance == 0) + status = MS_TRUE; + } else { + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; } break; case MS_SHAPE_LINE: - switch(shape.type) { /* make sure shape actually intersects the selectshape */ - case MS_SHAPE_POINT: - if(tolerance == 0) { /* just test for intersection */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance == 0) status = MS_TRUE; - } else { - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_LINE: - if(tolerance == 0) { /* just test for intersection */ - status = msIntersectPolylines(&shape, &selectshape); - } else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_POLYGON: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectPolylinePolygon(&selectshape, &shape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(&selectshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - default: - status = MS_FALSE; - break; + if (tolerance == 0) { /* just test for intersection */ + status = msIntersectPolylines(&shape, &selectshape); + } else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + case MS_SHAPE_POLYGON: + if (tolerance == 0) /* just test for intersection */ + status = msIntersectPolylinePolygon(&selectshape, &shape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(&selectshape, &shape); + if (distance < tolerance) + status = MS_TRUE; } break; default: - break; /* should never get here as we test for selection shape type explicitly earlier */ + status = MS_FALSE; + break; + } + break; + default: + break; /* should never get here as we test for selection shape type + explicitly earlier */ } - if(status == MS_TRUE) { + if (status == MS_TRUE) { /* Should we skip this feature? */ if (!msLayerGetPaging(lp) && map->query.startindex > 1) { --map->query.startindex; @@ -1620,7 +1820,8 @@ int msQueryByFeatures(mapObj *map) msFreeShape(&shape); /* check shape count */ - if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) { + if (lp->maxfeatures > 0 && + lp->maxfeatures == lp->resultcache->numresults) { status = MS_DONE; break; } @@ -1633,23 +1834,28 @@ int msQueryByFeatures(mapObj *map) msFreeShape(&selectshape); - if(status != MS_DONE) return(MS_FAILURE); + if (status != MS_DONE) + return (MS_FAILURE); } /* next selection shape */ - if(lp->resultcache == NULL || lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */ - } /* next layer */ + if (lp->resultcache == NULL || lp->resultcache->numresults == 0) + msLayerClose(lp); /* no need to keep the layer open */ + } /* next layer */ /* was anything found? */ - for(l=start; l>=stop; l--) { - if(l == map->query.slayer) continue; /* skip the selection layer */ - if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0) return(MS_SUCCESS); + for (l = start; l >= stop; l--) { + if (l == map->query.slayer) + continue; /* skip the selection layer */ + if (GET_LAYER(map, l)->resultcache && + GET_LAYER(map, l)->resultcache->numresults > 0) + return (MS_SUCCESS); } if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("msQueryByFeatures(): No matching record(s) found."); + msDebug("msQueryByFeatures(): No matching record(s) found."); } - return(MS_SUCCESS); + return (MS_SUCCESS); } /* msQueryByPoint() @@ -1666,10 +1872,9 @@ int msQueryByFeatures(mapObj *map) * returned are the first ones found in each layer and are not necessarily * the closest ones). */ -int msQueryByPoint(mapObj *map) -{ +int msQueryByPoint(mapObj *map) { int l; - int start, stop=0; + int start, stop = 0; double d, t; double layer_tolerance; @@ -1688,20 +1893,21 @@ int msQueryByPoint(mapObj *map) initQueryCache(&queryCache); - if(map->query.type != MS_QUERY_BY_POINT) { - msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByPoint()"); - return(MS_FAILURE); + if (map->query.type != MS_QUERY_BY_POINT) { + msSetError(MS_QUERYERR, "The query is not properly defined.", + "msQueryByPoint()"); + return (MS_FAILURE); } msInitShape(&shape); - if(map->query.layer < 0 || map->query.layer >= map->numlayers) - start = map->numlayers-1; + if (map->query.layer < 0 || map->query.layer >= map->numlayers) + start = map->numlayers - 1; else start = stop = map->query.layer; - for(l=start; l>=stop; l--) { - reprojectionObj* reprojector = NULL; + for (l = start; l >= stop; l--) { + reprojectionObj *reprojector = NULL; lp = (GET_LAYER(map, l)); if (map->query.maxfeatures == 0) break; /* nothing else to do */ @@ -1711,53 +1917,69 @@ int msQueryByPoint(mapObj *map) /* using mapscript, the map->query.startindex will be unset... */ if (lp->startindex > 1 && map->query.startindex < 0) map->query.startindex = lp->startindex; - + /* conditions may have changed since this layer last drawn, so set layer->project true to recheck projection needs (Bug #673) */ lp->project = MS_TRUE; - /* free any previous search results, do it now in case one of the next few tests fail */ - if(lp->resultcache) { - if(lp->resultcache->results) free(lp->resultcache->results); + /* free any previous search results, do it now in case one of the next few + * tests fail */ + if (lp->resultcache) { + if (lp->resultcache->results) + free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; } - if(!msIsLayerQueryable(lp)) continue; - if(lp->status == MS_OFF) continue; + if (!msIsLayerQueryable(lp)) + continue; + if (lp->status == MS_OFF) + continue; - if(map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } /* Raster layers are handled specially. */ - if( lp->type == MS_LAYER_RASTER ) { - if( msRasterQueryByPoint( map, lp, map->query.mode, map->query.point, map->query.buffer, map->query.maxresults ) == MS_FAILURE ) + if (lp->type == MS_LAYER_RASTER) { + if (msRasterQueryByPoint(map, lp, map->query.mode, map->query.point, + map->query.buffer, + map->query.maxresults) == MS_FAILURE) return MS_FAILURE; continue; } - /* Get the layer tolerance default is 3 for point and line layers, 0 for others */ - if(lp->tolerance == -1) { - if(lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) + /* Get the layer tolerance default is 3 for point and line layers, 0 for + * others */ + if (lp->tolerance == -1) { + if (lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) layer_tolerance = 3; else layer_tolerance = 0; } else layer_tolerance = lp->tolerance; - if(map->query.buffer <= 0) { /* use layer tolerance */ - if(lp->toleranceunits == MS_PIXELS) - t = layer_tolerance * MS_MAX(MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width), - MS_CELLSIZE(map->extent.miny, map->extent.maxy, map->height)); + if (map->query.buffer <= 0) { /* use layer tolerance */ + if (lp->toleranceunits == MS_PIXELS) + t = layer_tolerance * + MS_MAX( + MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width), + MS_CELLSIZE(map->extent.miny, map->extent.maxy, map->height)); else - t = layer_tolerance * (msInchesPerUnit(lp->toleranceunits,0)/msInchesPerUnit(map->units,0)); + t = layer_tolerance * (msInchesPerUnit(lp->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); } else /* use buffer distance */ t = map->query.buffer; @@ -1770,31 +1992,35 @@ int msQueryByPoint(mapObj *map) paging = msLayerGetPaging(lp); msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); msLayerEnablePaging(lp, paging); /* build item list, we want *all* items */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); /* identify target shapes */ searchrect = rect; lp->project = msProjectionsDiffer(&(lp->projection), &(map->projection)); - if(lp->project) - msProjectRect(&(map->projection), &(lp->projection), &searchrect); /* project the searchrect to source coords */ + if (lp->project) + msProjectRect(&(map->projection), &(lp->projection), + &searchrect); /* project the searchrect to source coords */ status = msLayerWhichShapes(lp, searchrect, MS_TRUE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(lp); continue; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(lp); - return(MS_FAILURE); + return (MS_FAILURE); } - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + lp->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); nclasses = 0; classgroup = NULL; @@ -1804,43 +2030,51 @@ int msQueryByPoint(mapObj *map) if (lp->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); - while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */ + while ((status = msLayerNextShape(lp, &shape)) == + MS_SUCCESS) { /* step through the shapes */ /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - if( lp->debug >= MS_DEBUGLEVEL_V ) - msDebug("msQueryByPoint(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if (lp->debug >= MS_DEBUGLEVEL_V) + msDebug("msQueryByPoint(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); msFreeShape(&shape); continue; } } shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ + if (!(lp->template) && ((shape.classindex == -1) || + (lp->class[shape.classindex] + -> status == MS_OFF))) { /* not a valid shape */ msFreeShape(&shape); continue; } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ + if (!(lp->template) && + !(lp->class[shape.classindex] -> template)) { /* no valid template */ msFreeShape(&shape); continue; } - if(lp->project) { - if( reprojector == NULL ) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msFreeShape(&shape); - status = MS_FAILURE; - break; - } + if (lp->project) { + if (reprojector == NULL) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { + msFreeShape(&shape); + status = MS_FAILURE; + break; + } } msProjectShapeEx(reprojector, &shape); } d = msDistancePointToShape(&(map->query.point), &shape); - if( d <= t ) { /* found one */ + if (d <= t) { /* found one */ /* Should we skip this feature? */ if (!paging && map->query.startindex > 1) { @@ -1849,7 +2083,7 @@ int msQueryByPoint(mapObj *map) continue; } - if(map->query.mode == MS_QUERY_SINGLE) { + if (map->query.mode == MS_QUERY_SINGLE) { cleanupResultCache(lp->resultcache); initQueryCache(&queryCache); addResult(map, lp->resultcache, &queryCache, &shape); @@ -1861,13 +2095,15 @@ int msQueryByPoint(mapObj *map) msFreeShape(&shape); - if(map->query.mode == MS_QUERY_MULTIPLE && map->query.maxresults > 0 && lp->resultcache->numresults == map->query.maxresults) { - status = MS_DONE; /* got enough results for this layer */ + if (map->query.mode == MS_QUERY_MULTIPLE && map->query.maxresults > 0 && + lp->resultcache->numresults == map->query.maxresults) { + status = MS_DONE; /* got enough results for this layer */ break; } /* check shape count */ - if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) { + if (lp->maxfeatures > 0 && + lp->maxfeatures == lp->resultcache->numresults) { status = MS_DONE; break; } @@ -1878,30 +2114,33 @@ int msQueryByPoint(mapObj *map) msProjectDestroyReprojector(reprojector); - if(status != MS_DONE) return(MS_FAILURE); + if (status != MS_DONE) + return (MS_FAILURE); - if(lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */ + if (lp->resultcache->numresults == 0) + msLayerClose(lp); /* no need to keep the layer open */ - if((lp->resultcache->numresults > 0) && (map->query.mode == MS_QUERY_SINGLE) && (map->query.maxresults == 0)) - break; /* no need to search any further */ - } /* next layer */ + if ((lp->resultcache->numresults > 0) && + (map->query.mode == MS_QUERY_SINGLE) && (map->query.maxresults == 0)) + break; /* no need to search any further */ + } /* next layer */ /* was anything found? */ - for(l=start; l>=stop; l--) { - if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0) - return(MS_SUCCESS); + for (l = start; l >= stop; l--) { + if (GET_LAYER(map, l)->resultcache && + GET_LAYER(map, l)->resultcache->numresults > 0) + return (MS_SUCCESS); } if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("msQueryByPoint(): No matching record(s) found."); + msDebug("msQueryByPoint(): No matching record(s) found."); } - return(MS_SUCCESS); + return (MS_SUCCESS); } -int msQueryByShape(mapObj *map) -{ - int start, stop=0, l; - shapeObj shape, *qshape=NULL; +int msQueryByShape(mapObj *map) { + int start, stop = 0, l; + shapeObj shape, *qshape = NULL; layerObj *lp; char status; double distance, tolerance, layer_tolerance; @@ -1914,32 +2153,36 @@ int msQueryByShape(mapObj *map) initQueryCache(&queryCache); - if(map->query.type != MS_QUERY_BY_SHAPE) { - msSetError(MS_QUERYERR, "The query is not properly defined.", "msQueryByShape()"); - return(MS_FAILURE); + if (map->query.type != MS_QUERY_BY_SHAPE) { + msSetError(MS_QUERYERR, "The query is not properly defined.", + "msQueryByShape()"); + return (MS_FAILURE); } - if(!(map->query.shape)) { + if (!(map->query.shape)) { msSetError(MS_QUERYERR, "Query shape is not defined.", "msQueryByShape()"); - return(MS_FAILURE); + return (MS_FAILURE); } - if(map->query.shape->type != MS_SHAPE_POLYGON && map->query.shape->type != MS_SHAPE_LINE && map->query.shape->type != MS_SHAPE_POINT) { - msSetError(MS_QUERYERR, "Query shape MUST be a polygon, line or point.", "msQueryByShape()"); - return(MS_FAILURE); + if (map->query.shape->type != MS_SHAPE_POLYGON && + map->query.shape->type != MS_SHAPE_LINE && + map->query.shape->type != MS_SHAPE_POINT) { + msSetError(MS_QUERYERR, "Query shape MUST be a polygon, line or point.", + "msQueryByShape()"); + return (MS_FAILURE); } msInitShape(&shape); qshape = map->query.shape; /* for brevity */ - if(map->query.layer < 0 || map->query.layer >= map->numlayers) - start = map->numlayers-1; + if (map->query.layer < 0 || map->query.layer >= map->numlayers) + start = map->numlayers - 1; else start = stop = map->query.layer; msComputeBounds(qshape); /* make sure an accurate extent exists */ - for(l=start; l>=stop; l--) { /* each layer */ - reprojectionObj* reprojector = NULL; + for (l = start; l >= stop; l--) { /* each layer */ + reprojectionObj *reprojector = NULL; lp = (GET_LAYER(map, l)); if (map->query.maxfeatures == 0) break; /* nothing else to do */ @@ -1954,81 +2197,99 @@ int msQueryByShape(mapObj *map) layer->project true to recheck projection needs (Bug #673) */ lp->project = MS_TRUE; - /* free any previous search results, do it now in case one of the next few tests fail */ - if(lp->resultcache) { - if(lp->resultcache->results) free(lp->resultcache->results); + /* free any previous search results, do it now in case one of the next few + * tests fail */ + if (lp->resultcache) { + if (lp->resultcache->results) + free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; } - if(!msIsLayerQueryable(lp)) continue; - if(lp->status == MS_OFF) continue; + if (!msIsLayerQueryable(lp)) + continue; + if (lp->status == MS_OFF) + continue; - if(map->scaledenom > 0) { - if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; - if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; + if (map->scaledenom > 0) { + if ((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) + continue; + if ((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) + continue; } if (lp->maxscaledenom <= 0 && lp->minscaledenom <= 0) { - if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; - if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; + if ((lp->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) + continue; + if ((lp->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) + continue; } /* Raster layers are handled specially. */ - if( lp->type == MS_LAYER_RASTER ) { - if( msRasterQueryByShape(map, lp, qshape) == MS_FAILURE ) + if (lp->type == MS_LAYER_RASTER) { + if (msRasterQueryByShape(map, lp, qshape) == MS_FAILURE) return MS_FAILURE; continue; } - /* Get the layer tolerance default is 3 for point and line layers, 0 for others */ - if(lp->tolerance == -1) { - if(lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) + /* Get the layer tolerance default is 3 for point and line layers, 0 for + * others */ + if (lp->tolerance == -1) { + if (lp->type == MS_LAYER_POINT || lp->type == MS_LAYER_LINE) layer_tolerance = 3; else layer_tolerance = 0; } else layer_tolerance = lp->tolerance; - if(lp->toleranceunits == MS_PIXELS) - tolerance = layer_tolerance * msAdjustExtent(&(map->extent), map->width, map->height); + if (lp->toleranceunits == MS_PIXELS) + tolerance = layer_tolerance * + msAdjustExtent(&(map->extent), map->width, map->height); else - tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits,0)/msInchesPerUnit(map->units,0)); + tolerance = layer_tolerance * (msInchesPerUnit(lp->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); msLayerClose(lp); /* reset */ status = msLayerOpen(lp); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); /* disable driver paging */ msLayerEnablePaging(lp, MS_FALSE); /* build item list, we want *all* items */ status = msLayerWhichItems(lp, MS_TRUE, NULL); - if(status != MS_SUCCESS) return(MS_FAILURE); + if (status != MS_SUCCESS) + return (MS_FAILURE); /* identify target shapes */ searchrect = qshape->bounds; - searchrect.minx -= tolerance; /* expand the search box to account for layer tolerances (e.g. buffered searches) */ + searchrect.minx -= tolerance; /* expand the search box to account for layer + tolerances (e.g. buffered searches) */ searchrect.maxx += tolerance; searchrect.miny -= tolerance; searchrect.maxy += tolerance; lp->project = msProjectionsDiffer(&(lp->projection), &(map->projection)); - if(lp->project) - msProjectRect(&(map->projection), &(lp->projection), &searchrect); /* project the searchrect to source coords */ + if (lp->project) + msProjectRect(&(map->projection), &(lp->projection), + &searchrect); /* project the searchrect to source coords */ status = msLayerWhichShapes(lp, searchrect, MS_TRUE); - if(status == MS_DONE) { /* no overlap */ + if (status == MS_DONE) { /* no overlap */ msLayerClose(lp); continue; - } else if(status != MS_SUCCESS) { + } else if (status != MS_SUCCESS) { msLayerClose(lp); - return(MS_FAILURE); + return (MS_FAILURE); } - lp->resultcache = (resultCacheObj *)malloc(sizeof(resultCacheObj)); /* allocate and initialize the result cache */ + lp->resultcache = (resultCacheObj *)malloc( + sizeof(resultCacheObj)); /* allocate and initialize the result cache */ MS_CHECK_ALLOC(lp->resultcache, sizeof(resultCacheObj), MS_FAILURE); - initResultCache( lp->resultcache); + initResultCache(lp->resultcache); nclasses = 0; if (lp->classgroup && lp->numclasses > 0) @@ -2037,115 +2298,136 @@ int msQueryByShape(mapObj *map) if (lp->minfeaturesize > 0) minfeaturesize = Pix2LayerGeoref(map, lp, lp->minfeaturesize); - while((status = msLayerNextShape(lp, &shape)) == MS_SUCCESS) { /* step through the shapes */ + while ((status = msLayerNextShape(lp, &shape)) == + MS_SUCCESS) { /* step through the shapes */ /* Check if the shape size is ok to be drawn */ - if ( (shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && (minfeaturesize > 0) ) { + if ((shape.type == MS_SHAPE_LINE || shape.type == MS_SHAPE_POLYGON) && + (minfeaturesize > 0)) { if (msShapeCheckSize(&shape, minfeaturesize) == MS_FALSE) { - if( lp->debug >= MS_DEBUGLEVEL_V ) - msDebug("msQueryByShape(): Skipping shape (%ld) because LAYER::MINFEATURESIZE is bigger than shape size\n", shape.index); + if (lp->debug >= MS_DEBUGLEVEL_V) + msDebug("msQueryByShape(): Skipping shape (%ld) because " + "LAYER::MINFEATURESIZE is bigger than shape size\n", + shape.index); msFreeShape(&shape); continue; } } shape.classindex = msShapeGetClass(lp, map, &shape, classgroup, nclasses); - if(!(lp->template) && ((shape.classindex == -1) || (lp->class[shape.classindex]->status == MS_OFF))) { /* not a valid shape */ + if (!(lp->template) && ((shape.classindex == -1) || + (lp->class[shape.classindex] + -> status == MS_OFF))) { /* not a valid shape */ msFreeShape(&shape); continue; } - if(!(lp->template) && !(lp->class[shape.classindex]->template)) { /* no valid template */ + if (!(lp->template) && + !(lp->class[shape.classindex] -> template)) { /* no valid template */ msFreeShape(&shape); continue; } - if(lp->project) { - if( reprojector == NULL ) { - reprojector = msProjectCreateReprojector(&(lp->projection), &(map->projection)); - if( reprojector == NULL ) { - msFreeShape(&shape); - status = MS_FAILURE; - break; - } + if (lp->project) { + if (reprojector == NULL) { + reprojector = + msProjectCreateReprojector(&(lp->projection), &(map->projection)); + if (reprojector == NULL) { + msFreeShape(&shape); + status = MS_FAILURE; + break; + } } msProjectShapeEx(reprojector, &shape); } - switch(qshape->type) { /* may eventually support types other than polygon or line */ - case MS_SHAPE_POLYGON: - switch(shape.type) { /* make sure shape actually intersects the shape */ - case MS_SHAPE_POINT: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectMultipointPolygon(&shape, qshape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_LINE: - if(tolerance == 0) { /* just test for intersection */ - status = msIntersectPolylinePolygon(&shape, qshape); - } else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_POLYGON: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectPolygons(&shape, qshape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - default: - break; + switch (qshape->type) { /* may eventually support types other than polygon + or line */ + case MS_SHAPE_POLYGON: + switch ( + shape.type) { /* make sure shape actually intersects the shape */ + case MS_SHAPE_POINT: + if (tolerance == 0) /* just test for intersection */ + status = msIntersectMultipointPolygon(&shape, qshape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; } break; case MS_SHAPE_LINE: - switch(shape.type) { /* make sure shape actually intersects the selectshape */ - case MS_SHAPE_POINT: - if(tolerance == 0) { /* just test for intersection */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance == 0) status = MS_TRUE; - } else { - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_LINE: - if(tolerance == 0) { /* just test for intersection */ - status = msIntersectPolylines(&shape, qshape); - } else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - case MS_SHAPE_POLYGON: - if(tolerance == 0) /* just test for intersection */ - status = msIntersectPolylinePolygon(qshape, &shape); - else { /* check distance, distance=0 means they intersect */ - distance = msDistanceShapeToShape(qshape, &shape); - if(distance < tolerance) status = MS_TRUE; - } - break; - default: - status = MS_FALSE; - break; + if (tolerance == 0) { /* just test for intersection */ + status = msIntersectPolylinePolygon(&shape, qshape); + } else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; } break; + case MS_SHAPE_POLYGON: + if (tolerance == 0) /* just test for intersection */ + status = msIntersectPolygons(&shape, qshape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + default: + break; + } + break; + case MS_SHAPE_LINE: + switch (shape.type) { /* make sure shape actually intersects the + selectshape */ case MS_SHAPE_POINT: - distance = msDistanceShapeToShape(qshape, &shape); - status = MS_FALSE; - if(tolerance == 0 && distance == 0) status = MS_TRUE; /* shapes intersect */ - else if(distance < tolerance) status = MS_TRUE; /* shapes are close enough */ + if (tolerance == 0) { /* just test for intersection */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance == 0) + status = MS_TRUE; + } else { + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + case MS_SHAPE_LINE: + if (tolerance == 0) { /* just test for intersection */ + status = msIntersectPolylines(&shape, qshape); + } else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } + break; + case MS_SHAPE_POLYGON: + if (tolerance == 0) /* just test for intersection */ + status = msIntersectPolylinePolygon(qshape, &shape); + else { /* check distance, distance=0 means they intersect */ + distance = msDistanceShapeToShape(qshape, &shape); + if (distance < tolerance) + status = MS_TRUE; + } break; default: - break; /* should never get here as we test for selection shape type explicitly earlier */ + status = MS_FALSE; + break; + } + break; + case MS_SHAPE_POINT: + distance = msDistanceShapeToShape(qshape, &shape); + status = MS_FALSE; + if (tolerance == 0 && distance == 0) + status = MS_TRUE; /* shapes intersect */ + else if (distance < tolerance) + status = MS_TRUE; /* shapes are close enough */ + break; + default: + break; /* should never get here as we test for selection shape type + explicitly earlier */ } - if(status == MS_TRUE) { + if (status == MS_TRUE) { /* Should we skip this feature? */ if (!msLayerGetPaging(lp) && map->query.startindex > 1) { --map->query.startindex; @@ -2157,7 +2439,8 @@ int msQueryByShape(mapObj *map) msFreeShape(&shape); /* check shape count */ - if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) { + if (lp->maxfeatures > 0 && + lp->maxfeatures == lp->resultcache->numresults) { status = MS_DONE; break; } @@ -2168,23 +2451,25 @@ int msQueryByShape(mapObj *map) msProjectDestroyReprojector(reprojector); - if(status != MS_DONE) { - return(MS_FAILURE); + if (status != MS_DONE) { + return (MS_FAILURE); } - if(lp->resultcache->numresults == 0) msLayerClose(lp); /* no need to keep the layer open */ - } /* next layer */ + if (lp->resultcache->numresults == 0) + msLayerClose(lp); /* no need to keep the layer open */ + } /* next layer */ /* was anything found? */ - for(l=start; l>=stop; l--) { - if(GET_LAYER(map, l)->resultcache && GET_LAYER(map, l)->resultcache->numresults > 0) - return(MS_SUCCESS); + for (l = start; l >= stop; l--) { + if (GET_LAYER(map, l)->resultcache && + GET_LAYER(map, l)->resultcache->numresults > 0) + return (MS_SUCCESS); } if (map->debug >= MS_DEBUGLEVEL_V) { - msDebug("msQueryByShape(): No matching record(s) found."); + msDebug("msQueryByShape(): No matching record(s) found."); } - return(MS_SUCCESS); + return (MS_SUCCESS); } /* msGetQueryResultBounds() @@ -2193,22 +2478,23 @@ int msQueryByShape(mapObj *map) * that contained query results and were included in the BBOX. * i.e. if we return 0 then the value in bounds is invalid. */ -int msGetQueryResultBounds(mapObj *map, rectObj *bounds) -{ - int i, found=0; +int msGetQueryResultBounds(mapObj *map, rectObj *bounds) { + int i, found = 0; rectObj tmpBounds; - for(i=0; inumlayers; i++) { + for (i = 0; i < map->numlayers; i++) { layerObj *lp; lp = (GET_LAYER(map, i)); - if(!lp->resultcache) continue; - if(lp->resultcache->numresults <= 0) continue; + if (!lp->resultcache) + continue; + if (lp->resultcache->numresults <= 0) + continue; tmpBounds = lp->resultcache->bounds; - if(found == 0) { + if (found == 0) { *bounds = tmpBounds; } else { msMergeRect(bounds, &tmpBounds); @@ -2225,22 +2511,21 @@ int msGetQueryResultBounds(mapObj *map, rectObj *bounds) * * Free layer's query results. If qlayer == -1, all layers will be treated. */ -void msQueryFree(mapObj *map, int qlayer) -{ +void msQueryFree(mapObj *map, int qlayer) { int l; /* counters */ - int start, stop=0; + int start, stop = 0; layerObj *lp; - if(qlayer < 0 || qlayer >= map->numlayers) - start = map->numlayers-1; + if (qlayer < 0 || qlayer >= map->numlayers) + start = map->numlayers - 1; else start = stop = qlayer; - for(l=start; l>=stop; l--) { + for (l = start; l >= stop; l--) { lp = (GET_LAYER(map, l)); - if(lp->resultcache) { - if(lp->resultcache->results) + if (lp->resultcache) { + if (lp->resultcache->results) free(lp->resultcache->results); free(lp->resultcache); lp->resultcache = NULL; diff --git a/mapraster.c b/mapraster.c index 472c675452..e5666605bf 100644 --- a/mapraster.c +++ b/mapraster.c @@ -35,8 +35,6 @@ #include "mapresample.h" #include "mapthread.h" - - extern int msyylex_destroy(void); extern int yyparse(parseObj *); @@ -58,37 +56,36 @@ extern parseResultObj yypresult; /* result of parsing, true/false */ /* msGetClass_String() */ /************************************************************************/ -static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixel_value, int firstClassToTry ) +static int msGetClass_String(layerObj *layer, colorObj *color, + const char *pixel_value, int firstClassToTry) { int i; - const char *tmpstr1=NULL; + const char *tmpstr1 = NULL; int numitems; - char *item_names[4] = { "pixel", "red", "green", "blue" }; + char *item_names[4] = {"pixel", "red", "green", "blue"}; char *item_values[4]; char red_value[8], green_value[8], blue_value[8]; /* -------------------------------------------------------------------- */ /* No need to do a lookup in the case of one default class. */ /* -------------------------------------------------------------------- */ - if((layer->numclasses == 1) && !(layer->class[0]->expression.string)) /* no need to do lookup */ - return(0); + if ((layer->numclasses == 1) && + !(layer->class[0] -> expression.string)) /* no need to do lookup */ + return (0); /* -------------------------------------------------------------------- */ /* Setup values list for expressions. */ /* -------------------------------------------------------------------- */ numitems = 4; - if( color->red == -1 && color->green == -1 && color->blue == -1 ) - { + if (color->red == -1 && color->green == -1 && color->blue == -1) { strcpy(red_value, "-1"); strcpy(green_value, "-1"); strcpy(blue_value, "-1"); - } - else - { - sprintf( red_value, "%d", color->red ); - sprintf( green_value, "%d", color->green ); - sprintf( blue_value, "%d", color->blue ); + } else { + sprintf(red_value, "%d", color->red); + sprintf(green_value, "%d", color->green); + sprintf(blue_value, "%d", color->blue); } item_values[0] = (char *)pixel_value; @@ -99,101 +96,109 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe /* -------------------------------------------------------------------- */ /* Loop over classes till we find a match. */ /* -------------------------------------------------------------------- */ - if( firstClassToTry >= layer->numclasses ) - firstClassToTry = -1; - for(i=0; inumclasses; i++) { + if (firstClassToTry >= layer->numclasses) + firstClassToTry = -1; + for (i = 0; i < layer->numclasses; i++) { - const int idx = firstClassToTry < 0 ? i : - i == 0 ? firstClassToTry : - i <= firstClassToTry ? i - 1: - i; + const int idx = firstClassToTry < 0 ? i + : i == 0 ? firstClassToTry + : i <= firstClassToTry ? i - 1 + : i; /* check for correct classgroup, if set */ - if ( layer->class[idx]->group && layer->classgroup && - strcasecmp(layer->class[idx]->group, layer->classgroup) != 0 ) + if (layer->class[idx] -> group && layer -> classgroup &&strcasecmp( + layer->class[idx] -> group, + layer -> classgroup) != 0) continue; /* Empty expression - always matches */ - if (layer->class[idx]->expression.string == NULL) - return(i); - - switch(layer->class[idx]->expression.type) { - - /* -------------------------------------------------------------------- */ - /* Simple string match */ - /* -------------------------------------------------------------------- */ - case(MS_STRING): - /* trim junk white space */ - tmpstr1= pixel_value; - while( *tmpstr1 == ' ' ) - tmpstr1++; - - if(strcmp(layer->class[idx]->expression.string, tmpstr1) == 0) return(idx); /* matched */ - break; + if (layer->class[idx] -> expression.string == NULL) + return (i); + + switch (layer->class[idx] -> expression.type) { + + /* -------------------------------------------------------------------- */ + /* Simple string match */ + /* -------------------------------------------------------------------- */ + case (MS_STRING): + /* trim junk white space */ + tmpstr1 = pixel_value; + while (*tmpstr1 == ' ') + tmpstr1++; + + if (strcmp(layer->class[idx] -> expression.string, tmpstr1) == 0) + return (idx); /* matched */ + break; - /* -------------------------------------------------------------------- */ - /* Regular expression. Rarely used for raster. */ - /* -------------------------------------------------------------------- */ - case(MS_REGEX): - if(!layer->class[idx]->expression.compiled) { - if(ms_regcomp(&(layer->class[idx]->expression.regex), layer->class[idx]->expression.string, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { /* compile the expression */ - msSetError(MS_REGEXERR, "Invalid regular expression.", "msGetClass()"); - return(-1); - } - layer->class[idx]->expression.compiled = MS_TRUE; + /* -------------------------------------------------------------------- */ + /* Regular expression. Rarely used for raster. */ + /* -------------------------------------------------------------------- */ + case (MS_REGEX): + if (!layer->class[idx] -> expression.compiled) { + if (ms_regcomp(&(layer->class[idx] -> expression.regex), + layer->class[idx] -> expression.string, + MS_REG_EXTENDED | MS_REG_NOSUB) != + 0) { /* compile the expression */ + msSetError(MS_REGEXERR, "Invalid regular expression.", + "msGetClass()"); + return (-1); } + layer->class[idx]->expression.compiled = MS_TRUE; + } - if(ms_regexec(&(layer->class[idx]->expression.regex), pixel_value, 0, NULL, 0) == 0) return(idx); /* got a match */ - break; - - /* -------------------------------------------------------------------- */ - /* Parsed expression. */ - /* -------------------------------------------------------------------- */ - case(MS_EXPRESSION): { - int status; - parseObj p; - shapeObj dummy_shape; - expressionObj *expression = &(layer->class[idx]->expression); + if (ms_regexec(&(layer->class[idx] -> expression.regex), pixel_value, 0, + NULL, 0) == 0) + return (idx); /* got a match */ + break; - dummy_shape.numvalues = numitems; - dummy_shape.values = item_values; + /* -------------------------------------------------------------------- */ + /* Parsed expression. */ + /* -------------------------------------------------------------------- */ + case (MS_EXPRESSION): { + int status; + parseObj p; + shapeObj dummy_shape; + expressionObj *expression = &(layer->class[idx] -> expression); - if( expression->tokens == NULL ) - msTokenizeExpression( expression, item_names, &numitems ); + dummy_shape.numvalues = numitems; + dummy_shape.values = item_values; - p.shape = &dummy_shape; - p.expr = expression; - p.expr->curtoken = p.expr->tokens; /* reset */ - p.type = MS_PARSE_TYPE_BOOLEAN; + if (expression->tokens == NULL) + msTokenizeExpression(expression, item_names, &numitems); - status = yyparse(&p); + p.shape = &dummy_shape; + p.expr = expression; + p.expr->curtoken = p.expr->tokens; /* reset */ + p.type = MS_PARSE_TYPE_BOOLEAN; - if (status != 0) { - msSetError(MS_PARSEERR, "Failed to parse expression: %s", "msGetClass_FloatRGB", expression->string); - return -1; - } + status = yyparse(&p); - if( p.result.intval ) - return idx; - break; + if (status != 0) { + msSetError(MS_PARSEERR, "Failed to parse expression: %s", + "msGetClass_FloatRGB", expression->string); + return -1; } + + if (p.result.intval) + return idx; + break; + } } } - return(-1); /* not found */ + return (-1); /* not found */ } /************************************************************************/ /* msGetClass() */ /************************************************************************/ -int msGetClass(layerObj *layer, colorObj *color, int colormap_index) -{ +int msGetClass(layerObj *layer, colorObj *color, int colormap_index) { char pixel_value[12]; - snprintf( pixel_value, sizeof(pixel_value), "%d", colormap_index ); + snprintf(pixel_value, sizeof(pixel_value), "%d", colormap_index); - return msGetClass_String( layer, color, pixel_value, -1 ); + return msGetClass_String(layer, color, pixel_value, -1); } /************************************************************************/ @@ -203,15 +208,15 @@ int msGetClass(layerObj *layer, colorObj *color, int colormap_index) /* pixel value. */ /************************************************************************/ -int msGetClass_FloatRGB(layerObj *layer, float fValue, int red, int green, int blue ) -{ - return msGetClass_FloatRGB_WithFirstClassToTry( - layer, fValue, red, green, blue, -1); +int msGetClass_FloatRGB(layerObj *layer, float fValue, int red, int green, + int blue) { + return msGetClass_FloatRGB_WithFirstClassToTry(layer, fValue, red, green, + blue, -1); } - -int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, int red, int green, int blue, int firstClassToTry ) -{ +int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, + int red, int green, int blue, + int firstClassToTry) { char pixel_value[100]; colorObj color; @@ -219,9 +224,9 @@ int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, int r color.green = green; color.blue = blue; - snprintf( pixel_value, sizeof(pixel_value), "%18g", fValue ); + snprintf(pixel_value, sizeof(pixel_value), "%18g", fValue); - return msGetClass_String( layer, &color, pixel_value, firstClassToTry ); + return msGetClass_String(layer, &color, pixel_value, firstClassToTry); } /************************************************************************/ @@ -231,142 +236,140 @@ int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, int r /************************************************************************/ int msDrawRasterSetupTileLayer(mapObj *map, layerObj *layer, - rectObj* psearchrect, - int is_query, - int* ptilelayerindex, /* output */ - int* ptileitemindex, /* output */ - int* ptilesrsindex, /* output */ - layerObj **ptlp /* output */ ) -{ - int i; - char* requested_fields; - int status; - layerObj* tlp = NULL; - - *ptilelayerindex = msGetLayerIndex(layer->map, layer->tileindex); - if(*ptilelayerindex == -1) { /* the tileindex references a file, not a layer */ - - /* so we create a temporary layer */ - tlp = (layerObj *) malloc(sizeof(layerObj)); - MS_CHECK_ALLOC(tlp, sizeof(layerObj), MS_FAILURE); - - initLayer(tlp, map); - *ptlp = tlp; - - /* set a few parameters for a very basic shapefile-based layer */ - tlp->name = msStrdup("TILE"); - tlp->type = MS_LAYER_TILEINDEX; - tlp->data = msStrdup(layer->tileindex); - - if( is_query ) - { - tlp->map = map; /*needed when scaletokens are applied, to extract current map scale */ - for(i = 0; i < layer->numscaletokens; i++) { - if(msGrowLayerScaletokens(tlp) == NULL) { - return MS_FAILURE; - } - initScaleToken(&tlp->scaletokens[i]); - msCopyScaleToken(&layer->scaletokens[i],&tlp->scaletokens[i]); - tlp->numscaletokens++; + rectObj *psearchrect, int is_query, + int *ptilelayerindex, /* output */ + int *ptileitemindex, /* output */ + int *ptilesrsindex, /* output */ + layerObj **ptlp /* output */) { + int i; + char *requested_fields; + int status; + layerObj *tlp = NULL; + + *ptilelayerindex = msGetLayerIndex(layer->map, layer->tileindex); + if (*ptilelayerindex == + -1) { /* the tileindex references a file, not a layer */ + + /* so we create a temporary layer */ + tlp = (layerObj *)malloc(sizeof(layerObj)); + MS_CHECK_ALLOC(tlp, sizeof(layerObj), MS_FAILURE); + + initLayer(tlp, map); + *ptlp = tlp; + + /* set a few parameters for a very basic shapefile-based layer */ + tlp->name = msStrdup("TILE"); + tlp->type = MS_LAYER_TILEINDEX; + tlp->data = msStrdup(layer->tileindex); + + if (is_query) { + tlp->map = map; /*needed when scaletokens are applied, to extract current + map scale */ + for (i = 0; i < layer->numscaletokens; i++) { + if (msGrowLayerScaletokens(tlp) == NULL) { + return MS_FAILURE; } + initScaleToken(&tlp->scaletokens[i]); + msCopyScaleToken(&layer->scaletokens[i], &tlp->scaletokens[i]); + tlp->numscaletokens++; } - - if (layer->projection.numargs > 0 && - EQUAL(layer->projection.args[0], "auto")) - { - tlp->projection.numargs = 1; - tlp->projection.args[0] = msStrdup("auto"); - } - - if (layer->filteritem) - tlp->filteritem = msStrdup(layer->filteritem); - if (layer->filter.string) { - if (layer->filter.type == MS_EXPRESSION) { - char* pszTmp = - (char *)msSmallMalloc(sizeof(char)*(strlen(layer->filter.string)+3)); - sprintf(pszTmp,"(%s)",layer->filter.string); - msLoadExpressionString(&tlp->filter, pszTmp); - free(pszTmp); - } else if (layer->filter.type == MS_REGEX || - layer->filter.type == MS_IREGEX) { - char* pszTmp = - (char *)msSmallMalloc(sizeof(char)*(strlen(layer->filter.string)+3)); - sprintf(pszTmp,"/%s/",layer->filter.string); - msLoadExpressionString(&tlp->filter, pszTmp); - free(pszTmp); - } else - msLoadExpressionString(&tlp->filter, layer->filter.string); - - tlp->filter.type = layer->filter.type; - } - - } else { - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) - return MS_FAILURE; - tlp = (GET_LAYER(layer->map, *ptilelayerindex)); - *ptlp = tlp; - } - status = msLayerOpen(tlp); - if(status != MS_SUCCESS) { - return status; } - /* fetch tileitem and tilesrs fields */ - requested_fields = (char*) msSmallMalloc(sizeof(char)*(strlen(layer->tileitem)+1+ - (layer->tilesrs ? strlen(layer->tilesrs) : 0) + 1)); - if( layer->tilesrs != NULL ) - sprintf(requested_fields, "%s,%s", layer->tileitem, layer->tilesrs); - else - strcpy(requested_fields, layer->tileitem); - status = msLayerWhichItems(tlp, MS_FALSE, requested_fields); - msFree(requested_fields); - if(status != MS_SUCCESS) { - return status; + if (layer->projection.numargs > 0 && + EQUAL(layer->projection.args[0], "auto")) { + tlp->projection.numargs = 1; + tlp->projection.args[0] = msStrdup("auto"); } - /* get the tileitem and tilesrs index */ - for(i=0; inumitems; i++) { - if(strcasecmp(tlp->items[i], layer->tileitem) == 0) { - *ptileitemindex = i; - } - if(layer->tilesrs != NULL && - strcasecmp(tlp->items[i], layer->tilesrs) == 0) { - *ptilesrsindex = i; - } + if (layer->filteritem) + tlp->filteritem = msStrdup(layer->filteritem); + if (layer->filter.string) { + if (layer->filter.type == MS_EXPRESSION) { + char *pszTmp = (char *)msSmallMalloc( + sizeof(char) * (strlen(layer->filter.string) + 3)); + sprintf(pszTmp, "(%s)", layer->filter.string); + msLoadExpressionString(&tlp->filter, pszTmp); + free(pszTmp); + } else if (layer->filter.type == MS_REGEX || + layer->filter.type == MS_IREGEX) { + char *pszTmp = (char *)msSmallMalloc( + sizeof(char) * (strlen(layer->filter.string) + 3)); + sprintf(pszTmp, "/%s/", layer->filter.string); + msLoadExpressionString(&tlp->filter, pszTmp); + free(pszTmp); + } else + msLoadExpressionString(&tlp->filter, layer->filter.string); + + tlp->filter.type = layer->filter.type; } - if(*ptileitemindex < 0) { /* didn't find it */ - msSetError(MS_MEMERR, - "Could not find attribute %s in tileindex.", - "msDrawRasterLayerLow()", - layer->tileitem); + + } else { + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; + tlp = (GET_LAYER(layer->map, *ptilelayerindex)); + *ptlp = tlp; + } + status = msLayerOpen(tlp); + if (status != MS_SUCCESS) { + return status; + } + + /* fetch tileitem and tilesrs fields */ + requested_fields = (char *)msSmallMalloc( + sizeof(char) * (strlen(layer->tileitem) + 1 + + (layer->tilesrs ? strlen(layer->tilesrs) : 0) + 1)); + if (layer->tilesrs != NULL) + sprintf(requested_fields, "%s,%s", layer->tileitem, layer->tilesrs); + else + strcpy(requested_fields, layer->tileitem); + status = msLayerWhichItems(tlp, MS_FALSE, requested_fields); + msFree(requested_fields); + if (status != MS_SUCCESS) { + return status; + } + + /* get the tileitem and tilesrs index */ + for (i = 0; i < tlp->numitems; i++) { + if (strcasecmp(tlp->items[i], layer->tileitem) == 0) { + *ptileitemindex = i; } - if(layer->tilesrs != NULL && *ptilesrsindex < 0) { /* didn't find it */ - msSetError(MS_MEMERR, - "Could not find attribute %s in tileindex.", - "msDrawRasterLayerLow()", - layer->tilesrs); - return MS_FAILURE; + if (layer->tilesrs != NULL && + strcasecmp(tlp->items[i], layer->tilesrs) == 0) { + *ptilesrsindex = i; } + } + if (*ptileitemindex < 0) { /* didn't find it */ + msSetError(MS_MEMERR, "Could not find attribute %s in tileindex.", + "msDrawRasterLayerLow()", layer->tileitem); + return MS_FAILURE; + } + if (layer->tilesrs != NULL && *ptilesrsindex < 0) { /* didn't find it */ + msSetError(MS_MEMERR, "Could not find attribute %s in tileindex.", + "msDrawRasterLayerLow()", layer->tilesrs); + return MS_FAILURE; + } - /* if necessary, project the searchrect to source coords */ - if((map->projection.numargs > 0) && (layer->projection.numargs > 0) && - !EQUAL(layer->projection.args[0], "auto")) { - if( msProjectRect(&map->projection, &layer->projection, psearchrect) - != MS_SUCCESS ) { - msDebug( "msDrawRasterLayerLow(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name ); - return MS_FAILURE; - } + /* if necessary, project the searchrect to source coords */ + if ((map->projection.numargs > 0) && (layer->projection.numargs > 0) && + !EQUAL(layer->projection.args[0], "auto")) { + if (msProjectRect(&map->projection, &layer->projection, psearchrect) != + MS_SUCCESS) { + msDebug("msDrawRasterLayerLow(%s): unable to reproject map request " + "rectangle into layer projection, canceling.\n", + layer->name); + return MS_FAILURE; } - else if((map->projection.numargs > 0) && (tlp->projection.numargs > 0) && - !EQUAL(tlp->projection.args[0], "auto")) { - if( msProjectRect(&map->projection, &tlp->projection, psearchrect) - != MS_SUCCESS ) { - msDebug( "msDrawRasterLayerLow(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name ); - return MS_FAILURE; - } + } else if ((map->projection.numargs > 0) && (tlp->projection.numargs > 0) && + !EQUAL(tlp->projection.args[0], "auto")) { + if (msProjectRect(&map->projection, &tlp->projection, psearchrect) != + MS_SUCCESS) { + msDebug("msDrawRasterLayerLow(%s): unable to reproject map request " + "rectangle into layer projection, canceling.\n", + layer->name); + return MS_FAILURE; } - return msLayerWhichShapes(tlp, *psearchrect, MS_FALSE); + } + return msLayerWhichShapes(tlp, *psearchrect, MS_FALSE); } /************************************************************************/ @@ -375,14 +378,12 @@ int msDrawRasterSetupTileLayer(mapObj *map, layerObj *layer, /* Cleanup the tile layer. */ /************************************************************************/ -void msDrawRasterCleanupTileLayer(layerObj* tlp, - int tilelayerindex) -{ - msLayerClose(tlp); - if(tilelayerindex == -1) { - freeLayer(tlp); - free(tlp); - } +void msDrawRasterCleanupTileLayer(layerObj *tlp, int tilelayerindex) { + msLayerClose(tlp); + if (tilelayerindex == -1) { + freeLayer(tlp); + free(tlp); + } } /************************************************************************/ @@ -391,39 +392,38 @@ void msDrawRasterCleanupTileLayer(layerObj* tlp, /* Iterate over the tile layer. */ /************************************************************************/ -int msDrawRasterIterateTileIndex(layerObj *layer, - layerObj* tlp, - shapeObj* ptshp, /* input-output */ - int tileitemindex, - int tilesrsindex, - char* tilename, /* output */ +int msDrawRasterIterateTileIndex(layerObj *layer, layerObj *tlp, + shapeObj *ptshp, /* input-output */ + int tileitemindex, int tilesrsindex, + char *tilename, /* output */ size_t sizeof_tilename, - char* tilesrsname, /* output */ - size_t sizeof_tilesrsname) -{ - int status; + char *tilesrsname, /* output */ + size_t sizeof_tilesrsname) { + int status; - status = msLayerNextShape(tlp, ptshp); - if( status == MS_FAILURE || status == MS_DONE ) { - return status; - } + status = msLayerNextShape(tlp, ptshp); + if (status == MS_FAILURE || status == MS_DONE) { + return status; + } - if(layer->data == NULL || strlen(layer->data) == 0 ) { /* assume whole filename is in attribute field */ - strlcpy( tilename, ptshp->values[tileitemindex], sizeof_tilename); - } else - snprintf(tilename, sizeof_tilename, "%s/%s", ptshp->values[tileitemindex], layer->data); + if (layer->data == NULL || + strlen(layer->data) == + 0) { /* assume whole filename is in attribute field */ + strlcpy(tilename, ptshp->values[tileitemindex], sizeof_tilename); + } else + snprintf(tilename, sizeof_tilename, "%s/%s", ptshp->values[tileitemindex], + layer->data); - tilesrsname[0] = '\0'; + tilesrsname[0] = '\0'; - if( tilesrsindex >= 0 ) - { - if(ptshp->values[tilesrsindex] != NULL ) - strlcpy( tilesrsname, ptshp->values[tilesrsindex], sizeof_tilesrsname ); - } + if (tilesrsindex >= 0) { + if (ptshp->values[tilesrsindex] != NULL) + strlcpy(tilesrsname, ptshp->values[tilesrsindex], sizeof_tilesrsname); + } - msFreeShape(ptshp); /* done with the shape */ + msFreeShape(ptshp); /* done with the shape */ - return status; + return status; } /************************************************************************/ @@ -433,25 +433,26 @@ int msDrawRasterIterateTileIndex(layerObj *layer, /************************************************************************/ int msDrawRasterBuildRasterPath(mapObj *map, layerObj *layer, - const char* filename, - char szPath[MS_MAXPATHLEN] /* output */) -{ - /* - ** If using a tileindex then build the path relative to that file if SHAPEPATH is not set. - */ - if(layer->tileindex && !map->shapepath) { - char tiAbsFilePath[MS_MAXPATHLEN]; - char *tiAbsDirPath = NULL; - - msTryBuildPath(tiAbsFilePath, map->mappath, layer->tileindex); /* absolute path to tileindex file */ - tiAbsDirPath = msGetPath(tiAbsFilePath); /* tileindex file's directory */ - msBuildPath(szPath, tiAbsDirPath, filename); - free(tiAbsDirPath); - } else { - msTryBuildPath3(szPath, map->mappath, map->shapepath, filename); - } + const char *filename, + char szPath[MS_MAXPATHLEN] /* output */) { + /* + ** If using a tileindex then build the path relative to that file if SHAPEPATH + *is not set. + */ + if (layer->tileindex && !map->shapepath) { + char tiAbsFilePath[MS_MAXPATHLEN]; + char *tiAbsDirPath = NULL; + + msTryBuildPath(tiAbsFilePath, map->mappath, + layer->tileindex); /* absolute path to tileindex file */ + tiAbsDirPath = msGetPath(tiAbsFilePath); /* tileindex file's directory */ + msBuildPath(szPath, tiAbsDirPath, filename); + free(tiAbsDirPath); + } else { + msTryBuildPath3(szPath, map->mappath, map->shapepath, filename); + } - return MS_SUCCESS; + return MS_SUCCESS; } /************************************************************************/ @@ -460,27 +461,25 @@ int msDrawRasterBuildRasterPath(mapObj *map, layerObj *layer, /* Return the CPL error message, and filter out sensitive info. */ /************************************************************************/ -const char* msDrawRasterGetCPLErrorMsg(const char* decrypted_path, - const char* szPath) -{ - const char *cpl_error_msg = CPLGetLastErrorMsg(); +const char *msDrawRasterGetCPLErrorMsg(const char *decrypted_path, + const char *szPath) { + const char *cpl_error_msg = CPLGetLastErrorMsg(); - /* we wish to avoid reporting decrypted paths */ - if( cpl_error_msg != NULL - && strstr(cpl_error_msg,decrypted_path) != NULL - && strcmp(decrypted_path,szPath) != 0 ) - cpl_error_msg = NULL; + /* we wish to avoid reporting decrypted paths */ + if (cpl_error_msg != NULL && strstr(cpl_error_msg, decrypted_path) != NULL && + strcmp(decrypted_path, szPath) != 0) + cpl_error_msg = NULL; - /* we wish to avoid reporting the stock GDALOpen error messages */ - if( cpl_error_msg != NULL - && (strstr(cpl_error_msg,"not recognised as a supported") != NULL - || strstr(cpl_error_msg,"does not exist") != NULL) ) - cpl_error_msg = NULL; + /* we wish to avoid reporting the stock GDALOpen error messages */ + if (cpl_error_msg != NULL && + (strstr(cpl_error_msg, "not recognised as a supported") != NULL || + strstr(cpl_error_msg, "does not exist") != NULL)) + cpl_error_msg = NULL; - if( cpl_error_msg == NULL ) - cpl_error_msg = ""; + if (cpl_error_msg == NULL) + cpl_error_msg = ""; - return cpl_error_msg; + return cpl_error_msg; } /************************************************************************/ @@ -489,175 +488,164 @@ const char* msDrawRasterGetCPLErrorMsg(const char* decrypted_path, /* Handle TILESRS or PROJECTION AUTO for each tile. */ /************************************************************************/ -int msDrawRasterLoadProjection(layerObj *layer, - GDALDatasetH hDS, - const char* filename, - int tilesrsindex, - const char* tilesrsname) -{ - /* - ** Generate the projection information if using TILESRS. - */ - if( tilesrsindex >= 0 ) - { - const char *pszWKT; - if( tilesrsname[0] != '\0' ) - pszWKT = tilesrsname; - else - pszWKT = GDALGetProjectionRef( hDS ); - if( pszWKT != NULL && strlen(pszWKT) > 0 ) { - if( msOGCWKT2ProjectionObj(pszWKT, &(layer->projection), - layer->debug ) != MS_SUCCESS ) { - char szLongMsg[MESSAGELENGTH*2]; - errorObj *ms_error = msGetErrorObj(); - - snprintf( szLongMsg, sizeof(szLongMsg), - "%s\n" - "PROJECTION '%s' cannot be used for this " - "GDAL raster (`%s').", - ms_error->message, pszWKT, filename); - szLongMsg[MESSAGELENGTH-1] = '\0'; - - msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", - szLongMsg); +int msDrawRasterLoadProjection(layerObj *layer, GDALDatasetH hDS, + const char *filename, int tilesrsindex, + const char *tilesrsname) { + /* + ** Generate the projection information if using TILESRS. + */ + if (tilesrsindex >= 0) { + const char *pszWKT; + if (tilesrsname[0] != '\0') + pszWKT = tilesrsname; + else + pszWKT = GDALGetProjectionRef(hDS); + if (pszWKT != NULL && strlen(pszWKT) > 0) { + if (msOGCWKT2ProjectionObj(pszWKT, &(layer->projection), layer->debug) != + MS_SUCCESS) { + char szLongMsg[MESSAGELENGTH * 2]; + errorObj *ms_error = msGetErrorObj(); + + snprintf(szLongMsg, sizeof(szLongMsg), + "%s\n" + "PROJECTION '%s' cannot be used for this " + "GDAL raster (`%s').", + ms_error->message, pszWKT, filename); + szLongMsg[MESSAGELENGTH - 1] = '\0'; + + msSetError(MS_OGRERR, "%s", "msDrawRasterLayer()", szLongMsg); - return MS_FAILURE; - } + return MS_FAILURE; } } - /* - ** Generate the projection information if using AUTO. - */ - else if (layer->projection.numargs > 0 && - EQUAL(layer->projection.args[0], "auto")) { - const char *pszWKT; - - pszWKT = GDALGetProjectionRef( hDS ); - - if( pszWKT != NULL && strlen(pszWKT) > 0 ) { - if( msOGCWKT2ProjectionObj(pszWKT, &(layer->projection), - layer->debug ) != MS_SUCCESS ) { - char szLongMsg[MESSAGELENGTH*2]; - errorObj *ms_error = msGetErrorObj(); - - snprintf( szLongMsg, sizeof(szLongMsg), - "%s\n" - "PROJECTION AUTO cannot be used for this " - "GDAL raster (`%s').", - ms_error->message, filename); - szLongMsg[MESSAGELENGTH-1] = '\0'; - - msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", - szLongMsg); + } + /* + ** Generate the projection information if using AUTO. + */ + else if (layer->projection.numargs > 0 && + EQUAL(layer->projection.args[0], "auto")) { + const char *pszWKT; + + pszWKT = GDALGetProjectionRef(hDS); + + if (pszWKT != NULL && strlen(pszWKT) > 0) { + if (msOGCWKT2ProjectionObj(pszWKT, &(layer->projection), layer->debug) != + MS_SUCCESS) { + char szLongMsg[MESSAGELENGTH * 2]; + errorObj *ms_error = msGetErrorObj(); + + snprintf(szLongMsg, sizeof(szLongMsg), + "%s\n" + "PROJECTION AUTO cannot be used for this " + "GDAL raster (`%s').", + ms_error->message, filename); + szLongMsg[MESSAGELENGTH - 1] = '\0'; + + msSetError(MS_OGRERR, "%s", "msDrawRasterLayer()", szLongMsg); - return MS_FAILURE; - } + return MS_FAILURE; } } + } - return MS_SUCCESS; + return MS_SUCCESS; } -typedef enum -{ - CDRT_OK, - CDRT_RETURN_MS_FAILURE, - CDRT_CONTINUE_NEXT_TILE +typedef enum { + CDRT_OK, + CDRT_RETURN_MS_FAILURE, + CDRT_CONTINUE_NEXT_TILE } CheckDatasetReturnType; /************************************************************************/ /* msDrawRasterLayerLowCheckDataset() */ /************************************************************************/ -static -CheckDatasetReturnType msDrawRasterLayerLowCheckDataset(mapObj *map, - layerObj *layer, - GDALDatasetH hDS, - const char* decrypted_path, - const char* szPath) -{ - /* - ** If GDAL doesn't recognise it, and it wasn't successfully opened - ** Generate an error. - */ - if(hDS == NULL) { - int ignore_missing = msMapIgnoreMissingData(map); - const char *cpl_error_msg = msDrawRasterGetCPLErrorMsg(decrypted_path, szPath); - - if(ignore_missing == MS_MISSING_DATA_FAIL) { - msSetError(MS_IOERR, "Corrupt, empty or missing file '%s' for layer '%s'. %s", "msDrawRasterLayerLow()", szPath, layer->name, cpl_error_msg ); - return(CDRT_RETURN_MS_FAILURE); - } else if( ignore_missing == MS_MISSING_DATA_LOG ) { - if( layer->debug || layer->map->debug ) { - msDebug( "Corrupt, empty or missing file '%s' for layer '%s' ... ignoring this missing data. %s\n", szPath, layer->name, cpl_error_msg ); - } - return(CDRT_CONTINUE_NEXT_TILE); - } else if( ignore_missing == MS_MISSING_DATA_IGNORE ) { - return(CDRT_CONTINUE_NEXT_TILE); - } else { - /* never get here */ - msSetError(MS_IOERR, "msIgnoreMissingData returned unexpected value.", "msDrawRasterLayerLow()"); - return(CDRT_RETURN_MS_FAILURE); +static CheckDatasetReturnType +msDrawRasterLayerLowCheckDataset(mapObj *map, layerObj *layer, GDALDatasetH hDS, + const char *decrypted_path, + const char *szPath) { + /* + ** If GDAL doesn't recognise it, and it wasn't successfully opened + ** Generate an error. + */ + if (hDS == NULL) { + int ignore_missing = msMapIgnoreMissingData(map); + const char *cpl_error_msg = + msDrawRasterGetCPLErrorMsg(decrypted_path, szPath); + + if (ignore_missing == MS_MISSING_DATA_FAIL) { + msSetError(MS_IOERR, + "Corrupt, empty or missing file '%s' for layer '%s'. %s", + "msDrawRasterLayerLow()", szPath, layer->name, cpl_error_msg); + return (CDRT_RETURN_MS_FAILURE); + } else if (ignore_missing == MS_MISSING_DATA_LOG) { + if (layer->debug || layer->map->debug) { + msDebug("Corrupt, empty or missing file '%s' for layer '%s' ... " + "ignoring this missing data. %s\n", + szPath, layer->name, cpl_error_msg); } + return (CDRT_CONTINUE_NEXT_TILE); + } else if (ignore_missing == MS_MISSING_DATA_IGNORE) { + return (CDRT_CONTINUE_NEXT_TILE); + } else { + /* never get here */ + msSetError(MS_IOERR, "msIgnoreMissingData returned unexpected value.", + "msDrawRasterLayerLow()"); + return (CDRT_RETURN_MS_FAILURE); } + } - return CDRT_OK; + return CDRT_OK; } /************************************************************************/ /* msDrawRasterLayerLowOpenDataset() */ /************************************************************************/ -void* msDrawRasterLayerLowOpenDataset(mapObj *map, layerObj *layer, - const char* filename, +void *msDrawRasterLayerLowOpenDataset(mapObj *map, layerObj *layer, + const char *filename, char szPath[MS_MAXPATHLEN], - char** p_decrypted_path) -{ - const char* pszPath; + char **p_decrypted_path) { + const char *pszPath; msGDALInitialize(); - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): Filename is: %s\n", layer->name, filename); + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): Filename is: %s\n", layer->name, + filename); - if( strncmp(filename, "debug) + if (layer->debug) msDebug("msDrawRasterLayerLow(%s): Path is: %s\n", layer->name, pszPath); - /* - ** Note: because we do decryption after the above path expansion - ** which depends on actually finding a file, it essentially means that - ** fancy path manipulation is essentially disabled when using encrypted - ** components. But that is mostly ok, since stuff like sde,postgres and - ** oracle georaster do not use real paths. - */ - *p_decrypted_path = msDecryptStringTokens( map, pszPath ); - if( *p_decrypted_path == NULL ) + /* + ** Note: because we do decryption after the above path expansion + ** which depends on actually finding a file, it essentially means that + ** fancy path manipulation is essentially disabled when using encrypted + ** components. But that is mostly ok, since stuff like sde,postgres and + ** oracle georaster do not use real paths. + */ + *p_decrypted_path = msDecryptStringTokens(map, pszPath); + if (*p_decrypted_path == NULL) return NULL; - msAcquireLock( TLOCK_GDAL ); - if( !layer->tileindex ) - { - char** connectionoptions = msGetStringListFromHashTable(&(layer->connectionoptions)); - GDALDatasetH hDS = GDALOpenEx( *p_decrypted_path, - GDAL_OF_RASTER | GDAL_OF_SHARED, - NULL, - (const char* const*)connectionoptions, - NULL); + msAcquireLock(TLOCK_GDAL); + if (!layer->tileindex) { + char **connectionoptions = + msGetStringListFromHashTable(&(layer->connectionoptions)); + GDALDatasetH hDS = + GDALOpenEx(*p_decrypted_path, GDAL_OF_RASTER | GDAL_OF_SHARED, NULL, + (const char *const *)connectionoptions, NULL); CSLDestroy(connectionoptions); return hDS; - } - else - { - return GDALOpenShared( *p_decrypted_path, GA_ReadOnly ); + } else { + return GDALOpenShared(*p_decrypted_path, GA_ReadOnly); } } @@ -665,84 +653,96 @@ void* msDrawRasterLayerLowOpenDataset(mapObj *map, layerObj *layer, /* msDrawRasterLayerLowCloseDataset() */ /************************************************************************/ -void msDrawRasterLayerLowCloseDataset(layerObj *layer, void* hDS) -{ - if( hDS ) +void msDrawRasterLayerLowCloseDataset(layerObj *layer, void *hDS) { + if (hDS) { + const char *close_connection; + close_connection = msLayerGetProcessingKey(layer, "CLOSE_CONNECTION"); + + if (close_connection == NULL && layer->tileindex == NULL) + close_connection = "DEFER"; + { - const char *close_connection; - close_connection = msLayerGetProcessingKey( layer, - "CLOSE_CONNECTION" ); - - if( close_connection == NULL && layer->tileindex == NULL ) - close_connection = "DEFER"; - - { - /* Due to how GDAL processes OVERVIEW_LEVEL, datasets returned are */ - /* not shared, despite being asked to, so close them for real */ - char** connectionoptions = msGetStringListFromHashTable(&(layer->connectionoptions)); - if( CSLFetchNameValue(connectionoptions, "OVERVIEW_LEVEL") ) - close_connection = NULL; - CSLDestroy(connectionoptions); - } + /* Due to how GDAL processes OVERVIEW_LEVEL, datasets returned are */ + /* not shared, despite being asked to, so close them for real */ + char **connectionoptions = + msGetStringListFromHashTable(&(layer->connectionoptions)); + if (CSLFetchNameValue(connectionoptions, "OVERVIEW_LEVEL")) + close_connection = NULL; + CSLDestroy(connectionoptions); + } - if( close_connection != NULL - && strcasecmp(close_connection,"DEFER") == 0 ) { - GDALDereferenceDataset( (GDALDatasetH)hDS ); - } else { - GDALClose( (GDALDatasetH)hDS ); - } - msReleaseLock( TLOCK_GDAL ); + if (close_connection != NULL && + strcasecmp(close_connection, "DEFER") == 0) { + GDALDereferenceDataset((GDALDatasetH)hDS); + } else { + GDALClose((GDALDatasetH)hDS); } + msReleaseLock(TLOCK_GDAL); + } } - /************************************************************************/ /* msDrawRasterLayerLowCheckIfMustDraw() */ /* */ /* Return 1 if the layer should be drawn. */ /************************************************************************/ -int msDrawRasterLayerLowCheckIfMustDraw(mapObj *map, layerObj *layer) -{ - if(!layer->data && !layer->tileindex && !(layer->connectiontype==MS_KERNELDENSITY || layer->connectiontype==MS_IDW)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): layer data and tileindex NULL ... doing nothing.", layer->name ); - return(0); +int msDrawRasterLayerLowCheckIfMustDraw(mapObj *map, layerObj *layer) { + if (!layer->data && !layer->tileindex && + !(layer->connectiontype == MS_KERNELDENSITY || + layer->connectiontype == MS_IDW)) { + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): layer data and tileindex NULL ... " + "doing nothing.", + layer->name); + return (0); } - if((layer->status != MS_ON) && (layer->status != MS_DEFAULT)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): not status ON or DEFAULT, doing nothing.", layer->name ); - return(0); + if ((layer->status != MS_ON) && (layer->status != MS_DEFAULT)) { + if (layer->debug) + msDebug( + "msDrawRasterLayerLow(%s): not status ON or DEFAULT, doing nothing.", + layer->name); + return (0); } - if(map->scaledenom > 0) { - if((layer->maxscaledenom > 0) && (map->scaledenom > layer->maxscaledenom)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): skipping, map scale %.2g > MAXSCALEDENOM=%g\n", - layer->name, map->scaledenom, layer->maxscaledenom ); - return(0); + if (map->scaledenom > 0) { + if ((layer->maxscaledenom > 0) && + (map->scaledenom > layer->maxscaledenom)) { + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): skipping, map scale %.2g > " + "MAXSCALEDENOM=%g\n", + layer->name, map->scaledenom, layer->maxscaledenom); + return (0); } - if((layer->minscaledenom > 0) && (map->scaledenom <= layer->minscaledenom)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): skipping, map scale %.2g < MINSCALEDENOM=%g\n", - layer->name, map->scaledenom, layer->minscaledenom ); - return(0); + if ((layer->minscaledenom > 0) && + (map->scaledenom <= layer->minscaledenom)) { + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): skipping, map scale %.2g < " + "MINSCALEDENOM=%g\n", + layer->name, map->scaledenom, layer->minscaledenom); + return (0); } } - if(layer->maxscaledenom <= 0 && layer->minscaledenom <= 0) { - if((layer->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > layer->maxgeowidth)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): skipping, map width %.2g > MAXSCALEDENOM=%g\n", layer->name, - (map->extent.maxx - map->extent.minx), layer->maxgeowidth ); - return(0); + if (layer->maxscaledenom <= 0 && layer->minscaledenom <= 0) { + if ((layer->maxgeowidth > 0) && + ((map->extent.maxx - map->extent.minx) > layer->maxgeowidth)) { + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): skipping, map width %.2g > " + "MAXSCALEDENOM=%g\n", + layer->name, (map->extent.maxx - map->extent.minx), + layer->maxgeowidth); + return (0); } - if((layer->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < layer->mingeowidth)) { - if(layer->debug) - msDebug( "msDrawRasterLayerLow(%s): skipping, map width %.2g < MINSCALEDENOM=%g\n", layer->name, - (map->extent.maxx - map->extent.minx), layer->mingeowidth ); - return(0); + if ((layer->mingeowidth > 0) && + ((map->extent.maxx - map->extent.minx) < layer->mingeowidth)) { + if (layer->debug) + msDebug("msDrawRasterLayerLow(%s): skipping, map width %.2g < " + "MINSCALEDENOM=%g\n", + layer->name, (map->extent.maxx - map->extent.minx), + layer->mingeowidth); + return (0); } } @@ -757,56 +757,50 @@ int msDrawRasterLayerLowCheckIfMustDraw(mapObj *map, layerObj *layer) /************************************************************************/ int msDrawRasterLayerLow(mapObj *map, layerObj *layer, imageObj *image, - rasterBufferObj *rb ) -{ - return msDrawRasterLayerLowWithDataset(map, layer, image, rb, NULL); + rasterBufferObj *rb) { + return msDrawRasterLayerLowWithDataset(map, layer, image, rb, NULL); } -int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, imageObj *image, - rasterBufferObj *rb, void* hDatasetIn ) -{ +int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, + imageObj *image, rasterBufferObj *rb, + void *hDatasetIn) { /* -------------------------------------------------------------------- */ /* As of MapServer 6.0 GDAL is required for rendering raster */ /* imagery. */ /* -------------------------------------------------------------------- */ int status, done; - char *filename=NULL, tilename[MS_MAXPATHLEN], tilesrsname[1024]; + char *filename = NULL, tilename[MS_MAXPATHLEN], tilesrsname[1024]; - layerObj *tlp=NULL; /* pointer to the tile layer either real or temporary */ - int tileitemindex=-1, tilelayerindex=-1, tilesrsindex=-1; + layerObj *tlp = NULL; /* pointer to the tile layer either real or temporary */ + int tileitemindex = -1, tilelayerindex = -1, tilesrsindex = -1; shapeObj tshp; - char szPath[MS_MAXPATHLEN] = { 0 }; + char szPath[MS_MAXPATHLEN] = {0}; char *decrypted_path = NULL; int final_status = MS_SUCCESS; rectObj searchrect; - GDALDatasetH hDS; - double adfGeoTransform[6]; + GDALDatasetH hDS; + double adfGeoTransform[6]; void *kernel_density_cleanup_ptr = NULL; - if(layer->debug > 0 || map->debug > 1) - msDebug( "msDrawRasterLayerLow(%s): entering.\n", layer->name ); + if (layer->debug > 0 || map->debug > 1) + msDebug("msDrawRasterLayerLow(%s): entering.\n", layer->name); - if( hDatasetIn == NULL && - !msDrawRasterLayerLowCheckIfMustDraw(map, layer) ) { + if (hDatasetIn == NULL && !msDrawRasterLayerLowCheckIfMustDraw(map, layer)) { return MS_SUCCESS; } msGDALInitialize(); - if(layer->tileindex) { /* we have an index file */ + if (layer->tileindex) { /* we have an index file */ msInitShape(&tshp); searchrect = map->extent; - status = msDrawRasterSetupTileLayer(map, layer, - &searchrect, - MS_FALSE, - &tilelayerindex, - &tileitemindex, - &tilesrsindex, - &tlp); - if(status != MS_SUCCESS) { + status = msDrawRasterSetupTileLayer(map, layer, &searchrect, MS_FALSE, + &tilelayerindex, &tileitemindex, + &tilesrsindex, &tlp); + if (status != MS_SUCCESS) { if (status != MS_DONE) final_status = status; goto cleanup; @@ -814,91 +808,89 @@ int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, imageObj *imag } done = MS_FALSE; - while(done != MS_TRUE) { - - if(layer->tileindex) { - status = msDrawRasterIterateTileIndex(layer, tlp, &tshp, - tileitemindex, tilesrsindex, - tilename, sizeof(tilename), - tilesrsname, sizeof(tilesrsname)); - if( status == MS_FAILURE) { + while (done != MS_TRUE) { + + if (layer->tileindex) { + status = msDrawRasterIterateTileIndex( + layer, tlp, &tshp, tileitemindex, tilesrsindex, tilename, + sizeof(tilename), tilesrsname, sizeof(tilesrsname)); + if (status == MS_FAILURE) { final_status = MS_FAILURE; break; } - if(status == MS_DONE) break; /* no more tiles/images */ + if (status == MS_DONE) + break; /* no more tiles/images */ filename = tilename; } else { filename = layer->data; done = MS_TRUE; /* only one image so we're done after this */ } - - if(layer->connectiontype == MS_KERNELDENSITY || layer->connectiontype == MS_IDW) { - msAcquireLock( TLOCK_GDAL ); - status = msInterpolationDataset(map, image, layer, &hDS, &kernel_density_cleanup_ptr); - if(status != MS_SUCCESS) { - msReleaseLock( TLOCK_GDAL ); + + if (layer->connectiontype == MS_KERNELDENSITY || + layer->connectiontype == MS_IDW) { + msAcquireLock(TLOCK_GDAL); + status = msInterpolationDataset(map, image, layer, &hDS, + &kernel_density_cleanup_ptr); + if (status != MS_SUCCESS) { + msReleaseLock(TLOCK_GDAL); final_status = status; goto cleanup; } done = MS_TRUE; - if(msProjectionsDiffer(&map->projection,&layer->projection)) { + if (msProjectionsDiffer(&map->projection, &layer->projection)) { char *mapProjStr = msGetProjectionString(&(map->projection)); /* Set the projection to the map file projection */ if (msLoadProjectionString(&(layer->projection), mapProjStr) != 0) { - GDALClose( hDS ); - msReleaseLock( TLOCK_GDAL ); - msSetError(MS_CGIERR, "Unable to set projection on interpolation layer.", "msDrawRasterLayerLow()"); - return(MS_FAILURE); + GDALClose(hDS); + msReleaseLock(TLOCK_GDAL); + msSetError(MS_CGIERR, + "Unable to set projection on interpolation layer.", + "msDrawRasterLayerLow()"); + return (MS_FAILURE); } free(mapProjStr); } } else { - if(strlen(filename) == 0) continue; - if( hDatasetIn ) - { + if (strlen(filename) == 0) + continue; + if (hDatasetIn) { hDS = (GDALDatasetH)hDatasetIn; - } - else - { + } else { hDS = (GDALDatasetH)msDrawRasterLayerLowOpenDataset( - map, layer, filename, szPath, &decrypted_path); + map, layer, filename, szPath, &decrypted_path); } } - if( hDatasetIn == NULL ) - { - CheckDatasetReturnType eRet = - msDrawRasterLayerLowCheckDataset(map,layer,hDS,decrypted_path,szPath); + if (hDatasetIn == NULL) { + CheckDatasetReturnType eRet = msDrawRasterLayerLowCheckDataset( + map, layer, hDS, decrypted_path, szPath); - msFree( decrypted_path ); - decrypted_path = NULL; + msFree(decrypted_path); + decrypted_path = NULL; - if( eRet == CDRT_CONTINUE_NEXT_TILE ) - { - msReleaseLock( TLOCK_GDAL ); - continue; - } - if( eRet == CDRT_RETURN_MS_FAILURE ) - { - msReleaseLock( TLOCK_GDAL ); - return MS_FAILURE; - } + if (eRet == CDRT_CONTINUE_NEXT_TILE) { + msReleaseLock(TLOCK_GDAL); + continue; + } + if (eRet == CDRT_RETURN_MS_FAILURE) { + msReleaseLock(TLOCK_GDAL); + return MS_FAILURE; + } } - if( msDrawRasterLoadProjection(layer, hDS, filename, tilesrsindex, tilesrsname) != MS_SUCCESS ) - { - if( hDatasetIn == NULL ) - { - GDALClose( hDS ); - msReleaseLock( TLOCK_GDAL ); - } - final_status = MS_FAILURE; - break; + if (msDrawRasterLoadProjection(layer, hDS, filename, tilesrsindex, + tilesrsname) != MS_SUCCESS) { + if (hDatasetIn == NULL) { + GDALClose(hDS); + msReleaseLock(TLOCK_GDAL); + } + final_status = MS_FAILURE; + break; } - msGetGDALGeoTransform( hDS, map, layer, adfGeoTransform ); + msGetGDALGeoTransform(hDS, map, layer, adfGeoTransform); /* ** We want to resample if the source image is rotated, if @@ -906,33 +898,27 @@ int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, imageObj *imag ** requested, or if the image has north-down instead of north-up. */ - if( ((adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 - || adfGeoTransform[5] > 0.0 || adfGeoTransform[1] < 0.0 ) - && layer->transform ) - || msProjectionsDiffer( &(map->projection), - &(layer->projection) ) - || CSLFetchNameValue( layer->processing, "RESAMPLE" ) != NULL ) { - status = msResampleGDALToMap( map, layer, image, rb, hDS ); - } - else - { - if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ) { - if( layer->debug || map->debug ) - msDebug( - "Layer %s has rotational coefficients but we\n" - "are unable to use them, projections support\n" - "needs to be built in.", - layer->name ); - + if (((adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 || + adfGeoTransform[5] > 0.0 || adfGeoTransform[1] < 0.0) && + layer->transform) || + msProjectionsDiffer(&(map->projection), &(layer->projection)) || + CSLFetchNameValue(layer->processing, "RESAMPLE") != NULL) { + status = msResampleGDALToMap(map, layer, image, rb, hDS); + } else { + if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { + if (layer->debug || map->debug) + msDebug("Layer %s has rotational coefficients but we\n" + "are unable to use them, projections support\n" + "needs to be built in.", + layer->name); } - status = msDrawRasterLayerGDAL(map, layer, image, rb, hDS ); + status = msDrawRasterLayerGDAL(map, layer, image, rb, hDS); } - if( status == -1 ) { - if( hDatasetIn == NULL ) - { - GDALClose( hDS ); - msReleaseLock( TLOCK_GDAL ); + if (status == -1) { + if (hDatasetIn == NULL) { + GDALClose(hDS); + msReleaseLock(TLOCK_GDAL); } final_status = MS_FAILURE; break; @@ -943,32 +929,36 @@ int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, imageObj *imag ** default to keeping open for single data files, and ** to closing for tile indexes */ - if(layer->connectiontype == MS_KERNELDENSITY || layer->connectiontype == MS_IDW) { + if (layer->connectiontype == MS_KERNELDENSITY || + layer->connectiontype == MS_IDW) { /* ** Fix issue #5330 - ** The in-memory kernel density heatmap gdal dataset handle (hDS) gets re-used - ** but the associated rasterband cache doesn't get flushed, which causes old data - ** to be rendered instead of the newly generated imagery. To fix, simply close the + ** The in-memory kernel density heatmap gdal dataset handle (hDS) gets + *re-used + ** but the associated rasterband cache doesn't get flushed, which causes + *old data + ** to be rendered instead of the newly generated imagery. To fix, simply + *close the ** the handle and prevent further re-use. - ** Note that instead of this workaround, we could explicitely set + ** Note that instead of this workaround, we could explicitely set ** CLOSE_CONNECTION=ALWAYS on the kerneldensity layer. */ - GDALClose( hDS ); - msReleaseLock( TLOCK_GDAL ); - } - else { - if( hDatasetIn == NULL) + GDALClose(hDS); + msReleaseLock(TLOCK_GDAL); + } else { + if (hDatasetIn == NULL) msDrawRasterLayerLowCloseDataset(layer, hDS); } } /* next tile */ cleanup: - if(layer->tileindex) { /* tiling clean-up */ + if (layer->tileindex) { /* tiling clean-up */ msDrawRasterCleanupTileLayer(tlp, tilelayerindex); } - if(kernel_density_cleanup_ptr) { - msCleanupInterpolationDataset(map, image, layer, kernel_density_cleanup_ptr); + if (kernel_density_cleanup_ptr) { + msCleanupInterpolationDataset(map, image, layer, + kernel_density_cleanup_ptr); } return final_status; @@ -978,10 +968,9 @@ int msDrawRasterLayerLowWithDataset(mapObj *map, layerObj *layer, imageObj *imag /* msDrawReferenceMap() */ /************************************************************************/ -imageObj *msDrawReferenceMap(mapObj *map) -{ +imageObj *msDrawReferenceMap(mapObj *map) { double cellsize; - int x1,y1,x2,y2; + int x1, y1, x2, y2; char szPath[MS_MAXPATHLEN]; int status = MS_SUCCESS; @@ -989,44 +978,51 @@ imageObj *msDrawReferenceMap(mapObj *map) styleObj style; /* check to see if we have enough information to actually proceed */ - if(!map->reference.image || map->reference.height == 0 || map->reference.width == 0) { - msSetError(MS_MISCERR, "Reference map configuration error.", "msDrawReferenceMap()"); + if (!map->reference.image || map->reference.height == 0 || + map->reference.width == 0) { + msSetError(MS_MISCERR, "Reference map configuration error.", + "msDrawReferenceMap()"); return NULL; } rendererVTableObj *renderer = MS_MAP_RENDERER(map); - rasterBufferObj *refImage = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj)); + rasterBufferObj *refImage = + (rasterBufferObj *)calloc(1, sizeof(rasterBufferObj)); MS_CHECK_ALLOC(refImage, sizeof(rasterBufferObj), NULL); - if(MS_SUCCESS != renderer->loadImageFromFile(msBuildPath(szPath, map->mappath, map->reference.image),refImage)) { - msSetError(MS_MISCERR,"Error loading reference image %s.","msDrawReferenceMap()",szPath); + if (MS_SUCCESS != + renderer->loadImageFromFile( + msBuildPath(szPath, map->mappath, map->reference.image), refImage)) { + msSetError(MS_MISCERR, "Error loading reference image %s.", + "msDrawReferenceMap()", szPath); free(refImage); return NULL; } image = msImageCreate(refImage->width, refImage->height, map->outputformat, - map->web.imagepath, map->web.imageurl, map->resolution, map->defresolution, &(map->reference.color)); - if(!image) - { - free(refImage); - return NULL; + map->web.imagepath, map->web.imageurl, map->resolution, + map->defresolution, &(map->reference.color)); + if (!image) { + free(refImage); + return NULL; } - status = renderer->mergeRasterBuffer(image,refImage,1.0,0,0,0,0,refImage->width, refImage->height); + status = renderer->mergeRasterBuffer(image, refImage, 1.0, 0, 0, 0, 0, + refImage->width, refImage->height); msFreeRasterBuffer(refImage); free(refImage); - if(MS_UNLIKELY(status == MS_FAILURE)) + if (MS_UNLIKELY(status == MS_FAILURE)) return NULL; /* make sure the extent given in mapfile fits the image */ - cellsize = msAdjustExtent(&(map->reference.extent), - image->width, image->height); + cellsize = + msAdjustExtent(&(map->reference.extent), image->width, image->height); /* convert map extent to reference image coordinates */ - x1 = MS_MAP2IMAGE_X(map->extent.minx, map->reference.extent.minx, cellsize); - x2 = MS_MAP2IMAGE_X(map->extent.maxx, map->reference.extent.minx, cellsize); - y1 = MS_MAP2IMAGE_Y(map->extent.maxy, map->reference.extent.maxy, cellsize); - y2 = MS_MAP2IMAGE_Y(map->extent.miny, map->reference.extent.maxy, cellsize); + x1 = MS_MAP2IMAGE_X(map->extent.minx, map->reference.extent.minx, cellsize); + x2 = MS_MAP2IMAGE_X(map->extent.maxx, map->reference.extent.minx, cellsize); + y1 = MS_MAP2IMAGE_Y(map->extent.maxy, map->reference.extent.maxy, cellsize); + y2 = MS_MAP2IMAGE_Y(map->extent.miny, map->reference.extent.maxy, cellsize); initStyle(&style); style.color = map->reference.color; @@ -1034,8 +1030,8 @@ imageObj *msDrawReferenceMap(mapObj *map) /* if extent are smaller than minbox size */ /* draw that extent on the reference image */ - if( (abs(x2 - x1) > map->reference.minboxsize) || - (abs(y2 - y1) > map->reference.minboxsize) ) { + if ((abs(x2 - x1) > map->reference.minboxsize) || + (abs(y2 - y1) > map->reference.minboxsize)) { shapeObj rect; lineObj line; pointObj points[5]; @@ -1060,34 +1056,37 @@ imageObj *msDrawReferenceMap(mapObj *map) line.numpoints = 5; - if( map->reference.maxboxsize == 0 || + if (map->reference.maxboxsize == 0 || ((abs(x2 - x1) < map->reference.maxboxsize) && - (abs(y2 - y1) < map->reference.maxboxsize)) ) { - if(MS_UNLIKELY(MS_FAILURE == msDrawShadeSymbol(map, image, &rect, &style, 1.0))) { + (abs(y2 - y1) < map->reference.maxboxsize))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawShadeSymbol(map, image, &rect, &style, 1.0))) { msFreeImage(image); return NULL; } } } else { /* else draw the marker symbol */ - if( map->reference.maxboxsize == 0 || + if (map->reference.maxboxsize == 0 || ((abs(x2 - x1) < map->reference.maxboxsize) && - (abs(y2 - y1) < map->reference.maxboxsize)) ) { + (abs(y2 - y1) < map->reference.maxboxsize))) { style.size = map->reference.markersize; /* if the marker symbol is specify draw this symbol else draw a cross */ - if(map->reference.marker || map->reference.markername) { + if (map->reference.marker || map->reference.markername) { pointObj point; - point.x = (double)(x1 + x2)/2; - point.y = (double)(y1 + y2)/2; + point.x = (double)(x1 + x2) / 2; + point.y = (double)(y1 + y2) / 2; - if(map->reference.marker) { + if (map->reference.marker) { style.symbol = map->reference.marker; } else { - style.symbol = msGetSymbolIndex(&map->symbolset, map->reference.markername, MS_TRUE); + style.symbol = msGetSymbolIndex(&map->symbolset, + map->reference.markername, MS_TRUE); } - if(MS_UNLIKELY(MS_FAILURE == msDrawMarkerSymbol(map, image, &point, &style, 1.0))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawMarkerSymbol(map, image, &point, &style, 1.0))) { msFreeImage(image); return NULL; } @@ -1098,35 +1097,36 @@ imageObj *msDrawReferenceMap(mapObj *map) pointObj point[8]; int i; /* determine the center point */ - x21 = MS_NINT((x1 + x2)/2); - y21 = MS_NINT((y1 + y2)/2); + x21 = MS_NINT((x1 + x2) / 2); + y21 = MS_NINT((y1 + y2) / 2); msInitShape(&cross); cross.numlines = 4; cross.line = lines; - for(i=0; i<4; i++) { + for (i = 0; i < 4; i++) { cross.line[i].numpoints = 2; - cross.line[i].point = &(point[2*i]); + cross.line[i].point = &(point[2 * i]); } /* draw a cross */ - cross.line[0].point[0].x = x21-8; + cross.line[0].point[0].x = x21 - 8; cross.line[0].point[0].y = y21; - cross.line[0].point[1].x = x21-3; + cross.line[0].point[1].x = x21 - 3; cross.line[0].point[1].y = y21; cross.line[1].point[0].x = x21; - cross.line[1].point[0].y = y21-8; + cross.line[1].point[0].y = y21 - 8; cross.line[1].point[1].x = x21; - cross.line[1].point[1].y = y21-3; + cross.line[1].point[1].y = y21 - 3; cross.line[2].point[0].x = x21; - cross.line[2].point[0].y = y21+3; + cross.line[2].point[0].y = y21 + 3; cross.line[2].point[1].x = x21; - cross.line[2].point[1].y = y21+8; - cross.line[3].point[0].x = x21+3; + cross.line[2].point[1].y = y21 + 8; + cross.line[3].point[0].x = x21 + 3; cross.line[3].point[0].y = y21; - cross.line[3].point[1].x = x21+8; + cross.line[3].point[1].x = x21 + 8; cross.line[3].point[1].y = y21; - if(MS_UNLIKELY(MS_FAILURE == msDrawLineSymbol(map,image,&cross,&style,1.0))) { + if (MS_UNLIKELY(MS_FAILURE == + msDrawLineSymbol(map, image, &cross, &style, 1.0))) { msFreeImage(image); return NULL; } @@ -1134,5 +1134,5 @@ imageObj *msDrawReferenceMap(mapObj *map) } } - return(image); + return (image); } diff --git a/mapraster.h b/mapraster.h index c581c66c31..2c692ea533 100644 --- a/mapraster.h +++ b/mapraster.h @@ -29,39 +29,32 @@ #ifndef MAPRASTER_H #define MAPRASTER_H - - int msDrawRasterSetupTileLayer(mapObj *map, layerObj *layer, - rectObj* psearchrect, - int is_query, - int* ptilelayerindex, /* output */ - int* ptileitemindex, /* output */ - int* ptilesrsindex, /* output */ - layerObj **ptlp /* output */ ); - - void msDrawRasterCleanupTileLayer(layerObj* tlp, - int tilelayerindex); - - int msDrawRasterIterateTileIndex(layerObj *layer, - layerObj* tlp, - shapeObj* ptshp, /* input-output */ - int tileitemindex, - int tilesrsindex, - char* tilename, /* output */ - size_t sizeof_tilename, - char* tilesrsname, /* output */ - size_t sizeof_tilesrsname); - - int msDrawRasterBuildRasterPath(mapObj *map, layerObj *layer, - const char* filename, - char szPath[MS_MAXPATHLEN]); - - const char* msDrawRasterGetCPLErrorMsg(const char* decrypted_path, - const char* szPath); - - int msDrawRasterLoadProjection(layerObj *layer, - GDALDatasetH hDS, - const char* filename, - int tilesrsindex, - const char* tilesrsname); +int msDrawRasterSetupTileLayer(mapObj *map, layerObj *layer, + rectObj *psearchrect, int is_query, + int *ptilelayerindex, /* output */ + int *ptileitemindex, /* output */ + int *ptilesrsindex, /* output */ + layerObj **ptlp /* output */); + +void msDrawRasterCleanupTileLayer(layerObj *tlp, int tilelayerindex); + +int msDrawRasterIterateTileIndex(layerObj *layer, layerObj *tlp, + shapeObj *ptshp, /* input-output */ + int tileitemindex, int tilesrsindex, + char *tilename, /* output */ + size_t sizeof_tilename, + char *tilesrsname, /* output */ + size_t sizeof_tilesrsname); + +int msDrawRasterBuildRasterPath(mapObj *map, layerObj *layer, + const char *filename, + char szPath[MS_MAXPATHLEN]); + +const char *msDrawRasterGetCPLErrorMsg(const char *decrypted_path, + const char *szPath); + +int msDrawRasterLoadProjection(layerObj *layer, GDALDatasetH hDS, + const char *filename, int tilesrsindex, + const char *tilesrsname); #endif /* MAPRASTER_H */ diff --git a/maprasterquery.c b/maprasterquery.c index 8d0dda8a6f..56c6799cf5 100644 --- a/maprasterquery.c +++ b/maprasterquery.c @@ -33,7 +33,6 @@ #include "mapthread.h" #include "mapraster.h" - int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record); int msRASTERLayerGetItems(layerObj *layer); @@ -54,41 +53,41 @@ typedef struct { int refcount; rectObj which_rect; - int next_shape; + int next_shape; double *qc_x; double *qc_y; double *qc_x_reproj; double *qc_y_reproj; float *qc_values; - int *qc_class; - int *qc_red; - int *qc_green; - int *qc_blue; - int *qc_count; - int *qc_tileindex; + int *qc_class; + int *qc_red; + int *qc_green; + int *qc_blue; + int *qc_count; + int *qc_tileindex; /* query bound in force */ shapeObj *searchshape; /* Only nearest result to this point. */ - int range_mode; /* MS_QUERY_SINGLE, MS_QUERY_MULTIPLE or -1 (skip test) */ - double range_dist; + int range_mode; /* MS_QUERY_SINGLE, MS_QUERY_MULTIPLE or -1 (skip test) */ + double range_dist; pointObj target_point; GDALColorTableH hCT; - double shape_tolerance; + double shape_tolerance; } rasterLayerInfo; -#define RQM_UNKNOWN 0 -#define RQM_ENTRY_PER_PIXEL 1 -#define RQM_HIST_ON_CLASS 2 -#define RQM_HIST_ON_VALUE 3 +#define RQM_UNKNOWN 0 +#define RQM_ENTRY_PER_PIXEL 1 +#define RQM_HIST_ON_CLASS 2 +#define RQM_HIST_ON_VALUE 3 -extern int InvGeoTransform( double *gt_in, double *gt_out ); -#define GEO_TRANS(tr,x,y) ((tr)[0]+(tr)[1]*(x)+(tr)[2]*(y)) +extern int InvGeoTransform(double *gt_in, double *gt_out); +#define GEO_TRANS(tr, x, y) ((tr)[0] + (tr)[1] * (x) + (tr)[2] * (y)) /************************************************************************/ /* addResult() */ @@ -97,18 +96,21 @@ extern int InvGeoTransform( double *gt_in, double *gt_out ); /* a small public API for managing results caches? */ /************************************************************************/ -static int addResult(resultCacheObj *cache, int classindex, int shapeindex, int tileindex) -{ +static int addResult(resultCacheObj *cache, int classindex, int shapeindex, + int tileindex) { int i; - if(cache->numresults == cache->cachesize) { /* just add it to the end */ - if(cache->cachesize == 0) - cache->results = (resultObj *) malloc(sizeof(resultObj)*MS_RESULTCACHEINCREMENT); + if (cache->numresults == cache->cachesize) { /* just add it to the end */ + if (cache->cachesize == 0) + cache->results = + (resultObj *)malloc(sizeof(resultObj) * MS_RESULTCACHEINCREMENT); else - cache->results = (resultObj *) realloc(cache->results, sizeof(resultObj)*(cache->cachesize+MS_RESULTCACHEINCREMENT)); - if(!cache->results) { + cache->results = (resultObj *)realloc( + cache->results, + sizeof(resultObj) * (cache->cachesize + MS_RESULTCACHEINCREMENT)); + if (!cache->results) { msSetError(MS_MEMERR, "Realloc() error.", "addResult()"); - return(MS_FAILURE); + return (MS_FAILURE); } cache->cachesize += MS_RESULTCACHEINCREMENT; } @@ -122,48 +124,48 @@ static int addResult(resultCacheObj *cache, int classindex, int shapeindex, int cache->results[i].shape = NULL; cache->numresults++; - return(MS_SUCCESS); + return (MS_SUCCESS); } /************************************************************************/ /* msRasterLayerInfoFree() */ /************************************************************************/ -static void msRasterLayerInfoFree( layerObj *layer ) +static void msRasterLayerInfoFree(layerObj *layer) { - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; - if( rlinfo == NULL ) + if (rlinfo == NULL) return; - if( rlinfo->qc_x != NULL ) { - free( rlinfo->qc_x ); - free( rlinfo->qc_y ); - free( rlinfo->qc_x_reproj ); - free( rlinfo->qc_y_reproj ); + if (rlinfo->qc_x != NULL) { + free(rlinfo->qc_x); + free(rlinfo->qc_y); + free(rlinfo->qc_x_reproj); + free(rlinfo->qc_y_reproj); } - if( rlinfo->qc_values ) - free( rlinfo->qc_values ); + if (rlinfo->qc_values) + free(rlinfo->qc_values); - if( rlinfo->qc_class ) { - free( rlinfo->qc_class ); + if (rlinfo->qc_class) { + free(rlinfo->qc_class); } - if( rlinfo->qc_red ) { - free( rlinfo->qc_red ); - free( rlinfo->qc_green ); - free( rlinfo->qc_blue ); + if (rlinfo->qc_red) { + free(rlinfo->qc_red); + free(rlinfo->qc_green); + free(rlinfo->qc_blue); } - if( rlinfo->qc_count != NULL ) - free( rlinfo->qc_count ); + if (rlinfo->qc_count != NULL) + free(rlinfo->qc_count); - if( rlinfo->qc_tileindex != NULL ) - free( rlinfo->qc_tileindex ); + if (rlinfo->qc_tileindex != NULL) + free(rlinfo->qc_tileindex); - free( rlinfo ); + free(rlinfo); layer->layerinfo = NULL; } @@ -172,15 +174,15 @@ static void msRasterLayerInfoFree( layerObj *layer ) /* msRasterLayerInfoInitialize() */ /************************************************************************/ -static void msRasterLayerInfoInitialize( layerObj *layer ) +static void msRasterLayerInfoInitialize(layerObj *layer) { - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; - if( rlinfo != NULL ) + if (rlinfo != NULL) return; - rlinfo = (rasterLayerInfo *) msSmallCalloc(1,sizeof(rasterLayerInfo)); + rlinfo = (rasterLayerInfo *)msSmallCalloc(1, sizeof(rasterLayerInfo)); layer->layerinfo = rlinfo; rlinfo->band_count = -1; @@ -192,15 +194,15 @@ static void msRasterLayerInfoInitialize( layerObj *layer ) /* We need to do this or the layer->layerinfo will be interpreted */ /* as shapefile access info because the default connectiontype is */ /* MS_SHAPEFILE. */ - if (layer->connectiontype != MS_WMS && layer->connectiontype != MS_KERNELDENSITY) + if (layer->connectiontype != MS_WMS && + layer->connectiontype != MS_KERNELDENSITY) layer->connectiontype = MS_RASTER; rlinfo->query_result_hard_max = 1000000; - if( CSLFetchNameValue( layer->processing, "RASTER_QUERY_MAX_RESULT" ) - != NULL ) { + if (CSLFetchNameValue(layer->processing, "RASTER_QUERY_MAX_RESULT") != NULL) { rlinfo->query_result_hard_max = - atoi(CSLFetchNameValue( layer->processing, "RASTER_QUERY_MAX_RESULT" )); + atoi(CSLFetchNameValue(layer->processing, "RASTER_QUERY_MAX_RESULT")); } } @@ -208,57 +210,55 @@ static void msRasterLayerInfoInitialize( layerObj *layer ) /* msRasterQueryAddPixel() */ /************************************************************************/ -static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, - pointObj *reprojectedLocation, - float *values ) +static void msRasterQueryAddPixel(layerObj *layer, pointObj *location, + pointObj *reprojectedLocation, float *values) { - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; int red = 0, green = 0, blue = 0, nodata = FALSE; int p_class = -1; - if( rlinfo->query_results == rlinfo->query_result_hard_max ) + if (rlinfo->query_results == rlinfo->query_result_hard_max) return; /* -------------------------------------------------------------------- */ /* Is this our first time in? If so, do an initial allocation */ /* for the data arrays suitable to our purposes. */ /* -------------------------------------------------------------------- */ - if( rlinfo->query_alloc_max == 0 ) { + if (rlinfo->query_alloc_max == 0) { rlinfo->query_alloc_max = 2; - switch( rlinfo->raster_query_mode ) { - case RQM_ENTRY_PER_PIXEL: - rlinfo->qc_x = (double *) - msSmallCalloc(sizeof(double),rlinfo->query_alloc_max); - rlinfo->qc_y = (double *) - msSmallCalloc(sizeof(double),rlinfo->query_alloc_max); - rlinfo->qc_x_reproj = (double *) - msSmallCalloc(sizeof(double),rlinfo->query_alloc_max); - rlinfo->qc_y_reproj = (double *) - msSmallCalloc(sizeof(double),rlinfo->query_alloc_max); - rlinfo->qc_values = (float *) - msSmallCalloc(sizeof(float), - rlinfo->query_alloc_max*rlinfo->band_count); - rlinfo->qc_red = (int *) - msSmallCalloc(sizeof(int),rlinfo->query_alloc_max); - rlinfo->qc_green = (int *) - msSmallCalloc(sizeof(int),rlinfo->query_alloc_max); - rlinfo->qc_blue = (int *) - msSmallCalloc(sizeof(int),rlinfo->query_alloc_max); - if( layer->numclasses > 0 ) - rlinfo->qc_class = (int *) - msSmallCalloc(sizeof(int),rlinfo->query_alloc_max); - break; - - case RQM_HIST_ON_CLASS: - break; - - case RQM_HIST_ON_VALUE: - break; - - default: - assert( FALSE ); + switch (rlinfo->raster_query_mode) { + case RQM_ENTRY_PER_PIXEL: + rlinfo->qc_x = + (double *)msSmallCalloc(sizeof(double), rlinfo->query_alloc_max); + rlinfo->qc_y = + (double *)msSmallCalloc(sizeof(double), rlinfo->query_alloc_max); + rlinfo->qc_x_reproj = + (double *)msSmallCalloc(sizeof(double), rlinfo->query_alloc_max); + rlinfo->qc_y_reproj = + (double *)msSmallCalloc(sizeof(double), rlinfo->query_alloc_max); + rlinfo->qc_values = (float *)msSmallCalloc( + sizeof(float), rlinfo->query_alloc_max * rlinfo->band_count); + rlinfo->qc_red = + (int *)msSmallCalloc(sizeof(int), rlinfo->query_alloc_max); + rlinfo->qc_green = + (int *)msSmallCalloc(sizeof(int), rlinfo->query_alloc_max); + rlinfo->qc_blue = + (int *)msSmallCalloc(sizeof(int), rlinfo->query_alloc_max); + if (layer->numclasses > 0) + rlinfo->qc_class = + (int *)msSmallCalloc(sizeof(int), rlinfo->query_alloc_max); + break; + + case RQM_HIST_ON_CLASS: + break; + + case RQM_HIST_ON_VALUE: + break; + + default: + assert(FALSE); } } @@ -266,59 +266,58 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* Reallocate the data arrays larger if they are near the max */ /* now. */ /* -------------------------------------------------------------------- */ - if( rlinfo->query_results == rlinfo->query_alloc_max ) { + if (rlinfo->query_results == rlinfo->query_alloc_max) { rlinfo->query_alloc_max = rlinfo->query_alloc_max * 2 + 100; - if( rlinfo->qc_x != NULL ) + if (rlinfo->qc_x != NULL) rlinfo->qc_x = msSmallRealloc(rlinfo->qc_x, sizeof(double) * rlinfo->query_alloc_max); - if( rlinfo->qc_y != NULL ) + if (rlinfo->qc_y != NULL) rlinfo->qc_y = msSmallRealloc(rlinfo->qc_y, sizeof(double) * rlinfo->query_alloc_max); - if( rlinfo->qc_x_reproj != NULL ) - rlinfo->qc_x_reproj = msSmallRealloc(rlinfo->qc_x_reproj, - sizeof(double) * rlinfo->query_alloc_max); - if( rlinfo->qc_y_reproj != NULL ) - rlinfo->qc_y_reproj = msSmallRealloc(rlinfo->qc_y_reproj, - sizeof(double) * rlinfo->query_alloc_max); - if( rlinfo->qc_values != NULL ) - rlinfo->qc_values = - msSmallRealloc(rlinfo->qc_values, - sizeof(float) * rlinfo->query_alloc_max - * rlinfo->band_count ); - if( rlinfo->qc_class != NULL ) + if (rlinfo->qc_x_reproj != NULL) + rlinfo->qc_x_reproj = msSmallRealloc( + rlinfo->qc_x_reproj, sizeof(double) * rlinfo->query_alloc_max); + if (rlinfo->qc_y_reproj != NULL) + rlinfo->qc_y_reproj = msSmallRealloc( + rlinfo->qc_y_reproj, sizeof(double) * rlinfo->query_alloc_max); + if (rlinfo->qc_values != NULL) + rlinfo->qc_values = msSmallRealloc( + rlinfo->qc_values, + sizeof(float) * rlinfo->query_alloc_max * rlinfo->band_count); + if (rlinfo->qc_class != NULL) rlinfo->qc_class = msSmallRealloc(rlinfo->qc_class, sizeof(int) * rlinfo->query_alloc_max); - if( rlinfo->qc_red != NULL ) - rlinfo->qc_red = msSmallRealloc(rlinfo->qc_red, - sizeof(int) * rlinfo->query_alloc_max); - if( rlinfo->qc_green != NULL ) + if (rlinfo->qc_red != NULL) + rlinfo->qc_red = + msSmallRealloc(rlinfo->qc_red, sizeof(int) * rlinfo->query_alloc_max); + if (rlinfo->qc_green != NULL) rlinfo->qc_green = msSmallRealloc(rlinfo->qc_green, sizeof(int) * rlinfo->query_alloc_max); - if( rlinfo->qc_blue != NULL ) + if (rlinfo->qc_blue != NULL) rlinfo->qc_blue = msSmallRealloc(rlinfo->qc_blue, sizeof(int) * rlinfo->query_alloc_max); - if( rlinfo->qc_count != NULL ) + if (rlinfo->qc_count != NULL) rlinfo->qc_count = msSmallRealloc(rlinfo->qc_count, sizeof(int) * rlinfo->query_alloc_max); - if( rlinfo->qc_tileindex != NULL ) - rlinfo->qc_tileindex = msSmallRealloc(rlinfo->qc_tileindex, - sizeof(int) * rlinfo->query_alloc_max); + if (rlinfo->qc_tileindex != NULL) + rlinfo->qc_tileindex = msSmallRealloc( + rlinfo->qc_tileindex, sizeof(int) * rlinfo->query_alloc_max); } /* -------------------------------------------------------------------- */ /* Handle colormap */ /* -------------------------------------------------------------------- */ - if( rlinfo->hCT != NULL ) { - int pct_index = (int) floor(values[0]); + if (rlinfo->hCT != NULL) { + int pct_index = (int)floor(values[0]); GDALColorEntry sEntry; - if( GDALGetColorEntryAsRGB( rlinfo->hCT, pct_index, &sEntry ) ) { + if (GDALGetColorEntryAsRGB(rlinfo->hCT, pct_index, &sEntry)) { red = sEntry.c1; green = sEntry.c2; blue = sEntry.c3; - if( sEntry.c4 == 0 ) + if (sEntry.c4 == 0) nodata = TRUE; } else nodata = TRUE; @@ -328,12 +327,12 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* Color derived from greyscale value. */ /* -------------------------------------------------------------------- */ else { - if( rlinfo->band_count >= 3 ) { - red = (int) MS_MAX(0,MS_MIN(255,values[0])); - green = (int) MS_MAX(0,MS_MIN(255,values[1])); - blue = (int) MS_MAX(0,MS_MIN(255,values[2])); + if (rlinfo->band_count >= 3) { + red = (int)MS_MAX(0, MS_MIN(255, values[0])); + green = (int)MS_MAX(0, MS_MIN(255, values[1])); + blue = (int)MS_MAX(0, MS_MIN(255, values[2])); } else { - red = green = blue = (int) MS_MAX(0,MS_MIN(255,values[0])); + red = green = blue = (int)MS_MAX(0, MS_MIN(255, values[0])); } } @@ -345,19 +344,18 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* described in: */ /* http://mapserver.gis.umn.edu/bugs/show_bug.cgi?id=1021 */ /* -------------------------------------------------------------------- */ - if( rlinfo->qc_class != NULL ) { - p_class = msGetClass_FloatRGB(layer, values[0], - red, green, blue ); + if (rlinfo->qc_class != NULL) { + p_class = msGetClass_FloatRGB(layer, values[0], red, green, blue); - if( p_class == -1 ) + if (p_class == -1) nodata = TRUE; else { nodata = FALSE; rlinfo->qc_class[rlinfo->query_results] = p_class; - if( layer->class[p_class]->numstyles > 0 ) { - red = layer->class[p_class]->styles[0]->color.red; + if (layer->class[p_class] -> numstyles > 0) { + red = layer->class[p_class]->styles[0]->color.red; green = layer->class[p_class]->styles[0]->color.green; - blue = layer->class[p_class]->styles[0]->color.blue; + blue = layer->class[p_class]->styles[0]->color.blue; } else { red = green = blue = 0; } @@ -374,7 +372,7 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* -------------------------------------------------------------------- */ /* Record spatial location. */ /* -------------------------------------------------------------------- */ - if( rlinfo->qc_x != NULL ) { + if (rlinfo->qc_x != NULL) { rlinfo->qc_x[rlinfo->query_results] = location->x; rlinfo->qc_y[rlinfo->query_results] = location->y; rlinfo->qc_x_reproj[rlinfo->query_results] = reprojectedLocation->x; @@ -384,15 +382,15 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* -------------------------------------------------------------------- */ /* Record actual pixel value(s). */ /* -------------------------------------------------------------------- */ - if( rlinfo->qc_values != NULL ) - memcpy( rlinfo->qc_values + rlinfo->query_results * rlinfo->band_count, - values, sizeof(float) * rlinfo->band_count ); + if (rlinfo->qc_values != NULL) + memcpy(rlinfo->qc_values + rlinfo->query_results * rlinfo->band_count, + values, sizeof(float) * rlinfo->band_count); /* -------------------------------------------------------------------- */ /* Add to the results cache. */ /* -------------------------------------------------------------------- */ - if( ! nodata ) { - addResult( layer->resultcache, p_class, rlinfo->query_results, 0 ); + if (!nodata) { + addResult(layer->resultcache, p_class, rlinfo->query_results, 0); rlinfo->query_results++; } } @@ -401,33 +399,33 @@ static void msRasterQueryAddPixel( layerObj *layer, pointObj *location, /* msRasterQueryByRectLow() */ /************************************************************************/ -static int -msRasterQueryByRectLow(mapObj *map, layerObj *layer, GDALDatasetH hDS, - rectObj queryRect) +static int msRasterQueryByRectLow(mapObj *map, layerObj *layer, + GDALDatasetH hDS, rectObj queryRect) { - double adfGeoTransform[6], adfInvGeoTransform[6]; - double dfXMin, dfYMin, dfXMax, dfYMax, dfX, dfY, dfAdjustedRange; - int nWinXOff, nWinYOff, nWinXSize, nWinYSize; - int nRXSize, nRYSize; - float *pafRaster; - int nBandCount, *panBandMap, iPixel, iLine; - CPLErr eErr; + double adfGeoTransform[6], adfInvGeoTransform[6]; + double dfXMin, dfYMin, dfXMax, dfYMax, dfX, dfY, dfAdjustedRange; + int nWinXOff, nWinYOff, nWinXSize, nWinYSize; + int nRXSize, nRYSize; + float *pafRaster; + int nBandCount, *panBandMap, iPixel, iLine; + CPLErr eErr; rasterLayerInfo *rlinfo; - rectObj searchrect; + rectObj searchrect; #if PROJ_VERSION_MAJOR < 6 - int mayNeedLonWrapAdjustment = MS_FALSE; + int mayNeedLonWrapAdjustment = MS_FALSE; #endif - rlinfo = (rasterLayerInfo *) layer->layerinfo; + rlinfo = (rasterLayerInfo *)layer->layerinfo; /* -------------------------------------------------------------------- */ /* Reproject the search rect into the projection of this */ /* layer/file if needed. */ /* -------------------------------------------------------------------- */ searchrect = queryRect; - layer->project = msProjectionsDiffer(&(layer->projection), &(map->projection)); - if(layer->project) + layer->project = + msProjectionsDiffer(&(layer->projection), &(map->projection)); + if (layer->project) msProjectRect(&(map->projection), &(layer->projection), &searchrect); /* -------------------------------------------------------------------- */ @@ -435,72 +433,70 @@ msRasterQueryByRectLow(mapObj *map, layerObj *layer, GDALDatasetH hDS, /* pixel/line extents on the file. Process all 4 corners, to */ /* build extents. */ /* -------------------------------------------------------------------- */ - nRXSize = GDALGetRasterXSize( hDS ); - nRYSize = GDALGetRasterYSize( hDS ); + nRXSize = GDALGetRasterXSize(hDS); + nRYSize = GDALGetRasterYSize(hDS); - msGetGDALGeoTransform( hDS, map, layer, adfGeoTransform ); - InvGeoTransform( adfGeoTransform, adfInvGeoTransform ); + msGetGDALGeoTransform(hDS, map, layer, adfGeoTransform); + InvGeoTransform(adfGeoTransform, adfInvGeoTransform); /* top left */ - dfXMin = dfXMax = GEO_TRANS(adfInvGeoTransform, - searchrect.minx, searchrect.maxy); - dfYMin = dfYMax = GEO_TRANS(adfInvGeoTransform+3, - searchrect.minx, searchrect.maxy); + dfXMin = dfXMax = + GEO_TRANS(adfInvGeoTransform, searchrect.minx, searchrect.maxy); + dfYMin = dfYMax = + GEO_TRANS(adfInvGeoTransform + 3, searchrect.minx, searchrect.maxy); /* top right */ - dfX = GEO_TRANS(adfInvGeoTransform , searchrect.maxx, searchrect.maxy); - dfY = GEO_TRANS(adfInvGeoTransform+3, searchrect.maxx, searchrect.maxy); - dfXMin = MS_MIN(dfXMin,dfX); - dfXMax = MS_MAX(dfXMax,dfX); - dfYMin = MS_MIN(dfYMin,dfY); - dfYMax = MS_MAX(dfYMax,dfY); + dfX = GEO_TRANS(adfInvGeoTransform, searchrect.maxx, searchrect.maxy); + dfY = GEO_TRANS(adfInvGeoTransform + 3, searchrect.maxx, searchrect.maxy); + dfXMin = MS_MIN(dfXMin, dfX); + dfXMax = MS_MAX(dfXMax, dfX); + dfYMin = MS_MIN(dfYMin, dfY); + dfYMax = MS_MAX(dfYMax, dfY); /* bottom left */ - dfX = GEO_TRANS(adfInvGeoTransform , searchrect.minx, searchrect.miny); - dfY = GEO_TRANS(adfInvGeoTransform+3, searchrect.minx, searchrect.miny); - dfXMin = MS_MIN(dfXMin,dfX); - dfXMax = MS_MAX(dfXMax,dfX); - dfYMin = MS_MIN(dfYMin,dfY); - dfYMax = MS_MAX(dfYMax,dfY); + dfX = GEO_TRANS(adfInvGeoTransform, searchrect.minx, searchrect.miny); + dfY = GEO_TRANS(adfInvGeoTransform + 3, searchrect.minx, searchrect.miny); + dfXMin = MS_MIN(dfXMin, dfX); + dfXMax = MS_MAX(dfXMax, dfX); + dfYMin = MS_MIN(dfYMin, dfY); + dfYMax = MS_MAX(dfYMax, dfY); /* bottom right */ - dfX = GEO_TRANS(adfInvGeoTransform , searchrect.maxx, searchrect.miny); - dfY = GEO_TRANS(adfInvGeoTransform+3, searchrect.maxx, searchrect.miny); - dfXMin = MS_MIN(dfXMin,dfX); - dfXMax = MS_MAX(dfXMax,dfX); - dfYMin = MS_MIN(dfYMin,dfY); - dfYMax = MS_MAX(dfYMax,dfY); + dfX = GEO_TRANS(adfInvGeoTransform, searchrect.maxx, searchrect.miny); + dfY = GEO_TRANS(adfInvGeoTransform + 3, searchrect.maxx, searchrect.miny); + dfXMin = MS_MIN(dfXMin, dfX); + dfXMax = MS_MAX(dfXMax, dfX); + dfYMin = MS_MIN(dfYMin, dfY); + dfYMax = MS_MAX(dfYMax, dfY); /* -------------------------------------------------------------------- */ /* Trim the rectangle to the area of the file itself, but out */ /* to the edges of the touched edge pixels. */ /* -------------------------------------------------------------------- */ - dfXMin = MS_MAX(0.0,MS_MIN(nRXSize,floor(dfXMin))); - dfYMin = MS_MAX(0.0,MS_MIN(nRYSize,floor(dfYMin))); - dfXMax = MS_MAX(0.0,MS_MIN(nRXSize,ceil(dfXMax))); - dfYMax = MS_MAX(0.0,MS_MIN(nRYSize,ceil(dfYMax))); + dfXMin = MS_MAX(0.0, MS_MIN(nRXSize, floor(dfXMin))); + dfYMin = MS_MAX(0.0, MS_MIN(nRYSize, floor(dfYMin))); + dfXMax = MS_MAX(0.0, MS_MIN(nRXSize, ceil(dfXMax))); + dfYMax = MS_MAX(0.0, MS_MIN(nRYSize, ceil(dfYMax))); /* -------------------------------------------------------------------- */ /* Convert to integer offset/size values. */ /* -------------------------------------------------------------------- */ - nWinXOff = (int) dfXMin; - nWinYOff = (int) dfYMin; - nWinXSize = (int) (dfXMax - dfXMin); - nWinYSize = (int) (dfYMax - dfYMin); + nWinXOff = (int)dfXMin; + nWinYOff = (int)dfYMin; + nWinXSize = (int)(dfXMax - dfXMin); + nWinYSize = (int)(dfYMax - dfYMin); /* -------------------------------------------------------------------- */ /* What bands are we operating on? */ /* -------------------------------------------------------------------- */ - panBandMap = msGetGDALBandList( layer, hDS, 0, &nBandCount ); + panBandMap = msGetGDALBandList(layer, hDS, 0, &nBandCount); - if( rlinfo->band_count == -1 ) + if (rlinfo->band_count == -1) rlinfo->band_count = nBandCount; - if( nBandCount != rlinfo->band_count ) { - msSetError( MS_IMGERR, - "Got %d bands, but expected %d bands.", - "msRasterQueryByRectLow()", - nBandCount, rlinfo->band_count ); + if (nBandCount != rlinfo->band_count) { + msSetError(MS_IMGERR, "Got %d bands, but expected %d bands.", + "msRasterQueryByRectLow()", nBandCount, rlinfo->band_count); return -1; } @@ -510,33 +506,30 @@ msRasterQueryByRectLow(mapObj *map, layerObj *layer, GDALDatasetH hDS, /* band in the file. Later we will deal with the various band */ /* selection criteria. */ /* -------------------------------------------------------------------- */ - pafRaster = (float *) - calloc(sizeof(float),nWinXSize*nWinYSize*nBandCount); - MS_CHECK_ALLOC(pafRaster, sizeof(float)*nWinXSize*nWinYSize*nBandCount, -1); + pafRaster = + (float *)calloc(sizeof(float), nWinXSize * nWinYSize * nBandCount); + MS_CHECK_ALLOC(pafRaster, sizeof(float) * nWinXSize * nWinYSize * nBandCount, + -1); - eErr = GDALDatasetRasterIO( hDS, GF_Read, - nWinXOff, nWinYOff, nWinXSize, nWinYSize, - pafRaster, nWinXSize, nWinYSize, GDT_Float32, - nBandCount, panBandMap, - 4 * nBandCount, - 4 * nBandCount * nWinXSize, - 4 ); + eErr = GDALDatasetRasterIO(hDS, GF_Read, nWinXOff, nWinYOff, nWinXSize, + nWinYSize, pafRaster, nWinXSize, nWinYSize, + GDT_Float32, nBandCount, panBandMap, + 4 * nBandCount, 4 * nBandCount * nWinXSize, 4); - if( eErr != CE_None ) { - msSetError( MS_IOERR, "GDALDatasetRasterIO() failed: %s", - "msRasterQueryByRectLow()", CPLGetLastErrorMsg() ); + if (eErr != CE_None) { + msSetError(MS_IOERR, "GDALDatasetRasterIO() failed: %s", + "msRasterQueryByRectLow()", CPLGetLastErrorMsg()); - free( pafRaster ); + free(pafRaster); return -1; } /* -------------------------------------------------------------------- */ /* Fetch color table for intepreting colors if needed. */ /* -------------------------------------------------------------------- */ - rlinfo->hCT = GDALGetRasterColorTable( - GDALGetRasterBand( hDS, panBandMap[0] ) ); + rlinfo->hCT = GDALGetRasterColorTable(GDALGetRasterBand(hDS, panBandMap[0])); - free( panBandMap ); + free(panBandMap); /* -------------------------------------------------------------------- */ /* When computing whether pixels are within range we do it */ @@ -546,47 +539,44 @@ msRasterQueryByRectLow(mapObj *map, layerObj *layer, GDALDatasetH hDS, /* add a fudge factor so that a range of zero will find the */ /* pixel the target falls in at least. */ /* -------------------------------------------------------------------- */ - dfAdjustedRange = - sqrt(adfGeoTransform[1] * adfGeoTransform[1] - + adfGeoTransform[2] * adfGeoTransform[2] - + adfGeoTransform[4] * adfGeoTransform[4] - + adfGeoTransform[5] * adfGeoTransform[5]) * 0.5 * 1.41421356237 - + sqrt( rlinfo->range_dist ); + dfAdjustedRange = sqrt(adfGeoTransform[1] * adfGeoTransform[1] + + adfGeoTransform[2] * adfGeoTransform[2] + + adfGeoTransform[4] * adfGeoTransform[4] + + adfGeoTransform[5] * adfGeoTransform[5]) * + 0.5 * 1.41421356237 + + sqrt(rlinfo->range_dist); dfAdjustedRange = dfAdjustedRange * dfAdjustedRange; #if PROJ_VERSION_MAJOR < 6 - if( layer->project && - msProjIsGeographicCRS(&(layer->projection)) && - msProjIsGeographicCRS(&(map->projection)) ) - { - double dfLonWrap = 0; - mayNeedLonWrapAdjustment = msProjectHasLonWrap(&(layer->projection), &dfLonWrap); - } + if (layer->project && msProjIsGeographicCRS(&(layer->projection)) && + msProjIsGeographicCRS(&(map->projection))) { + double dfLonWrap = 0; + mayNeedLonWrapAdjustment = + msProjectHasLonWrap(&(layer->projection), &dfLonWrap); + } #endif - reprojectionObj* reprojector = NULL; - if( layer->project ) - { - reprojector = msProjectCreateReprojector(&(layer->projection), &(map->projection)); + reprojectionObj *reprojector = NULL; + if (layer->project) { + reprojector = + msProjectCreateReprojector(&(layer->projection), &(map->projection)); } /* -------------------------------------------------------------------- */ /* Loop over all pixels determining which are "in". */ /* -------------------------------------------------------------------- */ - for( iLine = 0; iLine < nWinYSize; iLine++ ) { - for( iPixel = 0; iPixel < nWinXSize; iPixel++ ) { - pointObj sPixelLocation = {0}; + for (iLine = 0; iLine < nWinYSize; iLine++) { + for (iPixel = 0; iPixel < nWinXSize; iPixel++) { + pointObj sPixelLocation = {0}; - if( rlinfo->query_results == rlinfo->query_result_hard_max ) + if (rlinfo->query_results == rlinfo->query_result_hard_max) break; /* transform pixel/line to georeferenced */ - sPixelLocation.x = - GEO_TRANS(adfGeoTransform, - iPixel + nWinXOff + 0.5, iLine + nWinYOff + 0.5 ); - sPixelLocation.y = - GEO_TRANS(adfGeoTransform+3, - iPixel + nWinXOff + 0.5, iLine + nWinYOff + 0.5 ); + sPixelLocation.x = GEO_TRANS(adfGeoTransform, iPixel + nWinXOff + 0.5, + iLine + nWinYOff + 0.5); + sPixelLocation.y = GEO_TRANS(adfGeoTransform + 3, iPixel + nWinXOff + 0.5, + iLine + nWinYOff + 0.5); /* If projections differ, convert this back into the map */ /* projection for distance testing, and comprison to the */ @@ -594,80 +584,79 @@ msRasterQueryByRectLow(mapObj *map, layerObj *layer, GDALDatasetH hDS, /* in sPixelLocationInLayerSRS, so that we can return those */ /* coordinates if we have a hit */ pointObj sReprojectedPixelLocation = sPixelLocation; - if( reprojector ) - { + if (reprojector) { #if PROJ_VERSION_MAJOR < 6 /* Works around a bug in PROJ < 6 when reprojecting from a lon_wrap */ /* geogCRS to a geogCRS, and the input abs(longitude) is > 180. Then */ - /* lon_wrap was ignored and the output longitude remained as the source */ - if( mayNeedLonWrapAdjustment ) - { - if( rlinfo->target_point.x < sReprojectedPixelLocation.x - 180 ) - sReprojectedPixelLocation.x -= 360; - else if( rlinfo->target_point.x > sReprojectedPixelLocation.x + 180 ) - sReprojectedPixelLocation.x += 360; + /* lon_wrap was ignored and the output longitude remained as the source + */ + if (mayNeedLonWrapAdjustment) { + if (rlinfo->target_point.x < sReprojectedPixelLocation.x - 180) + sReprojectedPixelLocation.x -= 360; + else if (rlinfo->target_point.x > sReprojectedPixelLocation.x + 180) + sReprojectedPixelLocation.x += 360; } #endif - msProjectPointEx( reprojector, &sReprojectedPixelLocation); + msProjectPointEx(reprojector, &sReprojectedPixelLocation); } /* If we are doing QueryByShape, check against the shape now */ - if( rlinfo->searchshape != NULL ) { - if( rlinfo->shape_tolerance == 0.0 - && rlinfo->searchshape->type == MS_SHAPE_POLYGON ) { - if( msIntersectPointPolygon( - &sReprojectedPixelLocation, rlinfo->searchshape ) == MS_FALSE ) + if (rlinfo->searchshape != NULL) { + if (rlinfo->shape_tolerance == 0.0 && + rlinfo->searchshape->type == MS_SHAPE_POLYGON) { + if (msIntersectPointPolygon(&sReprojectedPixelLocation, + rlinfo->searchshape) == MS_FALSE) continue; } else { - shapeObj tempShape; - lineObj tempLine; + shapeObj tempShape; + lineObj tempLine; - memset( &tempShape, 0, sizeof(shapeObj) ); + memset(&tempShape, 0, sizeof(shapeObj)); tempShape.type = MS_SHAPE_POINT; tempShape.numlines = 1; tempShape.line = &tempLine; tempLine.numpoints = 1; tempLine.point = &sReprojectedPixelLocation; - if( msDistanceShapeToShape(rlinfo->searchshape, &tempShape) - > rlinfo->shape_tolerance ) + if (msDistanceShapeToShape(rlinfo->searchshape, &tempShape) > + rlinfo->shape_tolerance) continue; } } - if( rlinfo->range_mode >= 0 ) { + if (rlinfo->range_mode >= 0) { double dist; - dist = (rlinfo->target_point.x - sReprojectedPixelLocation.x) - * (rlinfo->target_point.x - sReprojectedPixelLocation.x) - + (rlinfo->target_point.y - sReprojectedPixelLocation.y) - * (rlinfo->target_point.y - sReprojectedPixelLocation.y); + dist = (rlinfo->target_point.x - sReprojectedPixelLocation.x) * + (rlinfo->target_point.x - sReprojectedPixelLocation.x) + + (rlinfo->target_point.y - sReprojectedPixelLocation.y) * + (rlinfo->target_point.y - sReprojectedPixelLocation.y); - if( dist >= dfAdjustedRange ) + if (dist >= dfAdjustedRange) continue; /* If we can only have one feature, trim range and clear */ /* previous result. */ - if( rlinfo->range_mode == MS_QUERY_SINGLE ) { + if (rlinfo->range_mode == MS_QUERY_SINGLE) { rlinfo->range_dist = dist; rlinfo->query_results = 0; } } - msRasterQueryAddPixel( layer, - &sPixelLocation, // return coords in layer SRS - &sReprojectedPixelLocation, - pafRaster - + (iLine*nWinXSize + iPixel) * nBandCount ); + msRasterQueryAddPixel(layer, + &sPixelLocation, // return coords in layer SRS + &sReprojectedPixelLocation, + pafRaster + + (iLine * nWinXSize + iPixel) * nBandCount); } } /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ - free( pafRaster ); - msProjectDestroyReprojector( reprojector ); + free(pafRaster); + msProjectDestroyReprojector(reprojector); return MS_SUCCESS; } @@ -680,13 +669,13 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) { int status = MS_SUCCESS; - char *filename=NULL; + char *filename = NULL; - layerObj *tlp=NULL; /* pointer to the tile layer either real or temporary */ - int tileitemindex=-1, tilelayerindex=-1, tilesrsindex=-1; + layerObj *tlp = NULL; /* pointer to the tile layer either real or temporary */ + int tileitemindex = -1, tilelayerindex = -1, tilesrsindex = -1; shapeObj tshp; char tilename[MS_PATH_LENGTH], tilesrsname[1024]; - int done, destroy_on_failure; + int done, destroy_on_failure; char szPath[MS_MAXPATHLEN]; rectObj searchrect; @@ -695,19 +684,20 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) /* -------------------------------------------------------------------- */ /* Get the layer info. */ /* -------------------------------------------------------------------- */ - if(!layer->layerinfo) { - msRasterLayerInfoInitialize( layer ); + if (!layer->layerinfo) { + msRasterLayerInfoInitialize(layer); destroy_on_failure = 1; } else { destroy_on_failure = 0; } - rlinfo = (rasterLayerInfo *) layer->layerinfo; + rlinfo = (rasterLayerInfo *)layer->layerinfo; /* -------------------------------------------------------------------- */ /* Clear old results cache. */ /* -------------------------------------------------------------------- */ - if(layer->resultcache) { - if(layer->resultcache->results) free(layer->resultcache->results); + if (layer->resultcache) { + if (layer->resultcache->results) + free(layer->resultcache->results); free(layer->resultcache); layer->resultcache = NULL; } @@ -718,50 +708,49 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) layer->resultcache = (resultCacheObj *)msSmallMalloc(sizeof(resultCacheObj)); layer->resultcache->results = NULL; layer->resultcache->numresults = layer->resultcache->cachesize = 0; - layer->resultcache->bounds.minx = - layer->resultcache->bounds.miny = - layer->resultcache->bounds.maxx = - layer->resultcache->bounds.maxy = -1; + layer->resultcache->bounds.minx = layer->resultcache->bounds.miny = + layer->resultcache->bounds.maxx = layer->resultcache->bounds.maxy = -1; /* -------------------------------------------------------------------- */ /* Check if we should really be acting on this layer and */ /* provide debug info in various cases. */ /* -------------------------------------------------------------------- */ - if(layer->debug > 0 || map->debug > 1) - msDebug( "msRasterQueryByRect(%s): entering.\n", layer->name ); + if (layer->debug > 0 || map->debug > 1) + msDebug("msRasterQueryByRect(%s): entering.\n", layer->name); - if(!layer->data && !layer->tileindex) { - if(layer->debug > 0 || map->debug > 0 ) - msDebug( "msRasterQueryByRect(%s): layer data and tileindex NULL ... doing nothing.", layer->name ); + if (!layer->data && !layer->tileindex) { + if (layer->debug > 0 || map->debug > 0) + msDebug("msRasterQueryByRect(%s): layer data and tileindex NULL ... " + "doing nothing.", + layer->name); return MS_SUCCESS; } - if((layer->status != MS_ON) && layer->status != MS_DEFAULT ) { - if(layer->debug > 0 ) - msDebug( "msRasterQueryByRect(%s): not status ON or DEFAULT, doing nothing.", layer->name ); + if ((layer->status != MS_ON) && layer->status != MS_DEFAULT) { + if (layer->debug > 0) + msDebug( + "msRasterQueryByRect(%s): not status ON or DEFAULT, doing nothing.", + layer->name); return MS_SUCCESS; } /* ==================================================================== */ /* Handle setting up tileindex layer. */ /* ==================================================================== */ - if(layer->tileindex) { /* we have an index file */ + if (layer->tileindex) { /* we have an index file */ msInitShape(&tshp); searchrect = queryRect; - status = msDrawRasterSetupTileLayer(map, layer, - &searchrect, - MS_TRUE, - &tilelayerindex, - &tileitemindex, - &tilesrsindex, - &tlp); + status = msDrawRasterSetupTileLayer(map, layer, &searchrect, MS_TRUE, + &tilelayerindex, &tileitemindex, + &tilesrsindex, &tlp); if (status != MS_SUCCESS) { goto cleanup; } } else { - /* we have to manually apply to scaletoken logic as we're not going through msLayerOpen() */ - status = msLayerApplyScaletokens(layer,map->scaledenom); + /* we have to manually apply to scaletoken logic as we're not going through + * msLayerOpen() */ + status = msLayerApplyScaletokens(layer, map->scaledenom); if (status != MS_SUCCESS) { goto cleanup; } @@ -771,31 +760,32 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) /* Iterate over all tiles (just one in untiled case). */ /* -------------------------------------------------------------------- */ done = MS_FALSE; - while( done == MS_FALSE && status == MS_SUCCESS ) { + while (done == MS_FALSE && status == MS_SUCCESS) { - GDALDatasetH hDS; + GDALDatasetH hDS; char *decrypted_path = NULL; /* -------------------------------------------------------------------- */ /* Get filename. */ /* -------------------------------------------------------------------- */ - if(layer->tileindex) { - status = msDrawRasterIterateTileIndex(layer, tlp, &tshp, - tileitemindex, tilesrsindex, - tilename, sizeof(tilename), - tilesrsname, sizeof(tilesrsname)); - if( status == MS_FAILURE) { + if (layer->tileindex) { + status = msDrawRasterIterateTileIndex( + layer, tlp, &tshp, tileitemindex, tilesrsindex, tilename, + sizeof(tilename), tilesrsname, sizeof(tilesrsname)); + if (status == MS_FAILURE) { break; } - if(status == MS_DONE) break; /* no more tiles/images */ + if (status == MS_DONE) + break; /* no more tiles/images */ filename = tilename; } else { filename = layer->data; done = MS_TRUE; /* only one image so we're done after this */ } - if(strlen(filename) == 0) continue; + if (strlen(filename) == 0) + continue; /* -------------------------------------------------------------------- */ /* Open the file. */ @@ -804,72 +794,69 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) msDrawRasterBuildRasterPath(map, layer, filename, szPath); - decrypted_path = msDecryptStringTokens( map, szPath ); - if( !decrypted_path ) { + decrypted_path = msDecryptStringTokens(map, szPath); + if (!decrypted_path) { status = MS_FAILURE; goto cleanup; } - msAcquireLock( TLOCK_GDAL ); - if( !layer->tileindex ) - { - char** connectionoptions = msGetStringListFromHashTable(&(layer->connectionoptions)); - hDS = GDALOpenEx(decrypted_path, - GDAL_OF_RASTER, - NULL, - (const char* const*)connectionoptions, - NULL); - CSLDestroy(connectionoptions); - } - else - { - hDS = GDALOpen(decrypted_path, GA_ReadOnly ); + msAcquireLock(TLOCK_GDAL); + if (!layer->tileindex) { + char **connectionoptions = + msGetStringListFromHashTable(&(layer->connectionoptions)); + hDS = GDALOpenEx(decrypted_path, GDAL_OF_RASTER, NULL, + (const char *const *)connectionoptions, NULL); + CSLDestroy(connectionoptions); + } else { + hDS = GDALOpen(decrypted_path, GA_ReadOnly); } - if( hDS == NULL ) { - int ignore_missing = msMapIgnoreMissingData( map ); - const char *cpl_error_msg = msDrawRasterGetCPLErrorMsg(decrypted_path, szPath); + if (hDS == NULL) { + int ignore_missing = msMapIgnoreMissingData(map); + const char *cpl_error_msg = + msDrawRasterGetCPLErrorMsg(decrypted_path, szPath); - msFree( decrypted_path ); + msFree(decrypted_path); decrypted_path = NULL; - msReleaseLock( TLOCK_GDAL ); + msReleaseLock(TLOCK_GDAL); - if ( ignore_missing == MS_MISSING_DATA_FAIL ) { - if( layer->debug || map->debug ) - msSetError( MS_IMGERR, - "Unable to open file %s for layer %s ... fatal error.\n%s", - "msRasterQueryByRect()", - szPath, layer->name, cpl_error_msg); + if (ignore_missing == MS_MISSING_DATA_FAIL) { + if (layer->debug || map->debug) + msSetError(MS_IMGERR, + "Unable to open file %s for layer %s ... fatal error.\n%s", + "msRasterQueryByRect()", szPath, layer->name, + cpl_error_msg); status = MS_FAILURE; goto cleanup; } - if( ignore_missing == MS_MISSING_DATA_LOG ) { - if( layer->debug || map->debug ) - msDebug( "Unable to open file %s for layer %s ... ignoring this missing data.\n%s", - filename, layer->name, cpl_error_msg ); + if (ignore_missing == MS_MISSING_DATA_LOG) { + if (layer->debug || map->debug) + msDebug("Unable to open file %s for layer %s ... ignoring this " + "missing data.\n%s", + filename, layer->name, cpl_error_msg); } continue; } - msFree( decrypted_path ); + msFree(decrypted_path); decrypted_path = NULL; - if( msDrawRasterLoadProjection(layer, hDS, filename, tilesrsindex, tilesrsname) != MS_SUCCESS ) - { - msReleaseLock( TLOCK_GDAL ); - status = MS_FAILURE; - goto cleanup; + if (msDrawRasterLoadProjection(layer, hDS, filename, tilesrsindex, + tilesrsname) != MS_SUCCESS) { + msReleaseLock(TLOCK_GDAL); + status = MS_FAILURE; + goto cleanup; } /* -------------------------------------------------------------------- */ /* Perform actual query on this file. */ /* -------------------------------------------------------------------- */ - if( status == MS_SUCCESS ) - status = msRasterQueryByRectLow( map, layer, hDS, queryRect ); + if (status == MS_SUCCESS) + status = msRasterQueryByRectLow(map, layer, hDS, queryRect); - GDALClose( hDS ); - msReleaseLock( TLOCK_GDAL ); + GDALClose(hDS); + msReleaseLock(TLOCK_GDAL); } /* next tile */ @@ -877,7 +864,7 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) /* Cleanup tileindex if it is open. */ /* -------------------------------------------------------------------- */ cleanup: - if(layer->tileindex) { /* tiling clean-up */ + if (layer->tileindex) { /* tiling clean-up */ msDrawRasterCleanupTileLayer(tlp, tilelayerindex); } else { msLayerRestoreFromScaletokens(layer); @@ -887,9 +874,9 @@ int msRasterQueryByRect(mapObj *map, layerObj *layer, rectObj queryRect) /* On failure, or empty result set, cleanup the rlinfo since we */ /* likely won't ever have it accessed or cleaned up later. */ /* -------------------------------------------------------------------- */ - if( status == MS_FAILURE || rlinfo->query_results == 0 ) { - if(destroy_on_failure) { - msRasterLayerInfoFree( layer ); + if (status == MS_FAILURE || rlinfo->query_results == 0) { + if (destroy_on_failure) { + msRasterLayerInfoFree(layer); } } else { /* populate the items/numitems layer-level values */ @@ -911,14 +898,14 @@ int msRasterQueryByShape(mapObj *map, layerObj *layer, shapeObj *selectshape) double tolerance; rectObj searchrect; - msRasterLayerInfoInitialize( layer ); + msRasterLayerInfoInitialize(layer); - rlinfo = (rasterLayerInfo *) layer->layerinfo; + rlinfo = (rasterLayerInfo *)layer->layerinfo; /* If the selection shape is point or line we use the default tolerance of 3, but for polygons we require an exact hit. */ - if(layer->tolerance == -1) { - if(selectshape->type == MS_SHAPE_POINT || + if (layer->tolerance == -1) { + if (selectshape->type == MS_SHAPE_POINT || selectshape->type == MS_SHAPE_LINE) tolerance = 3; else @@ -926,26 +913,26 @@ int msRasterQueryByShape(mapObj *map, layerObj *layer, shapeObj *selectshape) } else tolerance = layer->tolerance; - if(layer->toleranceunits == MS_PIXELS) - tolerance = tolerance - * msAdjustExtent(&(map->extent), map->width, map->height); + if (layer->toleranceunits == MS_PIXELS) + tolerance = + tolerance * msAdjustExtent(&(map->extent), map->width, map->height); else - tolerance = tolerance - * (msInchesPerUnit(layer->toleranceunits,0) - / msInchesPerUnit(map->units,0)); + tolerance = tolerance * (msInchesPerUnit(layer->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); rlinfo->searchshape = selectshape; rlinfo->shape_tolerance = tolerance; - msComputeBounds( selectshape ); + msComputeBounds(selectshape); searchrect = selectshape->bounds; - searchrect.minx -= tolerance; /* expand the search box to account for layer tolerances (e.g. buffered searches) */ + searchrect.minx -= tolerance; /* expand the search box to account for layer + tolerances (e.g. buffered searches) */ searchrect.maxx += tolerance; searchrect.miny -= tolerance; searchrect.maxy += tolerance; - status = msRasterQueryByRect( map, layer, searchrect ); + status = msRasterQueryByRect(map, layer, searchrect); rlinfo->searchshape = NULL; @@ -957,16 +944,15 @@ int msRasterQueryByShape(mapObj *map, layerObj *layer, shapeObj *selectshape) /************************************************************************/ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, - double buffer, int maxresults) -{ + double buffer, int maxresults) { int result; double layer_tolerance; rectObj bufferRect; rasterLayerInfo *rlinfo = NULL; - msRasterLayerInfoInitialize( layer ); + msRasterLayerInfoInitialize(layer); - rlinfo = (rasterLayerInfo *) layer->layerinfo; + rlinfo = (rasterLayerInfo *)layer->layerinfo; /* -------------------------------------------------------------------- */ /* If the buffer is not set, then use layer tolerances */ @@ -976,19 +962,18 @@ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, /* clear that there is any way of requesting a buffer size in */ /* underlying pixels. */ /* -------------------------------------------------------------------- */ - if(buffer <= 0) { /* use layer tolerance */ - if(layer->tolerance == -1) + if (buffer <= 0) { /* use layer tolerance */ + if (layer->tolerance == -1) layer_tolerance = 3; else layer_tolerance = layer->tolerance; - if(layer->toleranceunits == MS_PIXELS) - buffer = layer_tolerance - * msAdjustExtent(&(map->extent), map->width, map->height); + if (layer->toleranceunits == MS_PIXELS) + buffer = layer_tolerance * + msAdjustExtent(&(map->extent), map->width, map->height); else - buffer = layer_tolerance - * (msInchesPerUnit(layer->toleranceunits,0) - / msInchesPerUnit(map->units,0)); + buffer = layer_tolerance * (msInchesPerUnit(layer->toleranceunits, 0) / + msInchesPerUnit(map->units, 0)); } /* -------------------------------------------------------------------- */ @@ -1005,7 +990,7 @@ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, /* point. This will potentially be must more efficient than */ /* processing all pixels within the tolerance. */ /* -------------------------------------------------------------------- */ - if( mode == MS_QUERY_SINGLE ) { + if (mode == MS_QUERY_SINGLE) { rectObj pointRect; pointRect.minx = p.x; @@ -1014,8 +999,8 @@ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, pointRect.maxy = p.y; rlinfo->range_mode = MS_QUERY_SINGLE; - result = msRasterQueryByRect( map, layer, pointRect ); - if( rlinfo->query_results > 0 ) + result = msRasterQueryByRect(map, layer, pointRect); + if (rlinfo->query_results > 0) return result; } @@ -1030,13 +1015,13 @@ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, rlinfo->range_mode = mode; - if( maxresults != 0 ) { + if (maxresults != 0) { const int previous_maxresults = rlinfo->query_result_hard_max; rlinfo->query_result_hard_max = maxresults; - result = msRasterQueryByRect( map, layer, bufferRect ); + result = msRasterQueryByRect(map, layer, bufferRect); rlinfo->query_result_hard_max = previous_maxresults; } else { - result = msRasterQueryByRect( map, layer, bufferRect ); + result = msRasterQueryByRect(map, layer, bufferRect); } return result; @@ -1055,17 +1040,16 @@ int msRasterQueryByPoint(mapObj *map, layerObj *layer, int mode, pointObj p, /* msRASTERLayerOpen() */ /************************************************************************/ -int msRASTERLayerOpen(layerObj *layer) -{ +int msRASTERLayerOpen(layerObj *layer) { rasterLayerInfo *rlinfo; /* If we don't have info, initialize an empty one now */ - if( layer->layerinfo == NULL ) - msRasterLayerInfoInitialize( layer ); - if( layer->layerinfo == NULL ) + if (layer->layerinfo == NULL) + msRasterLayerInfoInitialize(layer); + if (layer->layerinfo == NULL) return MS_FAILURE; - rlinfo = (rasterLayerInfo *) layer->layerinfo; + rlinfo = (rasterLayerInfo *)layer->layerinfo; rlinfo->refcount = rlinfo->refcount + 1; @@ -1076,21 +1060,16 @@ int msRASTERLayerOpen(layerObj *layer) /* msRASTERIsLayerOpen() */ /************************************************************************/ -int msRASTERLayerIsOpen(layerObj *layer) -{ +int msRASTERLayerIsOpen(layerObj *layer) { if (layer->layerinfo) return MS_TRUE; return MS_FALSE; } - /************************************************************************/ /* msRASTERLayerFreeItemInfo() */ /************************************************************************/ -void msRASTERLayerFreeItemInfo(layerObj *layer) -{ - (void)layer; -} +void msRASTERLayerFreeItemInfo(layerObj *layer) { (void)layer; } /************************************************************************/ /* msRASTERLayerInitItemInfo() */ @@ -1098,8 +1077,7 @@ void msRASTERLayerFreeItemInfo(layerObj *layer) /* Perhaps we should be validating the requested items here? */ /************************************************************************/ -int msRASTERLayerInitItemInfo(layerObj *layer) -{ +int msRASTERLayerInitItemInfo(layerObj *layer) { (void)layer; return MS_SUCCESS; } @@ -1111,7 +1089,7 @@ int msRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { (void)isQuery; - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; rlinfo->which_rect = rect; rlinfo->next_shape = 0; @@ -1123,15 +1101,14 @@ int msRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) /* msRASTERLayerClose() */ /************************************************************************/ -int msRASTERLayerClose(layerObj *layer) -{ - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; +int msRASTERLayerClose(layerObj *layer) { + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; - if( rlinfo != NULL ) { + if (rlinfo != NULL) { rlinfo->refcount--; - if( rlinfo->refcount < 0 ) - msRasterLayerInfoFree( layer ); + if (rlinfo->refcount < 0) + msRasterLayerInfoFree(layer); } return MS_SUCCESS; } @@ -1140,12 +1117,10 @@ int msRASTERLayerClose(layerObj *layer) /* msRASTERLayerNextShape() */ /************************************************************************/ -int msRASTERLayerNextShape(layerObj *layer, shapeObj *shape) -{ - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; +int msRASTERLayerNextShape(layerObj *layer, shapeObj *shape) { + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; - if( rlinfo->next_shape < 0 - || rlinfo->next_shape >= rlinfo->query_results ) { + if (rlinfo->next_shape < 0 || rlinfo->next_shape >= rlinfo->query_results) { msFreeShape(shape); shape->type = MS_SHAPE_NULL; return MS_DONE; @@ -1156,7 +1131,7 @@ int msRASTERLayerNextShape(layerObj *layer, shapeObj *shape) record.tileindex = 0; record.classindex = record.resultindex = -1; - return msRASTERLayerGetShape( layer, shape, &record); + return msRASTERLayerGetShape(layer, shape, &record); } } @@ -1164,9 +1139,8 @@ int msRASTERLayerNextShape(layerObj *layer, shapeObj *shape) /* msRASTERLayerGetShape() */ /************************************************************************/ -int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) -{ - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; +int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; int i; long shapeindex = record->shapeindex; @@ -1177,19 +1151,18 @@ int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) /* -------------------------------------------------------------------- */ /* Validate requested record id. */ /* -------------------------------------------------------------------- */ - if( shapeindex < 0 || shapeindex >= rlinfo->query_results ) { + if (shapeindex < 0 || shapeindex >= rlinfo->query_results) { msSetError(MS_MISCERR, "Out of range shape index requested. Requested %ld\n" "but only %d shapes available.", - "msRASTERLayerGetShape()", - shapeindex, rlinfo->query_results ); + "msRASTERLayerGetShape()", shapeindex, rlinfo->query_results); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Apply the geometry. */ /* -------------------------------------------------------------------- */ - if( rlinfo->qc_x != NULL ) { + if (rlinfo->qc_x != NULL) { lineObj line; pointObj point; @@ -1202,56 +1175,55 @@ int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) point.y = rlinfo->qc_y[shapeindex]; point.m = 0.0; - msAddLine( shape, &line ); - msComputeBounds( shape ); + msAddLine(shape, &line); + msComputeBounds(shape); } /* -------------------------------------------------------------------- */ /* Apply the requested items. */ /* -------------------------------------------------------------------- */ - if( layer->numitems > 0 ) { - shape->values = (char **) msSmallMalloc(sizeof(char *) * layer->numitems); + if (layer->numitems > 0) { + shape->values = (char **)msSmallMalloc(sizeof(char *) * layer->numitems); shape->numvalues = layer->numitems; - for( i = 0; i < layer->numitems; i++ ) { + for (i = 0; i < layer->numitems; i++) { const size_t bufferSize = 1000; char szWork[1000]; szWork[0] = '\0'; - if( EQUAL(layer->items[i],"x") && rlinfo->qc_x_reproj ) - snprintf( szWork, bufferSize, "%.8g", rlinfo->qc_x_reproj[shapeindex] ); - else if( EQUAL(layer->items[i],"y") && rlinfo->qc_y_reproj ) - snprintf( szWork, bufferSize, "%.8g", rlinfo->qc_y_reproj[shapeindex] ); + if (EQUAL(layer->items[i], "x") && rlinfo->qc_x_reproj) + snprintf(szWork, bufferSize, "%.8g", rlinfo->qc_x_reproj[shapeindex]); + else if (EQUAL(layer->items[i], "y") && rlinfo->qc_y_reproj) + snprintf(szWork, bufferSize, "%.8g", rlinfo->qc_y_reproj[shapeindex]); - else if( EQUAL(layer->items[i],"value_list") && rlinfo->qc_values ) { + else if (EQUAL(layer->items[i], "value_list") && rlinfo->qc_values) { int iValue; - for( iValue = 0; iValue < rlinfo->band_count; iValue++ ) { - if( iValue != 0 ) - strlcat( szWork, ",", bufferSize); + for (iValue = 0; iValue < rlinfo->band_count; iValue++) { + if (iValue != 0) + strlcat(szWork, ",", bufferSize); - snprintf( szWork+strlen(szWork), bufferSize-strlen(szWork), "%.8g", - rlinfo->qc_values[shapeindex * rlinfo->band_count - + iValue] ); + snprintf(szWork + strlen(szWork), bufferSize - strlen(szWork), "%.8g", + rlinfo->qc_values[shapeindex * rlinfo->band_count + iValue]); } - } else if( EQUALN(layer->items[i],"value_",6) && rlinfo->qc_values ) { - int iValue = atoi(layer->items[i]+6); - snprintf( szWork, bufferSize, "%.8g", - rlinfo->qc_values[shapeindex*rlinfo->band_count+iValue] ); - } else if( EQUAL(layer->items[i],"class") && rlinfo->qc_class ) { + } else if (EQUALN(layer->items[i], "value_", 6) && rlinfo->qc_values) { + int iValue = atoi(layer->items[i] + 6); + snprintf(szWork, bufferSize, "%.8g", + rlinfo->qc_values[shapeindex * rlinfo->band_count + iValue]); + } else if (EQUAL(layer->items[i], "class") && rlinfo->qc_class) { int p_class = rlinfo->qc_class[shapeindex]; - if( layer->class[p_class]->name != NULL ) - snprintf( szWork, bufferSize, "%.999s", layer->class[p_class]->name ); + if (layer->class[p_class] -> name != NULL) + snprintf(szWork, bufferSize, "%.999s", layer->class[p_class] -> name); else - snprintf( szWork, bufferSize, "%d", p_class ); - } else if( EQUAL(layer->items[i],"red") && rlinfo->qc_red ) - snprintf( szWork, bufferSize, "%d", rlinfo->qc_red[shapeindex] ); - else if( EQUAL(layer->items[i],"green") && rlinfo->qc_green ) - snprintf( szWork, bufferSize, "%d", rlinfo->qc_green[shapeindex] ); - else if( EQUAL(layer->items[i],"blue") && rlinfo->qc_blue ) - snprintf( szWork, bufferSize, "%d", rlinfo->qc_blue[shapeindex] ); - else if( EQUAL(layer->items[i],"count") && rlinfo->qc_count ) - snprintf( szWork, bufferSize, "%d", rlinfo->qc_count[shapeindex] ); + snprintf(szWork, bufferSize, "%d", p_class); + } else if (EQUAL(layer->items[i], "red") && rlinfo->qc_red) + snprintf(szWork, bufferSize, "%d", rlinfo->qc_red[shapeindex]); + else if (EQUAL(layer->items[i], "green") && rlinfo->qc_green) + snprintf(szWork, bufferSize, "%d", rlinfo->qc_green[shapeindex]); + else if (EQUAL(layer->items[i], "blue") && rlinfo->qc_blue) + snprintf(szWork, bufferSize, "%d", rlinfo->qc_blue[shapeindex]); + else if (EQUAL(layer->items[i], "count") && rlinfo->qc_count) + snprintf(szWork, bufferSize, "%d", rlinfo->qc_count[shapeindex]); shape->values[i] = msStrdup(szWork); } @@ -1269,40 +1241,39 @@ int msRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) /* msRASTERLayerGetItems() */ /************************************************************************/ -int msRASTERLayerGetItems(layerObj *layer) -{ +int msRASTERLayerGetItems(layerObj *layer) { int maxnumitems = 0; - rasterLayerInfo *rlinfo = (rasterLayerInfo *) layer->layerinfo; + rasterLayerInfo *rlinfo = (rasterLayerInfo *)layer->layerinfo; - if( rlinfo == NULL ) + if (rlinfo == NULL) return MS_FAILURE; - maxnumitems = 8 + (rlinfo->qc_values?rlinfo->band_count:0); - layer->items = (char **) msSmallCalloc(sizeof(char *),maxnumitems); + maxnumitems = 8 + (rlinfo->qc_values ? rlinfo->band_count : 0); + layer->items = (char **)msSmallCalloc(sizeof(char *), maxnumitems); layer->numitems = 0; - if( rlinfo->qc_x_reproj ) + if (rlinfo->qc_x_reproj) layer->items[layer->numitems++] = msStrdup("x"); - if( rlinfo->qc_y_reproj ) + if (rlinfo->qc_y_reproj) layer->items[layer->numitems++] = msStrdup("y"); - if( rlinfo->qc_values ) { + if (rlinfo->qc_values) { int i; - for( i = 0; i < rlinfo->band_count; i++ ) { + for (i = 0; i < rlinfo->band_count; i++) { char szName[100]; - snprintf( szName, sizeof(szName), "value_%d", i ); + snprintf(szName, sizeof(szName), "value_%d", i); layer->items[layer->numitems++] = msStrdup(szName); } layer->items[layer->numitems++] = msStrdup("value_list"); } - if( rlinfo->qc_class ) + if (rlinfo->qc_class) layer->items[layer->numitems++] = msStrdup("class"); - if( rlinfo->qc_red ) + if (rlinfo->qc_red) layer->items[layer->numitems++] = msStrdup("red"); - if( rlinfo->qc_green ) + if (rlinfo->qc_green) layer->items[layer->numitems++] = msStrdup("green"); - if( rlinfo->qc_blue ) + if (rlinfo->qc_blue) layer->items[layer->numitems++] = msStrdup("blue"); - if( rlinfo->qc_count ) + if (rlinfo->qc_count) layer->items[layer->numitems++] = msStrdup("count"); assert(layer->numitems <= maxnumitems); @@ -1321,27 +1292,32 @@ int msRASTERLayerGetExtent(layerObj *layer, rectObj *extent) mapObj *map = layer->map; shapefileObj *tileshpfile; - if( (!layer->data || strlen(layer->data) == 0) - && layer->tileindex == NULL) { + if ((!layer->data || strlen(layer->data) == 0) && layer->tileindex == NULL) { /* should we be issuing a specific error about not supporting extents for tileindexed raster layers? */ return MS_FAILURE; } - if( map == NULL ) + if (map == NULL) return MS_FAILURE; - /* If the layer use a tileindex, return the extent of the tileindex shapefile/referenced layer */ + /* If the layer use a tileindex, return the extent of the tileindex + * shapefile/referenced layer */ if (layer->tileindex) { const int tilelayerindex = msGetLayerIndex(map, layer->tileindex); - if(tilelayerindex != -1) /* does the tileindex reference another layer */ + if (tilelayerindex != -1) /* does the tileindex reference another layer */ return msLayerGetExtent(GET_LAYER(map, tilelayerindex), extent); else { - tileshpfile = (shapefileObj *) malloc(sizeof(shapefileObj)); + tileshpfile = (shapefileObj *)malloc(sizeof(shapefileObj)); MS_CHECK_ALLOC(tileshpfile, sizeof(shapefileObj), MS_FAILURE); - if(msShapefileOpen(tileshpfile, "rb", msBuildPath3(szPath, map->mappath, map->shapepath, layer->tileindex), MS_TRUE) == -1) - if(msShapefileOpen(tileshpfile, "rb", msBuildPath(szPath, map->mappath, layer->tileindex), MS_TRUE) == -1) + if (msShapefileOpen(tileshpfile, "rb", + msBuildPath3(szPath, map->mappath, map->shapepath, + layer->tileindex), + MS_TRUE) == -1) + if (msShapefileOpen(tileshpfile, "rb", + msBuildPath(szPath, map->mappath, layer->tileindex), + MS_TRUE) == -1) return MS_FAILURE; *extent = tileshpfile->bounds; @@ -1352,34 +1328,32 @@ int msRASTERLayerGetExtent(layerObj *layer, rectObj *extent) } msTryBuildPath3(szPath, map->mappath, map->shapepath, layer->data); - char* decrypted_path = msDecryptStringTokens( map, szPath ); - if( !decrypted_path ) - return MS_FAILURE; - - char** connectionoptions = msGetStringListFromHashTable(&(layer->connectionoptions)); - GDALDatasetH hDS = GDALOpenEx(decrypted_path, - GDAL_OF_RASTER, - NULL, - (const char* const*)connectionoptions, - NULL); + char *decrypted_path = msDecryptStringTokens(map, szPath); + if (!decrypted_path) + return MS_FAILURE; + + char **connectionoptions = + msGetStringListFromHashTable(&(layer->connectionoptions)); + GDALDatasetH hDS = GDALOpenEx(decrypted_path, GDAL_OF_RASTER, NULL, + (const char *const *)connectionoptions, NULL); CSLDestroy(connectionoptions); - msFree( decrypted_path ); - if( hDS == NULL ) { + msFree(decrypted_path); + if (hDS == NULL) { return MS_FAILURE; } - const int nXSize = GDALGetRasterXSize( hDS ); - const int nYSize = GDALGetRasterYSize( hDS ); + const int nXSize = GDALGetRasterXSize(hDS); + const int nYSize = GDALGetRasterYSize(hDS); double adfGeoTransform[6] = {0}; - const CPLErr eErr = GDALGetGeoTransform( hDS, adfGeoTransform ); - if( eErr != CE_None ) { - GDALClose( hDS ); + const CPLErr eErr = GDALGetGeoTransform(hDS, adfGeoTransform); + if (eErr != CE_None) { + GDALClose(hDS); return MS_FAILURE; } /* If this appears to be an ungeoreferenced raster than flip it for mapservers purposes. */ - if( adfGeoTransform[5] == 1.0 && adfGeoTransform[3] == 0.0 ) { + if (adfGeoTransform[5] == 1.0 && adfGeoTransform[3] == 0.0) { adfGeoTransform[5] = -1.0; adfGeoTransform[3] = nYSize; } @@ -1393,7 +1367,6 @@ int msRASTERLayerGetExtent(layerObj *layer, rectObj *extent) return MS_SUCCESS; } - /************************************************************************/ /* msRASTERLayerSetTimeFilter() */ /* */ @@ -1410,14 +1383,13 @@ int msRASTERLayerGetExtent(layerObj *layer, rectObj *extent) /************************************************************************/ int msRASTERLayerSetTimeFilter(layerObj *layer, const char *timestring, - const char *timefield) -{ + const char *timefield) { int tilelayerindex; /* -------------------------------------------------------------------- */ /* If we don't have a tileindex the time filter has no effect. */ /* -------------------------------------------------------------------- */ - if( layer->tileindex == NULL ) + if (layer->tileindex == NULL) return MS_SUCCESS; /* -------------------------------------------------------------------- */ @@ -1432,26 +1404,24 @@ int msRASTERLayerSetTimeFilter(layerObj *layer, const char *timestring, /* This is propogated to the "working layer" created for the */ /* tileindex by code in mapraster.c. */ /* -------------------------------------------------------------------- */ - if( tilelayerindex == -1 ) - return msLayerMakeBackticsTimeFilter( layer, timestring, timefield ); + if (tilelayerindex == -1) + return msLayerMakeBackticsTimeFilter(layer, timestring, timefield); /* -------------------------------------------------------------------- */ /* Otherwise we invoke the tileindex layers SetTimeFilter */ /* method. */ /* -------------------------------------------------------------------- */ - if ( msCheckParentPointer(layer->map,"map")==MS_FAILURE ) + if (msCheckParentPointer(layer->map, "map") == MS_FAILURE) return MS_FAILURE; - return msLayerSetTimeFilter( layer->GET_LAYER(map,tilelayerindex), - timestring, timefield ); + return msLayerSetTimeFilter(layer->GET_LAYER(map, tilelayerindex), timestring, + timefield); } /************************************************************************/ /* msRASTERLayerInitializeVirtualTable() */ /************************************************************************/ -int -msRASTERLayerInitializeVirtualTable(layerObj *layer) -{ +int msRASTERLayerInitializeVirtualTable(layerObj *layer) { assert(layer != NULL); assert(layer->vtable != NULL); @@ -1476,4 +1446,3 @@ msRASTERLayerInitializeVirtualTable(layerObj *layer) return MS_SUCCESS; } - diff --git a/mapregex.c b/mapregex.c index 6a8a74fa6b..1566591627 100644 --- a/mapregex.c +++ b/mapregex.c @@ -46,38 +46,37 @@ doesn't #define away our ms_*/ #if defined(_WIN32) && !defined(__CYGWIN__) && _MSC_VER < 1900 -#define off_t long +#define off_t long #endif #include "mapserver.h" #include "mapregex.h" #include -MS_API_EXPORT(int) ms_regcomp(ms_regex_t *regex, const char *expr, int cflags) -{ +MS_API_EXPORT(int) ms_regcomp(ms_regex_t *regex, const char *expr, int cflags) { /* Must free in regfree() */ - regex_t* sys_regex = (regex_t*) msSmallMalloc(sizeof(regex_t)); - regex->sys_regex = (void*) sys_regex; + regex_t *sys_regex = (regex_t *)msSmallMalloc(sizeof(regex_t)); + regex->sys_regex = (void *)sys_regex; return regcomp(sys_regex, expr, cflags); } -MS_API_EXPORT(size_t) ms_regerror(int errcode, const ms_regex_t *regex, char *errbuf, size_t errbuf_size) -{ - return regerror(errcode, (regex_t*)(regex->sys_regex), errbuf, errbuf_size); +MS_API_EXPORT(size_t) +ms_regerror(int errcode, const ms_regex_t *regex, char *errbuf, + size_t errbuf_size) { + return regerror(errcode, (regex_t *)(regex->sys_regex), errbuf, errbuf_size); } -MS_API_EXPORT(int) ms_regexec(const ms_regex_t *regex, const char *string, size_t nmatch, ms_regmatch_t pmatch[], int eflags) -{ +MS_API_EXPORT(int) +ms_regexec(const ms_regex_t *regex, const char *string, size_t nmatch, + ms_regmatch_t pmatch[], int eflags) { /*This next line only works because we know that regmatch_t and ms_regmatch_t are exactly alike (POSIX STANDARD)*/ - return regexec((const regex_t*)(regex->sys_regex), - string, nmatch, - (regmatch_t*) pmatch, eflags); + return regexec((const regex_t *)(regex->sys_regex), string, nmatch, + (regmatch_t *)pmatch, eflags); } -MS_API_EXPORT(void) ms_regfree(ms_regex_t *regex) -{ - regfree((regex_t*)(regex->sys_regex)); +MS_API_EXPORT(void) ms_regfree(ms_regex_t *regex) { + regfree((regex_t *)(regex->sys_regex)); free(regex->sys_regex); return; } diff --git a/mapregex.h b/mapregex.h index 77a358f0c1..10bd765727 100644 --- a/mapregex.h +++ b/mapregex.h @@ -34,77 +34,75 @@ extern "C" { #endif - /* We want these to match the POSIX standard, so we need these*/ - /* === regex2.h === */ +/* We want these to match the POSIX standard, so we need these*/ +/* === regex2.h === */ #ifdef _WIN32 -#define MS_API_EXPORT(type) __declspec(dllexport) type __stdcall +#define MS_API_EXPORT(type) __declspec(dllexport) type __stdcall #elif defined(__GNUC__) && __GNUC__ >= 4 -#define MS_API_EXPORT(type) __attribute__ ((visibility("default"))) type +#define MS_API_EXPORT(type) __attribute__((visibility("default"))) type #else -#define MS_API_EXPORT(type) type +#define MS_API_EXPORT(type) type #endif - typedef struct { - void* sys_regex; - } ms_regex_t; +typedef struct { + void *sys_regex; +} ms_regex_t; - typedef int ms_regoff_t; - typedef struct { - ms_regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - ms_regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ - } ms_regmatch_t; +typedef int ms_regoff_t; +typedef struct { + ms_regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + ms_regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} ms_regmatch_t; - MS_API_EXPORT(int) ms_regcomp(ms_regex_t *, const char *, int); - MS_API_EXPORT(size_t) ms_regerror(int, const ms_regex_t *, char *, size_t); - MS_API_EXPORT(int) ms_regexec(const ms_regex_t *, const char *, size_t, ms_regmatch_t [], int); - MS_API_EXPORT(void) ms_regfree(ms_regex_t *); +MS_API_EXPORT(int) ms_regcomp(ms_regex_t *, const char *, int); +MS_API_EXPORT(size_t) ms_regerror(int, const ms_regex_t *, char *, size_t); +MS_API_EXPORT(int) +ms_regexec(const ms_regex_t *, const char *, size_t, ms_regmatch_t[], int); +MS_API_EXPORT(void) ms_regfree(ms_regex_t *); #ifndef BUILDING_REGEX_PROXY - /* === regcomp.c === */ -#define MS_REG_BASIC 0000 +/* === regcomp.c === */ +#define MS_REG_BASIC 0000 #define MS_REG_EXTENDED 0001 -#define MS_REG_ICASE 0002 -#define MS_REG_NOSUB 0004 -#define MS_REG_NEWLINE 0010 +#define MS_REG_ICASE 0002 +#define MS_REG_NOSUB 0004 +#define MS_REG_NEWLINE 0010 #define MS_REG_NOSPEC 0020 #define MS_REG_PEND 0040 #define MS_REG_DUMP 0200 - - /* === regerror.c === */ -#define MS_REG_OKAY 0 -#define MS_REG_NOMATCH 1 -#define MS_REG_BADPAT 2 -#define MS_REG_ECOLLATE 3 -#define MS_REG_ECTYPE 4 -#define MS_REG_EESCAPE 5 -#define MS_REG_ESUBREG 6 -#define MS_REG_EBRACK 7 -#define MS_REG_EPAREN 8 -#define MS_REG_EBRACE 9 -#define MS_REG_BADBR 10 +/* === regerror.c === */ +#define MS_REG_OKAY 0 +#define MS_REG_NOMATCH 1 +#define MS_REG_BADPAT 2 +#define MS_REG_ECOLLATE 3 +#define MS_REG_ECTYPE 4 +#define MS_REG_EESCAPE 5 +#define MS_REG_ESUBREG 6 +#define MS_REG_EBRACK 7 +#define MS_REG_EPAREN 8 +#define MS_REG_EBRACE 9 +#define MS_REG_BADBR 10 #define MS_REG_ERANGE 11 #define MS_REG_ESPACE 12 #define MS_REG_BADRPT 13 -#define MS_REG_EMPTY 14 +#define MS_REG_EMPTY 14 #define MS_REG_ASSERT 15 #define MS_REG_INVARG 16 -#define MS_REG_ATOI 255 /* convert name to number (!) */ -#define MS_REG_ITOA 0400 /* convert number to name (!) */ - +#define MS_REG_ATOI 255 /* convert name to number (!) */ +#define MS_REG_ITOA 0400 /* convert number to name (!) */ - /* === regexec.c === */ +/* === regexec.c === */ #define MS_REG_NOTBOL 00001 #define MS_REG_NOTEOL 00002 #define MS_REG_STARTEND 00004 -#define MS_REG_TRACE 00400 /* tracing of execution */ -#define MS_REG_LARGE 01000 /* force large representation */ -#define MS_REG_BACKR 02000 /* force use of backref code */ +#define MS_REG_TRACE 00400 /* tracing of execution */ +#define MS_REG_LARGE 01000 /* force large representation */ +#define MS_REG_BACKR 02000 /* force use of backref code */ #endif - #ifdef __cplusplus } #endif diff --git a/maprendering.c b/maprendering.c old mode 100755 new mode 100644 index e495319f99..3b5550e2fd --- a/maprendering.c +++ b/maprendering.c @@ -33,42 +33,41 @@ #include "mapcopy.h" #include "fontcache.h" -void computeSymbolStyle(symbolStyleObj *s, styleObj *src, symbolObj *symbol, double scalefactor, - double resolutionfactor) -{ +void computeSymbolStyle(symbolStyleObj *s, styleObj *src, symbolObj *symbol, + double scalefactor, double resolutionfactor) { double default_size; double target_size; double style_size; default_size = msSymbolGetDefaultSize(symbol); - style_size = (src->size==-1)?default_size:src->size; + style_size = (src->size == -1) ? default_size : src->size; INIT_SYMBOL_STYLE(*s); - if(symbol->type == MS_SYMBOL_PIXMAP) { + if (symbol->type == MS_SYMBOL_PIXMAP) { s->color = s->outlinecolor = NULL; - } else if(symbol->filled || symbol->type == MS_SYMBOL_TRUETYPE) { - if(MS_VALID_COLOR(src->color)) + } else if (symbol->filled || symbol->type == MS_SYMBOL_TRUETYPE) { + if (MS_VALID_COLOR(src->color)) s->color = &src->color; - if(MS_VALID_COLOR(src->outlinecolor)) + if (MS_VALID_COLOR(src->outlinecolor)) s->outlinecolor = &src->outlinecolor; } else { - if(MS_VALID_COLOR(src->color)) + if (MS_VALID_COLOR(src->color)) s->outlinecolor = &(src->color); - else if(MS_VALID_COLOR(src->outlinecolor)) + else if (MS_VALID_COLOR(src->outlinecolor)) s->outlinecolor = &(src->outlinecolor); s->color = NULL; } target_size = style_size * scalefactor; - target_size = MS_MAX(target_size, src->minsize*resolutionfactor); - target_size = MS_MIN(target_size, src->maxsize*resolutionfactor); + target_size = MS_MAX(target_size, src->minsize * resolutionfactor); + target_size = MS_MIN(target_size, src->maxsize * resolutionfactor); s->scale = target_size / default_size; s->gap = src->gap * target_size / style_size; - if(s->outlinecolor) { - s->outlinewidth = src->width * scalefactor; - s->outlinewidth = MS_MAX(s->outlinewidth, src->minwidth*resolutionfactor); - s->outlinewidth = MS_MIN(s->outlinewidth, src->maxwidth*resolutionfactor); + if (s->outlinecolor) { + s->outlinewidth = src->width * scalefactor; + s->outlinewidth = MS_MAX(s->outlinewidth, src->minwidth * resolutionfactor); + s->outlinewidth = MS_MIN(s->outlinewidth, src->maxwidth * resolutionfactor); } else { s->outlinewidth = 0; } @@ -76,35 +75,32 @@ void computeSymbolStyle(symbolStyleObj *s, styleObj *src, symbolObj *symbol, dou s->rotation = src->angle * MS_DEG_TO_RAD; } +#define COMPARE_COLORS(a, b) \ + (((a).red == (b).red) && ((a).green == (b).green) && \ + ((a).blue == (b).blue) && ((a).alpha == (b).alpha)) -#define COMPARE_COLORS(a,b) (\ - ((a).red==(b).red) && \ - ((a).green==(b).green) && \ - ((a).blue==(b).blue) && \ - ((a).alpha==(b).alpha)) - -tileCacheObj *searchTileCache(imageObj *img, symbolObj *symbol, symbolStyleObj *s, int width, int height) -{ +tileCacheObj *searchTileCache(imageObj *img, symbolObj *symbol, + symbolStyleObj *s, int width, int height) { tileCacheObj *cur = img->tilecache; - while(cur != NULL) { - if( cur->width == width - && cur->height == height - && cur->symbol == symbol - && cur->outlinewidth == s->outlinewidth - && cur->rotation == s->rotation - && cur->scale == s->scale - && (!s->color || COMPARE_COLORS(cur->color,*s->color)) - && (!s->backgroundcolor || COMPARE_COLORS(cur->backgroundcolor,*s->backgroundcolor)) - && (!s->outlinecolor || COMPARE_COLORS(cur->outlinecolor,*s->outlinecolor))) + while (cur != NULL) { + if (cur->width == width && cur->height == height && cur->symbol == symbol && + cur->outlinewidth == s->outlinewidth && cur->rotation == s->rotation && + cur->scale == s->scale && + (!s->color || COMPARE_COLORS(cur->color, *s->color)) && + (!s->backgroundcolor || + COMPARE_COLORS(cur->backgroundcolor, *s->backgroundcolor)) && + (!s->outlinecolor || + COMPARE_COLORS(cur->outlinecolor, *s->outlinecolor))) return cur; cur = cur->next; } return NULL; } -int preloadSymbol(symbolSetObj *symbolset, symbolObj *symbol, rendererVTableObj *renderer) { +int preloadSymbol(symbolSetObj *symbolset, symbolObj *symbol, + rendererVTableObj *renderer) { (void)symbolset; - switch(symbol->type) { + switch (symbol->type) { case MS_SYMBOL_VECTOR: case MS_SYMBOL_ELLIPSE: case MS_SYMBOL_SIMPLE: @@ -114,36 +110,38 @@ int preloadSymbol(symbolSetObj *symbolset, symbolObj *symbol, rendererVTableObj #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) return msPreloadSVGSymbol(symbol); #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "preloadSymbol()"); + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "preloadSymbol()"); return MS_FAILURE; #endif break; case (MS_SYMBOL_PIXMAP): { - if(!symbol->pixmap_buffer) { - if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol)) + if (!symbol->pixmap_buffer) { + if (MS_SUCCESS != msPreloadImageSymbol(renderer, symbol)) return MS_FAILURE; } - } - break; + } break; default: - msSetError(MS_MISCERR,"unsupported symbol type %d", "preloadSymbol()", symbol->type); + msSetError(MS_MISCERR, "unsupported symbol type %d", "preloadSymbol()", + symbol->type); return MS_FAILURE; } return MS_SUCCESS; } /* add a cached tile to the current image's cache */ -tileCacheObj *addTileCache(imageObj *img, - imageObj *tile, symbolObj *symbol, symbolStyleObj *style, int width, int height) -{ +tileCacheObj *addTileCache(imageObj *img, imageObj *tile, symbolObj *symbol, + symbolStyleObj *style, int width, int height) { tileCacheObj *cachep; - if(img->ntiles >= MS_IMAGECACHESIZE) { /* remove last element, size stays the same */ + if (img->ntiles >= + MS_IMAGECACHESIZE) { /* remove last element, size stays the same */ cachep = img->tilecache; /*go to the before last cache object*/ - while(cachep->next && cachep->next->next) cachep = cachep->next; - assert( cachep->next ); + while (cachep->next && cachep->next->next) + cachep = cachep->next; + assert(cachep->next); /*free the last tile's data*/ msFreeImage(cachep->next->image); @@ -158,7 +156,7 @@ tileCacheObj *addTileCache(imageObj *img, } else { img->ntiles += 1; - cachep = (tileCacheObj*)malloc(sizeof(tileCacheObj)); + cachep = (tileCacheObj *)malloc(sizeof(tileCacheObj)); MS_CHECK_ALLOC(cachep, sizeof(tileCacheObj), NULL); cachep->next = img->tilecache; img->tilecache = cachep; @@ -170,23 +168,27 @@ tileCacheObj *addTileCache(imageObj *img, cachep->outlinewidth = style->outlinewidth; cachep->scale = style->scale; cachep->rotation = style->rotation; - if(style->color) MS_COPYCOLOR(&cachep->color,style->color); - if(style->outlinecolor) MS_COPYCOLOR(&cachep->outlinecolor,style->outlinecolor); + if (style->color) + MS_COPYCOLOR(&cachep->color, style->color); + if (style->outlinecolor) + MS_COPYCOLOR(&cachep->outlinecolor, style->outlinecolor); cachep->width = width; cachep->height = height; cachep->symbol = symbol; - return(cachep); + return (cachep); } /* helper function to center glyph on the desired point */ -static int drawGlyphMarker(imageObj *img, face_element *face, glyph_element *glyphc, double px, double py, int size, double rotation, - colorObj *clr, colorObj *oclr, int olwidth) -{ +static int drawGlyphMarker(imageObj *img, face_element *face, + glyph_element *glyphc, double px, double py, + int size, double rotation, colorObj *clr, + colorObj *oclr, int olwidth) { double ox, oy; textPathObj path; glyphObj glyph; rendererVTableObj *renderer = img->format->vtable; - if(!renderer->renderGlyphs) return MS_FAILURE; + if (!renderer->renderGlyphs) + return MS_FAILURE; path.numglyphs = 1; glyph.glyph = glyphc; glyph.face = face; @@ -195,9 +197,9 @@ static int drawGlyphMarker(imageObj *img, face_element *face, glyph_element *gly glyph.rot = rotation; ox = (glyphc->metrics.maxx + glyphc->metrics.minx) / 2.0; oy = (glyphc->metrics.maxy + glyphc->metrics.miny) / 2.0; - if(rotation != 0) { + if (rotation != 0) { double sina, cosa; - double rox,roy; + double rox, roy; sina = sin(rotation); cosa = cos(rotation); rox = ox * cosa - oy * sina; @@ -216,210 +218,238 @@ static int drawGlyphMarker(imageObj *img, face_element *face, glyph_element *gly return renderer->renderGlyphs(img, &ts, clr, oclr, olwidth, MS_TRUE); } - -imageObj *getTile(imageObj *img, symbolObj *symbol, symbolStyleObj *s, int width, int height, - int seamlessmode) -{ +imageObj *getTile(imageObj *img, symbolObj *symbol, symbolStyleObj *s, + int width, int height, int seamlessmode) { tileCacheObj *tile; int status = MS_SUCCESS; rendererVTableObj *renderer = img->format->vtable; - if(width==-1 || height == -1) { - width=height=MS_MAX(symbol->sizex,symbol->sizey); + if (width == -1 || height == -1) { + width = height = MS_MAX(symbol->sizex, symbol->sizey); } - tile = searchTileCache(img,symbol,s,width,height); + tile = searchTileCache(img, symbol, s, width, height); - if(tile==NULL) { + if (tile == NULL) { imageObj *tileimg; - double p_x,p_y; - tileimg = msImageCreate(width,height,img->format,NULL,NULL,img->resolution, img->resolution, NULL); - if(MS_UNLIKELY(!tileimg)) { + double p_x, p_y; + tileimg = msImageCreate(width, height, img->format, NULL, NULL, + img->resolution, img->resolution, NULL); + if (MS_UNLIKELY(!tileimg)) { return NULL; } - if(!seamlessmode) { - p_x = width/2.0; - p_y = height/2.0; - switch(symbol->type) { - case (MS_SYMBOL_TRUETYPE): - { - unsigned int unicode; - glyph_element *glyphc; - face_element *face = msGetFontFace(symbol->font, &img->map->fontset); - if(MS_UNLIKELY(!face)) { status = MS_FAILURE; break; } - msUTF8ToUniChar(symbol->character, &unicode); - unicode = msGetGlyphIndex(face,unicode); - glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(s->scale),1), unicode); - if(MS_UNLIKELY(!glyphc)) { status = MS_FAILURE; break; } - status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, s->rotation, - s->color, s->outlinecolor, s->outlinewidth); - } - break; - case (MS_SYMBOL_PIXMAP): - status = msPreloadImageSymbol(renderer,symbol); - if(MS_UNLIKELY(status == MS_FAILURE)) { break; } - status = renderer->renderPixmapSymbol(tileimg, p_x, p_y, symbol, s); + if (!seamlessmode) { + p_x = width / 2.0; + p_y = height / 2.0; + switch (symbol->type) { + case (MS_SYMBOL_TRUETYPE): { + unsigned int unicode; + glyph_element *glyphc; + face_element *face = msGetFontFace(symbol->font, &img->map->fontset); + if (MS_UNLIKELY(!face)) { + status = MS_FAILURE; break; - case (MS_SYMBOL_ELLIPSE): - status = renderer->renderEllipseSymbol(tileimg, p_x, p_y,symbol, s); + } + msUTF8ToUniChar(symbol->character, &unicode); + unicode = msGetGlyphIndex(face, unicode); + glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(s->scale), 1), unicode); + if (MS_UNLIKELY(!glyphc)) { + status = MS_FAILURE; break; - case (MS_SYMBOL_VECTOR): - status = renderer->renderVectorSymbol(tileimg, p_x, p_y, symbol, s); + } + status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, + s->rotation, s->color, s->outlinecolor, + s->outlinewidth); + } break; + case (MS_SYMBOL_PIXMAP): + status = msPreloadImageSymbol(renderer, symbol); + if (MS_UNLIKELY(status == MS_FAILURE)) { break; + } + status = renderer->renderPixmapSymbol(tileimg, p_x, p_y, symbol, s); + break; + case (MS_SYMBOL_ELLIPSE): + status = renderer->renderEllipseSymbol(tileimg, p_x, p_y, symbol, s); + break; + case (MS_SYMBOL_VECTOR): + status = renderer->renderVectorSymbol(tileimg, p_x, p_y, symbol, s); + break; - case (MS_SYMBOL_SVG): + case (MS_SYMBOL_SVG): #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) - status = msPreloadSVGSymbol(symbol); - if(MS_LIKELY(status == MS_SUCCESS)) { - if (renderer->supports_svg) { - status = renderer->renderSVGSymbol(tileimg, p_x, p_y, symbol, s); - } else { - status = msRenderRasterizedSVGSymbol(tileimg,p_x,p_y,symbol, s); - } + status = msPreloadSVGSymbol(symbol); + if (MS_LIKELY(status == MS_SUCCESS)) { + if (renderer->supports_svg) { + status = renderer->renderSVGSymbol(tileimg, p_x, p_y, symbol, s); + } else { + status = msRenderRasterizedSVGSymbol(tileimg, p_x, p_y, symbol, s); } + } #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "getTile()"); - status = MS_FAILURE; + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "getTile()"); + status = MS_FAILURE; #endif - break; - default: - msSetError(MS_SYMERR, "Unknown symbol type %d", "getTile()", symbol->type); - status = MS_FAILURE; - break; + break; + default: + msSetError(MS_SYMERR, "Unknown symbol type %d", "getTile()", + symbol->type); + status = MS_FAILURE; + break; } - if(MS_UNLIKELY(status == MS_FAILURE)) { + if (MS_UNLIKELY(status == MS_FAILURE)) { msFreeImage(tileimg); return NULL; } } else { /* - * in seamless mode, we render the the symbol 9 times on a 3x3 grid to account for - * antialiasing blending from one tile to the next. We finally keep the center tile + * in seamless mode, we render the the symbol 9 times on a 3x3 grid to + * account for antialiasing blending from one tile to the next. We finally + * keep the center tile */ - imageObj *tile3img = msImageCreate(width*3,height*3,img->format,NULL,NULL, - img->resolution, img->resolution, NULL); - int i,j; + imageObj *tile3img = + msImageCreate(width * 3, height * 3, img->format, NULL, NULL, + img->resolution, img->resolution, NULL); + int i, j; rasterBufferObj tmpraster; - for(i=1; i<=3; i++) { - p_x = (i+0.5)*width; - for(j=1; j<=3; j++) { - p_y = (j+0.5) * height; - switch(symbol->type) { - case (MS_SYMBOL_TRUETYPE): - { - unsigned int unicode; - glyph_element *glyphc; - face_element *face = msGetFontFace(symbol->font, &img->map->fontset); - if(MS_UNLIKELY(!face)) { status = MS_FAILURE; break; } - msUTF8ToUniChar(symbol->character, &unicode); - unicode = msGetGlyphIndex(face,unicode); - glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(s->scale),1), unicode); - if(MS_UNLIKELY(!glyphc)) { status = MS_FAILURE; break; } - status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, s->rotation, - s->color, s->outlinecolor, s->outlinewidth); - } - break; - case (MS_SYMBOL_PIXMAP): - status = msPreloadImageSymbol(renderer,symbol); - if(MS_UNLIKELY(status == MS_FAILURE)) { break; } - status = renderer->renderPixmapSymbol(tile3img, p_x, p_y, symbol, s); + for (i = 1; i <= 3; i++) { + p_x = (i + 0.5) * width; + for (j = 1; j <= 3; j++) { + p_y = (j + 0.5) * height; + switch (symbol->type) { + case (MS_SYMBOL_TRUETYPE): { + unsigned int unicode; + glyph_element *glyphc; + face_element *face = + msGetFontFace(symbol->font, &img->map->fontset); + if (MS_UNLIKELY(!face)) { + status = MS_FAILURE; break; - case (MS_SYMBOL_ELLIPSE): - status = renderer->renderEllipseSymbol(tile3img, p_x, p_y,symbol, s); + } + msUTF8ToUniChar(symbol->character, &unicode); + unicode = msGetGlyphIndex(face, unicode); + glyphc = + msGetGlyphByIndex(face, MS_MAX(MS_NINT(s->scale), 1), unicode); + if (MS_UNLIKELY(!glyphc)) { + status = MS_FAILURE; break; - case (MS_SYMBOL_VECTOR): - status = renderer->renderVectorSymbol(tile3img, p_x, p_y, symbol, s); + } + status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, + s->rotation, s->color, s->outlinecolor, + s->outlinewidth); + } break; + case (MS_SYMBOL_PIXMAP): + status = msPreloadImageSymbol(renderer, symbol); + if (MS_UNLIKELY(status == MS_FAILURE)) { break; - default: - msSetError(MS_SYMERR, "BUG: Seamless mode is only for vector symbols", "getTile()"); - return NULL; + } + status = + renderer->renderPixmapSymbol(tile3img, p_x, p_y, symbol, s); + break; + case (MS_SYMBOL_ELLIPSE): + status = + renderer->renderEllipseSymbol(tile3img, p_x, p_y, symbol, s); + break; + case (MS_SYMBOL_VECTOR): + status = + renderer->renderVectorSymbol(tile3img, p_x, p_y, symbol, s); + break; + default: + msSetError(MS_SYMERR, + "BUG: Seamless mode is only for vector symbols", + "getTile()"); + return NULL; } - if(MS_UNLIKELY(status == MS_FAILURE)) { + if (MS_UNLIKELY(status == MS_FAILURE)) { msFreeImage(tile3img); return NULL; } } } - status = MS_IMAGE_RENDERER(tile3img)->getRasterBufferHandle(tile3img,&tmpraster); - if(MS_UNLIKELY(status == MS_FAILURE)) { + status = MS_IMAGE_RENDERER(tile3img)->getRasterBufferHandle(tile3img, + &tmpraster); + if (MS_UNLIKELY(status == MS_FAILURE)) { msFreeImage(tile3img); return NULL; } - status = renderer->mergeRasterBuffer(tileimg, - &tmpraster, - 1.0,width,height,0,0,width,height - ); + status = renderer->mergeRasterBuffer(tileimg, &tmpraster, 1.0, width, + height, 0, 0, width, height); msFreeImage(tile3img); } - if(MS_UNLIKELY(status == MS_FAILURE)) { + if (MS_UNLIKELY(status == MS_FAILURE)) { msFreeImage(tileimg); return NULL; } - tile = addTileCache(img,tileimg,symbol,s,width,height); + tile = addTileCache(img, tileimg, symbol, s, width, height); } return tile->image; } int msImagePolylineMarkers(imageObj *image, shapeObj *p, symbolObj *symbol, symbolStyleObj *style, double spacing, - double initialgap, int auto_angle) -{ + double initialgap, int auto_angle) { rendererVTableObj *renderer = MS_IMAGE_RENDERER(image); - int i,j; + int i, j; pointObj point; double original_rotation = style->rotation; - double symbol_width,symbol_height; + double symbol_width, symbol_height; glyph_element *glyphc = NULL; face_element *face = NULL; int ret = MS_SUCCESS; - if(symbol->type != MS_SYMBOL_TRUETYPE) { - symbol_width = MS_MAX(1,symbol->sizex*style->scale); - symbol_height = MS_MAX(1,symbol->sizey*style->scale); + if (symbol->type != MS_SYMBOL_TRUETYPE) { + symbol_width = MS_MAX(1, symbol->sizex * style->scale); + symbol_height = MS_MAX(1, symbol->sizey * style->scale); } else { unsigned int unicode; msUTF8ToUniChar(symbol->character, &unicode); face = msGetFontFace(symbol->font, &image->map->fontset); - if(MS_UNLIKELY(!face)) return MS_FAILURE; - unicode = msGetGlyphIndex(face,unicode); - glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(style->scale),1), unicode); - if(MS_UNLIKELY(!glyphc)) return MS_FAILURE; + if (MS_UNLIKELY(!face)) + return MS_FAILURE; + unicode = msGetGlyphIndex(face, unicode); + glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(style->scale), 1), unicode); + if (MS_UNLIKELY(!glyphc)) + return MS_FAILURE; symbol_width = glyphc->metrics.maxx - glyphc->metrics.minx; symbol_height = glyphc->metrics.maxy - glyphc->metrics.miny; } - for(i=0; inumlines; i++) { + for (i = 0; i < p->numlines; i++) { int line_in = 0; - double line_length=0; + double line_length = 0; double current_length; - if(initialgap < 0) { - current_length = spacing/2.0; /* initial padding for each line */ + if (initialgap < 0) { + current_length = spacing / 2.0; /* initial padding for each line */ } else { current_length = initialgap; /* initial padding for each line */ } - for(j=1; jline[i].numpoints; j++) { - double rx,ry,theta,length; - length = sqrt((pow((p->line[i].point[j].x - p->line[i].point[j-1].x),2) + pow((p->line[i].point[j].y - p->line[i].point[j-1].y),2))); + for (j = 1; j < p->line[i].numpoints; j++) { + double rx, ry, theta, length; + length = + sqrt((pow((p->line[i].point[j].x - p->line[i].point[j - 1].x), 2) + + pow((p->line[i].point[j].y - p->line[i].point[j - 1].y), 2))); line_length += length; - if(length==0)continue; - rx = (p->line[i].point[j].x - p->line[i].point[j-1].x)/length; - ry = (p->line[i].point[j].y - p->line[i].point[j-1].y)/length; + if (length == 0) + continue; + rx = (p->line[i].point[j].x - p->line[i].point[j - 1].x) / length; + ry = (p->line[i].point[j].y - p->line[i].point[j - 1].y) / length; if (auto_angle) { theta = asin(ry); - if(rx < 0) { + if (rx < 0) { theta += MS_PI; - } else theta = -theta; + } else + theta = -theta; style->rotation = original_rotation + theta; } while (current_length <= length) { point.x = p->line[i].point[j - 1].x + current_length * rx; point.y = p->line[i].point[j - 1].y + current_length * ry; - if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { + if (symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { double ox, oy; ox = (0.5 - symbol->anchorpoint_x) * symbol_width; oy = (0.5 - symbol->anchorpoint_y) * symbol_height; - if(style->rotation != 0) { - double sina,cosa; - double rox,roy; + if (style->rotation != 0) { + double sina, cosa; + double rox, roy; sina = sin(-style->rotation); cosa = cos(-style->rotation); rox = ox * cosa - oy * sina; @@ -433,44 +463,53 @@ int msImagePolylineMarkers(imageObj *image, shapeObj *p, symbolObj *symbol, } /* if the point is not in the map extent, skip it. (POLYLINE_NO_CLIP) */ - if ( (point.x < -(symbol_width) || point.x > (image->width+symbol_width)) || - (point.y < -(symbol_height) || point.y > (image->height+symbol_height)) ) { + if ((point.x < -(symbol_width) || + point.x > (image->width + symbol_width)) || + (point.y < -(symbol_height) || + point.y > (image->height + symbol_height))) { current_length += spacing; - line_in=1; + line_in = 1; continue; } - + switch (symbol->type) { - case MS_SYMBOL_PIXMAP: - ret = renderer->renderPixmapSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_ELLIPSE: - ret = renderer->renderEllipseSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_VECTOR: - ret = renderer->renderVectorSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_TRUETYPE: - ret = drawGlyphMarker(image, face, glyphc, point.x, point.y, style->scale, style->rotation, - style->color, style->outlinecolor, style->outlinewidth); - break; - case (MS_SYMBOL_SVG): + case MS_SYMBOL_PIXMAP: + ret = renderer->renderPixmapSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_ELLIPSE: + ret = renderer->renderEllipseSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_VECTOR: + ret = renderer->renderVectorSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_TRUETYPE: + ret = drawGlyphMarker(image, face, glyphc, point.x, point.y, + style->scale, style->rotation, style->color, + style->outlinecolor, style->outlinewidth); + break; + case (MS_SYMBOL_SVG): #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) - if (renderer->supports_svg) { - ret = renderer->renderSVGSymbol(image, point.x, point.y, symbol, style); - } else { - ret = msRenderRasterizedSVGSymbol(image,point.x,point.y,symbol, style); - } + if (renderer->supports_svg) { + ret = renderer->renderSVGSymbol(image, point.x, point.y, symbol, + style); + } else { + ret = msRenderRasterizedSVGSymbol(image, point.x, point.y, symbol, + style); + } #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msImagePolylineMarkers()()"); - ret = MS_FAILURE; + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "msImagePolylineMarkers()()"); + ret = MS_FAILURE; #endif - break; + break; } - if( ret != MS_SUCCESS) + if (ret != MS_SUCCESS) return ret; current_length += spacing; - line_in=1; + line_in = 1; } current_length -= length; @@ -481,76 +520,84 @@ int msImagePolylineMarkers(imageObj *image, shapeObj *p, symbolObj *symbol, * specified, add one now we don't add the symbol if the line is shorter * than the length of the symbol itself */ - if(initialgap < 0 && !line_in && line_length>symbol_width) { + if (initialgap < 0 && !line_in && line_length > symbol_width) { /* total lengths of beginnning and end of current segment */ - double before_length=0,after_length=0; + double before_length = 0, after_length = 0; /*optimize*/ line_length /= 2.0; - for(j=1; jline[i].numpoints; j++) { + for (j = 1; j < p->line[i].numpoints; j++) { double length; - length = sqrt((pow((p->line[i].point[j].x - p->line[i].point[j-1].x),2) + pow((p->line[i].point[j].y - p->line[i].point[j-1].y),2))); + length = + sqrt((pow((p->line[i].point[j].x - p->line[i].point[j - 1].x), 2) + + pow((p->line[i].point[j].y - p->line[i].point[j - 1].y), 2))); after_length += length; - if(after_length>line_length) { - double rx,ry,theta; + if (after_length > line_length) { + double rx, ry, theta; /* offset where the symbol should be drawn on the current * segment */ double offset = line_length - before_length; - rx = (p->line[i].point[j].x - p->line[i].point[j-1].x)/length; - ry = (p->line[i].point[j].y - p->line[i].point[j-1].y)/length; + rx = (p->line[i].point[j].x - p->line[i].point[j - 1].x) / length; + ry = (p->line[i].point[j].y - p->line[i].point[j - 1].y) / length; if (auto_angle) { theta = asin(ry); - if(rx < 0) { + if (rx < 0) { theta += MS_PI; - } else theta = -theta; + } else + theta = -theta; style->rotation = original_rotation + theta; } point.x = p->line[i].point[j - 1].x + offset * rx; point.y = p->line[i].point[j - 1].y + offset * ry; switch (symbol->type) { - case MS_SYMBOL_PIXMAP: - ret = renderer->renderPixmapSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_ELLIPSE: - ret = renderer->renderEllipseSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_VECTOR: - ret = renderer->renderVectorSymbol(image, point.x, point.y, symbol, style); - break; - case MS_SYMBOL_TRUETYPE: - ret = drawGlyphMarker(image, face, glyphc, point.x, point.y, style->scale, style->rotation, - style->color, style->outlinecolor, style->outlinewidth); - break; - case (MS_SYMBOL_SVG): + case MS_SYMBOL_PIXMAP: + ret = renderer->renderPixmapSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_ELLIPSE: + ret = renderer->renderEllipseSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_VECTOR: + ret = renderer->renderVectorSymbol(image, point.x, point.y, symbol, + style); + break; + case MS_SYMBOL_TRUETYPE: + ret = drawGlyphMarker(image, face, glyphc, point.x, point.y, + style->scale, style->rotation, style->color, + style->outlinecolor, style->outlinewidth); + break; + case (MS_SYMBOL_SVG): #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) - if (renderer->supports_svg) { - ret = renderer->renderSVGSymbol(image, point.x, point.y, symbol, style); - } else { - ret = msRenderRasterizedSVGSymbol(image,point.x,point.y,symbol, style); - } + if (renderer->supports_svg) { + ret = renderer->renderSVGSymbol(image, point.x, point.y, symbol, + style); + } else { + ret = msRenderRasterizedSVGSymbol(image, point.x, point.y, symbol, + style); + } #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msImagePolylineMarkers()()"); - ret = MS_FAILURE; + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "msImagePolylineMarkers()()"); + ret = MS_FAILURE; #endif - break; + break; } break; /* we have rendered the single marker for this line */ } before_length += length; } } - } return ret; } -int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, - styleObj *style, double scalefactor) -{ +int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style, + double scalefactor) { int status = MS_SUCCESS; if (image) { if (MS_RENDERER_PLUGIN(image->format)) { @@ -572,23 +619,25 @@ int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, symbol->renderer = renderer; width = style->width * scalefactor; - width = MS_MIN(width,style->maxwidth*image->resolutionfactor); - width = MS_MAX(width,style->minwidth*image->resolutionfactor); - if(style->width != 0) { + width = MS_MIN(width, style->maxwidth * image->resolutionfactor); + width = MS_MAX(width, style->minwidth * image->resolutionfactor); + if (style->width != 0) { finalscalefactor = width / style->width; } else { finalscalefactor = 1.0; } - if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) { - offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_SINGLE_SIDED_OFFSET); - } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) { - offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET); - } else if(style->offsetx!=0 || style->offsety!=0) { + if (style->offsety == MS_STYLE_SINGLE_SIDED_OFFSET) { + offsetLine = msOffsetPolyline(p, style->offsetx * finalscalefactor, + MS_STYLE_SINGLE_SIDED_OFFSET); + } else if (style->offsety == MS_STYLE_DOUBLE_SIDED_OFFSET) { + offsetLine = msOffsetPolyline(p, style->offsetx * finalscalefactor, + MS_STYLE_DOUBLE_SIDED_OFFSET); + } else if (style->offsetx != 0 || style->offsety != 0) { offsetLine = msOffsetPolyline(p, style->offsetx * finalscalefactor, style->offsety * finalscalefactor); } - if(style->symbol == 0 || (symbol->type==MS_SYMBOL_SIMPLE)) { + if (style->symbol == 0 || (symbol->type == MS_SYMBOL_SIMPLE)) { strokeStyleObj s; s.linecap = style->linecap; s.linejoin = style->linejoin; @@ -596,69 +645,79 @@ int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, s.antialiased = style->antialiased; s.width = width; s.patternlength = style->patternlength; - for(i=0; ipattern[i] * finalscalefactor; - s.patternoffset = (style->initialgap<=0) ? 0 : (style->initialgap * finalscalefactor); + s.patternoffset = (style->initialgap <= 0) + ? 0 + : (style->initialgap * finalscalefactor); - if(MS_VALID_COLOR(style->color)) + if (MS_VALID_COLOR(style->color)) s.color = &style->color; - else if(MS_VALID_COLOR(style->outlinecolor)) + else if (MS_VALID_COLOR(style->outlinecolor)) s.color = &style->outlinecolor; else { - /* msSetError(MS_MISCERR,"no color defined for line styling","msDrawLineSymbol()"); - * not really an error */ + /* msSetError(MS_MISCERR,"no color defined for line + * styling","msDrawLineSymbol()"); not really an error */ status = MS_SUCCESS; goto line_cleanup; } - status = renderer->renderLine(image,offsetLine,&s); + status = renderer->renderLine(image, offsetLine, &s); } else { symbolStyleObj s; - if(preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) { + if (preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) { status = MS_FAILURE; goto line_cleanup; } INIT_SYMBOL_STYLE(s); - computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor); + computeSymbolStyle(&s, style, symbol, scalefactor, + image->resolutionfactor); s.style = style; /* compute a markerStyle and use it on the line */ - if(style->gap<0) { - /* special function that treats any other symbol used as a marker, not a brush */ - status = msImagePolylineMarkers(image,offsetLine,symbol,&s,-s.gap, - style->initialgap * finalscalefactor, 1); - } else if(style->gap>0) { - status = msImagePolylineMarkers(image,offsetLine,symbol,&s,s.gap, - style->initialgap * finalscalefactor,0); + if (style->gap < 0) { + /* special function that treats any other symbol used as a marker, not + * a brush */ + status = + msImagePolylineMarkers(image, offsetLine, symbol, &s, -s.gap, + style->initialgap * finalscalefactor, 1); + } else if (style->gap > 0) { + status = + msImagePolylineMarkers(image, offsetLine, symbol, &s, s.gap, + style->initialgap * finalscalefactor, 0); } else { - if(renderer->renderLineTiled != NULL) { - int pw,ph; - imageObj* tile=NULL; - if(s.scale != 1) { + if (renderer->renderLineTiled != NULL) { + int pw, ph; + imageObj *tile = NULL; + if (s.scale != 1) { pw = MS_NINT(symbol->sizex * s.scale); ph = MS_NINT(symbol->sizey * s.scale); } else { pw = symbol->sizex; ph = symbol->sizey; } - if(pw<1) pw=1; - if(ph<1) ph=1; - tile = getTile(image, symbol,&s,pw,ph,0); + if (pw < 1) + pw = 1; + if (ph < 1) + ph = 1; + tile = getTile(image, symbol, &s, pw, ph, 0); status = renderer->renderLineTiled(image, offsetLine, tile); } else { - msSetError(MS_RENDERERERR, "renderer does not support brushed lines", "msDrawLineSymbol()"); + msSetError(MS_RENDERERERR, + "renderer does not support brushed lines", + "msDrawLineSymbol()"); status = MS_FAILURE; } } } -line_cleanup: - if(offsetLine!=p) { + line_cleanup: + if (offsetLine != p) { msFreeShape(offsetLine); msFree(offsetLine); } return status; - } else if( MS_RENDERER_IMAGEMAP(image->format) ) + } else if (MS_RENDERER_IMAGEMAP(image->format)) msDrawLineSymbolIM(map, image, p, style, scalefactor); else { msSetError(MS_RENDERERERR, "unsupported renderer", "msDrawLineSymbol()"); @@ -670,8 +729,8 @@ int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p, return status; } -int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style, double scalefactor) -{ +int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, + styleObj *style, double scalefactor) { int ret = MS_SUCCESS; symbolObj *symbol; if (!p) @@ -690,9 +749,9 @@ int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style * this behavior is kind of a mapfile hack, and must be * kept for backwards compatibility */ - if (symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG ) { + if (symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) { if (!MS_VALID_COLOR(style->color)) { - if(MS_VALID_COLOR(style->outlinecolor)) + if (MS_VALID_COLOR(style->outlinecolor)) return msDrawLineSymbol(map, image, p, style, scalefactor); else { /* just do nothing if no color has been set */ @@ -705,128 +764,140 @@ int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style rendererVTableObj *renderer = image->format->vtable; shapeObj *offsetPolygon = NULL; /* store a reference to the renderer to be used for freeing */ - if(style->symbol) + if (style->symbol) symbol->renderer = renderer; if (style->offsetx != 0 || style->offsety != 0) { - if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) { - offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor, MS_STYLE_SINGLE_SIDED_OFFSET); - } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) { - offsetPolygon = msOffsetPolyline(p,style->offsetx * scalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET); + if (style->offsety == MS_STYLE_SINGLE_SIDED_OFFSET) { + offsetPolygon = msOffsetPolyline(p, style->offsetx * scalefactor, + MS_STYLE_SINGLE_SIDED_OFFSET); + } else if (style->offsety == MS_STYLE_DOUBLE_SIDED_OFFSET) { + offsetPolygon = msOffsetPolyline(p, style->offsetx * scalefactor, + MS_STYLE_DOUBLE_SIDED_OFFSET); } else { - offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor,style->offsety*scalefactor); + offsetPolygon = msOffsetPolyline(p, style->offsetx * scalefactor, + style->offsety * scalefactor); } } else { - offsetPolygon=p; + offsetPolygon = p; } /* simple polygon drawing, without any specific symbol. * also draws an optional outline */ - if(style->symbol == 0 || symbol->type == MS_SYMBOL_SIMPLE) { - ret = renderer->renderPolygon(image,offsetPolygon,&style->color); - if(ret != MS_SUCCESS) goto cleanup; - if(MS_VALID_COLOR(style->outlinecolor)) { + if (style->symbol == 0 || symbol->type == MS_SYMBOL_SIMPLE) { + ret = renderer->renderPolygon(image, offsetPolygon, &style->color); + if (ret != MS_SUCCESS) + goto cleanup; + if (MS_VALID_COLOR(style->outlinecolor)) { strokeStyleObj s; INIT_STROKE_STYLE(s); s.color = &style->outlinecolor; s.color->alpha = style->color.alpha; - s.width = (style->width == 0)?scalefactor:style->width*scalefactor; + s.width = + (style->width == 0) ? scalefactor : style->width * scalefactor; s.width = MS_MIN(s.width, style->maxwidth); s.width = MS_MAX(s.width, style->minwidth); - ret = renderer->renderLine(image,offsetPolygon,&s); + ret = renderer->renderLine(image, offsetPolygon, &s); } goto cleanup; /*finished plain polygon*/ - } else if(symbol->type == MS_SYMBOL_HATCH) { + } else if (symbol->type == MS_SYMBOL_HATCH) { double width, spacing; double pattern[MS_MAXPATTERNLENGTH]; int i; - width = (style->width <= 0)?scalefactor:style->width*scalefactor; - width = MS_MIN(width, style->maxwidth*image->resolutionfactor); - width = MS_MAX(width, style->minwidth*image->resolutionfactor); - spacing = (style->size <= 0)?scalefactor:style->size*scalefactor; - spacing = MS_MIN(spacing, style->maxsize*image->resolutionfactor); - spacing = MS_MAX(spacing, style->minsize*image->resolutionfactor); + width = (style->width <= 0) ? scalefactor : style->width * scalefactor; + width = MS_MIN(width, style->maxwidth * image->resolutionfactor); + width = MS_MAX(width, style->minwidth * image->resolutionfactor); + spacing = (style->size <= 0) ? scalefactor : style->size * scalefactor; + spacing = MS_MIN(spacing, style->maxsize * image->resolutionfactor); + spacing = MS_MAX(spacing, style->minsize * image->resolutionfactor); /* scale the pattern by the factor applied to the width */ - for(i=0; ipatternlength; i++) { - pattern[i] = style->pattern[i]*width/style->width; + for (i = 0; i < style->patternlength; i++) { + pattern[i] = style->pattern[i] * width / style->width; } - ret = msHatchPolygon(image,offsetPolygon,spacing,width,pattern,style->patternlength,style->angle, &style->color); + ret = msHatchPolygon(image, offsetPolygon, spacing, width, pattern, + style->patternlength, style->angle, &style->color); goto cleanup; } else { symbolStyleObj s; - int pw,ph; + int pw, ph; imageObj *tile; int seamless = 0; - if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) { + if (preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) { ret = MS_FAILURE; goto cleanup; } INIT_SYMBOL_STYLE(s); - computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor); + computeSymbolStyle(&s, style, symbol, scalefactor, + image->resolutionfactor); s.style = style; - if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) { - ret = MS_SUCCESS; /* nothing to do (colors are required except for PIXMAP symbols */ + if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && + symbol->type != MS_SYMBOL_SVG) { + ret = MS_SUCCESS; /* nothing to do (colors are required except for + PIXMAP symbols */ goto cleanup; } - if(s.backgroundcolor) { - ret = renderer->renderPolygon(image,offsetPolygon, s.backgroundcolor); - if(ret != MS_SUCCESS) goto cleanup; + if (s.backgroundcolor) { + ret = + renderer->renderPolygon(image, offsetPolygon, s.backgroundcolor); + if (ret != MS_SUCCESS) + goto cleanup; } - if(s.scale != 1) { + if (s.scale != 1) { if (s.gap > 0) { - pw = MS_MAX(MS_NINT(s.gap),symbol->sizex * s.scale); - ph = MS_MAX(MS_NINT(s.gap),symbol->sizey * s.scale); + pw = MS_MAX(MS_NINT(s.gap), symbol->sizex * s.scale); + ph = MS_MAX(MS_NINT(s.gap), symbol->sizey * s.scale); } else { pw = MS_NINT(symbol->sizex * s.scale); ph = MS_NINT(symbol->sizey * s.scale); } } else { if (s.gap > 0) { - pw = MS_MAX(s.gap,symbol->sizex); - ph = MS_MAX(s.gap,symbol->sizey); + pw = MS_MAX(s.gap, symbol->sizex); + ph = MS_MAX(s.gap, symbol->sizey); } else { pw = symbol->sizex; ph = symbol->sizey; } } - if(pw<1) pw=1; - if(ph<1) ph=1; - - /* if we're doing vector symbols with an antialiased pixel rendererer, we want to enable - * seamless mode, i.e. comute a tile that accounts for the blending of neighbouring - * tiles at the tile border + if (pw < 1) + pw = 1; + if (ph < 1) + ph = 1; + + /* if we're doing vector symbols with an antialiased pixel rendererer, + * we want to enable seamless mode, i.e. comute a tile that accounts for + * the blending of neighbouring tiles at the tile border */ - if(symbol->type == MS_SYMBOL_VECTOR && style->gap == 0 && + if (symbol->type == MS_SYMBOL_VECTOR && style->gap == 0 && (image->format->renderer == MS_RENDER_WITH_AGG || image->format->renderer == MS_RENDER_WITH_CAIRO_RASTER)) { seamless = 1; } - tile = getTile(image,symbol,&s,pw,ph,seamless); - ret = renderer->renderPolygonTiled(image,offsetPolygon, tile); + tile = getTile(image, symbol, &s, pw, ph, seamless); + ret = renderer->renderPolygonTiled(image, offsetPolygon, tile); } -cleanup: + cleanup: if (offsetPolygon != p) { msFreeShape(offsetPolygon); msFree(offsetPolygon); } return ret; - } else if( MS_RENDERER_IMAGEMAP(image->format) ) + } else if (MS_RENDERER_IMAGEMAP(image->format)) msDrawShadeSymbolIM(map, image, p, style, scalefactor); } return ret; } -int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *style, - double scalefactor) -{ +int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, + styleObj *style, double scalefactor) { int ret = MS_SUCCESS; if (!p) return MS_SUCCESS; @@ -834,29 +905,29 @@ int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *styl return MS_SUCCESS; /* no such symbol, 0 is OK */ if (image) { - if(MS_RENDERER_PLUGIN(image->format)) { + if (MS_RENDERER_PLUGIN(image->format)) { rendererVTableObj *renderer = image->format->vtable; symbolStyleObj s; - double p_x,p_y; + double p_x, p_y; symbolObj *symbol = map->symbolset.symbol[style->symbol]; /* store a reference to the renderer to be used for freeing */ symbol->renderer = renderer; - if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) { + if (preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) { return MS_FAILURE; } - computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor); + computeSymbolStyle(&s, style, symbol, scalefactor, + image->resolutionfactor); s.style = style; if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) { - return MS_SUCCESS; // nothing to do if no color, except for pixmap symbols + return MS_SUCCESS; // nothing to do if no color, except for pixmap + // symbols } - if(s.scale == 0) { + if (s.scale == 0) { return MS_SUCCESS; } - - /* TODO: skip the drawing of the symbol if it's smaller than a pixel ? if (s.size < 1) return; // size too small @@ -865,27 +936,27 @@ int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *styl p_x = p->x; p_y = p->y; - if (style->polaroffsetpixel != 0 || - style->polaroffsetangle != 0) { + if (style->polaroffsetpixel != 0 || style->polaroffsetangle != 0) { double angle = style->polaroffsetangle * MS_DEG_TO_RAD; - p_x += (style->polaroffsetpixel * cos(-angle)) * scalefactor; - p_y += (style->polaroffsetpixel * sin(-angle)) * scalefactor; + p_x += (style->polaroffsetpixel * cos(-angle)) * scalefactor; + p_y += (style->polaroffsetpixel * sin(-angle)) * scalefactor; } - p_x += style->offsetx * scalefactor; - p_y += style->offsety * scalefactor; + p_x += style->offsetx * scalefactor; + p_y += style->offsety * scalefactor; - if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { - double sx,sy; + if (symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) { + double sx, sy; double ox, oy; - if(MS_UNLIKELY(MS_FAILURE == msGetMarkerSize(map, style, &sx, &sy, scalefactor))) { + if (MS_UNLIKELY(MS_FAILURE == + msGetMarkerSize(map, style, &sx, &sy, scalefactor))) { return MS_FAILURE; } ox = (0.5 - symbol->anchorpoint_x) * sx; oy = (0.5 - symbol->anchorpoint_y) * sy; - if(s.rotation != 0) { + if (s.rotation != 0) { double sina, cosa; - double rox,roy; + double rox, roy; sina = sin(-s.rotation); cosa = cos(-s.rotation); rox = ox * cosa - oy * sina; @@ -898,77 +969,76 @@ int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *styl } } - if(renderer->use_imagecache) { - imageObj *tile = getTile(image, symbol, &s, -1, -1,0); - if(tile!=NULL) + if (renderer->use_imagecache) { + imageObj *tile = getTile(image, symbol, &s, -1, -1, 0); + if (tile != NULL) return renderer->renderTile(image, tile, p_x, p_y); else { - msSetError(MS_RENDERERERR, "problem creating cached tile", "msDrawMarkerSymbol()"); + msSetError(MS_RENDERERERR, "problem creating cached tile", + "msDrawMarkerSymbol()"); return MS_FAILURE; } } switch (symbol->type) { - case (MS_SYMBOL_TRUETYPE): { - unsigned int unicode; - glyph_element *glyphc; - face_element *face = msGetFontFace(symbol->font, &map->fontset); - if(MS_UNLIKELY(!face)) return MS_FAILURE; - msUTF8ToUniChar(symbol->character,&unicode); - unicode = msGetGlyphIndex(face,unicode); - glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(s.scale),1), unicode); - if(MS_UNLIKELY(!glyphc)) return MS_FAILURE; - ret = drawGlyphMarker(image, face, glyphc, p_x, p_y, s.scale, s.rotation, s.color, s.outlinecolor, s.outlinewidth); - } - break; - case (MS_SYMBOL_PIXMAP): { - assert(symbol->pixmap_buffer); - ret = renderer->renderPixmapSymbol(image,p_x,p_y,symbol,&s); - } - break; - case (MS_SYMBOL_ELLIPSE): { - ret = renderer->renderEllipseSymbol(image, p_x, p_y,symbol, &s); - } - break; - case (MS_SYMBOL_VECTOR): { - ret = renderer->renderVectorSymbol(image, p_x, p_y, symbol, &s); - } - break; - case (MS_SYMBOL_SVG): { - if (renderer->supports_svg) { - ret = renderer->renderSVGSymbol(image, p_x, p_y, symbol, &s); - } else { + case (MS_SYMBOL_TRUETYPE): { + unsigned int unicode; + glyph_element *glyphc; + face_element *face = msGetFontFace(symbol->font, &map->fontset); + if (MS_UNLIKELY(!face)) + return MS_FAILURE; + msUTF8ToUniChar(symbol->character, &unicode); + unicode = msGetGlyphIndex(face, unicode); + glyphc = msGetGlyphByIndex(face, MS_MAX(MS_NINT(s.scale), 1), unicode); + if (MS_UNLIKELY(!glyphc)) + return MS_FAILURE; + ret = + drawGlyphMarker(image, face, glyphc, p_x, p_y, s.scale, s.rotation, + s.color, s.outlinecolor, s.outlinewidth); + } break; + case (MS_SYMBOL_PIXMAP): { + assert(symbol->pixmap_buffer); + ret = renderer->renderPixmapSymbol(image, p_x, p_y, symbol, &s); + } break; + case (MS_SYMBOL_ELLIPSE): { + ret = renderer->renderEllipseSymbol(image, p_x, p_y, symbol, &s); + } break; + case (MS_SYMBOL_VECTOR): { + ret = renderer->renderVectorSymbol(image, p_x, p_y, symbol, &s); + } break; + case (MS_SYMBOL_SVG): { + if (renderer->supports_svg) { + ret = renderer->renderSVGSymbol(image, p_x, p_y, symbol, &s); + } else { #if defined(USE_SVG_CAIRO) || defined(USE_RSVG) - ret = msRenderRasterizedSVGSymbol(image, p_x,p_y, symbol, &s); + ret = msRenderRasterizedSVGSymbol(image, p_x, p_y, symbol, &s); #else - msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()"); - return MS_FAILURE; + msSetError(MS_SYMERR, "SVG symbol support is not enabled.", + "msDrawMarkerSymbol()"); + return MS_FAILURE; #endif - } } + } break; + default: break; - default: - break; } return ret; - } else if( MS_RENDERER_IMAGEMAP(image->format) ) + } else if (MS_RENDERER_IMAGEMAP(image->format)) msDrawMarkerSymbolIM(map, image, p, style, scalefactor); - } return ret; } - -int msDrawLabelBounds(mapObj *map, imageObj *image, label_bounds *bnds, styleObj *style, double scalefactor) -{ +int msDrawLabelBounds(mapObj *map, imageObj *image, label_bounds *bnds, + styleObj *style, double scalefactor) { /* - * helper function to draw label bounds, where we might have only a rectObj and not - * a lineObj/shapeObj + * helper function to draw label bounds, where we might have only a rectObj + * and not a lineObj/shapeObj */ shapeObj shape; shape.numlines = 1; - if(bnds->poly) { + if (bnds->poly) { shape.line = bnds->poly; - return msDrawShadeSymbol(map,image,&shape,style,scalefactor); + return msDrawShadeSymbol(map, image, &shape, style, scalefactor); } else { pointObj pnts1[5]; lineObj l; @@ -978,34 +1048,40 @@ int msDrawLabelBounds(mapObj *map, imageObj *image, label_bounds *bnds, styleObj pnts1[2].x = pnts1[3].x = bnds->bbox.maxx; pnts1[0].y = pnts1[3].y = pnts1[4].y = bnds->bbox.miny; pnts1[1].y = pnts1[2].y = bnds->bbox.maxy; - (void)pnts1[0].x; (void)pnts1[0].y; - (void)pnts1[1].x; (void)pnts1[1].y; - (void)pnts1[2].x; (void)pnts1[2].y; - (void)pnts1[3].x; (void)pnts1[3].y; - (void)pnts1[4].x; (void)pnts1[4].y; + (void)pnts1[0].x; + (void)pnts1[0].y; + (void)pnts1[1].x; + (void)pnts1[1].y; + (void)pnts1[2].x; + (void)pnts1[2].y; + (void)pnts1[3].x; + (void)pnts1[3].y; + (void)pnts1[4].x; + (void)pnts1[4].y; shape.line = &l; // must return from this block - return msDrawShadeSymbol(map,image,&shape,style,scalefactor); + return msDrawShadeSymbol(map, image, &shape, style, scalefactor); } } -int msDrawTextSymbol(mapObj *map, imageObj *image, pointObj labelPnt, textSymbolObj *ts) -{ +int msDrawTextSymbol(mapObj *map, imageObj *image, pointObj labelPnt, + textSymbolObj *ts) { (void)map; rendererVTableObj *renderer = image->format->vtable; colorObj *c = NULL, *oc = NULL; int ow; assert(ts->textpath); - if(!renderer->renderGlyphs) return MS_FAILURE; + if (!renderer->renderGlyphs) + return MS_FAILURE; - if(!ts->textpath->absolute) { + if (!ts->textpath->absolute) { int g; - double cosa,sina; + double cosa, sina; double x = labelPnt.x; double y = labelPnt.y; - if(ts->rotation != 0) { + if (ts->rotation != 0) { cosa = cos(ts->rotation); sina = sin(ts->rotation); - for(g=0;gtextpath->numglyphs;g++) { + for (g = 0; g < ts->textpath->numglyphs; g++) { double ox = ts->textpath->glyphs[g].pnt.x; double oy = ts->textpath->glyphs[g].pnt.y; ts->textpath->glyphs[g].pnt.x = ox * cosa + oy * sina + x; @@ -1013,100 +1089,106 @@ int msDrawTextSymbol(mapObj *map, imageObj *image, pointObj labelPnt, textSymbol ts->textpath->glyphs[g].rot = ts->rotation; } } else { - for(g=0;gtextpath->numglyphs;g++) { + for (g = 0; g < ts->textpath->numglyphs; g++) { ts->textpath->glyphs[g].pnt.x += x; ts->textpath->glyphs[g].pnt.y += y; } } } - if(MS_VALID_COLOR(ts->label->shadowcolor)) { + if (MS_VALID_COLOR(ts->label->shadowcolor)) { textSymbolObj *ts_shadow; int g; double ox, oy; - double cosa,sina; + double cosa, sina; int ret; - if(ts->rotation != 0) { + if (ts->rotation != 0) { cosa = cos(ts->rotation); sina = sin(ts->rotation); - ox = ts->scalefactor * (cosa * ts->label->shadowsizex + - sina * ts->label->shadowsizey); - oy = ts->scalefactor * (-sina * ts->label->shadowsizex + - cosa * ts->label->shadowsizey); - } - else { + ox = ts->scalefactor * + (cosa * ts->label->shadowsizex + sina * ts->label->shadowsizey); + oy = ts->scalefactor * + (-sina * ts->label->shadowsizex + cosa * ts->label->shadowsizey); + } else { ox = ts->scalefactor * ts->label->shadowsizex; oy = ts->scalefactor * ts->label->shadowsizey; } ts_shadow = msSmallMalloc(sizeof(textSymbolObj)); initTextSymbol(ts_shadow); - msCopyTextSymbol(ts_shadow,ts); + msCopyTextSymbol(ts_shadow, ts); - for(g=0;gtextpath->numglyphs;g++) { + for (g = 0; g < ts_shadow->textpath->numglyphs; g++) { ts_shadow->textpath->glyphs[g].pnt.x += ox; ts_shadow->textpath->glyphs[g].pnt.y += oy; } - ret = renderer->renderGlyphs(image,ts_shadow,&ts->label->shadowcolor,NULL,0, MS_FALSE); + ret = renderer->renderGlyphs(image, ts_shadow, &ts->label->shadowcolor, + NULL, 0, MS_FALSE); freeTextSymbol(ts_shadow); msFree(ts_shadow); - if( ret != MS_SUCCESS ) + if (ret != MS_SUCCESS) return ret; } - if(MS_VALID_COLOR(ts->label->color)) + if (MS_VALID_COLOR(ts->label->color)) c = &ts->label->color; - if(MS_VALID_COLOR(ts->label->outlinecolor)) + if (MS_VALID_COLOR(ts->label->outlinecolor)) oc = &ts->label->outlinecolor; - ow = MS_NINT((double)ts->label->outlinewidth * ((double)ts->textpath->glyph_size / (double)ts->label->size)); - return renderer->renderGlyphs(image,ts,c,oc,ow, MS_FALSE); - + ow = MS_NINT((double)ts->label->outlinewidth * + ((double)ts->textpath->glyph_size / (double)ts->label->size)); + return renderer->renderGlyphs(image, ts, c, oc, ow, MS_FALSE); } /************************************************************************/ /* msCircleDrawLineSymbol */ /* */ /************************************************************************/ -int msCircleDrawLineSymbol(mapObj *map, imageObj *image, pointObj *p, double r, styleObj *style, double scalefactor) -{ +int msCircleDrawLineSymbol(mapObj *map, imageObj *image, pointObj *p, double r, + styleObj *style, double scalefactor) { shapeObj *circle; int status; - if (!image) return MS_FAILURE; + if (!image) + return MS_FAILURE; circle = msRasterizeArc(p->x, p->y, r, 0, 360, 0); - if (!circle) return MS_FAILURE; + if (!circle) + return MS_FAILURE; status = msDrawLineSymbol(map, image, circle, style, scalefactor); msFreeShape(circle); msFree(circle); return status; } -int msCircleDrawShadeSymbol(mapObj *map, imageObj *image, pointObj *p, double r, styleObj *style, double scalefactor) -{ +int msCircleDrawShadeSymbol(mapObj *map, imageObj *image, pointObj *p, double r, + styleObj *style, double scalefactor) { shapeObj *circle; int status; - if (!image) return MS_FAILURE; + if (!image) + return MS_FAILURE; circle = msRasterizeArc(p->x, p->y, r, 0, 360, 0); - if (!circle) return MS_FAILURE; + if (!circle) + return MS_FAILURE; status = msDrawShadeSymbol(map, image, circle, style, scalefactor); msFreeShape(circle); msFree(circle); return status; } -int msDrawPieSlice(mapObj *map, imageObj *image, pointObj *p, styleObj *style, double radius, double start, double end) -{ +int msDrawPieSlice(mapObj *map, imageObj *image, pointObj *p, styleObj *style, + double radius, double start, double end) { int status; shapeObj *circle; double center_x = p->x; double center_y = p->y; - if (!image) return MS_FAILURE; - if(style->offsetx>0) { - center_x+=style->offsetx*cos(((-start-end)*MS_PI/360.)); - center_y-=style->offsetx*sin(((-start-end)*MS_PI/360.)); + if (!image) + return MS_FAILURE; + if (style->offsetx > 0) { + center_x += style->offsetx * cos(((-start - end) * MS_PI / 360.)); + center_y -= style->offsetx * sin(((-start - end) * MS_PI / 360.)); } circle = msRasterizeArc(center_x, center_y, radius, start, end, 1); - if (!circle) return MS_FAILURE; + if (!circle) + return MS_FAILURE; status = msDrawShadeSymbol(map, image, circle, style, 1.0); msFreeShape(circle); msFree(circle); @@ -1122,16 +1204,19 @@ int msDrawPieSlice(mapObj *map, imageObj *image, pointObj *p, styleObj *style, d * caching mechanism */ -void msOutlineRenderingPrepareStyle(styleObj *pStyle, mapObj *map, layerObj *layer, imageObj *image) -{ +void msOutlineRenderingPrepareStyle(styleObj *pStyle, mapObj *map, + layerObj *layer, imageObj *image) { colorObj tmp; if (pStyle->outlinewidth > 0) { /* adapt width (must take scalefactor into account) */ - pStyle->width += (pStyle->outlinewidth / (layer->scalefactor/image->resolutionfactor)) * 2; + pStyle->width += (pStyle->outlinewidth / + (layer->scalefactor / image->resolutionfactor)) * + 2; pStyle->minwidth += pStyle->outlinewidth * 2; pStyle->maxwidth += pStyle->outlinewidth * 2; - pStyle->size += (pStyle->outlinewidth/layer->scalefactor*(map->resolution/map->defresolution)); + pStyle->size += (pStyle->outlinewidth / layer->scalefactor * + (map->resolution / map->defresolution)); /*swap color and outlinecolor*/ tmp = pStyle->color; @@ -1146,16 +1231,19 @@ void msOutlineRenderingPrepareStyle(styleObj *pStyle, mapObj *map, layerObj *lay * second pass of the caching mechanism */ -void msOutlineRenderingRestoreStyle(styleObj *pStyle, mapObj *map, layerObj *layer, imageObj *image) -{ +void msOutlineRenderingRestoreStyle(styleObj *pStyle, mapObj *map, + layerObj *layer, imageObj *image) { colorObj tmp; if (pStyle->outlinewidth > 0) { /* reset widths to original state */ - pStyle->width -= (pStyle->outlinewidth / (layer->scalefactor/image->resolutionfactor)) * 2; + pStyle->width -= (pStyle->outlinewidth / + (layer->scalefactor / image->resolutionfactor)) * + 2; pStyle->minwidth -= pStyle->outlinewidth * 2; pStyle->maxwidth -= pStyle->outlinewidth * 2; - pStyle->size -= (pStyle->outlinewidth/layer->scalefactor*(map->resolution/map->defresolution)); + pStyle->size -= (pStyle->outlinewidth / layer->scalefactor * + (map->resolution / map->defresolution)); /*reswap colors to original state*/ tmp = pStyle->color; diff --git a/mapresample.c b/mapresample.c index d0dfb9cf77..c3fd1210c6 100644 --- a/mapresample.c +++ b/mapresample.c @@ -31,9 +31,9 @@ #include "mapresample.h" #include "mapthread.h" - - -#define SKIP_MASK(x,y) (mask_rb && !*(mask_rb->data.rgba.a+(y)*mask_rb->data.rgba.row_step+(x)*mask_rb->data.rgba.pixel_step)) +#define SKIP_MASK(x, y) \ + (mask_rb && !*(mask_rb->data.rgba.a + (y)*mask_rb->data.rgba.row_step + \ + (x)*mask_rb->data.rgba.pixel_step)) /************************************************************************/ /* InvGeoTransform() */ @@ -42,10 +42,10 @@ /* implicit [1 0 0] final row. */ /************************************************************************/ -int InvGeoTransform( double *gt_in, double *gt_out ) +int InvGeoTransform(double *gt_in, double *gt_out) { - double det, inv_det; + double det, inv_det; /* we assume a 3rd row that is [1 0 0] */ @@ -53,20 +53,20 @@ int InvGeoTransform( double *gt_in, double *gt_out ) det = gt_in[1] * gt_in[5] - gt_in[2] * gt_in[4]; - if( fabs(det) < 0.000000000000001 ) + if (fabs(det) < 0.000000000000001) return 0; inv_det = 1.0 / det; /* compute adjoint, and devide by determinate */ - gt_out[1] = gt_in[5] * inv_det; + gt_out[1] = gt_in[5] * inv_det; gt_out[4] = -gt_in[4] * inv_det; gt_out[2] = -gt_in[2] * inv_det; - gt_out[5] = gt_in[1] * inv_det; + gt_out[5] = gt_in[1] * inv_det; - gt_out[0] = ( gt_in[2] * gt_in[3] - gt_in[0] * gt_in[5]) * inv_det; + gt_out[0] = (gt_in[2] * gt_in[3] - gt_in[0] * gt_in[5]) * inv_det; gt_out[3] = (-gt_in[1] * gt_in[3] + gt_in[0] * gt_in[4]) * inv_det; return 1; @@ -76,133 +76,121 @@ int InvGeoTransform( double *gt_in, double *gt_out ) /* msNearestRasterResample() */ /************************************************************************/ -static int -msNearestRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, - imageObj *psDstImage, rasterBufferObj *dst_rb, - SimpleTransformer pfnTransform, void *pCBData, - int debug, rasterBufferObj *mask_rb, - int bWrapAtLeftRight ) +static int msNearestRasterResampler( + imageObj *psSrcImage, rasterBufferObj *src_rb, imageObj *psDstImage, + rasterBufferObj *dst_rb, SimpleTransformer pfnTransform, void *pCBData, + int debug, rasterBufferObj *mask_rb, int bWrapAtLeftRight) { - double *x, *y; - int nDstX, nDstY; - int *panSuccess; - int nDstXSize = psDstImage->width; - int nDstYSize = psDstImage->height; - int nSrcXSize = psSrcImage->width; - int nSrcYSize = psSrcImage->height; - int nFailedPoints = 0, nSetPoints = 0; - assert(!MS_RENDERER_PLUGIN(psSrcImage->format) || src_rb->type == MS_BUFFER_BYTE_RGBA); - - - x = (double *) msSmallMalloc( sizeof(double) * nDstXSize ); - y = (double *) msSmallMalloc( sizeof(double) * nDstXSize ); - panSuccess = (int *) msSmallMalloc( sizeof(int) * nDstXSize ); - - for( nDstY = 0; nDstY < nDstYSize; nDstY++ ) { - for( nDstX = 0; nDstX < nDstXSize; nDstX++ ) { + double *x, *y; + int nDstX, nDstY; + int *panSuccess; + int nDstXSize = psDstImage->width; + int nDstYSize = psDstImage->height; + int nSrcXSize = psSrcImage->width; + int nSrcYSize = psSrcImage->height; + int nFailedPoints = 0, nSetPoints = 0; + assert(!MS_RENDERER_PLUGIN(psSrcImage->format) || + src_rb->type == MS_BUFFER_BYTE_RGBA); + + x = (double *)msSmallMalloc(sizeof(double) * nDstXSize); + y = (double *)msSmallMalloc(sizeof(double) * nDstXSize); + panSuccess = (int *)msSmallMalloc(sizeof(int) * nDstXSize); + + for (nDstY = 0; nDstY < nDstYSize; nDstY++) { + for (nDstX = 0; nDstX < nDstXSize; nDstX++) { x[nDstX] = nDstX + 0.5; y[nDstX] = nDstY + 0.5; } - pfnTransform( pCBData, nDstXSize, x, y, panSuccess ); + pfnTransform(pCBData, nDstXSize, x, y, panSuccess); - for( nDstX = 0; nDstX < nDstXSize; nDstX++ ) { - int nSrcX, nSrcY; - if(SKIP_MASK(nDstX,nDstY)) + for (nDstX = 0; nDstX < nDstXSize; nDstX++) { + int nSrcX, nSrcY; + if (SKIP_MASK(nDstX, nDstY)) continue; - if( !panSuccess[nDstX] ) { + if (!panSuccess[nDstX]) { nFailedPoints++; continue; } - nSrcX = (int) x[nDstX]; - nSrcY = (int) y[nDstX]; + nSrcX = (int)x[nDstX]; + nSrcY = (int)y[nDstX]; - if( bWrapAtLeftRight && nSrcX >= nSrcXSize && nSrcX < 2 * nSrcXSize ) - nSrcX -= nSrcXSize; + if (bWrapAtLeftRight && nSrcX >= nSrcXSize && nSrcX < 2 * nSrcXSize) + nSrcX -= nSrcXSize; /* * We test the original floating point values to * avoid errors related to asymmetric rounding around zero. * (Also note bug #3120 regarding nearly redundent x/y < 0 checks). */ - if( x[nDstX] < 0.0 || y[nDstX] < 0.0 - || nSrcX < 0 || nSrcY < 0 - || nSrcX >= nSrcXSize || nSrcY >= nSrcYSize ) { + if (x[nDstX] < 0.0 || y[nDstX] < 0.0 || nSrcX < 0 || nSrcY < 0 || + nSrcX >= nSrcXSize || nSrcY >= nSrcYSize) { continue; } - if( MS_RENDERER_PLUGIN(psSrcImage->format) ) { + if (MS_RENDERER_PLUGIN(psSrcImage->format)) { int src_rb_off; - rgbaArrayObj *src,*dst; - assert( src_rb && dst_rb ); - assert( src_rb->type == MS_BUFFER_BYTE_RGBA ); + rgbaArrayObj *src, *dst; + assert(src_rb && dst_rb); + assert(src_rb->type == MS_BUFFER_BYTE_RGBA); src = &src_rb->data.rgba; dst = &dst_rb->data.rgba; - src_rb_off = nSrcX * src->pixel_step - + nSrcY * src->row_step; + src_rb_off = nSrcX * src->pixel_step + nSrcY * src->row_step; - if( src->a == NULL || src->a[src_rb_off] == 255 ) { + if (src->a == NULL || src->a[src_rb_off] == 255) { int dst_rb_off; - dst_rb_off = nDstX * dst->pixel_step - + nDstY * dst->row_step; + dst_rb_off = nDstX * dst->pixel_step + nDstY * dst->row_step; nSetPoints++; dst->r[dst_rb_off] = src->r[src_rb_off]; dst->g[dst_rb_off] = src->g[src_rb_off]; dst->b[dst_rb_off] = src->b[src_rb_off]; - if( dst->a ) + if (dst->a) dst->a[dst_rb_off] = 255; - } else if( src->a[src_rb_off] != 0 ) { + } else if (src->a[src_rb_off] != 0) { int dst_rb_off; - dst_rb_off = nDstX * dst->pixel_step - + nDstY * dst->row_step; + dst_rb_off = nDstX * dst->pixel_step + nDstY * dst->row_step; nSetPoints++; /* actual alpha blending is required */ - msAlphaBlendPM( src->r[src_rb_off], - src->g[src_rb_off], - src->b[src_rb_off], - src->a[src_rb_off], - dst->r + dst_rb_off, - dst->g + dst_rb_off, - dst->b + dst_rb_off, - dst->a ? dst->a + dst_rb_off : NULL ); - + msAlphaBlendPM( + src->r[src_rb_off], src->g[src_rb_off], src->b[src_rb_off], + src->a[src_rb_off], dst->r + dst_rb_off, dst->g + dst_rb_off, + dst->b + dst_rb_off, dst->a ? dst->a + dst_rb_off : NULL); } - } else if( MS_RENDERER_RAWDATA(psSrcImage->format) ) { + } else if (MS_RENDERER_RAWDATA(psSrcImage->format)) { int band, src_off, dst_off; src_off = nSrcX + nSrcY * psSrcImage->width; - if( !MS_GET_BIT(psSrcImage->img_mask,src_off) ) + if (!MS_GET_BIT(psSrcImage->img_mask, src_off)) continue; nSetPoints++; dst_off = nDstX + nDstY * psDstImage->width; - MS_SET_BIT(psDstImage->img_mask,dst_off); - - for( band = 0; band < psSrcImage->format->bands; band++ ) { - if( psSrcImage->format->imagemode == MS_IMAGEMODE_INT16 ) { - psDstImage->img.raw_16bit[dst_off] - = psSrcImage->img.raw_16bit[src_off]; - } else if( psSrcImage->format->imagemode - == MS_IMAGEMODE_FLOAT32) { - psDstImage->img.raw_float[dst_off] - = psSrcImage->img.raw_float[src_off]; - } else if(psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { - psDstImage->img.raw_byte[dst_off] - = psSrcImage->img.raw_byte[src_off]; + MS_SET_BIT(psDstImage->img_mask, dst_off); + + for (band = 0; band < psSrcImage->format->bands; band++) { + if (psSrcImage->format->imagemode == MS_IMAGEMODE_INT16) { + psDstImage->img.raw_16bit[dst_off] = + psSrcImage->img.raw_16bit[src_off]; + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { + psDstImage->img.raw_float[dst_off] = + psSrcImage->img.raw_float[src_off]; + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { + psDstImage->img.raw_byte[dst_off] = + psSrcImage->img.raw_byte[src_off]; } else { - assert( 0 ); + assert(0); } src_off += psSrcImage->width * psSrcImage->height; dst_off += psDstImage->width * psDstImage->height; @@ -211,17 +199,17 @@ msNearestRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, } } - free( panSuccess ); - free( x ); - free( y ); + free(panSuccess); + free(x); + free(y); /* -------------------------------------------------------------------- */ /* Some debugging output. */ /* -------------------------------------------------------------------- */ - if( nFailedPoints > 0 && debug ) { - msDebug( "msNearestRasterResampler: " - "%d failed to transform, %d actually set.\n", - nFailedPoints, nSetPoints ); + if (nFailedPoints > 0 && debug) { + msDebug("msNearestRasterResampler: " + "%d failed to transform, %d actually set.\n", + nFailedPoints, nSetPoints); } return 0; @@ -231,59 +219,58 @@ msNearestRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, /* msSourceSample() */ /************************************************************************/ -static void msSourceSample( imageObj *psSrcImage, rasterBufferObj *rb, - int iSrcX, int iSrcY, double *padfPixelSum, - double dfWeight, double *pdfWeightSum ) +static void msSourceSample(imageObj *psSrcImage, rasterBufferObj *rb, int iSrcX, + int iSrcY, double *padfPixelSum, double dfWeight, + double *pdfWeightSum) { - if( MS_RENDERER_PLUGIN(psSrcImage->format) ) { + if (MS_RENDERER_PLUGIN(psSrcImage->format)) { rgbaArrayObj *rgba; int rb_off; assert(rb && rb->type == MS_BUFFER_BYTE_RGBA); rgba = &(rb->data.rgba); rb_off = iSrcX * rgba->pixel_step + iSrcY * rgba->row_step; - if( rgba->a == NULL || rgba->a[rb_off] > 1 ) { + if (rgba->a == NULL || rgba->a[rb_off] > 1) { padfPixelSum[0] += rgba->r[rb_off] * dfWeight; padfPixelSum[1] += rgba->g[rb_off] * dfWeight; padfPixelSum[2] += rgba->b[rb_off] * dfWeight; - if( rgba->a == NULL ) + if (rgba->a == NULL) *pdfWeightSum += dfWeight; else *pdfWeightSum += dfWeight * (rgba->a[rb_off] / 255.0); } - } else if( MS_RENDERER_RAWDATA(psSrcImage->format) ) { + } else if (MS_RENDERER_RAWDATA(psSrcImage->format)) { int band; int src_off; src_off = iSrcX + iSrcY * psSrcImage->width; - if( !MS_GET_BIT(psSrcImage->img_mask,src_off) ) + if (!MS_GET_BIT(psSrcImage->img_mask, src_off)) return; - for( band = 0; band < psSrcImage->format->bands; band++ ) { - if( psSrcImage->format->imagemode == MS_IMAGEMODE_INT16 ) { + for (band = 0; band < psSrcImage->format->bands; band++) { + if (psSrcImage->format->imagemode == MS_IMAGEMODE_INT16) { int nValue; nValue = psSrcImage->img.raw_16bit[src_off]; padfPixelSum[band] += dfWeight * nValue; - } else if( psSrcImage->format->imagemode - == MS_IMAGEMODE_FLOAT32) { + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { float fValue; fValue = psSrcImage->img.raw_float[src_off]; padfPixelSum[band] += fValue * dfWeight; - } else if(psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { int nValue; nValue = psSrcImage->img.raw_byte[src_off]; padfPixelSum[band] += nValue * dfWeight; } else { - assert( 0 ); + assert(0); return; } @@ -297,56 +284,53 @@ static void msSourceSample( imageObj *psSrcImage, rasterBufferObj *rb, /* msBilinearRasterResample() */ /************************************************************************/ -static int -msBilinearRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, - imageObj *psDstImage, rasterBufferObj *dst_rb, - SimpleTransformer pfnTransform, void *pCBData, - int debug, rasterBufferObj *mask_rb, - int bWrapAtLeftRight ) +static int msBilinearRasterResampler( + imageObj *psSrcImage, rasterBufferObj *src_rb, imageObj *psDstImage, + rasterBufferObj *dst_rb, SimpleTransformer pfnTransform, void *pCBData, + int debug, rasterBufferObj *mask_rb, int bWrapAtLeftRight) { - double *x, *y; - int nDstX, nDstY, i; - int *panSuccess; - int nDstXSize = psDstImage->width; - int nDstYSize = psDstImage->height; - int nSrcXSize = psSrcImage->width; - int nSrcYSize = psSrcImage->height; - int nFailedPoints = 0, nSetPoints = 0; - double *padfPixelSum; - int bandCount = MS_MAX(4,psSrcImage->format->bands); - - padfPixelSum = (double *) msSmallMalloc(sizeof(double) * bandCount); - - - - x = (double *) msSmallMalloc( sizeof(double) * nDstXSize ); - y = (double *) msSmallMalloc( sizeof(double) * nDstXSize ); - panSuccess = (int *) msSmallMalloc( sizeof(int) * nDstXSize ); - - for( nDstY = 0; nDstY < nDstYSize; nDstY++ ) { - for( nDstX = 0; nDstX < nDstXSize; nDstX++ ) { + double *x, *y; + int nDstX, nDstY, i; + int *panSuccess; + int nDstXSize = psDstImage->width; + int nDstYSize = psDstImage->height; + int nSrcXSize = psSrcImage->width; + int nSrcYSize = psSrcImage->height; + int nFailedPoints = 0, nSetPoints = 0; + double *padfPixelSum; + int bandCount = MS_MAX(4, psSrcImage->format->bands); + + padfPixelSum = (double *)msSmallMalloc(sizeof(double) * bandCount); + + x = (double *)msSmallMalloc(sizeof(double) * nDstXSize); + y = (double *)msSmallMalloc(sizeof(double) * nDstXSize); + panSuccess = (int *)msSmallMalloc(sizeof(int) * nDstXSize); + + for (nDstY = 0; nDstY < nDstYSize; nDstY++) { + for (nDstX = 0; nDstX < nDstXSize; nDstX++) { x[nDstX] = nDstX + 0.5; y[nDstX] = nDstY + 0.5; } - pfnTransform( pCBData, nDstXSize, x, y, panSuccess ); + pfnTransform(pCBData, nDstXSize, x, y, panSuccess); - for( nDstX = 0; nDstX < nDstXSize; nDstX++ ) { - int nSrcX, nSrcY, nSrcX2, nSrcY2; - double dfRatioX2, dfRatioY2, dfWeightSum = 0.0; - if(SKIP_MASK(nDstX,nDstY)) continue; + for (nDstX = 0; nDstX < nDstXSize; nDstX++) { + int nSrcX, nSrcY, nSrcX2, nSrcY2; + double dfRatioX2, dfRatioY2, dfWeightSum = 0.0; + if (SKIP_MASK(nDstX, nDstY)) + continue; - if( !panSuccess[nDstX] ) { + if (!panSuccess[nDstX]) { nFailedPoints++; continue; } /* If we are right off the source, skip this pixel */ - nSrcX = (int) floor(x[nDstX]); - nSrcY = (int) floor(y[nDstX]); - if( nSrcX < 0 || (!bWrapAtLeftRight && nSrcX >= nSrcXSize) - || nSrcY < 0 || nSrcY >= nSrcYSize ) + nSrcX = (int)floor(x[nDstX]); + nSrcY = (int)floor(y[nDstX]); + if (nSrcX < 0 || (!bWrapAtLeftRight && nSrcX >= nSrcXSize) || nSrcY < 0 || + nSrcY >= nSrcYSize) continue; /* @@ -356,106 +340,102 @@ msBilinearRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, x[nDstX] -= 0.5; y[nDstX] -= 0.5; - nSrcX = (int) floor(x[nDstX]); - nSrcY = (int) floor(y[nDstX]); + nSrcX = (int)floor(x[nDstX]); + nSrcY = (int)floor(y[nDstX]); - nSrcX2 = nSrcX+1; - nSrcY2 = nSrcY+1; + nSrcX2 = nSrcX + 1; + nSrcY2 = nSrcY + 1; dfRatioX2 = x[nDstX] - nSrcX; dfRatioY2 = y[nDstX] - nSrcY; /* Trim in stuff one pixel off the edge */ - nSrcX = MS_MAX(nSrcX,0); - nSrcY = MS_MAX(nSrcY,0); - if( !bWrapAtLeftRight ) - nSrcX2 = MS_MIN(nSrcX2,nSrcXSize-1); - nSrcY2 = MS_MIN(nSrcY2,nSrcYSize-1); + nSrcX = MS_MAX(nSrcX, 0); + nSrcY = MS_MAX(nSrcY, 0); + if (!bWrapAtLeftRight) + nSrcX2 = MS_MIN(nSrcX2, nSrcXSize - 1); + nSrcY2 = MS_MIN(nSrcY2, nSrcYSize - 1); - memset( padfPixelSum, 0, sizeof(double) * bandCount); + memset(padfPixelSum, 0, sizeof(double) * bandCount); - msSourceSample( psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY, padfPixelSum, - (1.0 - dfRatioX2) * (1.0 - dfRatioY2), - &dfWeightSum ); + msSourceSample(psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY, padfPixelSum, + (1.0 - dfRatioX2) * (1.0 - dfRatioY2), &dfWeightSum); - msSourceSample( psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY, padfPixelSum, - (dfRatioX2) * (1.0 - dfRatioY2), - &dfWeightSum ); + msSourceSample(psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY, + padfPixelSum, (dfRatioX2) * (1.0 - dfRatioY2), + &dfWeightSum); - msSourceSample( psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY2, padfPixelSum, - (1.0 - dfRatioX2) * (dfRatioY2), - &dfWeightSum ); + msSourceSample(psSrcImage, src_rb, nSrcX % nSrcXSize, nSrcY2, + padfPixelSum, (1.0 - dfRatioX2) * (dfRatioY2), + &dfWeightSum); - msSourceSample( psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY2, padfPixelSum, - (dfRatioX2) * (dfRatioY2), - &dfWeightSum ); + msSourceSample(psSrcImage, src_rb, nSrcX2 % nSrcXSize, nSrcY2, + padfPixelSum, (dfRatioX2) * (dfRatioY2), &dfWeightSum); - if( dfWeightSum == 0.0 ) + if (dfWeightSum == 0.0) continue; - if( MS_RENDERER_PLUGIN(psSrcImage->format) ) { + if (MS_RENDERER_PLUGIN(psSrcImage->format)) { assert(src_rb && dst_rb); - assert( src_rb->type == MS_BUFFER_BYTE_RGBA ); - assert( src_rb->type == dst_rb->type ); - + assert(src_rb->type == MS_BUFFER_BYTE_RGBA); + assert(src_rb->type == dst_rb->type); nSetPoints++; - if( dfWeightSum > 0.001 ) { - int dst_rb_off = nDstX * dst_rb->data.rgba.pixel_step + nDstY * dst_rb->data.rgba.row_step; + if (dfWeightSum > 0.001) { + int dst_rb_off = nDstX * dst_rb->data.rgba.pixel_step + + nDstY * dst_rb->data.rgba.row_step; unsigned char red, green, blue, alpha; - red = (unsigned char) MS_MAX(0,MS_MIN(255,padfPixelSum[0])); - green = (unsigned char) MS_MAX(0,MS_MIN(255,padfPixelSum[1])); - blue = (unsigned char) MS_MAX(0,MS_MIN(255,padfPixelSum[2])); - alpha = (unsigned char)MS_MAX(0,MS_MIN(255,255.5*dfWeightSum)); - - msAlphaBlendPM( red, green, blue, alpha, - dst_rb->data.rgba.r + dst_rb_off, - dst_rb->data.rgba.g + dst_rb_off, - dst_rb->data.rgba.b + dst_rb_off, - (dst_rb->data.rgba.a == NULL) ? NULL : dst_rb->data.rgba.a + dst_rb_off ); + red = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[0])); + green = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[1])); + blue = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[2])); + alpha = (unsigned char)MS_MAX(0, MS_MIN(255, 255.5 * dfWeightSum)); + + msAlphaBlendPM( + red, green, blue, alpha, dst_rb->data.rgba.r + dst_rb_off, + dst_rb->data.rgba.g + dst_rb_off, + dst_rb->data.rgba.b + dst_rb_off, + (dst_rb->data.rgba.a == NULL) ? NULL + : dst_rb->data.rgba.a + dst_rb_off); } - } else if( MS_RENDERER_RAWDATA(psSrcImage->format) ) { + } else if (MS_RENDERER_RAWDATA(psSrcImage->format)) { int band; int dst_off = nDstX + nDstY * psDstImage->width; - for( i = 0; i < bandCount; i++ ) - padfPixelSum[i] /= dfWeightSum; - - MS_SET_BIT(psDstImage->img_mask,dst_off); - - for( band = 0; band < psSrcImage->format->bands; band++ ) { - if( psSrcImage->format->imagemode == MS_IMAGEMODE_INT16 ) { - psDstImage->img.raw_16bit[dst_off] - = (short) padfPixelSum[band]; - } else if( psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { - psDstImage->img.raw_float[dst_off] - = (float) padfPixelSum[band]; - } else if( psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE ) { - psDstImage->img.raw_byte[dst_off] - = (unsigned char)MS_MAX(0,MS_MIN(255,padfPixelSum[band])); + for (i = 0; i < bandCount; i++) + padfPixelSum[i] /= dfWeightSum; + + MS_SET_BIT(psDstImage->img_mask, dst_off); + + for (band = 0; band < psSrcImage->format->bands; band++) { + if (psSrcImage->format->imagemode == MS_IMAGEMODE_INT16) { + psDstImage->img.raw_16bit[dst_off] = (short)padfPixelSum[band]; + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { + psDstImage->img.raw_float[dst_off] = (float)padfPixelSum[band]; + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { + psDstImage->img.raw_byte[dst_off] = + (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[band])); } - dst_off += psDstImage->width*psDstImage->height; + dst_off += psDstImage->width * psDstImage->height; } } } } - free( padfPixelSum ); - free( panSuccess ); - free( x ); - free( y ); + free(padfPixelSum); + free(panSuccess); + free(x); + free(y); /* -------------------------------------------------------------------- */ /* Some debugging output. */ /* -------------------------------------------------------------------- */ - if( nFailedPoints > 0 && debug ) - { - msDebug( "msBilinearRasterResampler: " - "%d failed to transform, %d actually set.\n", - nFailedPoints, nSetPoints ); + if (nFailedPoints > 0 && debug) { + msDebug("msBilinearRasterResampler: " + "%d failed to transform, %d actually set.\n", + nFailedPoints, nSetPoints); } return 0; @@ -465,48 +445,47 @@ msBilinearRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, /* msAverageSample() */ /************************************************************************/ -static int -msAverageSample( imageObj *psSrcImage, rasterBufferObj *src_rb, - double dfXMin, double dfYMin, double dfXMax, double dfYMax, - double *padfPixelSum, - double *pdfAlpha01 ) +static int msAverageSample(imageObj *psSrcImage, rasterBufferObj *src_rb, + double dfXMin, double dfYMin, double dfXMax, + double dfYMax, double *padfPixelSum, + double *pdfAlpha01) { int nXMin, nXMax, nYMin, nYMax, iX, iY; double dfWeightSum = 0.0; double dfMaxWeight = 0.0; - nXMin = (int) dfXMin; - nYMin = (int) dfYMin; - nXMax = (int) ceil(dfXMax); - nYMax = (int) ceil(dfYMax); + nXMin = (int)dfXMin; + nYMin = (int)dfYMin; + nXMax = (int)ceil(dfXMax); + nYMax = (int)ceil(dfYMax); *pdfAlpha01 = 0.0; - for( iY = nYMin; iY < nYMax; iY++ ) { + for (iY = nYMin; iY < nYMax; iY++) { double dfYCellMin, dfYCellMax; - dfYCellMin = MS_MAX(iY,dfYMin); - dfYCellMax = MS_MIN(iY+1,dfYMax); + dfYCellMin = MS_MAX(iY, dfYMin); + dfYCellMax = MS_MIN(iY + 1, dfYMax); - for( iX = nXMin; iX < nXMax; iX++ ) { + for (iX = nXMin; iX < nXMax; iX++) { double dfXCellMin, dfXCellMax, dfWeight; - dfXCellMin = MS_MAX(iX,dfXMin); - dfXCellMax = MS_MIN(iX+1,dfXMax); + dfXCellMin = MS_MAX(iX, dfXMin); + dfXCellMax = MS_MIN(iX + 1, dfXMax); - dfWeight = (dfXCellMax-dfXCellMin) * (dfYCellMax-dfYCellMin); + dfWeight = (dfXCellMax - dfXCellMin) * (dfYCellMax - dfYCellMin); - msSourceSample( psSrcImage, src_rb, iX, iY, padfPixelSum, - dfWeight, &dfWeightSum ); + msSourceSample(psSrcImage, src_rb, iX, iY, padfPixelSum, dfWeight, + &dfWeightSum); dfMaxWeight += dfWeight; } } - if( dfWeightSum == 0.0 ) + if (dfWeightSum == 0.0) return MS_FALSE; - for( iX = 0; iX < 4; iX++ ) + for (iX = 0; iX < 4; iX++) padfPixelSum[iX] /= dfWeightSum; *pdfAlpha01 = dfWeightSum / dfMaxWeight; @@ -519,115 +498,107 @@ msAverageSample( imageObj *psSrcImage, rasterBufferObj *src_rb, /************************************************************************/ static int -msAverageRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, - imageObj *psDstImage, rasterBufferObj *dst_rb, - SimpleTransformer pfnTransform, void *pCBData, - int debug, rasterBufferObj *mask_rb ) +msAverageRasterResampler(imageObj *psSrcImage, rasterBufferObj *src_rb, + imageObj *psDstImage, rasterBufferObj *dst_rb, + SimpleTransformer pfnTransform, void *pCBData, + int debug, rasterBufferObj *mask_rb) { - double *x1, *y1, *x2, *y2; - int nDstX, nDstY; - int *panSuccess1, *panSuccess2; - int nDstXSize = psDstImage->width; - int nDstYSize = psDstImage->height; - int nFailedPoints = 0, nSetPoints = 0; - double *padfPixelSum; - - int bandCount = MS_MAX(4,psSrcImage->format->bands); - - padfPixelSum = (double *) msSmallMalloc(sizeof(double) * bandCount); - - - - x1 = (double *) msSmallMalloc( sizeof(double) * (nDstXSize+1) ); - y1 = (double *) msSmallMalloc( sizeof(double) * (nDstXSize+1) ); - x2 = (double *) msSmallMalloc( sizeof(double) * (nDstXSize+1) ); - y2 = (double *) msSmallMalloc( sizeof(double) * (nDstXSize+1) ); - panSuccess1 = (int *) msSmallMalloc( sizeof(int) * (nDstXSize+1) ); - panSuccess2 = (int *) msSmallMalloc( sizeof(int) * (nDstXSize+1) ); - - for( nDstY = 0; nDstY < nDstYSize; nDstY++ ) { - for( nDstX = 0; nDstX <= nDstXSize; nDstX++ ) { + double *x1, *y1, *x2, *y2; + int nDstX, nDstY; + int *panSuccess1, *panSuccess2; + int nDstXSize = psDstImage->width; + int nDstYSize = psDstImage->height; + int nFailedPoints = 0, nSetPoints = 0; + double *padfPixelSum; + + int bandCount = MS_MAX(4, psSrcImage->format->bands); + + padfPixelSum = (double *)msSmallMalloc(sizeof(double) * bandCount); + + x1 = (double *)msSmallMalloc(sizeof(double) * (nDstXSize + 1)); + y1 = (double *)msSmallMalloc(sizeof(double) * (nDstXSize + 1)); + x2 = (double *)msSmallMalloc(sizeof(double) * (nDstXSize + 1)); + y2 = (double *)msSmallMalloc(sizeof(double) * (nDstXSize + 1)); + panSuccess1 = (int *)msSmallMalloc(sizeof(int) * (nDstXSize + 1)); + panSuccess2 = (int *)msSmallMalloc(sizeof(int) * (nDstXSize + 1)); + + for (nDstY = 0; nDstY < nDstYSize; nDstY++) { + for (nDstX = 0; nDstX <= nDstXSize; nDstX++) { x1[nDstX] = nDstX; y1[nDstX] = nDstY; x2[nDstX] = nDstX; - y2[nDstX] = nDstY+1; + y2[nDstX] = nDstY + 1; } - pfnTransform( pCBData, nDstXSize+1, x1, y1, panSuccess1 ); - pfnTransform( pCBData, nDstXSize+1, x2, y2, panSuccess2 ); + pfnTransform(pCBData, nDstXSize + 1, x1, y1, panSuccess1); + pfnTransform(pCBData, nDstXSize + 1, x2, y2, panSuccess2); - for( nDstX = 0; nDstX < nDstXSize; nDstX++ ) { - double dfXMin, dfYMin, dfXMax, dfYMax; - double dfAlpha01; - if(SKIP_MASK(nDstX,nDstY)) continue; + for (nDstX = 0; nDstX < nDstXSize; nDstX++) { + double dfXMin, dfYMin, dfXMax, dfYMax; + double dfAlpha01; + if (SKIP_MASK(nDstX, nDstY)) + continue; /* Do not generate a pixel unless all four corners transformed */ - if( !panSuccess1[nDstX] || !panSuccess1[nDstX+1] - || !panSuccess2[nDstX] || !panSuccess2[nDstX+1] ) { + if (!panSuccess1[nDstX] || !panSuccess1[nDstX + 1] || + !panSuccess2[nDstX] || !panSuccess2[nDstX + 1]) { nFailedPoints++; continue; } - dfXMin = MS_MIN(MS_MIN(x1[nDstX],x1[nDstX+1]), - MS_MIN(x2[nDstX],x2[nDstX+1])); - dfYMin = MS_MIN(MS_MIN(y1[nDstX],y1[nDstX+1]), - MS_MIN(y2[nDstX],y2[nDstX+1])); - dfXMax = MS_MAX(MS_MAX(x1[nDstX],x1[nDstX+1]), - MS_MAX(x2[nDstX],x2[nDstX+1])); - dfYMax = MS_MAX(MS_MAX(y1[nDstX],y1[nDstX+1]), - MS_MAX(y2[nDstX],y2[nDstX+1])); - - dfXMin = MS_MIN(MS_MAX(dfXMin,0),psSrcImage->width+1); - dfYMin = MS_MIN(MS_MAX(dfYMin,0),psSrcImage->height+1); - dfXMax = MS_MIN(MS_MAX(-1,dfXMax),psSrcImage->width); - dfYMax = MS_MIN(MS_MAX(-1,dfYMax),psSrcImage->height); - - memset( padfPixelSum, 0, sizeof(double)*bandCount ); - - if( !msAverageSample( psSrcImage, src_rb, - dfXMin, dfYMin, dfXMax, dfYMax, - padfPixelSum, &dfAlpha01 ) ) + dfXMin = MS_MIN(MS_MIN(x1[nDstX], x1[nDstX + 1]), + MS_MIN(x2[nDstX], x2[nDstX + 1])); + dfYMin = MS_MIN(MS_MIN(y1[nDstX], y1[nDstX + 1]), + MS_MIN(y2[nDstX], y2[nDstX + 1])); + dfXMax = MS_MAX(MS_MAX(x1[nDstX], x1[nDstX + 1]), + MS_MAX(x2[nDstX], x2[nDstX + 1])); + dfYMax = MS_MAX(MS_MAX(y1[nDstX], y1[nDstX + 1]), + MS_MAX(y2[nDstX], y2[nDstX + 1])); + + dfXMin = MS_MIN(MS_MAX(dfXMin, 0), psSrcImage->width + 1); + dfYMin = MS_MIN(MS_MAX(dfYMin, 0), psSrcImage->height + 1); + dfXMax = MS_MIN(MS_MAX(-1, dfXMax), psSrcImage->width); + dfYMax = MS_MIN(MS_MAX(-1, dfYMax), psSrcImage->height); + + memset(padfPixelSum, 0, sizeof(double) * bandCount); + + if (!msAverageSample(psSrcImage, src_rb, dfXMin, dfYMin, dfXMax, dfYMax, + padfPixelSum, &dfAlpha01)) continue; - if( MS_RENDERER_PLUGIN(psSrcImage->format) ) { + if (MS_RENDERER_PLUGIN(psSrcImage->format)) { assert(dst_rb && src_rb); - assert( dst_rb->type == MS_BUFFER_BYTE_RGBA ); - assert( src_rb->type == dst_rb ->type ); + assert(dst_rb->type == MS_BUFFER_BYTE_RGBA); + assert(src_rb->type == dst_rb->type); nSetPoints++; - if( dfAlpha01 > 0 ) { + if (dfAlpha01 > 0) { unsigned char red, green, blue, alpha; - red = (unsigned char) - MS_MAX(0,MS_MIN(255,padfPixelSum[0]+0.5)); - green = (unsigned char) - MS_MAX(0,MS_MIN(255,padfPixelSum[1]+0.5)); - blue = (unsigned char) - MS_MAX(0,MS_MIN(255,padfPixelSum[2]+0.5)); - alpha = (unsigned char) - MS_MAX(0,MS_MIN(255,255*dfAlpha01+0.5)); - - RB_MIX_PIXEL(dst_rb,nDstX,nDstY, - red, green, blue, alpha ); + red = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[0] + 0.5)); + green = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[1] + 0.5)); + blue = (unsigned char)MS_MAX(0, MS_MIN(255, padfPixelSum[2] + 0.5)); + alpha = (unsigned char)MS_MAX(0, MS_MIN(255, 255 * dfAlpha01 + 0.5)); + + RB_MIX_PIXEL(dst_rb, nDstX, nDstY, red, green, blue, alpha); } - } else if( MS_RENDERER_RAWDATA(psSrcImage->format) ) { + } else if (MS_RENDERER_RAWDATA(psSrcImage->format)) { int band; int dst_off = nDstX + nDstY * psDstImage->width; - MS_SET_BIT(psDstImage->img_mask,dst_off); - - for( band = 0; band < psSrcImage->format->bands; band++ ) { - if( psSrcImage->format->imagemode == MS_IMAGEMODE_INT16 ) { - psDstImage->img.raw_16bit[dst_off] - = (short) (padfPixelSum[band]+0.5); - } else if( psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { - psDstImage->img.raw_float[dst_off] - = (float) padfPixelSum[band]; - } else if( psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE ) { - psDstImage->img.raw_byte[dst_off] - = (unsigned char) padfPixelSum[band]; + MS_SET_BIT(psDstImage->img_mask, dst_off); + + for (band = 0; band < psSrcImage->format->bands; band++) { + if (psSrcImage->format->imagemode == MS_IMAGEMODE_INT16) { + psDstImage->img.raw_16bit[dst_off] = + (short)(padfPixelSum[band] + 0.5); + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) { + psDstImage->img.raw_float[dst_off] = (float)padfPixelSum[band]; + } else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) { + psDstImage->img.raw_byte[dst_off] = + (unsigned char)padfPixelSum[band]; } dst_off += psDstImage->width * psDstImage->height; @@ -636,22 +607,21 @@ msAverageRasterResampler( imageObj *psSrcImage, rasterBufferObj *src_rb, } } - free( padfPixelSum ); - free( panSuccess1 ); - free( x1 ); - free( y1 ); - free( panSuccess2 ); - free( x2 ); - free( y2 ); + free(padfPixelSum); + free(panSuccess1); + free(x1); + free(y1); + free(panSuccess2); + free(x2); + free(y2); /* -------------------------------------------------------------------- */ /* Some debugging output. */ /* -------------------------------------------------------------------- */ - if( nFailedPoints > 0 && debug ) - { - msDebug( "msAverageRasterResampler: " - "%d failed to transform, %d actually set.\n", - nFailedPoints, nSetPoints ); + if (nFailedPoints > 0 && debug) { + msDebug("msAverageRasterResampler: " + "%d failed to transform, %d actually set.\n", + nFailedPoints, nSetPoints); } return 0; @@ -672,9 +642,9 @@ typedef struct { int bDstIsGeographic; double adfDstGeoTransform[6]; - int bUseProj; + int bUseProj; #if PROJ_VERSION_MAJOR >= 6 - reprojectionObj* pReprojectionDstToSrc; + reprojectionObj *pReprojectionDstToSrc; #endif } msProjTransformInfo; @@ -682,17 +652,16 @@ typedef struct { /* msInitProjTransformer() */ /************************************************************************/ -void *msInitProjTransformer( projectionObj *psSrc, - double *padfSrcGeoTransform, - projectionObj *psDst, - double *padfDstGeoTransform ) +void *msInitProjTransformer(projectionObj *psSrc, double *padfSrcGeoTransform, + projectionObj *psDst, double *padfDstGeoTransform) { int backup_src_need_gt; int backup_dst_need_gt; msProjTransformInfo *psPTInfo; - psPTInfo = (msProjTransformInfo *) msSmallCalloc(1,sizeof(msProjTransformInfo)); + psPTInfo = + (msProjTransformInfo *)msSmallCalloc(1, sizeof(msProjTransformInfo)); /* -------------------------------------------------------------------- */ /* We won't even use PROJ.4 if either coordinate system is */ @@ -702,9 +671,8 @@ void *msInitProjTransformer( projectionObj *psSrc, psSrc->gt.need_geotransform = 0; backup_dst_need_gt = psDst->gt.need_geotransform; psDst->gt.need_geotransform = 0; - psPTInfo->bUseProj = - (psSrc->proj != NULL && psDst->proj != NULL - && msProjectionsDiffer( psSrc, psDst ) ); + psPTInfo->bUseProj = (psSrc->proj != NULL && psDst->proj != NULL && + msProjectionsDiffer(psSrc, psDst)); psSrc->gt.need_geotransform = backup_src_need_gt; psDst->gt.need_geotransform = backup_dst_need_gt; @@ -714,13 +682,12 @@ void *msInitProjTransformer( projectionObj *psSrc, /* the transformer. */ /* -------------------------------------------------------------------- */ psPTInfo->psSrcProjObj = psSrc; - if( psPTInfo->bUseProj ) + if (psPTInfo->bUseProj) psPTInfo->bSrcIsGeographic = msProjIsGeographicCRS(psSrc); else psPTInfo->bSrcIsGeographic = MS_FALSE; - if( !InvGeoTransform(padfSrcGeoTransform, - psPTInfo->adfInvSrcGeoTransform) ) { + if (!InvGeoTransform(padfSrcGeoTransform, psPTInfo->adfInvSrcGeoTransform)) { free(psPTInfo); return NULL; } @@ -729,22 +696,19 @@ void *msInitProjTransformer( projectionObj *psSrc, /* Record destination image information. */ /* -------------------------------------------------------------------- */ psPTInfo->psDstProjObj = psDst; - if( psPTInfo->bUseProj ) + if (psPTInfo->bUseProj) psPTInfo->bDstIsGeographic = msProjIsGeographicCRS(psDst); else psPTInfo->bDstIsGeographic = MS_FALSE; - memcpy( psPTInfo->adfDstGeoTransform, padfDstGeoTransform, - sizeof(double) * 6 ); + memcpy(psPTInfo->adfDstGeoTransform, padfDstGeoTransform, sizeof(double) * 6); #if PROJ_VERSION_MAJOR >= 6 - if( psPTInfo->bUseProj ) - { - psPTInfo->pReprojectionDstToSrc = - msProjectCreateReprojector( psPTInfo->psDstProjObj, psPTInfo->psSrcProjObj ); - if( !psPTInfo->pReprojectionDstToSrc ) - { - free(psPTInfo); - return NULL; + if (psPTInfo->bUseProj) { + psPTInfo->pReprojectionDstToSrc = msProjectCreateReprojector( + psPTInfo->psDstProjObj, psPTInfo->psSrcProjObj); + if (!psPTInfo->pReprojectionDstToSrc) { + free(psPTInfo); + return NULL; } } #endif @@ -756,57 +720,56 @@ void *msInitProjTransformer( projectionObj *psSrc, /* msFreeProjTransformer() */ /************************************************************************/ -void msFreeProjTransformer( void * pCBData ) +void msFreeProjTransformer(void *pCBData) { #if PROJ_VERSION_MAJOR >= 6 - if( pCBData ) - { - msProjTransformInfo *psPTInfo = (msProjTransformInfo *)pCBData; - msProjectDestroyReprojector(psPTInfo->pReprojectionDstToSrc); + if (pCBData) { + msProjTransformInfo *psPTInfo = (msProjTransformInfo *)pCBData; + msProjectDestroyReprojector(psPTInfo->pReprojectionDstToSrc); } #endif - free( pCBData ); + free(pCBData); } /************************************************************************/ /* msProjTransformer */ /************************************************************************/ -int msProjTransformer( void *pCBData, int nPoints, - double *x, double *y, int *panSuccess ) +int msProjTransformer(void *pCBData, int nPoints, double *x, double *y, + int *panSuccess) { - int i; - msProjTransformInfo *psPTInfo = (msProjTransformInfo*) pCBData; - double x_out; + int i; + msProjTransformInfo *psPTInfo = (msProjTransformInfo *)pCBData; + double x_out; /* -------------------------------------------------------------------- */ /* Transform into destination georeferenced space. */ /* -------------------------------------------------------------------- */ - for( i = 0; i < nPoints; i++ ) { - x_out = psPTInfo->adfDstGeoTransform[0] - + psPTInfo->adfDstGeoTransform[1] * x[i] - + psPTInfo->adfDstGeoTransform[2] * y[i]; - y[i] = psPTInfo->adfDstGeoTransform[3] - + psPTInfo->adfDstGeoTransform[4] * x[i] - + psPTInfo->adfDstGeoTransform[5] * y[i]; + for (i = 0; i < nPoints; i++) { + x_out = psPTInfo->adfDstGeoTransform[0] + + psPTInfo->adfDstGeoTransform[1] * x[i] + + psPTInfo->adfDstGeoTransform[2] * y[i]; + y[i] = psPTInfo->adfDstGeoTransform[3] + + psPTInfo->adfDstGeoTransform[4] * x[i] + + psPTInfo->adfDstGeoTransform[5] * y[i]; x[i] = x_out; panSuccess[i] = 1; } #if PROJ_VERSION_MAJOR >= 6 - if( psPTInfo->bUseProj ) { - if( msProjectTransformPoints( psPTInfo->pReprojectionDstToSrc, - nPoints, x, y ) != MS_SUCCESS ) { - for( i = 0; i < nPoints; i++ ) + if (psPTInfo->bUseProj) { + if (msProjectTransformPoints(psPTInfo->pReprojectionDstToSrc, nPoints, x, + y) != MS_SUCCESS) { + for (i = 0; i < nPoints; i++) panSuccess[i] = 0; return MS_FALSE; } - for( i = 0; i < nPoints; i++ ) { - if( x[i] == HUGE_VAL || y[i] == HUGE_VAL ) + for (i = 0; i < nPoints; i++) { + if (x[i] == HUGE_VAL || y[i] == HUGE_VAL) panSuccess[i] = 0; } } @@ -814,8 +777,8 @@ int msProjTransformer( void *pCBData, int nPoints, /* -------------------------------------------------------------------- */ /* Transform from degrees to radians if geographic. */ /* -------------------------------------------------------------------- */ - if( psPTInfo->bDstIsGeographic ) { - for( i = 0; i < nPoints; i++ ) { + if (psPTInfo->bDstIsGeographic) { + for (i = 0; i < nPoints; i++) { x[i] = x[i] * DEG_TO_RAD; y[i] = y[i] * DEG_TO_RAD; } @@ -824,28 +787,28 @@ int msProjTransformer( void *pCBData, int nPoints, /* -------------------------------------------------------------------- */ /* Transform back to source projection space. */ /* -------------------------------------------------------------------- */ - if( psPTInfo->bUseProj ) { + if (psPTInfo->bUseProj) { double *z; int tr_result; - z = (double *) msSmallCalloc(sizeof(double),nPoints); + z = (double *)msSmallCalloc(sizeof(double), nPoints); - msAcquireLock( TLOCK_PROJ ); - tr_result = pj_transform( psPTInfo->psDstProjObj->proj, psPTInfo->psSrcProjObj->proj, - nPoints, 1, x, y, z); - msReleaseLock( TLOCK_PROJ ); + msAcquireLock(TLOCK_PROJ); + tr_result = pj_transform(psPTInfo->psDstProjObj->proj, + psPTInfo->psSrcProjObj->proj, nPoints, 1, x, y, z); + msReleaseLock(TLOCK_PROJ); - if( tr_result != 0 ) { - free( z ); - for( i = 0; i < nPoints; i++ ) + if (tr_result != 0) { + free(z); + for (i = 0; i < nPoints; i++) panSuccess[i] = 0; return MS_FALSE; } - free( z ); + free(z); - for( i = 0; i < nPoints; i++ ) { - if( x[i] == HUGE_VAL || y[i] == HUGE_VAL ) + for (i = 0; i < nPoints; i++) { + if (x[i] == HUGE_VAL || y[i] == HUGE_VAL) panSuccess[i] = 0; } } @@ -853,9 +816,9 @@ int msProjTransformer( void *pCBData, int nPoints, /* -------------------------------------------------------------------- */ /* Transform back to degrees if source is geographic. */ /* -------------------------------------------------------------------- */ - if( psPTInfo->bSrcIsGeographic ) { - for( i = 0; i < nPoints; i++ ) { - if( panSuccess[i] ) { + if (psPTInfo->bSrcIsGeographic) { + for (i = 0; i < nPoints; i++) { + if (panSuccess[i]) { x[i] = x[i] * RAD_TO_DEG; y[i] = y[i] * RAD_TO_DEG; } @@ -866,14 +829,14 @@ int msProjTransformer( void *pCBData, int nPoints, /* -------------------------------------------------------------------- */ /* Transform to source raster space. */ /* -------------------------------------------------------------------- */ - for( i = 0; i < nPoints; i++ ) { - if( panSuccess[i] ) { - x_out = psPTInfo->adfInvSrcGeoTransform[0] - + psPTInfo->adfInvSrcGeoTransform[1] * x[i] - + psPTInfo->adfInvSrcGeoTransform[2] * y[i]; - y[i] = psPTInfo->adfInvSrcGeoTransform[3] - + psPTInfo->adfInvSrcGeoTransform[4] * x[i] - + psPTInfo->adfInvSrcGeoTransform[5] * y[i]; + for (i = 0; i < nPoints; i++) { + if (panSuccess[i]) { + x_out = psPTInfo->adfInvSrcGeoTransform[0] + + psPTInfo->adfInvSrcGeoTransform[1] * x[i] + + psPTInfo->adfInvSrcGeoTransform[2] * y[i]; + y[i] = psPTInfo->adfInvSrcGeoTransform[3] + + psPTInfo->adfInvSrcGeoTransform[4] * x[i] + + psPTInfo->adfInvSrcGeoTransform[5] * y[i]; x[i] = x_out; } else { x[i] = -1; @@ -892,23 +855,23 @@ int msProjTransformer( void *pCBData, int nPoints, typedef struct { SimpleTransformer pfnBaseTransformer; - void *pBaseCBData; + void *pBaseCBData; - double dfMaxError; + double dfMaxError; } msApproxTransformInfo; /************************************************************************/ /* msInitApproxTransformer() */ /************************************************************************/ -static void *msInitApproxTransformer( SimpleTransformer pfnBaseTransformer, - void *pBaseCBData, - double dfMaxError ) +static void *msInitApproxTransformer(SimpleTransformer pfnBaseTransformer, + void *pBaseCBData, double dfMaxError) { msApproxTransformInfo *psATInfo; - psATInfo = (msApproxTransformInfo *) msSmallMalloc(sizeof(msApproxTransformInfo)); + psATInfo = + (msApproxTransformInfo *)msSmallMalloc(sizeof(msApproxTransformInfo)); psATInfo->pfnBaseTransformer = pfnBaseTransformer; psATInfo->pBaseCBData = pBaseCBData; psATInfo->dfMaxError = dfMaxError; @@ -920,35 +883,34 @@ static void *msInitApproxTransformer( SimpleTransformer pfnBaseTransformer, /* msFreeApproxTransformer() */ /************************************************************************/ -static void msFreeApproxTransformer( void * pCBData ) +static void msFreeApproxTransformer(void *pCBData) { - free( pCBData ); + free(pCBData); } /************************************************************************/ /* msApproxTransformer */ /************************************************************************/ -static int msApproxTransformer( void *pCBData, int nPoints, - double *x, double *y, int *panSuccess ) +static int msApproxTransformer(void *pCBData, int nPoints, double *x, double *y, + int *panSuccess) { - msApproxTransformInfo *psATInfo = (msApproxTransformInfo *) pCBData; + msApproxTransformInfo *psATInfo = (msApproxTransformInfo *)pCBData; double x2[3], y2[3], dfDeltaX, dfDeltaY, dfError, dfDist; int nMiddle, anSuccess2[3], i, bSuccess; - nMiddle = (nPoints-1)/2; + nMiddle = (nPoints - 1) / 2; /* -------------------------------------------------------------------- */ /* Bail if our preconditions are not met, or if error is not */ /* acceptable. */ /* -------------------------------------------------------------------- */ - if( y[0] != y[nPoints-1] || y[0] != y[nMiddle] - || x[0] == x[nPoints-1] || x[0] == x[nMiddle] - || psATInfo->dfMaxError == 0.0 || nPoints <= 5 ) { - return psATInfo->pfnBaseTransformer( psATInfo->pBaseCBData, nPoints, - x, y, panSuccess ); + if (y[0] != y[nPoints - 1] || y[0] != y[nMiddle] || x[0] == x[nPoints - 1] || + x[0] == x[nMiddle] || psATInfo->dfMaxError == 0.0 || nPoints <= 5) { + return psATInfo->pfnBaseTransformer(psATInfo->pBaseCBData, nPoints, x, y, + panSuccess); } /* -------------------------------------------------------------------- */ @@ -958,44 +920,39 @@ static int msApproxTransformer( void *pCBData, int nPoints, y2[0] = y[0]; x2[1] = x[nMiddle]; y2[1] = y[nMiddle]; - x2[2] = x[nPoints-1]; - y2[2] = y[nPoints-1]; + x2[2] = x[nPoints - 1]; + y2[2] = y[nPoints - 1]; - bSuccess = - psATInfo->pfnBaseTransformer( psATInfo->pBaseCBData, 3, x2, y2, - anSuccess2 ); - if( !bSuccess || !anSuccess2[0] || !anSuccess2[1] || !anSuccess2[2] ) - return psATInfo->pfnBaseTransformer( psATInfo->pBaseCBData, nPoints, - x, y, panSuccess ); + bSuccess = psATInfo->pfnBaseTransformer(psATInfo->pBaseCBData, 3, x2, y2, + anSuccess2); + if (!bSuccess || !anSuccess2[0] || !anSuccess2[1] || !anSuccess2[2]) + return psATInfo->pfnBaseTransformer(psATInfo->pBaseCBData, nPoints, x, y, + panSuccess); /* -------------------------------------------------------------------- */ /* Is the error at the middle acceptable relative to an */ /* interpolation of the middle position? */ /* -------------------------------------------------------------------- */ - dfDeltaX = (x2[2] - x2[0]) / (x[nPoints-1] - x[0]); - dfDeltaY = (y2[2] - y2[0]) / (x[nPoints-1] - x[0]); + dfDeltaX = (x2[2] - x2[0]) / (x[nPoints - 1] - x[0]); + dfDeltaY = (y2[2] - y2[0]) / (x[nPoints - 1] - x[0]); - dfError = fabs((x2[0] + dfDeltaX * (x[nMiddle] - x[0])) - x2[1]) - + fabs((y2[0] + dfDeltaY * (x[nMiddle] - x[0])) - y2[1]); + dfError = fabs((x2[0] + dfDeltaX * (x[nMiddle] - x[0])) - x2[1]) + + fabs((y2[0] + dfDeltaY * (x[nMiddle] - x[0])) - y2[1]); - if( dfError > psATInfo->dfMaxError ) { - bSuccess = - msApproxTransformer( psATInfo, nMiddle, x, y, panSuccess ); + if (dfError > psATInfo->dfMaxError) { + bSuccess = msApproxTransformer(psATInfo, nMiddle, x, y, panSuccess); - if( !bSuccess ) { - return psATInfo->pfnBaseTransformer( psATInfo->pBaseCBData, - nPoints, - x, y, panSuccess ); + if (!bSuccess) { + return psATInfo->pfnBaseTransformer(psATInfo->pBaseCBData, nPoints, x, y, + panSuccess); } - bSuccess = - msApproxTransformer( psATInfo, nPoints - nMiddle, - x+nMiddle, y+nMiddle, panSuccess+nMiddle ); + bSuccess = msApproxTransformer(psATInfo, nPoints - nMiddle, x + nMiddle, + y + nMiddle, panSuccess + nMiddle); - if( !bSuccess ) { - return psATInfo->pfnBaseTransformer( psATInfo->pBaseCBData, - nPoints, - x, y, panSuccess ); + if (!bSuccess) { + return psATInfo->pfnBaseTransformer(psATInfo->pBaseCBData, nPoints, x, y, + panSuccess); } return 1; @@ -1004,7 +961,7 @@ static int msApproxTransformer( void *pCBData, int nPoints, /* -------------------------------------------------------------------- */ /* Error is OK, linearly interpolate all points along line. */ /* -------------------------------------------------------------------- */ - for( i = nPoints-1; i >= 0; i-- ) { + for (i = nPoints - 1; i >= 0; i--) { dfDist = (x[i] - x[0]); y[i] = y2[0] + dfDeltaY * dfDist; x[i] = x2[0] + dfDeltaX * dfDist; @@ -1021,24 +978,21 @@ static int msApproxTransformer( void *pCBData, int nPoints, /* onto the source raster. */ /************************************************************************/ -static int msTransformMapToSource( int nDstXSize, int nDstYSize, - double * adfDstGeoTransform, - projectionObj *psDstProj, - int nSrcXSize, int nSrcYSize, - double * adfInvSrcGeoTransform, - projectionObj *psSrcProj, - rectObj *psSrcExtent, - int bUseGrid ) +static int +msTransformMapToSource(int nDstXSize, int nDstYSize, double *adfDstGeoTransform, + projectionObj *psDstProj, int nSrcXSize, int nSrcYSize, + double *adfInvSrcGeoTransform, projectionObj *psSrcProj, + rectObj *psSrcExtent, int bUseGrid) { int nFailures = 0; -#define EDGE_STEPS 10 -#define MAX_SIZE ((EDGE_STEPS+1)*(EDGE_STEPS+1)) +#define EDGE_STEPS 10 +#define MAX_SIZE ((EDGE_STEPS + 1) * (EDGE_STEPS + 1)) - int i, nSamples = 0, bOutInit = 0; - double dfRatio; - double x[MAX_SIZE], y[MAX_SIZE]; + int i, nSamples = 0, bOutInit = 0; + double dfRatio; + double x[MAX_SIZE], y[MAX_SIZE]; #if PROJ_VERSION_MAJOR < 6 double z[MAX_SIZE]; #endif @@ -1046,16 +1000,16 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* -------------------------------------------------------------------- */ /* Collect edges in map image pixel/line coordinates */ /* -------------------------------------------------------------------- */ - if( !bUseGrid ) { - for( dfRatio = 0.0; dfRatio <= 1.001; dfRatio += (1.0/EDGE_STEPS) ) { - assert( nSamples < MAX_SIZE ); - x[nSamples ] = dfRatio * nDstXSize; + if (!bUseGrid) { + for (dfRatio = 0.0; dfRatio <= 1.001; dfRatio += (1.0 / EDGE_STEPS)) { + assert(nSamples < MAX_SIZE); + x[nSamples] = dfRatio * nDstXSize; y[nSamples++] = 0.0; - x[nSamples ] = dfRatio * nDstXSize; + x[nSamples] = dfRatio * nDstXSize; y[nSamples++] = nDstYSize; - x[nSamples ] = 0.0; + x[nSamples] = 0.0; y[nSamples++] = dfRatio * nDstYSize; - x[nSamples ] = nDstXSize; + x[nSamples] = nDstXSize; y[nSamples++] = dfRatio * nDstYSize; } } @@ -1066,10 +1020,10 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, else { double dfRatio2; - for( dfRatio = 0.0; dfRatio <= 1.001; dfRatio += (1.0/EDGE_STEPS) ) { - for( dfRatio2=0.0; dfRatio2 <= 1.001; dfRatio2 += (1.0/EDGE_STEPS)) { - assert( nSamples < MAX_SIZE ); - x[nSamples ] = dfRatio2 * nDstXSize; + for (dfRatio = 0.0; dfRatio <= 1.001; dfRatio += (1.0 / EDGE_STEPS)) { + for (dfRatio2 = 0.0; dfRatio2 <= 1.001; dfRatio2 += (1.0 / EDGE_STEPS)) { + assert(nSamples < MAX_SIZE); + x[nSamples] = dfRatio2 * nDstXSize; y[nSamples++] = dfRatio * nDstYSize; } } @@ -1078,16 +1032,14 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* -------------------------------------------------------------------- */ /* transform to map georeferenced units */ /* -------------------------------------------------------------------- */ - for( i = 0; i < nSamples; i++ ) { - double x_out, y_out; + for (i = 0; i < nSamples; i++) { + double x_out, y_out; - x_out = adfDstGeoTransform[0] - + x[i] * adfDstGeoTransform[1] - + y[i] * adfDstGeoTransform[2]; + x_out = adfDstGeoTransform[0] + x[i] * adfDstGeoTransform[1] + + y[i] * adfDstGeoTransform[2]; - y_out = adfDstGeoTransform[3] - + x[i] * adfDstGeoTransform[4] - + y[i] * adfDstGeoTransform[5]; + y_out = adfDstGeoTransform[3] + x[i] * adfDstGeoTransform[4] + + y[i] * adfDstGeoTransform[5]; x[i] = x_out; y[i] = y_out; @@ -1099,36 +1051,37 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* -------------------------------------------------------------------- */ /* Transform to layer georeferenced coordinates. */ /* -------------------------------------------------------------------- */ - if( psDstProj->proj && psSrcProj->proj ) { + if (psDstProj->proj && psSrcProj->proj) { #if PROJ_VERSION_MAJOR >= 6 - reprojectionObj* reprojector = msProjectCreateReprojector(psDstProj, psSrcProj); - if( !reprojector ) - return MS_FALSE; - if( msProjectTransformPoints( reprojector, nSamples, x, y ) != MS_SUCCESS ) { + reprojectionObj *reprojector = + msProjectCreateReprojector(psDstProj, psSrcProj); + if (!reprojector) + return MS_FALSE; + if (msProjectTransformPoints(reprojector, nSamples, x, y) != MS_SUCCESS) { msProjectDestroyReprojector(reprojector); return MS_FALSE; } msProjectDestroyReprojector(reprojector); #else int tr_result; - if( msProjIsGeographicCRS(psDstProj) ) { - for( i = 0; i < nSamples; i++ ) { + if (msProjIsGeographicCRS(psDstProj)) { + for (i = 0; i < nSamples; i++) { x[i] = x[i] * DEG_TO_RAD; y[i] = y[i] * DEG_TO_RAD; } } - msAcquireLock( TLOCK_PROJ ); - tr_result = pj_transform( psDstProj->proj, psSrcProj->proj, - nSamples, 1, x, y, z ); - msReleaseLock( TLOCK_PROJ ); + msAcquireLock(TLOCK_PROJ); + tr_result = + pj_transform(psDstProj->proj, psSrcProj->proj, nSamples, 1, x, y, z); + msReleaseLock(TLOCK_PROJ); - if( tr_result != 0 ) + if (tr_result != 0) return MS_FALSE; - if( msProjIsGeographicCRS(psSrcProj) ) { - for( i = 0; i < nSamples; i++ ) { - if( x[i] != HUGE_VAL && y[i] != HUGE_VAL ) { + if (msProjIsGeographicCRS(psSrcProj)) { + for (i = 0; i < nSamples; i++) { + if (x[i] != HUGE_VAL && y[i] != HUGE_VAL) { x[i] = x[i] * RAD_TO_DEG; y[i] = y[i] * RAD_TO_DEG; } @@ -1141,14 +1094,12 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* If we just using the edges (not a grid) and we go some */ /* errors, then we need to restart using a grid pattern. */ /* -------------------------------------------------------------------- */ - if( !bUseGrid ) { - for( i = 0; i < nSamples; i++ ) { - if( x[i] == HUGE_VAL || y[i] == HUGE_VAL ) { - return msTransformMapToSource( nDstXSize, nDstYSize, - adfDstGeoTransform, psDstProj, - nSrcXSize, nSrcYSize, - adfInvSrcGeoTransform,psSrcProj, - psSrcExtent, 1 ); + if (!bUseGrid) { + for (i = 0; i < nSamples; i++) { + if (x[i] == HUGE_VAL || y[i] == HUGE_VAL) { + return msTransformMapToSource( + nDstXSize, nDstYSize, adfDstGeoTransform, psDstProj, nSrcXSize, + nSrcYSize, adfInvSrcGeoTransform, psSrcProj, psSrcExtent, 1); } } } @@ -1156,22 +1107,20 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* -------------------------------------------------------------------- */ /* transform to layer raster coordinates, and collect bounds. */ /* -------------------------------------------------------------------- */ - for( i = 0; i < nSamples; i++ ) { - double x_out, y_out; + for (i = 0; i < nSamples; i++) { + double x_out, y_out; - if( x[i] == HUGE_VAL || y[i] == HUGE_VAL ) { + if (x[i] == HUGE_VAL || y[i] == HUGE_VAL) { nFailures++; continue; } - x_out = adfInvSrcGeoTransform[0] - + x[i]*adfInvSrcGeoTransform[1] - + y[i]*adfInvSrcGeoTransform[2]; - y_out = adfInvSrcGeoTransform[3] - + x[i]*adfInvSrcGeoTransform[4] - + y[i]*adfInvSrcGeoTransform[5]; + x_out = adfInvSrcGeoTransform[0] + x[i] * adfInvSrcGeoTransform[1] + + y[i] * adfInvSrcGeoTransform[2]; + y_out = adfInvSrcGeoTransform[3] + x[i] * adfInvSrcGeoTransform[4] + + y[i] * adfInvSrcGeoTransform[5]; - if( !bOutInit ) { + if (!bOutInit) { psSrcExtent->minx = psSrcExtent->maxx = x_out; psSrcExtent->miny = psSrcExtent->maxy = y_out; bOutInit = 1; @@ -1188,142 +1137,136 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* projection. In that case we must check if the points at */ /* lon_wrap +/- 180deg are in the output raster. */ /* -------------------------------------------------------------------- */ - if( bOutInit && msProjIsGeographicCRS(psSrcProj) ) - { - double dfLonWrap = 0; - int bHasLonWrap = msProjectHasLonWrap(psSrcProj, &dfLonWrap); + if (bOutInit && msProjIsGeographicCRS(psSrcProj)) { + double dfLonWrap = 0; + int bHasLonWrap = msProjectHasLonWrap(psSrcProj, &dfLonWrap); - if( bHasLonWrap ) - { - double x2[2], y2[2]; + if (bHasLonWrap) { + double x2[2], y2[2]; #if PROJ_VERSION_MAJOR < 6 - double z2[2]; + double z2[2]; #endif - int nCountY = 0; - double dfY = 0.0; - double dfXMinOut = 0.0; - double dfYMinOut = 0.0; - double dfXMaxOut = 0.0; - double dfYMaxOut = 0.0; - const double dfHalfRes = adfDstGeoTransform[1] / 2; - - /* Find out average y coordinate in src projection */ - for( i = 0; i < nSamples; i++ ) { - if( y[i] != HUGE_VAL ) { - dfY += y[i]; - nCountY ++; - } - } - dfY /= nCountY; - - /* Compute bounds of output raster */ - for( i = 0; i < 4; i ++ ) - { - double dfX = adfDstGeoTransform[0] + - ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[1] + - ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[2]; - double dfY = adfDstGeoTransform[3] + - ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[4] + - ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[5]; - if( i == 0 || dfX < dfXMinOut ) dfXMinOut = dfX; - if( i == 0 || dfY < dfYMinOut ) dfYMinOut = dfY; - if( i == 0 || dfX > dfXMaxOut ) dfXMaxOut = dfX; - if( i == 0 || dfY > dfYMaxOut ) dfYMaxOut = dfY; - } + int nCountY = 0; + double dfY = 0.0; + double dfXMinOut = 0.0; + double dfYMinOut = 0.0; + double dfXMaxOut = 0.0; + double dfYMaxOut = 0.0; + const double dfHalfRes = adfDstGeoTransform[1] / 2; + + /* Find out average y coordinate in src projection */ + for (i = 0; i < nSamples; i++) { + if (y[i] != HUGE_VAL) { + dfY += y[i]; + nCountY++; + } + } + dfY /= nCountY; + + /* Compute bounds of output raster */ + for (i = 0; i < 4; i++) { + double dfX = + adfDstGeoTransform[0] + + ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[1] + + ((i == 1 || i == 3) ? nDstYSize : 0) * adfDstGeoTransform[2]; + double dfY = + adfDstGeoTransform[3] + + ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[4] + + ((i == 1 || i == 3) ? nDstYSize : 0) * adfDstGeoTransform[5]; + if (i == 0 || dfX < dfXMinOut) + dfXMinOut = dfX; + if (i == 0 || dfY < dfYMinOut) + dfYMinOut = dfY; + if (i == 0 || dfX > dfXMaxOut) + dfXMaxOut = dfX; + if (i == 0 || dfY > dfYMaxOut) + dfYMaxOut = dfY; + } - x2[0] = dfLonWrap-180+1e-7; - y2[0] = dfY; + x2[0] = dfLonWrap - 180 + 1e-7; + y2[0] = dfY; - x2[1] = dfLonWrap+180-1e-7; - y2[1] = dfY; + x2[1] = dfLonWrap + 180 - 1e-7; + y2[1] = dfY; #if PROJ_VERSION_MAJOR >= 6 - { - reprojectionObj* reprojector = msProjectCreateReprojector(psSrcProj, psDstProj); - if( reprojector ) - { - msProjectTransformPoints( reprojector, 2, x2, y2 ); - msProjectDestroyReprojector(reprojector); - } - } + { + reprojectionObj *reprojector = + msProjectCreateReprojector(psSrcProj, psDstProj); + if (reprojector) { + msProjectTransformPoints(reprojector, 2, x2, y2); + msProjectDestroyReprojector(reprojector); + } + } #else - z2[0] = 0.0; - z2[1] = 0.0; - msAcquireLock( TLOCK_PROJ ); - pj_transform( psSrcProj->proj, psDstProj->proj, - 2, 1, x2, y2, z2 ); - msReleaseLock( TLOCK_PROJ ); + z2[0] = 0.0; + z2[1] = 0.0; + msAcquireLock(TLOCK_PROJ); + pj_transform(psSrcProj->proj, psDstProj->proj, 2, 1, x2, y2, z2); + msReleaseLock(TLOCK_PROJ); #endif - if( x2[0] >= dfXMinOut - dfHalfRes && x2[0] <= dfXMaxOut + dfHalfRes && - y2[0] >= dfYMinOut && y2[0] <= dfYMaxOut ) - { - double x_out = adfInvSrcGeoTransform[0] - + (dfLonWrap-180)*adfInvSrcGeoTransform[1] - + dfY*adfInvSrcGeoTransform[2]; - double y_out = adfInvSrcGeoTransform[3] - + (dfLonWrap-180)*adfInvSrcGeoTransform[4] - + dfY*adfInvSrcGeoTransform[5]; - - /* Does the raster cover, at least, a whole 360 deg range ? */ - if( nSrcXSize >= (int)(adfInvSrcGeoTransform[1] * 360) ) - { - psSrcExtent->minx = 0; - psSrcExtent->maxx = nSrcXSize; - } - else - { - psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out); - psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out); - } - psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out); - psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out); - } + if (x2[0] >= dfXMinOut - dfHalfRes && x2[0] <= dfXMaxOut + dfHalfRes && + y2[0] >= dfYMinOut && y2[0] <= dfYMaxOut) { + double x_out = adfInvSrcGeoTransform[0] + + (dfLonWrap - 180) * adfInvSrcGeoTransform[1] + + dfY * adfInvSrcGeoTransform[2]; + double y_out = adfInvSrcGeoTransform[3] + + (dfLonWrap - 180) * adfInvSrcGeoTransform[4] + + dfY * adfInvSrcGeoTransform[5]; + + /* Does the raster cover, at least, a whole 360 deg range ? */ + if (nSrcXSize >= (int)(adfInvSrcGeoTransform[1] * 360)) { + psSrcExtent->minx = 0; + psSrcExtent->maxx = nSrcXSize; + } else { + psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out); + psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out); + } + psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out); + psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out); + } - if( x2[1] >= dfXMinOut - dfHalfRes && x2[1] <= dfXMaxOut + dfHalfRes && - y2[1] >= dfYMinOut && y2[1] <= dfYMaxOut ) - { - double x_out = adfInvSrcGeoTransform[0] - + (dfLonWrap+180)*adfInvSrcGeoTransform[1] - + dfY*adfInvSrcGeoTransform[2]; - double y_out = adfInvSrcGeoTransform[3] - + (dfLonWrap+180)*adfInvSrcGeoTransform[4] - + dfY*adfInvSrcGeoTransform[5]; - - /* Does the raster cover, at least, a whole 360 deg range ? */ - if( nSrcXSize >= (int)(adfInvSrcGeoTransform[1] * 360) ) - { - psSrcExtent->minx = 0; - psSrcExtent->maxx = nSrcXSize; - } - else - { - psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out); - psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out); - } - psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out); - psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out); - } + if (x2[1] >= dfXMinOut - dfHalfRes && x2[1] <= dfXMaxOut + dfHalfRes && + y2[1] >= dfYMinOut && y2[1] <= dfYMaxOut) { + double x_out = adfInvSrcGeoTransform[0] + + (dfLonWrap + 180) * adfInvSrcGeoTransform[1] + + dfY * adfInvSrcGeoTransform[2]; + double y_out = adfInvSrcGeoTransform[3] + + (dfLonWrap + 180) * adfInvSrcGeoTransform[4] + + dfY * adfInvSrcGeoTransform[5]; + + /* Does the raster cover, at least, a whole 360 deg range ? */ + if (nSrcXSize >= (int)(adfInvSrcGeoTransform[1] * 360)) { + psSrcExtent->minx = 0; + psSrcExtent->maxx = nSrcXSize; + } else { + psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out); + psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out); + } + psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out); + psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out); } + } } - if( !bOutInit ) + if (!bOutInit) return MS_FALSE; /* -------------------------------------------------------------------- */ /* If we had some failures, we need to expand the region to */ /* represent our very coarse sampling grid. */ /* -------------------------------------------------------------------- */ - if( nFailures > 0 ) { - int nGrowAmountX = (int) - (psSrcExtent->maxx - psSrcExtent->minx)/EDGE_STEPS + 1; - int nGrowAmountY = (int) - (psSrcExtent->maxy - psSrcExtent->miny)/EDGE_STEPS + 1; + if (nFailures > 0) { + int nGrowAmountX = + (int)(psSrcExtent->maxx - psSrcExtent->minx) / EDGE_STEPS + 1; + int nGrowAmountY = + (int)(psSrcExtent->maxy - psSrcExtent->miny) / EDGE_STEPS + 1; - psSrcExtent->minx = MS_MAX(psSrcExtent->minx - nGrowAmountX,0); - psSrcExtent->miny = MS_MAX(psSrcExtent->miny - nGrowAmountY,0); - psSrcExtent->maxx = MS_MIN(psSrcExtent->maxx + nGrowAmountX,nSrcXSize); - psSrcExtent->maxy = MS_MIN(psSrcExtent->maxy + nGrowAmountY,nSrcYSize); + psSrcExtent->minx = MS_MAX(psSrcExtent->minx - nGrowAmountX, 0); + psSrcExtent->miny = MS_MAX(psSrcExtent->miny - nGrowAmountY, 0); + psSrcExtent->maxx = MS_MIN(psSrcExtent->maxx + nGrowAmountX, nSrcXSize); + psSrcExtent->maxy = MS_MIN(psSrcExtent->maxy + nGrowAmountY, nSrcYSize); } return MS_TRUE; @@ -1333,45 +1276,45 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize, /* msResampleGDALToMap() */ /************************************************************************/ -int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, - rasterBufferObj *rb, GDALDatasetH hDS ) +int msResampleGDALToMap(mapObj *map, layerObj *layer, imageObj *image, + rasterBufferObj *rb, GDALDatasetH hDS) { - int nSrcXSize, nSrcYSize, nDstXSize, nDstYSize; - int result, bSuccess; - double adfSrcGeoTransform[6], adfDstGeoTransform[6]; - double adfInvSrcGeoTransform[6], dfNominalCellSize; + int nSrcXSize, nSrcYSize, nDstXSize, nDstYSize; + int result, bSuccess; + double adfSrcGeoTransform[6], adfDstGeoTransform[6]; + double adfInvSrcGeoTransform[6], dfNominalCellSize; rectObj sSrcExtent = {0}, sOrigSrcExtent; - mapObj sDummyMap; - imageObj *srcImage; - void *pTCBData; - void *pACBData; - char **papszAlteredProcessing = NULL; - int nLoadImgXSize, nLoadImgYSize; - double dfOversampleRatio; + mapObj sDummyMap; + imageObj *srcImage; + void *pTCBData; + void *pACBData; + char **papszAlteredProcessing = NULL; + int nLoadImgXSize, nLoadImgYSize; + double dfOversampleRatio; rasterBufferObj src_rb, *psrc_rb = NULL, *mask_rb = NULL; - int bAddPixelMargin = MS_TRUE; - int bWrapAtLeftRight = MS_FALSE; - + int bAddPixelMargin = MS_TRUE; + int bWrapAtLeftRight = MS_FALSE; - const char *resampleMode = CSLFetchNameValue( layer->processing, - "RESAMPLE" ); + const char *resampleMode = CSLFetchNameValue(layer->processing, "RESAMPLE"); - if( resampleMode == NULL ) + if (resampleMode == NULL) resampleMode = "NEAREST"; - - if(layer->mask) { + + if (layer->mask) { int ret, maskLayerIdx; layerObj *maskLayer; - maskLayerIdx = msGetLayerIndex(map,layer->mask); - if(maskLayerIdx == -1) { - msSetError(MS_MISCERR, "Invalid mask layer specified", "msResampleGDALToMap()"); + maskLayerIdx = msGetLayerIndex(map, layer->mask); + if (maskLayerIdx == -1) { + msSetError(MS_MISCERR, "Invalid mask layer specified", + "msResampleGDALToMap()"); return -1; } maskLayer = GET_LAYER(map, maskLayerIdx); - mask_rb = msSmallCalloc(1,sizeof(rasterBufferObj)); - ret = MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,mask_rb); - if(ret != MS_SUCCESS) { + mask_rb = msSmallCalloc(1, sizeof(rasterBufferObj)); + ret = MS_IMAGE_RENDERER(maskLayer->maskimage) + ->getRasterBufferHandle(maskLayer->maskimage, mask_rb); + if (ret != MS_SUCCESS) { free(mask_rb); return -1; } @@ -1381,11 +1324,10 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* We will require source and destination to have a valid */ /* projection object. */ /* -------------------------------------------------------------------- */ - if( map->projection.proj == NULL - || layer->projection.proj == NULL ) { - if( layer->debug ) - msDebug( "msResampleGDALToMap(): " - "Either map or layer projection is NULL, assuming compatible.\n" ); + if (map->projection.proj == NULL || layer->projection.proj == NULL) { + if (layer->debug) + msDebug("msResampleGDALToMap(): " + "Either map or layer projection is NULL, assuming compatible.\n"); } /* -------------------------------------------------------------------- */ @@ -1394,14 +1336,14 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, nDstXSize = image->width; nDstYSize = image->height; - memcpy( adfDstGeoTransform, map->gt.geotransform, sizeof(double)*6 ); + memcpy(adfDstGeoTransform, map->gt.geotransform, sizeof(double) * 6); - msGetGDALGeoTransform( hDS, map, layer, adfSrcGeoTransform ); + msGetGDALGeoTransform(hDS, map, layer, adfSrcGeoTransform); - nSrcXSize = GDALGetRasterXSize( hDS ); - nSrcYSize = GDALGetRasterYSize( hDS ); + nSrcXSize = GDALGetRasterXSize(hDS); + nSrcYSize = GDALGetRasterYSize(hDS); - InvGeoTransform( adfSrcGeoTransform, adfInvSrcGeoTransform ); + InvGeoTransform(adfSrcGeoTransform, adfInvSrcGeoTransform); /* -------------------------------------------------------------------- */ /* We need to find the extents in the source layer projection */ @@ -1409,46 +1351,43 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* collecting the extents of a region around the edge of the */ /* destination chunk. */ /* -------------------------------------------------------------------- */ - if( CSLFetchBoolean( layer->processing, "LOAD_WHOLE_IMAGE", FALSE ) ) + if (CSLFetchBoolean(layer->processing, "LOAD_WHOLE_IMAGE", FALSE)) bSuccess = FALSE; else { - bSuccess = - msTransformMapToSource( nDstXSize, nDstYSize, adfDstGeoTransform, - &(map->projection), - nSrcXSize, nSrcYSize,adfInvSrcGeoTransform, - &(layer->projection), - &sSrcExtent, FALSE ); - if (bSuccess) { - /* -------------------------------------------------------------------- */ - /* Repeat transformation for a rectangle interior to the output */ - /* requested region. If the latter results in a more extreme y */ - /* extent, then extend extents in source layer projection to */ - /* southern/northing bounds and entire x extent. */ - /* -------------------------------------------------------------------- */ - memcpy( &sOrigSrcExtent, &sSrcExtent, sizeof(sSrcExtent) ); + bSuccess = msTransformMapToSource(nDstXSize, nDstYSize, adfDstGeoTransform, + &(map->projection), nSrcXSize, nSrcYSize, + adfInvSrcGeoTransform, + &(layer->projection), &sSrcExtent, FALSE); + if (bSuccess) { + /* -------------------------------------------------------------------- */ + /* Repeat transformation for a rectangle interior to the output */ + /* requested region. If the latter results in a more extreme y */ + /* extent, then extend extents in source layer projection to */ + /* southern/northing bounds and entire x extent. */ + /* -------------------------------------------------------------------- */ + memcpy(&sOrigSrcExtent, &sSrcExtent, sizeof(sSrcExtent)); adfDstGeoTransform[0] = adfDstGeoTransform[0] + adfDstGeoTransform[1]; adfDstGeoTransform[3] = adfDstGeoTransform[3] + adfDstGeoTransform[5]; - bSuccess = - msTransformMapToSource( nDstXSize-2, nDstYSize-2, adfDstGeoTransform, - &(map->projection), - nSrcXSize, nSrcYSize,adfInvSrcGeoTransform, - &(layer->projection), - &sSrcExtent, FALSE ); + bSuccess = msTransformMapToSource( + nDstXSize - 2, nDstYSize - 2, adfDstGeoTransform, &(map->projection), + nSrcXSize, nSrcYSize, adfInvSrcGeoTransform, &(layer->projection), + &sSrcExtent, FALSE); /* Reset this array to its original value! */ - memcpy( adfDstGeoTransform, map->gt.geotransform, sizeof(double)*6 ); + memcpy(adfDstGeoTransform, map->gt.geotransform, sizeof(double) * 6); if (bSuccess) { - if (sSrcExtent.maxy > sOrigSrcExtent.maxy || sSrcExtent.miny < sOrigSrcExtent.miny) { - msDebug( "msTransformMapToSource(): extending bounds.\n"); - sOrigSrcExtent.minx = 0; - sOrigSrcExtent.maxx = nSrcXSize; - if (sSrcExtent.maxy > sOrigSrcExtent.maxy) - sOrigSrcExtent.maxy = nSrcYSize; - if (sSrcExtent.miny < sOrigSrcExtent.miny) - sOrigSrcExtent.miny = 0; - } + if (sSrcExtent.maxy > sOrigSrcExtent.maxy || + sSrcExtent.miny < sOrigSrcExtent.miny) { + msDebug("msTransformMapToSource(): extending bounds.\n"); + sOrigSrcExtent.minx = 0; + sOrigSrcExtent.maxx = nSrcXSize; + if (sSrcExtent.maxy > sOrigSrcExtent.maxy) + sOrigSrcExtent.maxy = nSrcYSize; + if (sSrcExtent.miny < sOrigSrcExtent.miny) + sOrigSrcExtent.miny = 0; + } } - memcpy( &sSrcExtent, &sOrigSrcExtent, sizeof(sOrigSrcExtent) ); + memcpy(&sSrcExtent, &sOrigSrcExtent, sizeof(sOrigSrcExtent)); bSuccess = TRUE; } } @@ -1460,14 +1399,15 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* result in the raster being loaded at a higher resolution */ /* than really needed but should give decent results. */ /* -------------------------------------------------------------------- */ - if( !bSuccess ) { - if( layer->debug ) { - if( CSLFetchBoolean( layer->processing, "LOAD_WHOLE_IMAGE", FALSE )) - msDebug( "msResampleGDALToMap(): " - "LOAD_WHOLE_IMAGE set, loading whole image.\n" ); + if (!bSuccess) { + if (layer->debug) { + if (CSLFetchBoolean(layer->processing, "LOAD_WHOLE_IMAGE", FALSE)) + msDebug("msResampleGDALToMap(): " + "LOAD_WHOLE_IMAGE set, loading whole image.\n"); else - msDebug( "msTransformMapToSource(): " - "pj_transform() failed. Out of bounds? Loading whole image.\n" ); + msDebug( + "msTransformMapToSource(): " + "pj_transform() failed. Out of bounds? Loading whole image.\n"); } sSrcExtent.minx = 0; @@ -1485,72 +1425,70 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* and that the underlying raster is tiled and share the same */ /* tiling scheme as the queried tile mode. */ /* -------------------------------------------------------------------- */ -#define IS_ALMOST_INTEGER(x, eps) (fabs((x)-(int)((x)+0.5)) < (eps)) +#define IS_ALMOST_INTEGER(x, eps) (fabs((x) - (int)((x) + 0.5)) < (eps)) - if( adfSrcGeoTransform[1] > 0.0 && adfSrcGeoTransform[2] == 0.0 && + if (adfSrcGeoTransform[1] > 0.0 && adfSrcGeoTransform[2] == 0.0 && adfSrcGeoTransform[4] == 0.0 && adfSrcGeoTransform[5] < 0.0 && IS_ALMOST_INTEGER(sSrcExtent.minx, 0.1) && IS_ALMOST_INTEGER(sSrcExtent.miny, 0.1) && IS_ALMOST_INTEGER(sSrcExtent.maxx, 0.1) && IS_ALMOST_INTEGER(sSrcExtent.maxy, 0.1) && - !msProjectionsDiffer( &(map->projection), &(layer->projection)) ) - { - double dfXFactor, dfYFactor; - - sSrcExtent.minx = (int)(sSrcExtent.minx + 0.5); - sSrcExtent.miny = (int)(sSrcExtent.miny + 0.5); - sSrcExtent.maxx = (int)(sSrcExtent.maxx + 0.5); - sSrcExtent.maxy = (int)(sSrcExtent.maxy + 0.5); - - if( (int)(sSrcExtent.maxx - sSrcExtent.minx + 0.5) == nDstXSize && - (int)(sSrcExtent.maxy - sSrcExtent.miny + 0.5) == nDstYSize ) - { - if( layer->debug ) - msDebug( "msResampleGDALToMap(): Request matching raster resolution and pixel boundaries. " - "No need to do resampling/reprojection.\n" ); - msFree(mask_rb); - return msDrawRasterLayerGDAL( map, layer, image, rb, hDS ); - } + !msProjectionsDiffer(&(map->projection), &(layer->projection))) { + double dfXFactor, dfYFactor; + + sSrcExtent.minx = (int)(sSrcExtent.minx + 0.5); + sSrcExtent.miny = (int)(sSrcExtent.miny + 0.5); + sSrcExtent.maxx = (int)(sSrcExtent.maxx + 0.5); + sSrcExtent.maxy = (int)(sSrcExtent.maxy + 0.5); + + if ((int)(sSrcExtent.maxx - sSrcExtent.minx + 0.5) == nDstXSize && + (int)(sSrcExtent.maxy - sSrcExtent.miny + 0.5) == nDstYSize) { + if (layer->debug) + msDebug("msResampleGDALToMap(): Request matching raster resolution and " + "pixel boundaries. " + "No need to do resampling/reprojection.\n"); + msFree(mask_rb); + return msDrawRasterLayerGDAL(map, layer, image, rb, hDS); + } - dfXFactor = (sSrcExtent.maxx - sSrcExtent.minx) / nDstXSize; - dfYFactor = (sSrcExtent.maxy - sSrcExtent.miny) / nDstYSize; - if( IS_ALMOST_INTEGER(dfXFactor, 1e-5) && - IS_ALMOST_INTEGER(dfYFactor, 1e-5) && - IS_ALMOST_INTEGER(sSrcExtent.minx/dfXFactor, 0.1) && - IS_ALMOST_INTEGER(sSrcExtent.miny/dfXFactor, 0.1) && - IS_ALMOST_INTEGER(sSrcExtent.maxx/dfYFactor, 0.1) && - IS_ALMOST_INTEGER(sSrcExtent.maxy/dfYFactor, 0.1) ) - { - bAddPixelMargin = MS_FALSE; - if( layer->debug ) - msDebug( "msResampleGDALToMap(): Request matching raster resolution " - "and pixel boundaries matching an integral subsampling factor\n" ); - } + dfXFactor = (sSrcExtent.maxx - sSrcExtent.minx) / nDstXSize; + dfYFactor = (sSrcExtent.maxy - sSrcExtent.miny) / nDstYSize; + if (IS_ALMOST_INTEGER(dfXFactor, 1e-5) && + IS_ALMOST_INTEGER(dfYFactor, 1e-5) && + IS_ALMOST_INTEGER(sSrcExtent.minx / dfXFactor, 0.1) && + IS_ALMOST_INTEGER(sSrcExtent.miny / dfXFactor, 0.1) && + IS_ALMOST_INTEGER(sSrcExtent.maxx / dfYFactor, 0.1) && + IS_ALMOST_INTEGER(sSrcExtent.maxy / dfYFactor, 0.1)) { + bAddPixelMargin = MS_FALSE; + if (layer->debug) + msDebug( + "msResampleGDALToMap(): Request matching raster resolution " + "and pixel boundaries matching an integral subsampling factor\n"); + } } /* -------------------------------------------------------------------- */ /* Project desired extents out by 2 pixels, and then strip to */ /* available data. */ /* -------------------------------------------------------------------- */ - memcpy( &sOrigSrcExtent, &sSrcExtent, sizeof(sSrcExtent) ); + memcpy(&sOrigSrcExtent, &sSrcExtent, sizeof(sSrcExtent)); - if( bAddPixelMargin ) - { - sSrcExtent.minx = floor(sSrcExtent.minx-1.0); - sSrcExtent.maxx = ceil (sSrcExtent.maxx+1.0); - sSrcExtent.miny = floor(sSrcExtent.miny-1.0); - sSrcExtent.maxy = ceil (sSrcExtent.maxy+1.0); + if (bAddPixelMargin) { + sSrcExtent.minx = floor(sSrcExtent.minx - 1.0); + sSrcExtent.maxx = ceil(sSrcExtent.maxx + 1.0); + sSrcExtent.miny = floor(sSrcExtent.miny - 1.0); + sSrcExtent.maxy = ceil(sSrcExtent.maxy + 1.0); } - sSrcExtent.minx = MS_MAX(0,sSrcExtent.minx); - sSrcExtent.maxx = MS_MIN(sSrcExtent.maxx, nSrcXSize ); - sSrcExtent.miny = MS_MAX(sSrcExtent.miny, 0 ); - sSrcExtent.maxy = MS_MIN(sSrcExtent.maxy, nSrcYSize ); + sSrcExtent.minx = MS_MAX(0, sSrcExtent.minx); + sSrcExtent.maxx = MS_MIN(sSrcExtent.maxx, nSrcXSize); + sSrcExtent.miny = MS_MAX(sSrcExtent.miny, 0); + sSrcExtent.maxy = MS_MIN(sSrcExtent.maxy, nSrcYSize); - if( sSrcExtent.maxx <= sSrcExtent.minx - || sSrcExtent.maxy <= sSrcExtent.miny ) { - if( layer->debug ) - msDebug( "msResampleGDALToMap(): no overlap ... no result.\n" ); + if (sSrcExtent.maxx <= sSrcExtent.minx || + sSrcExtent.maxy <= sSrcExtent.miny) { + if (layer->debug) + msDebug("msResampleGDALToMap(): no overlap ... no result.\n"); msFree(mask_rb); return 0; } @@ -1561,9 +1499,9 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* -------------------------------------------------------------------- */ dfOversampleRatio = 2.0; - if( CSLFetchNameValue( layer->processing, "OVERSAMPLE_RATIO" ) != NULL ) { + if (CSLFetchNameValue(layer->processing, "OVERSAMPLE_RATIO") != NULL) { dfOversampleRatio = - atof(CSLFetchNameValue( layer->processing, "OVERSAMPLE_RATIO" )); + atof(CSLFetchNameValue(layer->processing, "OVERSAMPLE_RATIO")); } /* -------------------------------------------------------------------- */ @@ -1572,9 +1510,8 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* at near to full resolution. Otherwise we will read the data */ /* at twice the resolution of the eventual map. */ /* -------------------------------------------------------------------- */ - dfNominalCellSize = - sqrt(adfSrcGeoTransform[1] * adfSrcGeoTransform[1] - + adfSrcGeoTransform[2] * adfSrcGeoTransform[2]); + dfNominalCellSize = sqrt(adfSrcGeoTransform[1] * adfSrcGeoTransform[1] + + adfSrcGeoTransform[2] * adfSrcGeoTransform[2]); /* Check first that the requested extent is not well beyond than the source */ /* raster. This might be the case for example if asking to visualize */ @@ -1582,21 +1519,24 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* But restrict that to rasters of modest size, otherwise we may end up */ /* requesting very large dimensions in other legit reprojection cases */ /* See https://github.com/mapserver/mapserver/issues/5402 */ - if( !(sOrigSrcExtent.minx <= -4 * nSrcXSize && sOrigSrcExtent.miny <= -4 * nSrcYSize && - sOrigSrcExtent.maxx >= 5 * nSrcXSize && sOrigSrcExtent.maxy >= 5 * nSrcYSize && - nSrcXSize < 4000 && nSrcYSize < 4000) - && (sOrigSrcExtent.maxx - sOrigSrcExtent.minx) > dfOversampleRatio * nDstXSize - && !CSLFetchBoolean( layer->processing, "LOAD_FULL_RES_IMAGE", FALSE )) + if (!(sOrigSrcExtent.minx <= -4 * nSrcXSize && + sOrigSrcExtent.miny <= -4 * nSrcYSize && + sOrigSrcExtent.maxx >= 5 * nSrcXSize && + sOrigSrcExtent.maxy >= 5 * nSrcYSize && nSrcXSize < 4000 && + nSrcYSize < 4000) && + (sOrigSrcExtent.maxx - sOrigSrcExtent.minx) > + dfOversampleRatio * nDstXSize && + !CSLFetchBoolean(layer->processing, "LOAD_FULL_RES_IMAGE", FALSE)) sDummyMap.cellsize = - (dfNominalCellSize * (sOrigSrcExtent.maxx - sOrigSrcExtent.minx)) - / (dfOversampleRatio * nDstXSize); + (dfNominalCellSize * (sOrigSrcExtent.maxx - sOrigSrcExtent.minx)) / + (dfOversampleRatio * nDstXSize); else sDummyMap.cellsize = dfNominalCellSize; - nLoadImgXSize = MS_MAX(1, (int) (sSrcExtent.maxx - sSrcExtent.minx) - * (dfNominalCellSize / sDummyMap.cellsize)); - nLoadImgYSize = MS_MAX(1, (int) (sSrcExtent.maxy - sSrcExtent.miny) - * (dfNominalCellSize / sDummyMap.cellsize)); + nLoadImgXSize = MS_MAX(1, (int)(sSrcExtent.maxx - sSrcExtent.minx) * + (dfNominalCellSize / sDummyMap.cellsize)); + nLoadImgYSize = MS_MAX(1, (int)(sSrcExtent.maxy - sSrcExtent.miny) * + (dfNominalCellSize / sDummyMap.cellsize)); /* ** Because the previous calculation involved some round off, we need @@ -1604,50 +1544,44 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, ** RAW_WINDOW (at least in X). Re: bug 1715. */ sDummyMap.cellsize = - ((sSrcExtent.maxx - sSrcExtent.minx) * dfNominalCellSize) - / nLoadImgXSize; + ((sSrcExtent.maxx - sSrcExtent.minx) * dfNominalCellSize) / nLoadImgXSize; - if( layer->debug ) - msDebug( "msResampleGDALToMap in effect: cellsize = %f\n", - sDummyMap.cellsize ); + if (layer->debug) + msDebug("msResampleGDALToMap in effect: cellsize = %f\n", + sDummyMap.cellsize); - adfSrcGeoTransform[0] += - + adfSrcGeoTransform[1] * sSrcExtent.minx - + adfSrcGeoTransform[2] * sSrcExtent.miny; + adfSrcGeoTransform[0] += +adfSrcGeoTransform[1] * sSrcExtent.minx + + adfSrcGeoTransform[2] * sSrcExtent.miny; adfSrcGeoTransform[1] *= (sDummyMap.cellsize / dfNominalCellSize); adfSrcGeoTransform[2] *= (sDummyMap.cellsize / dfNominalCellSize); - adfSrcGeoTransform[3] += - + adfSrcGeoTransform[4] * sSrcExtent.minx - + adfSrcGeoTransform[5] * sSrcExtent.miny; + adfSrcGeoTransform[3] += +adfSrcGeoTransform[4] * sSrcExtent.minx + + adfSrcGeoTransform[5] * sSrcExtent.miny; adfSrcGeoTransform[4] *= (sDummyMap.cellsize / dfNominalCellSize); adfSrcGeoTransform[5] *= (sDummyMap.cellsize / dfNominalCellSize); /* In the non-rotated case, make sure that the geotransform exactly */ /* matches the sSrcExtent, even if that generates non-square pixels (#1715) */ /* The rotated case should ideally be dealt with, but not for now... */ - if( adfSrcGeoTransform[2] == 0 && adfSrcGeoTransform[4] == 0 && + if (adfSrcGeoTransform[2] == 0 && adfSrcGeoTransform[4] == 0 && adfSrcGeoTransform[5] < 0 && /* But do that only if the pixels were square before, otherwise */ /* this is going to mess with source rasters whose pixels aren't at */ /* all square (#5445) */ fabs(fabs(adfSrcGeoTransform[1]) - fabs(adfSrcGeoTransform[5])) < - 0.01 * fabs(adfSrcGeoTransform[1]) ) - { - adfSrcGeoTransform[1] = (sSrcExtent.maxx - sSrcExtent.minx) * - dfNominalCellSize / nLoadImgXSize; - adfSrcGeoTransform[5] = -(sSrcExtent.maxy - sSrcExtent.miny) * - dfNominalCellSize / nLoadImgYSize; + 0.01 * fabs(adfSrcGeoTransform[1])) { + adfSrcGeoTransform[1] = + (sSrcExtent.maxx - sSrcExtent.minx) * dfNominalCellSize / nLoadImgXSize; + adfSrcGeoTransform[5] = -(sSrcExtent.maxy - sSrcExtent.miny) * + dfNominalCellSize / nLoadImgYSize; } - papszAlteredProcessing = CSLDuplicate( layer->processing ); - papszAlteredProcessing = - CSLSetNameValue( papszAlteredProcessing, "RAW_WINDOW", - CPLSPrintf( "%d %d %d %d", - (int) sSrcExtent.minx, - (int) sSrcExtent.miny, - (int) (sSrcExtent.maxx-sSrcExtent.minx), - (int) (sSrcExtent.maxy-sSrcExtent.miny))); + papszAlteredProcessing = CSLDuplicate(layer->processing); + papszAlteredProcessing = CSLSetNameValue( + papszAlteredProcessing, "RAW_WINDOW", + CPLSPrintf("%d %d %d %d", (int)sSrcExtent.minx, (int)sSrcExtent.miny, + (int)(sSrcExtent.maxx - sSrcExtent.minx), + (int)(sSrcExtent.maxy - sSrcExtent.miny))); /* -------------------------------------------------------------------- */ /* We clone this without referencing it knowing that the */ @@ -1660,7 +1594,7 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* We make a copy so we can easily modify the outputformat used */ /* for the temporary image to include transparentency support. */ /* -------------------------------------------------------------------- */ - sDummyMap.outputformat = msCloneOutputFormat( image->format ); + sDummyMap.outputformat = msCloneOutputFormat(image->format); sDummyMap.width = nLoadImgXSize; sDummyMap.height = nLoadImgYSize; sDummyMap.mappath = map->mappath; @@ -1673,40 +1607,45 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* as our transparent color, but ensure it is initalized in the */ /* map so that normal transparent avoidance will apply. */ /* -------------------------------------------------------------------- */ - if( MS_RENDERER_PLUGIN(sDummyMap.outputformat) ) { + if (MS_RENDERER_PLUGIN(sDummyMap.outputformat)) { assert(rb); msInitializeRendererVTable(sDummyMap.outputformat); - assert( sDummyMap.outputformat->imagemode == MS_IMAGEMODE_RGB - || sDummyMap.outputformat->imagemode == MS_IMAGEMODE_RGBA ); + assert(sDummyMap.outputformat->imagemode == MS_IMAGEMODE_RGB || + sDummyMap.outputformat->imagemode == MS_IMAGEMODE_RGBA); sDummyMap.outputformat->transparent = MS_TRUE; sDummyMap.outputformat->imagemode = MS_IMAGEMODE_RGBA; - MS_INIT_COLOR(sDummyMap.imagecolor,-1,-1,-1,255); + MS_INIT_COLOR(sDummyMap.imagecolor, -1, -1, -1, 255); } /* -------------------------------------------------------------------- */ /* Setup a dummy map object we can use to read from the source */ /* raster, with the newly established extents, and resolution. */ /* -------------------------------------------------------------------- */ - srcImage = msImageCreate( nLoadImgXSize, nLoadImgYSize, - sDummyMap.outputformat, NULL, NULL, - map->resolution, map->defresolution, &(sDummyMap.imagecolor)); + srcImage = msImageCreate(nLoadImgXSize, nLoadImgYSize, sDummyMap.outputformat, + NULL, NULL, map->resolution, map->defresolution, + &(sDummyMap.imagecolor)); if (srcImage == NULL) { msFree(mask_rb); return -1; /* msSetError() should have been called already */ } - if( MS_RENDERER_PLUGIN( srcImage->format ) ) { + if (MS_RENDERER_PLUGIN(srcImage->format)) { psrc_rb = &src_rb; - memset( psrc_rb, 0, sizeof(rasterBufferObj) ); - if( srcImage->format->vtable->supports_pixel_buffer ) { - if(MS_UNLIKELY(MS_FAILURE == srcImage->format->vtable->getRasterBufferHandle( srcImage, psrc_rb ))) { + memset(psrc_rb, 0, sizeof(rasterBufferObj)); + if (srcImage->format->vtable->supports_pixel_buffer) { + if (MS_UNLIKELY(MS_FAILURE == + srcImage->format->vtable->getRasterBufferHandle( + srcImage, psrc_rb))) { msFree(mask_rb); return -1; } } else { - if(MS_UNLIKELY(MS_FAILURE == srcImage->format->vtable->initializeRasterBuffer(psrc_rb,nLoadImgXSize, nLoadImgYSize,MS_IMAGEMODE_RGBA))) { + if (MS_UNLIKELY( + MS_FAILURE == + srcImage->format->vtable->initializeRasterBuffer( + psrc_rb, nLoadImgXSize, nLoadImgYSize, MS_IMAGEMODE_RGBA))) { msFree(mask_rb); return -1; } @@ -1719,22 +1658,22 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* -------------------------------------------------------------------- */ { char **papszSavedProcessing = layer->processing; - char* origMask = layer->mask; + char *origMask = layer->mask; layer->mask = NULL; layer->processing = papszAlteredProcessing; - result = msDrawRasterLayerGDAL( &sDummyMap, layer, srcImage, - psrc_rb, hDS ); + result = msDrawRasterLayerGDAL(&sDummyMap, layer, srcImage, psrc_rb, hDS); layer->processing = papszSavedProcessing; layer->mask = origMask; - CSLDestroy( papszAlteredProcessing ); + CSLDestroy(papszAlteredProcessing); - if( result ) { - if( MS_RENDERER_PLUGIN( srcImage->format ) && !srcImage->format->vtable->supports_pixel_buffer) + if (result) { + if (MS_RENDERER_PLUGIN(srcImage->format) && + !srcImage->format->vtable->supports_pixel_buffer) msFreeRasterBuffer(psrc_rb); - msFreeImage( srcImage ); + msFreeImage(srcImage); msFree(mask_rb); return result; @@ -1745,17 +1684,16 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* Setup transformations between our source image, and the */ /* target map image. */ /* -------------------------------------------------------------------- */ - pTCBData = msInitProjTransformer( &(layer->projection), - adfSrcGeoTransform, - &(map->projection), - adfDstGeoTransform ); + pTCBData = msInitProjTransformer(&(layer->projection), adfSrcGeoTransform, + &(map->projection), adfDstGeoTransform); - if( pTCBData == NULL ) { - if( layer->debug ) - msDebug( "msInitProjTransformer() returned NULL.\n" ); - if( MS_RENDERER_PLUGIN( srcImage->format ) && !srcImage->format->vtable->supports_pixel_buffer) + if (pTCBData == NULL) { + if (layer->debug) + msDebug("msInitProjTransformer() returned NULL.\n"); + if (MS_RENDERER_PLUGIN(srcImage->format) && + !srcImage->format->vtable->supports_pixel_buffer) msFreeRasterBuffer(psrc_rb); - msFreeImage( srcImage ); + msFreeImage(srcImage); msFree(mask_rb); return MS_PROJERR; } @@ -1764,44 +1702,41 @@ int msResampleGDALToMap( mapObj *map, layerObj *layer, imageObj *image, /* It is cheaper to use linear approximations as long as our */ /* error is modest (less than 0.333 pixels). */ /* -------------------------------------------------------------------- */ - pACBData = msInitApproxTransformer( msProjTransformer, pTCBData, 0.333 ); + pACBData = msInitApproxTransformer(msProjTransformer, pTCBData, 0.333); - if( msProjIsGeographicCRS(&(layer->projection)) ) - { - /* Does the raster cover a whole 360 deg range ? */ - if( nSrcXSize == (int)(adfInvSrcGeoTransform[1] * 360 + 0.5) ) - bWrapAtLeftRight = MS_TRUE; + if (msProjIsGeographicCRS(&(layer->projection))) { + /* Does the raster cover a whole 360 deg range ? */ + if (nSrcXSize == (int)(adfInvSrcGeoTransform[1] * 360 + 0.5)) + bWrapAtLeftRight = MS_TRUE; } /* -------------------------------------------------------------------- */ /* Perform the resampling. */ /* -------------------------------------------------------------------- */ - if( EQUAL(resampleMode,"AVERAGE") ) - result = - msAverageRasterResampler( srcImage, psrc_rb, image, rb, - msApproxTransformer, pACBData, - layer->debug, mask_rb ); - else if( EQUAL(resampleMode,"BILINEAR") ) - result = - msBilinearRasterResampler( srcImage, psrc_rb, image, rb, - msApproxTransformer, pACBData, - layer->debug, mask_rb, bWrapAtLeftRight ); + if (EQUAL(resampleMode, "AVERAGE")) + result = msAverageRasterResampler(srcImage, psrc_rb, image, rb, + msApproxTransformer, pACBData, + layer->debug, mask_rb); + else if (EQUAL(resampleMode, "BILINEAR")) + result = msBilinearRasterResampler(srcImage, psrc_rb, image, rb, + msApproxTransformer, pACBData, + layer->debug, mask_rb, bWrapAtLeftRight); else - result = - msNearestRasterResampler( srcImage, psrc_rb, image, rb, - msApproxTransformer, pACBData, - layer->debug, mask_rb, bWrapAtLeftRight ); + result = msNearestRasterResampler(srcImage, psrc_rb, image, rb, + msApproxTransformer, pACBData, + layer->debug, mask_rb, bWrapAtLeftRight); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ msFree(mask_rb); - if( MS_RENDERER_PLUGIN( srcImage->format ) && !srcImage->format->vtable->supports_pixel_buffer) + if (MS_RENDERER_PLUGIN(srcImage->format) && + !srcImage->format->vtable->supports_pixel_buffer) msFreeRasterBuffer(psrc_rb); - msFreeImage( srcImage ); + msFreeImage(srcImage); - msFreeProjTransformer( pTCBData ); - msFreeApproxTransformer( pACBData ); + msFreeProjTransformer(pTCBData); + msFreeApproxTransformer(pACBData); return result; } diff --git a/mapresample.h b/mapresample.h index c46bf0012b..f7d6a1f7f1 100644 --- a/mapresample.h +++ b/mapresample.h @@ -36,19 +36,16 @@ #include #include -typedef int (*SimpleTransformer)( void *pCBData, int nPoints, - double *x, double *y, int *panSuccess ); +typedef int (*SimpleTransformer)(void *pCBData, int nPoints, double *x, + double *y, int *panSuccess); -void *msInitProjTransformer( projectionObj *psSrc, - double *padfSrcGeoTransform, - projectionObj *psDst, - double *padfDstGeoTransform ); -void msFreeProjTransformer( void * ); -int msProjTransformer( void *pCBData, int nPoints, - double *x, double *y, int *panSuccess ); +void *msInitProjTransformer(projectionObj *psSrc, double *padfSrcGeoTransform, + projectionObj *psDst, double *padfDstGeoTransform); +void msFreeProjTransformer(void *); +int msProjTransformer(void *pCBData, int nPoints, double *x, double *y, + int *panSuccess); -int msResampleGDALToMap( mapObj *map, layerObj *layer, - imageObj *image, rasterBufferObj *rb, - GDALDatasetH hDS ); +int msResampleGDALToMap(mapObj *map, layerObj *layer, imageObj *image, + rasterBufferObj *rb, GDALDatasetH hDS); #endif /* ndef RESAMPLE_H */ diff --git a/mapscale.c b/mapscale.c index 334191f8d4..c78a5d5e0e 100644 --- a/mapscale.c +++ b/mapscale.c @@ -29,127 +29,134 @@ #include "mapserver.h" - - #define VMARGIN 3 /* buffer around the scalebar */ #define HMARGIN 3 #define VSPACING .8 /* spacing (% of font height) between scalebar and text */ -#define VSLOP 5 /* makes things fit a bit better vertically */ +#define VSLOP 5 /* makes things fit a bit better vertically */ /* ** Match this with with unit enumerations is mapserver.h */ -static char *unitText[9]= {"in", "ft", "mi", "m", "km", "dd", "??", "??", "NM"}; /* MS_PIXEL and MS_PERCENTAGE not used */ -double inchesPerUnit[9]= {1, 12, 63360.0, 39.3701, 39370.1, 4374754, 1, 1, 72913.3858 }; - -static double roundInterval(double d) -{ - if(d<.001) - return(MS_NINT(d*10000)/10000.0); - if(d<.01) - return(MS_NINT(d*1000)/1000.0); - if(d<.1) - return(MS_NINT(d*100)/100.0); - if(d<1) - return(MS_NINT(d*10)/10.0); - if(d<100) - return(MS_NINT(d)); - if(d<1000) - return(MS_NINT(d/10) * 10); - if(d<10000) - return(MS_NINT(d/100) * 100); - if(d<100000) - return(MS_NINT(d/1000) * 1000); - if(d<1000000) - return(MS_NINT(d/10000) * 10000); - if(d<10000000) - return(MS_NINT(d/100000) * 100000); - if(d<100000000) - return(MS_NINT(d/1000000) * 1000000); - - return(-1); +static char *unitText[9] = { + "in", "ft", "mi", "m", "km", + "dd", "??", "??", "NM"}; /* MS_PIXEL and MS_PERCENTAGE not used */ +double inchesPerUnit[9] = {1, 12, 63360.0, 39.3701, 39370.1, + 4374754, 1, 1, 72913.3858}; + +static double roundInterval(double d) { + if (d < .001) + return (MS_NINT(d * 10000) / 10000.0); + if (d < .01) + return (MS_NINT(d * 1000) / 1000.0); + if (d < .1) + return (MS_NINT(d * 100) / 100.0); + if (d < 1) + return (MS_NINT(d * 10) / 10.0); + if (d < 100) + return (MS_NINT(d)); + if (d < 1000) + return (MS_NINT(d / 10) * 10); + if (d < 10000) + return (MS_NINT(d / 100) * 100); + if (d < 100000) + return (MS_NINT(d / 1000) * 1000); + if (d < 1000000) + return (MS_NINT(d / 10000) * 10000); + if (d < 10000000) + return (MS_NINT(d / 100000) * 100000); + if (d < 100000000) + return (MS_NINT(d / 1000000) * 1000000); + + return (-1); } /* -** Calculate the approximate scale based on a few parameters. Note that this assumes the scale is -** the same in the x direction as in the y direction, so run msAdjustExtent(...) first. +** Calculate the approximate scale based on a few parameters. Note that this +*assumes the scale is +** the same in the x direction as in the y direction, so run msAdjustExtent(...) +*first. */ -int msCalculateScale(rectObj extent, int units, int width, int height, double resolution, double *scale) -{ +int msCalculateScale(rectObj extent, int units, int width, int height, + double resolution, double *scale) { double md, gd, center_y; /* if((extent.maxx == extent.minx) || (extent.maxy == extent.miny)) */ - if(!MS_VALID_EXTENT(extent)) { - msSetError(MS_MISCERR, "Invalid image extent, minx=%lf, miny=%lf, maxx=%lf, maxy=%lf.", "msCalculateScale()", extent.minx, extent.miny, extent.maxx, extent.maxy); - return(MS_FAILURE); + if (!MS_VALID_EXTENT(extent)) { + msSetError(MS_MISCERR, + "Invalid image extent, minx=%lf, miny=%lf, maxx=%lf, maxy=%lf.", + "msCalculateScale()", extent.minx, extent.miny, extent.maxx, + extent.maxy); + return (MS_FAILURE); } - if((width <= 0) || (height <= 0)) { - msSetError(MS_MISCERR, "Invalid image width or height.", "msCalculateScale()"); - return(MS_FAILURE); + if ((width <= 0) || (height <= 0)) { + msSetError(MS_MISCERR, "Invalid image width or height.", + "msCalculateScale()"); + return (MS_FAILURE); } switch (units) { - case(MS_DD): - case(MS_METERS): - case(MS_KILOMETERS): - case(MS_MILES): - case(MS_NAUTICALMILES): - case(MS_INCHES): - case(MS_FEET): - center_y = (extent.miny+extent.maxy)/2.0; - md = (width-1)/(resolution*msInchesPerUnit(units, center_y)); /* remember, we use a pixel-center to pixel-center extent, hence the width-1 */ - gd = extent.maxx - extent.minx; - *scale = gd/md; - break; - default: - *scale = -1; /* this is not an error */ - break; + case (MS_DD): + case (MS_METERS): + case (MS_KILOMETERS): + case (MS_MILES): + case (MS_NAUTICALMILES): + case (MS_INCHES): + case (MS_FEET): + center_y = (extent.miny + extent.maxy) / 2.0; + md = (width - 1) / + (resolution * + msInchesPerUnit( + units, center_y)); /* remember, we use a pixel-center to + pixel-center extent, hence the width-1 */ + gd = extent.maxx - extent.minx; + *scale = gd / md; + break; + default: + *scale = -1; /* this is not an error */ + break; } - return(MS_SUCCESS); + return (MS_SUCCESS); } -double msInchesPerUnit(int units, double center_lat) -{ +double msInchesPerUnit(int units, double center_lat) { (void)center_lat; double lat_adj = 1.0, ipu = 1.0; switch (units) { - case(MS_METERS): - case(MS_KILOMETERS): - case(MS_MILES): - case(MS_NAUTICALMILES): - case(MS_INCHES): - case(MS_FEET): - ipu = inchesPerUnit[units]; - break; - case(MS_DD): - /* With geographical (DD) coordinates, we adjust the inchesPerUnit - * based on the latitude of the center of the view. For this we assume - * we have a perfect sphere and just use cos(lat) in our calculation. - */ + case (MS_METERS): + case (MS_KILOMETERS): + case (MS_MILES): + case (MS_NAUTICALMILES): + case (MS_INCHES): + case (MS_FEET): + ipu = inchesPerUnit[units]; + break; + case (MS_DD): + /* With geographical (DD) coordinates, we adjust the inchesPerUnit + * based on the latitude of the center of the view. For this we assume + * we have a perfect sphere and just use cos(lat) in our calculation. + */ #ifdef ENABLE_VARIABLE_INCHES_PER_DEGREE - if (center_lat != 0.0) { - double cos_lat; - cos_lat = cos(MS_PI*center_lat/180.0); - lat_adj = sqrt(1+cos_lat*cos_lat)/sqrt(2.0); - } + if (center_lat != 0.0) { + double cos_lat; + cos_lat = cos(MS_PI * center_lat / 180.0); + lat_adj = sqrt(1 + cos_lat * cos_lat) / sqrt(2.0); + } #endif - ipu = inchesPerUnit[units]*lat_adj; - break; - default: - break; + ipu = inchesPerUnit[units] * lat_adj; + break; + default: + break; } return ipu; } - #define X_STEP_SIZE 5 -imageObj *msDrawScalebar(mapObj *map) -{ +imageObj *msDrawScalebar(mapObj *map) { int status; char label[32]; double i, msx; @@ -157,7 +164,7 @@ imageObj *msDrawScalebar(mapObj *map) int isx, sx, sy, ox, oy, state, dsx; pointObj p; rectObj r; - imageObj *image = NULL; + imageObj *image = NULL; double fontWidth, fontHeight; outputFormatObj *format = NULL; strokeStyleObj strokeStyle = {0}; @@ -167,232 +174,252 @@ imageObj *msDrawScalebar(mapObj *map) textSymbolObj ts; rendererVTableObj *renderer; - strokeStyle.patternlength=0; + strokeStyle.patternlength = 0; initTextSymbol(&ts); - if((int)map->units == -1) { + if ((int)map->units == -1) { msSetError(MS_MISCERR, "Map units not set.", "msDrawScalebar()"); - return(NULL); + return (NULL); } renderer = MS_MAP_RENDERER(map); - if(!renderer || !MS_MAP_RENDERER(map)->supports_pixel_buffer) { - msSetError(MS_MISCERR, "Outputformat not supported for scalebar", "msDrawScalebar()"); - return(NULL); + if (!renderer || !MS_MAP_RENDERER(map)->supports_pixel_buffer) { + msSetError(MS_MISCERR, "Outputformat not supported for scalebar", + "msDrawScalebar()"); + return (NULL); } - - msPopulateTextSymbolForLabelAndString(&ts,&map->scalebar.label,msStrdup("0123456789"),1.0,map->resolution/map->defresolution, 0); + + msPopulateTextSymbolForLabelAndString( + &ts, &map->scalebar.label, msStrdup("0123456789"), 1.0, + map->resolution / map->defresolution, 0); /* - * A string containing the ten decimal digits is rendered to compute an average cell size - * for each number, which is used later to place labels on the scalebar. + * A string containing the ten decimal digits is rendered to compute an + * average cell size for each number, which is used later to place labels on + * the scalebar. */ - - if(msGetTextSymbolSize(map,&ts,&r) != MS_SUCCESS) { + if (msGetTextSymbolSize(map, &ts, &r) != MS_SUCCESS) { return NULL; } - fontWidth = (r.maxx-r.minx)/10.0; - fontHeight = r.maxy -r.miny; + fontWidth = (r.maxx - r.minx) / 10.0; + fontHeight = r.maxy - r.miny; map->cellsize = msAdjustExtent(&(map->extent), map->width, map->height); - status = msCalculateScale(map->extent, map->units, map->width, map->height, map->resolution, &map->scaledenom); - if(status != MS_SUCCESS) { - return(NULL); + status = msCalculateScale(map->extent, map->units, map->width, map->height, + map->resolution, &map->scaledenom); + if (status != MS_SUCCESS) { + return (NULL); } - dsx = map->scalebar.width - 2*HMARGIN; + dsx = map->scalebar.width - 2 * HMARGIN; do { - msx = (map->cellsize * dsx)/(msInchesPerUnit(map->scalebar.units,0)/msInchesPerUnit(map->units,0)); - i = roundInterval(msx/map->scalebar.intervals); - snprintf(label, sizeof(label), "%g", map->scalebar.intervals*i); /* last label */ - isx = MS_NINT((i/(msInchesPerUnit(map->units,0)/msInchesPerUnit(map->scalebar.units,0)))/map->cellsize); - sx = (map->scalebar.intervals*isx) + MS_NINT((1.5 + strlen(label)/2.0 + strlen(unitText[map->scalebar.units]))*fontWidth); - - if(sx <= (map->scalebar.width - 2*HMARGIN)) break; /* it will fit */ - - dsx -= X_STEP_SIZE; /* change the desired size in hopes that it will fit in user supplied width */ - } while(1); - - sy = (2*VMARGIN) + MS_NINT(VSPACING*fontHeight) + fontHeight + map->scalebar.height - VSLOP; + msx = (map->cellsize * dsx) / (msInchesPerUnit(map->scalebar.units, 0) / + msInchesPerUnit(map->units, 0)); + i = roundInterval(msx / map->scalebar.intervals); + snprintf(label, sizeof(label), "%g", + map->scalebar.intervals * i); /* last label */ + isx = MS_NINT((i / (msInchesPerUnit(map->units, 0) / + msInchesPerUnit(map->scalebar.units, 0))) / + map->cellsize); + sx = (map->scalebar.intervals * isx) + + MS_NINT((1.5 + strlen(label) / 2.0 + + strlen(unitText[map->scalebar.units])) * + fontWidth); + + if (sx <= (map->scalebar.width - 2 * HMARGIN)) + break; /* it will fit */ + + dsx -= X_STEP_SIZE; /* change the desired size in hopes that it will fit in + user supplied width */ + } while (1); + + sy = (2 * VMARGIN) + MS_NINT(VSPACING * fontHeight) + fontHeight + + map->scalebar.height - VSLOP; /*Ensure we have an image format representing the options for the scalebar.*/ - msApplyOutputFormat( &format, map->outputformat, map->scalebar.transparent); + msApplyOutputFormat(&format, map->outputformat, map->scalebar.transparent); - if(map->scalebar.transparent == MS_OFF) { - if(!MS_VALID_COLOR(map->scalebar.imagecolor)) - MS_INIT_COLOR(map->scalebar.imagecolor,255,255,255,255); + if (map->scalebar.transparent == MS_OFF) { + if (!MS_VALID_COLOR(map->scalebar.imagecolor)) + MS_INIT_COLOR(map->scalebar.imagecolor, 255, 255, 255, 255); } - image = msImageCreate(map->scalebar.width, sy, format, - map->web.imagepath, map->web.imageurl, map->resolution, map->defresolution, &map->scalebar.imagecolor); + image = msImageCreate(map->scalebar.width, sy, format, map->web.imagepath, + map->web.imageurl, map->resolution, map->defresolution, + &map->scalebar.imagecolor); /* did we succeed in creating the image? */ - if(!image) { + if (!image) { msSetError(MS_MISCERR, "Unable to initialize image.", "msDrawScalebar()"); return NULL; } image->map = map; /* drop this reference to output format */ - msApplyOutputFormat( &format, NULL, MS_NOOVERRIDE); - - switch(map->scalebar.align) { - case(MS_ALIGN_LEFT): - ox = HMARGIN; - break; - case(MS_ALIGN_RIGHT): - ox = MS_NINT((map->scalebar.width - sx) + fontWidth); - break; - default: - ox = MS_NINT((map->scalebar.width - sx)/2.0 + fontWidth/2.0); /* center the computed scalebar */ + msApplyOutputFormat(&format, NULL, MS_NOOVERRIDE); + + switch (map->scalebar.align) { + case (MS_ALIGN_LEFT): + ox = HMARGIN; + break; + case (MS_ALIGN_RIGHT): + ox = MS_NINT((map->scalebar.width - sx) + fontWidth); + break; + default: + ox = MS_NINT((map->scalebar.width - sx) / 2.0 + + fontWidth / 2.0); /* center the computed scalebar */ } oy = VMARGIN; - switch(map->scalebar.style) { - case(0): { - - line.numpoints = 5; - line.point = points; - shape.line = &line; - shape.numlines = 1; - if(MS_VALID_COLOR(map->scalebar.color)) { - INIT_STROKE_STYLE(strokeStyle); - strokeStyle.color = &map->scalebar.outlinecolor; - strokeStyle.color->alpha = 255; - strokeStyle.width = 1; + switch (map->scalebar.style) { + case (0): { + + line.numpoints = 5; + line.point = points; + shape.line = &line; + shape.numlines = 1; + if (MS_VALID_COLOR(map->scalebar.color)) { + INIT_STROKE_STYLE(strokeStyle); + strokeStyle.color = &map->scalebar.outlinecolor; + strokeStyle.color->alpha = 255; + strokeStyle.width = 1; + } + map->scalebar.backgroundcolor.alpha = 255; + map->scalebar.color.alpha = 255; + state = 1; /* 1 means filled */ + for (j = 0; j < map->scalebar.intervals; j++) { + points[0].x = points[4].x = points[3].x = ox + j * isx + 0.5; + points[0].y = points[4].y = points[1].y = oy + 0.5; + points[1].x = points[2].x = ox + (j + 1) * isx + 0.5; + points[2].y = points[3].y = oy + map->scalebar.height + 0.5; + if (state == 1 && MS_VALID_COLOR(map->scalebar.color)) + status = renderer->renderPolygon(image, &shape, &map->scalebar.color); + else if (MS_VALID_COLOR(map->scalebar.backgroundcolor)) + status = renderer->renderPolygon(image, &shape, + &map->scalebar.backgroundcolor); + + if (MS_UNLIKELY(status == MS_FAILURE)) { + goto scale_cleanup; } - map->scalebar.backgroundcolor.alpha = 255; - map->scalebar.color.alpha = 255; - state = 1; /* 1 means filled */ - for(j=0; jscalebar.intervals; j++) { - points[0].x = points[4].x = points[3].x = ox + j*isx + 0.5; - points[0].y = points[4].y = points[1].y = oy + 0.5; - points[1].x = points[2].x = ox + (j+1)*isx + 0.5; - points[2].y = points[3].y = oy + map->scalebar.height + 0.5; - if(state == 1 && MS_VALID_COLOR(map->scalebar.color)) - status = renderer->renderPolygon(image,&shape,&map->scalebar.color); - else if(MS_VALID_COLOR(map->scalebar.backgroundcolor)) - status = renderer->renderPolygon(image,&shape,&map->scalebar.backgroundcolor); - - if(MS_UNLIKELY(status == MS_FAILURE)) { - goto scale_cleanup; - } - if(strokeStyle.color) { - status = renderer->renderLine(image,&shape,&strokeStyle); + if (strokeStyle.color) { + status = renderer->renderLine(image, &shape, &strokeStyle); - if(MS_UNLIKELY(status == MS_FAILURE)) { - goto scale_cleanup; - } - } - - sprintf(label, "%g", j*i); - map->scalebar.label.position = MS_CC; - p.x = ox + j*isx; /* + MS_NINT(fontPtr->w/2); */ - p.y = oy + map->scalebar.height + MS_NINT(VSPACING*fontHeight); - status = msDrawLabel(map,image,p,msStrdup(label),&map->scalebar.label,1.0); - if(MS_UNLIKELY(status == MS_FAILURE)) { + if (MS_UNLIKELY(status == MS_FAILURE)) { goto scale_cleanup; } - state = -state; } - sprintf(label, "%g", j*i); - ox = ox + j*isx - MS_NINT((strlen(label)*fontWidth)/2.0); - sprintf(label, "%g %s", j*i, unitText[map->scalebar.units]); - map->scalebar.label.position = MS_CR; - p.x = ox; /* + MS_NINT(fontPtr->w/2); */ - p.y = oy + map->scalebar.height + MS_NINT(VSPACING*fontHeight); - status = msDrawLabel(map,image,p,msStrdup(label),&map->scalebar.label,1.0); - if(MS_UNLIKELY(status == MS_FAILURE)) { + + sprintf(label, "%g", j * i); + map->scalebar.label.position = MS_CC; + p.x = ox + j * isx; /* + MS_NINT(fontPtr->w/2); */ + p.y = oy + map->scalebar.height + MS_NINT(VSPACING * fontHeight); + status = msDrawLabel(map, image, p, msStrdup(label), &map->scalebar.label, + 1.0); + if (MS_UNLIKELY(status == MS_FAILURE)) { goto scale_cleanup; } - break; + state = -state; + } + sprintf(label, "%g", j * i); + ox = ox + j * isx - MS_NINT((strlen(label) * fontWidth) / 2.0); + sprintf(label, "%g %s", j * i, unitText[map->scalebar.units]); + map->scalebar.label.position = MS_CR; + p.x = ox; /* + MS_NINT(fontPtr->w/2); */ + p.y = oy + map->scalebar.height + MS_NINT(VSPACING * fontHeight); + status = + msDrawLabel(map, image, p, msStrdup(label), &map->scalebar.label, 1.0); + if (MS_UNLIKELY(status == MS_FAILURE)) { + goto scale_cleanup; + } + break; + } + case (1): { + line.numpoints = 2; + line.point = points; + shape.line = &line; + shape.numlines = 1; + if (MS_VALID_COLOR(map->scalebar.color)) { + strokeStyle.width = 1; + strokeStyle.color = &map->scalebar.color; } - case(1): { - line.numpoints = 2; - line.point = points; - shape.line = &line; - shape.numlines = 1; - if(MS_VALID_COLOR(map->scalebar.color)) { - strokeStyle.width = 1; - strokeStyle.color = &map->scalebar.color; - } - points[0].y = points[1].y = oy; - points[0].x = ox; - points[1].x = ox + isx*map->scalebar.intervals; - status = renderer->renderLine(image,&shape,&strokeStyle); - if(MS_UNLIKELY(status == MS_FAILURE)) { + points[0].y = points[1].y = oy; + points[0].x = ox; + points[1].x = ox + isx * map->scalebar.intervals; + status = renderer->renderLine(image, &shape, &strokeStyle); + if (MS_UNLIKELY(status == MS_FAILURE)) { + goto scale_cleanup; + } + + points[0].y = oy; + points[1].y = oy + map->scalebar.height; + p.y = oy + map->scalebar.height + MS_NINT(VSPACING * fontHeight); + for (j = 0; j <= map->scalebar.intervals; j++) { + points[0].x = points[1].x = ox + j * isx; + status = renderer->renderLine(image, &shape, &strokeStyle); + if (MS_UNLIKELY(status == MS_FAILURE)) { goto scale_cleanup; } - points[0].y = oy; - points[1].y = oy + map->scalebar.height; - p.y = oy + map->scalebar.height + MS_NINT(VSPACING*fontHeight); - for(j=0; j<=map->scalebar.intervals; j++) { - points[0].x = points[1].x = ox + j*isx; - status = renderer->renderLine(image,&shape,&strokeStyle); - if(MS_UNLIKELY(status == MS_FAILURE)) { - goto scale_cleanup; - } - - sprintf(label, "%g", j*i); - if(j!=map->scalebar.intervals) { - map->scalebar.label.position = MS_CC; - p.x = ox + j*isx; /* + MS_NINT(fontPtr->w/2); */ - } else { - sprintf(label, "%g %s", j*i, unitText[map->scalebar.units]); - map->scalebar.label.position = MS_CR; - p.x = ox + j*isx - MS_NINT((strlen(label)*fontWidth)/2.0); - } - status = msDrawLabel(map,image,p,msStrdup(label),&map->scalebar.label,1.0); - if(MS_UNLIKELY(status == MS_FAILURE)) { - goto scale_cleanup; - } + sprintf(label, "%g", j * i); + if (j != map->scalebar.intervals) { + map->scalebar.label.position = MS_CC; + p.x = ox + j * isx; /* + MS_NINT(fontPtr->w/2); */ + } else { + sprintf(label, "%g %s", j * i, unitText[map->scalebar.units]); + map->scalebar.label.position = MS_CR; + p.x = ox + j * isx - MS_NINT((strlen(label) * fontWidth) / 2.0); + } + status = msDrawLabel(map, image, p, msStrdup(label), &map->scalebar.label, + 1.0); + if (MS_UNLIKELY(status == MS_FAILURE)) { + goto scale_cleanup; } - break; } - default: - msSetError(MS_MISCERR, "Unsupported scalebar style.", "msDrawScalebar()"); - return(NULL); + break; + } + default: + msSetError(MS_MISCERR, "Unsupported scalebar style.", "msDrawScalebar()"); + return (NULL); } scale_cleanup: freeTextSymbol(&ts); - if(MS_UNLIKELY(status == MS_FAILURE)) { + if (MS_UNLIKELY(status == MS_FAILURE)) { msFreeImage(image); return NULL; } - return(image); - + return (image); } -int msEmbedScalebar(mapObj *map, imageObj *img) -{ - int l,index,s,status = MS_SUCCESS; +int msEmbedScalebar(mapObj *map, imageObj *img) { + int l, index, s, status = MS_SUCCESS; pointObj point; imageObj *image = NULL; rendererVTableObj *renderer; symbolObj *embededSymbol; - char* imageType = NULL; + char *imageType = NULL; index = msGetSymbolIndex(&(map->symbolset), "scalebar", MS_FALSE); - if(index != -1) - msRemoveSymbol(&(map->symbolset), index); /* remove cached symbol in case the function is called multiple - times with different zoom levels */ + if (index != -1) + msRemoveSymbol(&(map->symbolset), + index); /* remove cached symbol in case the function is + called multiple times with different zoom levels */ - if((embededSymbol=msGrowSymbolSet(&map->symbolset)) == NULL) + if ((embededSymbol = msGrowSymbolSet(&map->symbolset)) == NULL) return MS_FAILURE; s = map->symbolset.numsymbols; map->symbolset.numsymbols++; - if(!MS_RENDERER_PLUGIN(map->outputformat) || !MS_MAP_RENDERER(map)->supports_pixel_buffer) { + if (!MS_RENDERER_PLUGIN(map->outputformat) || + !MS_MAP_RENDERER(map)->supports_pixel_buffer) { imageType = msStrdup(map->imagetype); /* save format */ - if MS_DRIVER_CAIRO(map->outputformat) - map->outputformat = msSelectOutputFormat( map, "cairopng" ); + if MS_DRIVER_CAIRO (map->outputformat) + map->outputformat = msSelectOutputFormat(map, "cairopng"); else - map->outputformat = msSelectOutputFormat( map, "png" ); - + map->outputformat = msSelectOutputFormat(map, "png"); + msInitializeRendererVTable(map->outputformat); } renderer = MS_MAP_RENDERER(map); @@ -400,17 +427,20 @@ int msEmbedScalebar(mapObj *map, imageObj *img) image = msDrawScalebar(map); if (imageType) { - map->outputformat = msSelectOutputFormat( map, imageType ); /* restore format */ + map->outputformat = + msSelectOutputFormat(map, imageType); /* restore format */ msFree(imageType); } - if(!image) { + if (!image) { return MS_FAILURE; } - embededSymbol->pixmap_buffer = calloc(1,sizeof(rasterBufferObj)); - MS_CHECK_ALLOC(embededSymbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); + embededSymbol->pixmap_buffer = calloc(1, sizeof(rasterBufferObj)); + MS_CHECK_ALLOC(embededSymbol->pixmap_buffer, sizeof(rasterBufferObj), + MS_FAILURE); - if(MS_SUCCESS != renderer->getRasterBufferCopy(image,embededSymbol->pixmap_buffer)) { + if (MS_SUCCESS != + renderer->getRasterBufferCopy(image, embededSymbol->pixmap_buffer)) { return MS_FAILURE; } @@ -418,52 +448,67 @@ int msEmbedScalebar(mapObj *map, imageObj *img) embededSymbol->name = msStrdup("scalebar"); embededSymbol->sizex = embededSymbol->pixmap_buffer->width; embededSymbol->sizey = embededSymbol->pixmap_buffer->height; - if(map->scalebar.transparent) { + if (map->scalebar.transparent) { embededSymbol->transparent = MS_TRUE; embededSymbol->transparentcolor = 0; } - switch(map->scalebar.position) { - case(MS_LL): - point.x = MS_NINT(embededSymbol->pixmap_buffer->width/2.0) + map->scalebar.offsetx; - point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0) - map->scalebar.offsety; - break; - case(MS_LR): - point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width/2.0) - map->scalebar.offsetx; - point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0) - map->scalebar.offsety; - break; - case(MS_LC): - point.x = MS_NINT(map->width/2.0) + map->scalebar.offsetx; - point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0) - map->scalebar.offsety; - break; - case(MS_UR): - point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width/2.0) - map->scalebar.offsetx; - point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0) + map->scalebar.offsety; - break; - case(MS_UL): - point.x = MS_NINT(embededSymbol->pixmap_buffer->width/2.0) + map->scalebar.offsetx; - point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0) + map->scalebar.offsety; - break; - case(MS_UC): - point.x = MS_NINT(map->width/2.0) + map->scalebar.offsetx; - point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0) + map->scalebar.offsety; - break; + switch (map->scalebar.position) { + case (MS_LL): + point.x = MS_NINT(embededSymbol->pixmap_buffer->width / 2.0) + + map->scalebar.offsetx; + point.y = map->height - + MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) - + map->scalebar.offsety; + break; + case (MS_LR): + point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width / 2.0) - + map->scalebar.offsetx; + point.y = map->height - + MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) - + map->scalebar.offsety; + break; + case (MS_LC): + point.x = MS_NINT(map->width / 2.0) + map->scalebar.offsetx; + point.y = map->height - + MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) - + map->scalebar.offsety; + break; + case (MS_UR): + point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width / 2.0) - + map->scalebar.offsetx; + point.y = MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) + + map->scalebar.offsety; + break; + case (MS_UL): + point.x = MS_NINT(embededSymbol->pixmap_buffer->width / 2.0) + + map->scalebar.offsetx; + point.y = MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) + + map->scalebar.offsety; + break; + case (MS_UC): + point.x = MS_NINT(map->width / 2.0) + map->scalebar.offsetx; + point.y = MS_NINT(embededSymbol->pixmap_buffer->height / 2.0) + + map->scalebar.offsety; + break; } l = msGetLayerIndex(map, "__embed__scalebar"); - if(l == -1) { + if (l == -1) { if (msGrowMapLayers(map) == NULL) - return(-1); + return (-1); l = map->numlayers; map->numlayers++; - if(initLayer((GET_LAYER(map, l)), map) == -1) return(-1); + if (initLayer((GET_LAYER(map, l)), map) == -1) + return (-1); GET_LAYER(map, l)->name = msStrdup("__embed__scalebar"); GET_LAYER(map, l)->type = MS_LAYER_POINT; - if (msGrowLayerClasses( GET_LAYER(map, l) ) == NULL) - return(-1); + if (msGrowLayerClasses(GET_LAYER(map, l)) == NULL) + return (-1); - if(initClass(GET_LAYER(map, l)->class[0]) == -1) return(-1); + if (initClass(GET_LAYER(map, l)->class[0]) == -1) + return (-1); GET_LAYER(map, l)->numclasses = 1; /* so we make sure to free it */ /* update the layer order list with the layer's index. */ @@ -471,41 +516,48 @@ int msEmbedScalebar(mapObj *map, imageObj *img) } GET_LAYER(map, l)->status = MS_ON; - if(map->scalebar.postlabelcache) { /* add it directly to the image */ - if(msMaybeAllocateClassStyle(GET_LAYER(map, l)->class[0], 0)==MS_FAILURE) return MS_FAILURE; + if (map->scalebar.postlabelcache) { /* add it directly to the image */ + if (msMaybeAllocateClassStyle(GET_LAYER(map, l)->class[0], 0) == MS_FAILURE) + return MS_FAILURE; GET_LAYER(map, l)->class[0]->styles[0]->symbol = s; - status = msDrawMarkerSymbol(map, img, &point, GET_LAYER(map, l)->class[0]->styles[0], 1.0); - if(MS_UNLIKELY(status == MS_FAILURE)) { + status = msDrawMarkerSymbol(map, img, &point, + GET_LAYER(map, l)->class[0] -> styles[0], 1.0); + if (MS_UNLIKELY(status == MS_FAILURE)) { goto embed_cleanup; } } else { - if(!GET_LAYER(map, l)->class[0]->labels) { - if(msGrowClassLabels(GET_LAYER(map, l)->class[0]) == NULL) return MS_FAILURE; - initLabel(GET_LAYER(map, l)->class[0]->labels[0]); + if (!GET_LAYER(map, l)->class[0] -> labels) { + if (msGrowClassLabels(GET_LAYER(map, l)->class[0]) == NULL) + return MS_FAILURE; + initLabel(GET_LAYER(map, l)->class[0] -> labels[0]); GET_LAYER(map, l)->class[0]->numlabels = 1; GET_LAYER(map, l)->class[0]->labels[0]->force = MS_TRUE; - GET_LAYER(map, l)->class[0]->labels[0]->size = MS_MEDIUM; /* must set a size to have a valid label definition */ + GET_LAYER(map, l)->class[0]->labels[0]->size = + MS_MEDIUM; /* must set a size to have a valid label definition */ GET_LAYER(map, l)->class[0]->labels[0]->priority = MS_MAX_LABEL_PRIORITY; } - if(GET_LAYER(map, l)->class[0]->labels[0]->numstyles == 0) { - if(msGrowLabelStyles(GET_LAYER(map,l)->class[0]->labels[0]) == NULL) - return(MS_FAILURE); - GET_LAYER(map,l)->class[0]->labels[0]->numstyles = 1; - initStyle(GET_LAYER(map,l)->class[0]->labels[0]->styles[0]); - GET_LAYER(map,l)->class[0]->labels[0]->styles[0]->_geomtransform.type = MS_GEOMTRANSFORM_LABELPOINT; + if (GET_LAYER(map, l)->class[0] -> labels[0] -> numstyles == 0) { + if (msGrowLabelStyles(GET_LAYER(map, l)->class[0] -> labels[0]) == NULL) + return (MS_FAILURE); + GET_LAYER(map, l)->class[0]->labels[0]->numstyles = 1; + initStyle(GET_LAYER(map, l)->class[0] -> labels[0] -> styles[0]); + GET_LAYER(map, l)->class[0]->labels[0]->styles[0]->_geomtransform.type = + MS_GEOMTRANSFORM_LABELPOINT; } - GET_LAYER(map,l)->class[0]->labels[0]->styles[0]->symbol = s; - status = msAddLabel(map, img, GET_LAYER(map, l)->class[0]->labels[0], l, 0, NULL, &point, -1, NULL); - if(MS_UNLIKELY(status == MS_FAILURE)) { + GET_LAYER(map, l)->class[0]->labels[0]->styles[0]->symbol = s; + status = msAddLabel(map, img, GET_LAYER(map, l)->class[0] -> labels[0], l, + 0, NULL, &point, -1, NULL); + if (MS_UNLIKELY(status == MS_FAILURE)) { goto embed_cleanup; } } embed_cleanup: - /* Mark layer as deleted so that it doesn't interfere with html legends or with saving maps */ + /* Mark layer as deleted so that it doesn't interfere with html legends or + * with saving maps */ GET_LAYER(map, l)->status = MS_DELETE; - msFreeImage( image ); + msFreeImage(image); return status; } @@ -523,29 +575,30 @@ int msEmbedScalebar(mapObj *map, imageObj *img) /* */ /* Base on the function msCalculateScale (mapscale.c) */ /************************************************************************/ -double GetDeltaExtentsUsingScale(double scale, int units, double centerLat, int width, double resolution) -{ +double GetDeltaExtentsUsingScale(double scale, int units, double centerLat, + int width, double resolution) { double md = 0.0; double dfDelta = -1.0; - if (scale <= 0 || width <=0) + if (scale <= 0 || width <= 0) return -1; switch (units) { - case(MS_DD): - case(MS_METERS): - case(MS_KILOMETERS): - case(MS_MILES): - case(MS_NAUTICALMILES): - case(MS_INCHES): - case(MS_FEET): - /* remember, we use a pixel-center to pixel-center extent, hence the width-1 */ - md = (width-1)/(resolution*msInchesPerUnit(units,centerLat)); - dfDelta = md * scale; - break; - - default: - break; + case (MS_DD): + case (MS_METERS): + case (MS_KILOMETERS): + case (MS_MILES): + case (MS_NAUTICALMILES): + case (MS_INCHES): + case (MS_FEET): + /* remember, we use a pixel-center to pixel-center extent, hence the width-1 + */ + md = (width - 1) / (resolution * msInchesPerUnit(units, centerLat)); + dfDelta = md * scale; + break; + + default: + break; } return dfDelta; @@ -561,10 +614,9 @@ double GetDeltaExtentsUsingScale(double scale, int units, double centerLat, int /* considered to be the Y origin. */ /* */ /************************************************************************/ -double Pix2Georef(int nPixPos, int nPixMin, int nPixMax, - double dfGeoMin, double dfGeoMax, int bULisYOrig) -{ - double dfPosGeo = 0.0; +double Pix2Georef(int nPixPos, int nPixMin, int nPixMax, double dfGeoMin, + double dfGeoMax, int bULisYOrig) { + double dfPosGeo = 0.0; const double dfWidthGeo = dfGeoMax - dfGeoMin; const int nWidthPix = nPixMax - nPixMin; @@ -586,18 +638,20 @@ double Pix2Georef(int nPixPos, int nPixMin, int nPixMax, } /* This function converts a pixel value in geo ref. The return value is in - * layer units. This function has been added for the purpose of the ticket #1340 */ + * layer units. This function has been added for the purpose of the ticket #1340 + */ -double Pix2LayerGeoref(mapObj *map, layerObj *layer, int value) -{ - double cellsize = MS_MAX(MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width), - MS_CELLSIZE(map->extent.miny, map->extent.maxy, map->height)); +double Pix2LayerGeoref(mapObj *map, layerObj *layer, int value) { + double cellsize = + MS_MAX(MS_CELLSIZE(map->extent.minx, map->extent.maxx, map->width), + MS_CELLSIZE(map->extent.miny, map->extent.maxy, map->height)); - double resolutionFactor = map->resolution/map->defresolution; + double resolutionFactor = map->resolution / map->defresolution; double unitsFactor = 1; if (layer->sizeunits != MS_PIXELS) - unitsFactor = msInchesPerUnit(map->units,0)/msInchesPerUnit(layer->sizeunits,0); + unitsFactor = + msInchesPerUnit(map->units, 0) / msInchesPerUnit(layer->sizeunits, 0); - return value*cellsize*resolutionFactor*unitsFactor; + return value * cellsize * resolutionFactor * unitsFactor; } diff --git a/mapscript/python/examples/project_csv.py b/mapscript/python/examples/project_csv.py index 6a740f67b3..8c4fa51a21 100755 --- a/mapscript/python/examples/project_csv.py +++ b/mapscript/python/examples/project_csv.py @@ -9,9 +9,10 @@ """ -import sys import csv +import sys from io import open + import mapscript @@ -22,7 +23,7 @@ def main(input_file, x_field_idx, y_field_idx, input_proj, output_proj): proj_out = mapscript.projectionObj(output_proj) # open file - with open(input_file, encoding='utf-8') as f: + with open(input_file, encoding="utf-8") as f: # read csv csv_in = csv.reader(f) headers = next(csv_in) @@ -48,13 +49,16 @@ def usage(): """ Display usage if program is used incorrectly """ - print("Syntax: %s " % sys.argv[0]) + print( + "Syntax: %s " + % sys.argv[0] + ) sys.exit(2) # check input parameters -if (len(sys.argv) != 6): +if len(sys.argv) != 6: usage() @@ -67,6 +71,6 @@ def usage(): # get projection codes -input_proj = "init="+sys.argv[4].lower() -output_proj = "init="+sys.argv[5].lower() +input_proj = "init=" + sys.argv[4].lower() +output_proj = "init=" + sys.argv[5].lower() main(input_file, x_field_idx, y_field_idx, input_proj, output_proj) diff --git a/mapscript/python/examples/shpdump.py b/mapscript/python/examples/shpdump.py index 25d241acfc..d78f09702f 100755 --- a/mapscript/python/examples/shpdump.py +++ b/mapscript/python/examples/shpdump.py @@ -9,9 +9,10 @@ """ -import mapscript -import sys import os +import sys + +import mapscript def plural(x): @@ -21,8 +22,8 @@ def plural(x): Useful in print statements to avoid something like 'point(s)' """ if x > 1: - return 's' - return '' + return "s" + return "" def get_shapefile_object(sf_path): @@ -56,7 +57,15 @@ def main(sf_path): # get the object at index i sf_obj.get(i, s_obj) print("Shape %i has %i part%s" % (i, s_obj.numlines, plural(s_obj.numlines))) - print("Bounds (%f, %f) (%f, %f)" % (s_obj.bounds.minx, s_obj.bounds.miny, s_obj.bounds.maxx, s_obj.bounds.maxy)) + print( + "Bounds (%f, %f) (%f, %f)" + % ( + s_obj.bounds.minx, + s_obj.bounds.miny, + s_obj.bounds.maxx, + s_obj.bounds.maxy, + ) + ) # loop through parts of each shape @@ -65,7 +74,9 @@ def main(sf_path): # get the jth part of the ith object part = s_obj.get(j) - print("Part %i has %i point%s" % (j, part.numpoints, plural(part.numpoints))) + print( + "Part %i has %i point%s" % (j, part.numpoints, plural(part.numpoints)) + ) # loop through points in each part diff --git a/mapscript/python/examples/shpinfo.py b/mapscript/python/examples/shpinfo.py index 58297dd5e5..4d3f463342 100755 --- a/mapscript/python/examples/shpinfo.py +++ b/mapscript/python/examples/shpinfo.py @@ -8,9 +8,10 @@ python shpinfo.py point.shp """ -import mapscript -import sys import os +import sys + +import mapscript def get_shapefile_object(sf_path): @@ -31,30 +32,33 @@ def get_shapefile_details(sf_obj): # dictionary of shapefile types types = { - mapscript.MS_SHAPEFILE_POINT: 'Point', - mapscript.MS_SHAPEFILE_ARC: 'Line', - mapscript.MS_SHAPEFILE_POLYGON: 'Polygon', - mapscript.MS_SHAPEFILE_MULTIPOINT: 'Multipoint', - - mapscript.MS_SHP_POINTZ: 'PointZ', - mapscript.MS_SHP_ARCZ: 'LineZ', - mapscript.MS_SHP_POLYGONZ: 'PolygonZ', - mapscript.MS_SHP_MULTIPOINTZ: 'MultipointZ', - - mapscript.MS_SHP_POINTM: 'Multipoint', - mapscript.MS_SHP_ARCM: 'LineM', - mapscript.MS_SHP_POLYGONM: 'PolygonM', - mapscript.MS_SHP_MULTIPOINTM: 'MultipointM' - } + mapscript.MS_SHAPEFILE_POINT: "Point", + mapscript.MS_SHAPEFILE_ARC: "Line", + mapscript.MS_SHAPEFILE_POLYGON: "Polygon", + mapscript.MS_SHAPEFILE_MULTIPOINT: "Multipoint", + mapscript.MS_SHP_POINTZ: "PointZ", + mapscript.MS_SHP_ARCZ: "LineZ", + mapscript.MS_SHP_POLYGONZ: "PolygonZ", + mapscript.MS_SHP_MULTIPOINTZ: "MultipointZ", + mapscript.MS_SHP_POINTM: "Multipoint", + mapscript.MS_SHP_ARCM: "LineM", + mapscript.MS_SHP_POLYGONM: "PolygonM", + mapscript.MS_SHP_MULTIPOINTM: "MultipointM", + } # print out basic information that is part of the shapefile object print("\tType: %s" % types[sf_obj.type]) - print("\tBounds: (%f, %f) (%f, %f)" % (sf_obj.bounds.minx, - sf_obj.bounds.miny, - sf_obj.bounds.maxx, - sf_obj.bounds.maxy)) + print( + "\tBounds: (%f, %f) (%f, %f)" + % ( + sf_obj.bounds.minx, + sf_obj.bounds.miny, + sf_obj.bounds.maxx, + sf_obj.bounds.maxy, + ) + ) print("\tNumber of features: %i" % sf_obj.numshapes) @@ -70,14 +74,21 @@ def get_dbf_details(sf_obj): print("\tNumber of records in DBF: %i" % dbf_obj.nRecords) print("\tNumber of fields: %i" % dbf_obj.nFields) print("") - print("\t%-20s %12s %8s %10s" % ("Name", "Type", "Length", "Decimals")) + print("\t%-20s %12s %8s %10s" % ("Name", "Type", "Length", "Decimals")) print("\t-----------------------------------------------------") # print out field characteristics for idx in range(0, dbf_obj.nFields): - print("\t%-20s %12s %8d %10d" % (dbf_obj.getFieldName(idx), dbf_obj.getFieldType(idx), - dbf_obj.getFieldWidth(idx), dbf_obj.getFieldDecimals(idx))) + print( + "\t%-20s %12s %8d %10d" + % ( + dbf_obj.getFieldName(idx), + dbf_obj.getFieldType(idx), + dbf_obj.getFieldWidth(idx), + dbf_obj.getFieldDecimals(idx), + ) + ) def main(sf_path): diff --git a/mapscript/python/examples/wxs.py b/mapscript/python/examples/wxs.py index 1cb4de9a66..5dcd56dcc2 100644 --- a/mapscript/python/examples/wxs.py +++ b/mapscript/python/examples/wxs.py @@ -10,6 +10,7 @@ """ import sys import xml.dom.minidom + import mapscript @@ -36,8 +37,10 @@ def main(map_file): result = mapscript.msIO_getStdoutBufferBytes() # [('Content-Type', 'application/vnd.ogc.wms_xml; charset=UTF-8'), ('Content-Length', '11385')] - response_headers = [('Content-Type', content_type), - ('Content-Length', str(len(result)))] + response_headers = [ + ("Content-Type", content_type), + ("Content-Length", str(len(result))), + ] assert int(response_headers[1][1]) > 0 diff --git a/mapscript/python/mapscript/__init__.py b/mapscript/python/mapscript/__init__.py index 3cf3909dfe..9efc851e32 100644 --- a/mapscript/python/mapscript/__init__.py +++ b/mapscript/python/mapscript/__init__.py @@ -1,7 +1,7 @@ -import sys -import platform -import os import inspect +import os +import platform +import sys # As of Python 3.8 PATH can no longer be used to resolve the MapServer # DLLs on Windows. Instead users will be required to set a new MAPSERVER_DLL_PATH @@ -17,27 +17,26 @@ def add_dll_path(pth): os.add_dll_directory(pth) else: # add the directory to the Windows path for earlier Python version - os.environ['PATH'] = pth + ';' + os.environ['PATH'] + os.environ["PATH"] = pth + ";" + os.environ["PATH"] -if platform.system() == 'Windows': - mapserver_dll_path = os.getenv('MAPSERVER_DLL_PATH', '') - dll_paths = list(filter(os.path.exists, mapserver_dll_path.split(';'))) +if platform.system() == "Windows": + mapserver_dll_path = os.getenv("MAPSERVER_DLL_PATH", "") + dll_paths = list(filter(os.path.exists, mapserver_dll_path.split(";"))) # add paths in the order listed in the string dll_paths.reverse() for pth in dll_paths: add_dll_path(pth) -from .mapscript import * - +from .mapscript import * # NOQA # change all the class module names from mapscript.mapscript to mapscript for key, value in globals().copy().items(): - if inspect.isclass(value) and value.__module__.startswith('mapscript.'): - value.__module__= 'mapscript' + if inspect.isclass(value) and value.__module__.startswith("mapscript."): + value.__module__ = "mapscript" # remove the submodule name -del mapscript +del mapscript # NOQA diff --git a/mapscript/python/tests/cases/class_test.py b/mapscript/python/tests/cases/class_test.py index ac58805881..634afa350c 100644 --- a/mapscript/python/tests/cases/class_test.py +++ b/mapscript/python/tests/cases/class_test.py @@ -25,12 +25,13 @@ # =========================================================================== import unittest + import mapscript + from .testing import MapTestCase class ClassObjTestCase(unittest.TestCase): - def testConstructorNoArg(self): c = mapscript.classObj() assert c.thisown == 1 @@ -39,7 +40,7 @@ def testConstructorNoArg(self): def testConstructorWithArg(self): lyr = mapscript.layerObj() - lyr.name = 'foo' + lyr.name = "foo" c = mapscript.classObj(lyr) assert c.thisown == 1 assert c.layer.name == lyr.name @@ -48,14 +49,14 @@ def testConstructorWithArg(self): def testGetSetAttributes(self): c = mapscript.classObj() - val = '/tmp/legend.png' + val = "/tmp/legend.png" c.keyimage = val assert c.keyimage == val c.debug = mapscript.MS_TRUE assert c.debug == mapscript.MS_TRUE - val = 'Group1' + val = "Group1" c.group = val assert c.group == val @@ -71,24 +72,23 @@ def testGetSetAttributes(self): c.minscaledenom = val assert c.minscaledenom == val - val = 'Class1' + val = "Class1" c.name = val assert c.name == val c.status = mapscript.MS_OFF assert c.status == mapscript.MS_OFF - val = 'template.html' + val = "template.html" c.template = val assert c.template == val - val = 'Title1' + val = "Title1" c.title = val assert c.title == val class ClassCloningTestCase(unittest.TestCase): - def testCloneClass(self): """check attributes of a cloned class""" c = mapscript.classObj() @@ -103,42 +103,42 @@ class ClassIconTestCase(MapTestCase): """testing for bug 1250""" def testAlphaTransparentPixmap(self): - lo = self.map.getLayerByName('INLINE-PIXMAP-RGBA') + lo = self.map.getLayerByName("INLINE-PIXMAP-RGBA") co = lo.getClass(0) - self.map.selectOutputFormat('PNG') + self.map.selectOutputFormat("PNG") im = co.createLegendIcon(self.map, lo, 48, 48) - im.save('testAlphaTransparentPixmapIcon.png') + im.save("testAlphaTransparentPixmapIcon.png") def testAlphaTransparentPixmapPNG24(self): - lo = self.map.getLayerByName('INLINE-PIXMAP-RGBA') + lo = self.map.getLayerByName("INLINE-PIXMAP-RGBA") co = lo.getClass(0) - self.map.selectOutputFormat('PNG24') + self.map.selectOutputFormat("PNG24") im = co.createLegendIcon(self.map, lo, 48, 48) - im.save('testAlphaTransparentPixmapIcon24.png') + im.save("testAlphaTransparentPixmapIcon24.png") def testAlphaTransparentPixmapJPG(self): - lo = self.map.getLayerByName('INLINE-PIXMAP-RGBA') + lo = self.map.getLayerByName("INLINE-PIXMAP-RGBA") co = lo.getClass(0) - self.map.selectOutputFormat('JPEG') + self.map.selectOutputFormat("JPEG") im = co.createLegendIcon(self.map, lo, 48, 48) - im.save('testAlphaTransparentPixmapIcon.jpg') + im.save("testAlphaTransparentPixmapIcon.jpg") def testIndexedTransparentPixmap(self): - lo = self.map.getLayerByName('INLINE-PIXMAP-PCT') + lo = self.map.getLayerByName("INLINE-PIXMAP-PCT") lo.type = mapscript.MS_LAYER_POINT co = lo.getClass(0) - self.map.selectOutputFormat('PNG') + self.map.selectOutputFormat("PNG") im = co.createLegendIcon(self.map, lo, 32, 32) - im.save('testIndexedTransparentPixmapIcon.png') + im.save("testIndexedTransparentPixmapIcon.png") def testIndexedTransparentPixmapJPG(self): - lo = self.map.getLayerByName('INLINE-PIXMAP-PCT') + lo = self.map.getLayerByName("INLINE-PIXMAP-PCT") lo.type = mapscript.MS_LAYER_POINT co = lo.getClass(0) - self.map.selectOutputFormat('JPEG') + self.map.selectOutputFormat("JPEG") im = co.createLegendIcon(self.map, lo, 32, 32) - im.save('testIndexedTransparentPixmapIcon.jpg') + im.save("testIndexedTransparentPixmapIcon.jpg") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/clone_test.py b/mapscript/python/tests/cases/clone_test.py index cebfeb93d9..7024558162 100644 --- a/mapscript/python/tests/cases/clone_test.py +++ b/mapscript/python/tests/cases/clone_test.py @@ -25,7 +25,9 @@ # =========================================================================== import unittest + import mapscript + from .testing import TESTMAPFILE @@ -42,7 +44,6 @@ def tearDown(self): class MapCloningTestCase(MapCloneTestCase): - def testClonedName(self): """MapCloningTestCase.testClonedName: the name of a cloned map equals the original""" assert self.mapobj_clone.name == self.mapobj_orig.name @@ -50,8 +51,7 @@ def testClonedName(self): def testClonedLayers(self): """MapCloningTestCase.testClonedLayers: the layers of a cloned map equal the original""" assert self.mapobj_clone.numlayers == self.mapobj_orig.numlayers - assert self.mapobj_clone.getLayer(0).data \ - == self.mapobj_orig.getLayer(0).data + assert self.mapobj_clone.getLayer(0).data == self.mapobj_orig.getLayer(0).data def testSetFontSet(self): """MapCloningTestCase.testSetFontSet: the number of fonts in a cloned map equal original""" @@ -66,33 +66,33 @@ def testDrawClone(self): """drawing a cloned map works properly""" msimg = self.mapobj_clone.draw() assert msimg.thisown == 1 - filename = 'testClone.png' - fh = open(filename, 'wb') + filename = "testClone.png" + fh = open(filename, "wb") msimg.write(fh) fh.close() def testDrawCloneJPEG(self): """drawing a cloned map works properly""" - self.mapobj_clone.selectOutputFormat('JPEG') - self.mapobj_clone.getLayerByName('INLINE-PIXMAP-RGBA').status = mapscript.MS_ON + self.mapobj_clone.selectOutputFormat("JPEG") + self.mapobj_clone.getLayerByName("INLINE-PIXMAP-RGBA").status = mapscript.MS_ON msimg = self.mapobj_clone.draw() assert msimg.thisown == 1 - filename = 'testClone.jpg' - fh = open(filename, 'wb') + filename = "testClone.jpg" + fh = open(filename, "wb") msimg.write(fh) fh.close() def testDrawClonePNG24(self): """drawing a cloned map works properly""" - self.mapobj_clone.selectOutputFormat('PNG24') - self.mapobj_clone.getLayerByName('INLINE-PIXMAP-RGBA').status = mapscript.MS_ON + self.mapobj_clone.selectOutputFormat("PNG24") + self.mapobj_clone.getLayerByName("INLINE-PIXMAP-RGBA").status = mapscript.MS_ON msimg = self.mapobj_clone.draw() assert msimg.thisown == 1 - filename = 'testClonePNG24.png' - fh = open(filename, 'wb') + filename = "testClonePNG24.png" + fh = open(filename, "wb") msimg.write(fh) fh.close() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/cluster_test.py b/mapscript/python/tests/cases/cluster_test.py index 3b3321d86b..3691a9d15a 100644 --- a/mapscript/python/tests/cases/cluster_test.py +++ b/mapscript/python/tests/cases/cluster_test.py @@ -25,18 +25,18 @@ # =========================================================================== import unittest + import mapscript class ClusterObjTestCase(unittest.TestCase): - def testClusterObjUpdateFromString(self): """a cluster can be updated from a string""" c = mapscript.clusterObj() c.updateFromString("CLUSTER \n MAXDISTANCE 5 \n REGION \n 'rectangle' END") assert c.maxdistance == 5 - assert c.region == 'rectangle' + assert c.region == "rectangle" s = c.convertToString() assert s == 'CLUSTER\n MAXDISTANCE 5\n REGION "rectangle"\nEND # CLUSTER\n' @@ -44,17 +44,17 @@ def testClusterObjUpdateFromString(self): def testClusterObjGetSetFilter(self): """a cluster filter can be set and read""" c = mapscript.clusterObj() - filter = '[attr1] > 5' + filter = "[attr1] > 5" c.setFilter(filter) assert '"{}"'.format(filter) == c.getFilterString() def testClusterObjGetSetGroup(self): """a cluster filter can be set and read""" c = mapscript.clusterObj() - exp = '100' # TODO not sure what would be a relevant expression here + exp = "100" # TODO not sure what would be a relevant expression here c.setGroup(exp) assert '"{}"'.format(exp) == c.getGroupString() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/color_test.py b/mapscript/python/tests/cases/color_test.py index 53cb76c6f2..cfdf94d0a9 100644 --- a/mapscript/python/tests/cases/color_test.py +++ b/mapscript/python/tests/cases/color_test.py @@ -25,11 +25,11 @@ # =========================================================================== import unittest + import mapscript class ColorObjTestCase(unittest.TestCase): - def testColorObjConstructorNoArgs(self): """a color can be initialized with no arguments""" c = mapscript.colorObj() @@ -43,7 +43,7 @@ def testColorObjConstructorArgs(self): def testColorObjToHex(self): """a color can be outputted as hex""" c = mapscript.colorObj(255, 255, 255) - assert c.toHex() == '#ffffff' + assert c.toHex() == "#ffffff" def testColorObjToHexBadly(self): """raise an error in the case of an undefined color""" @@ -59,20 +59,20 @@ def testColorObjSetRGB(self): def testColorObjSetHexLower(self): """a color can be set using lower case hex""" c = mapscript.colorObj() - c.setHex('#ffffff64') + c.setHex("#ffffff64") assert (c.red, c.green, c.blue, c.alpha) == (255, 255, 255, 100) def testColorObjSetHexUpper(self): """a color can be set using upper case hex""" c = mapscript.colorObj() - c.setHex('#FFFFFF') + c.setHex("#FFFFFF") assert (c.red, c.green, c.blue) == (255, 255, 255) def testColorObjSetHexBadly(self): """invalid hex color string raises proper error""" c = mapscript.colorObj() - self.assertRaises(mapscript.MapServerError, c.setHex, '#fffffg') + self.assertRaises(mapscript.MapServerError, c.setHex, "#fffffg") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/config_test.py b/mapscript/python/tests/cases/config_test.py index 9505d7a705..66eecad0de 100644 --- a/mapscript/python/tests/cases/config_test.py +++ b/mapscript/python/tests/cases/config_test.py @@ -25,12 +25,13 @@ # =========================================================================== import unittest + import mapscript + from .testing import TESTCONFIGFILE class ConfigConstructorTestCase(unittest.TestCase): - def testConfigConstructorFilenameArg(self): """ConfigConstructorTestCase.testConfigConstructorFilenameArg: map constructor with filename argument""" test_config = mapscript.configObj(TESTCONFIGFILE) @@ -39,7 +40,6 @@ def testConfigConstructorFilenameArg(self): class ConfigHashTableTests(unittest.TestCase): - def testGetEnv(self): test_config = mapscript.configObj(TESTCONFIGFILE) @@ -59,5 +59,5 @@ def testGetPlugins(self): assert test_config.plugins.numitems == 0 -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/font_test.py b/mapscript/python/tests/cases/font_test.py index 5a2eee752d..4ea0cacc2a 100644 --- a/mapscript/python/tests/cases/font_test.py +++ b/mapscript/python/tests/cases/font_test.py @@ -26,17 +26,17 @@ import os import unittest + import mapscript + from .testing import TESTS_PATH class FontTestCase(unittest.TestCase): - def testSettingFonts(self): mo = mapscript.mapObj() assert mo.fontset.numfonts == 0 - mo.fontset.fonts.set('Vera', os.path.join(TESTS_PATH, 'vera', - 'Vera.ttf')) + mo.fontset.fonts.set("Vera", os.path.join(TESTS_PATH, "vera", "Vera.ttf")) # NB: this does *not* increment the fonset.numfonts -- new bug mo.setSize(300, 300) @@ -50,14 +50,14 @@ def testSettingFonts(self): co = mapscript.classObj() lbl = mapscript.labelObj() lbl.type = mapscript.MS_TRUETYPE - lbl.font = 'Vera' + lbl.font = "Vera" lbl.size = 10 - lbl.color.setHex('#000000') + lbl.color.setHex("#000000") co.addLabel(lbl) so = mapscript.styleObj() so.symbol = 0 - so.color.setHex('#000000') + so.color.setHex("#000000") co.insertStyle(so) lo.insertClass(co) @@ -70,7 +70,7 @@ def testSettingFonts(self): shape = mapscript.shapeObj(lo.type) shape.add(line) shape.setBounds() - shape.text = 'Foo' + shape.text = "Foo" shape.classindex = 0 lo.addFeature(shape) @@ -78,8 +78,8 @@ def testSettingFonts(self): # im = mo.prepareImage() # shape.draw(mo, lo, im) - im.save('testSettingFonts.png') + im.save("testSettingFonts.png") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/hash_test.py b/mapscript/python/tests/cases/hash_test.py index fa21a1b1c6..ee11f4cb7a 100644 --- a/mapscript/python/tests/cases/hash_test.py +++ b/mapscript/python/tests/cases/hash_test.py @@ -25,24 +25,26 @@ # =========================================================================== import unittest + import mapscript -from .testing import MapTestCase +from .testing import MapTestCase # =========================================================================== # Base class for hashtable tests. Derived classes use these tests, but # defined different values for self.table. + class HashTableBaseTestCase(object): - keys = ['key1', 'key2', 'key3', 'key4'] - values = ['value1', 'value2', 'value3', 'value4'] + keys = ["key1", "key2", "key3", "key4"] + values = ["value1", "value2", "value3", "value4"] def testUseNonExistentKey(self): - assert self.table.get('bogus') is None + assert self.table.get("bogus") is None def testUseNonExistentKeyWithDefault(self): - assert self.table.get('bogus', 'default') == 'default' + assert self.table.get("bogus", "default") == "default" def testGetValue(self): for key, value in zip(self.keys, self.values): @@ -52,9 +54,9 @@ def testGetValue(self): def testGetValueWithDefault(self): for key, value in zip(self.keys, self.values): - assert self.table.get(key, 'foo') == value - assert self.table.get(key.upper(), 'foo') == value - assert self.table.get(key.capitalize(), 'foo') == value + assert self.table.get(key, "foo") == value + assert self.table.get(key.upper(), "foo") == value + assert self.table.get(key.capitalize(), "foo") == value def testClear(self): self.table.clear() @@ -107,6 +109,7 @@ def testRemoveDictItem(self): # HashTable test case # + class HashTableTestCase(unittest.TestCase, HashTableBaseTestCase): """Tests of the MapServer HashTable object""" @@ -127,13 +130,13 @@ def testConstructor(self): # ============================================================================== # following tests use the tests/test.map fixture -class WebMetadataTestCase(MapTestCase, HashTableBaseTestCase): +class WebMetadataTestCase(MapTestCase, HashTableBaseTestCase): def setUp(self): MapTestCase.setUp(self) self.table = self.map.web.metadata - self.keys = ['key1', 'key2', 'key3', 'key4', 'ows_enable_request'] - self.values = ['value1', 'value2', 'value3', 'value4', '*'] + self.keys = ["key1", "key2", "key3", "key4", "ows_enable_request"] + self.values = ["value1", "value2", "value3", "value4", "*"] def tearDown(self): MapTestCase.tearDown(self) @@ -141,18 +144,16 @@ def tearDown(self): class LayerMetadataTestCase(WebMetadataTestCase): - def setUp(self): MapTestCase.setUp(self) self.table = self.map.getLayer(1).metadata class ClassMetadataTestCase(WebMetadataTestCase): - def setUp(self): MapTestCase.setUp(self) self.table = self.map.getLayer(1).getClass(0).metadata -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/image_test.py b/mapscript/python/tests/cases/image_test.py index 7e8ac4b992..f2732f7979 100644 --- a/mapscript/python/tests/cases/image_test.py +++ b/mapscript/python/tests/cases/image_test.py @@ -25,24 +25,25 @@ # =========================================================================== import unittest -from io import BytesIO import urllib +from io import BytesIO + import mapscript + from .testing import TEST_IMAGE as test_image from .testing import MapTestCase - have_image = False try: from PIL import Image + have_image = True except ImportError: pass class ImageObjTestCase(unittest.TestCase): - def testConstructor(self): """imageObj constructor works""" imgobj = mapscript.imageObj(10, 10) @@ -52,7 +53,7 @@ def testConstructor(self): def testConstructorWithFormat(self): """imageObj with an optional driver works""" - driver = 'AGG/PNG' + driver = "AGG/PNG" format = mapscript.outputFormatObj(driver) imgobj = mapscript.imageObj(10, 10, format) assert imgobj.thisown == 1 @@ -66,7 +67,7 @@ def xtestConstructorFilename(self): assert imgobj.thisown == 1 assert imgobj.height == 200 assert imgobj.width == 200 - imgobj.save('testConstructorFilename.png') + imgobj.save("testConstructorFilename.png") def xtestConstructorFilenameDriver(self): """imageObj with a filename and a driver works""" @@ -74,11 +75,11 @@ def xtestConstructorFilenameDriver(self): assert imgobj.thisown == 1 assert imgobj.height == 200 assert imgobj.width == 200 - imgobj.save('testConstructorFilenameDriver.png') + imgobj.save("testConstructorFilenameDriver.png") def xtestConstructorStream(self): """imageObj with a file stream works""" - f = open(test_image, 'rb') + f = open(test_image, "rb") imgobj = mapscript.imageObj(f) f.close() assert imgobj.thisown == 1 @@ -87,7 +88,7 @@ def xtestConstructorStream(self): def xtestConstructorBytesIO(self): """imageObj with a BytesIO works""" - with open(test_image, 'rb') as f: + with open(test_image, "rb") as f: data = f.read() s = BytesIO(data) imgobj = mapscript.imageObj(s) @@ -97,29 +98,28 @@ def xtestConstructorBytesIO(self): def xtestConstructorUrlStream(self): """imageObj with a URL stream works""" - url = urllib.urlopen('http://mapserver.org/_static/banner.png') - imgobj = mapscript.imageObj(url, 'AGG/JPEG') + url = urllib.urlopen("http://mapserver.org/_static/banner.png") + imgobj = mapscript.imageObj(url, "AGG/JPEG") assert imgobj.thisown == 1 assert imgobj.height == 68 assert imgobj.width == 439 - imgobj.save('testConstructorUrlStream.jpg') + imgobj.save("testConstructorUrlStream.jpg") class ImageWriteTestCase(MapTestCase): - def testImageWrite(self): """image writes data to an open filehandle""" image = self.map.draw() assert image.thisown == 1 - filename = 'testImageWrite.png' - fh = open(filename, 'wb') + filename = "testImageWrite.png" + fh = open(filename, "wb") image.write(fh) fh.close() if have_image: pyimg = Image.open(filename) - assert pyimg.format == 'PNG' + assert pyimg.format == "PNG" assert pyimg.size == (200, 200) - assert pyimg.mode == 'RGB' + assert pyimg.mode == "RGB" def testImageWriteBytesIO(self): """image writes data to a BytesIO instance""" @@ -129,14 +129,14 @@ def testImageWriteBytesIO(self): s = BytesIO() image.write(s) - filename = 'testImageWriteBytesIO.png' - with open(filename, 'wb') as fh: + filename = "testImageWriteBytesIO.png" + with open(filename, "wb") as fh: fh.write(s.getvalue()) if have_image: pyimg = Image.open(filename) - assert pyimg.format == 'PNG' + assert pyimg.format == "PNG" assert pyimg.size == (200, 200) - assert pyimg.mode == 'RGB' + assert pyimg.mode == "RGB" def testImageGetBytes(self): """image returns bytes""" @@ -145,15 +145,15 @@ def testImageGetBytes(self): s = BytesIO(image.getBytes()) - filename = 'testImageGetBytes.png' - with open(filename, 'wb') as fh: + filename = "testImageGetBytes.png" + with open(filename, "wb") as fh: fh.write(s.getvalue()) if have_image: pyimg = Image.open(filename) - assert pyimg.format == 'PNG' + assert pyimg.format == "PNG" assert pyimg.size == (200, 200) - assert pyimg.mode == 'RGB' + assert pyimg.mode == "RGB" -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/label_test.py b/mapscript/python/tests/cases/label_test.py index e427a05c48..0b963ecd08 100644 --- a/mapscript/python/tests/cases/label_test.py +++ b/mapscript/python/tests/cases/label_test.py @@ -25,32 +25,34 @@ # =========================================================================== import unittest + import mapscript + from .testing import MapTestCase class NewLabelsTestCase(MapTestCase): - def testLabelBinding(self): """attribute binding can be set and get""" new_label = mapscript.labelObj() - assert (not new_label.getBinding(mapscript.MS_LABEL_BINDING_COLOR)) + assert not new_label.getBinding(mapscript.MS_LABEL_BINDING_COLOR) new_label.setBinding(mapscript.MS_LABEL_BINDING_COLOR, "NEW_BINDING") - assert (new_label.getBinding(mapscript.MS_LABEL_BINDING_COLOR) == "NEW_BINDING") + assert new_label.getBinding(mapscript.MS_LABEL_BINDING_COLOR) == "NEW_BINDING" class LabelCacheMemberTestCase(MapTestCase): - def testCacheMemberText(self): """string attribute has been renamed to 'text' (bug 852)""" - lo = self.map.getLayerByName('POINT') + lo = self.map.getLayerByName("POINT") lo.status = mapscript.MS_ON img = self.map.draw() assert img is not None - assert self.map.labelcache.num_rendered_members == 1, self.map.labelcache.num_rendered_members + assert ( + self.map.labelcache.num_rendered_members == 1 + ), self.map.labelcache.num_rendered_members # label = self.map.nextLabel() # assert label.text == 'A Point', label.text -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/layer_test.py b/mapscript/python/tests/cases/layer_test.py index a38adf4b75..d5153d5765 100644 --- a/mapscript/python/tests/cases/layer_test.py +++ b/mapscript/python/tests/cases/layer_test.py @@ -26,19 +26,19 @@ import unittest from random import random + import mapscript + from .testing import MapTestCase class MapLayerTestCase(MapTestCase): - def setUp(self): MapTestCase.setUp(self) self.layer = self.map.getLayer(1) class LayerConstructorTestCase(MapLayerTestCase): - def testLayerConstructorNoArg(self): """test layer constructor with no argument""" layer = mapscript.layerObj() @@ -52,17 +52,16 @@ def testLayerConstructorMapArg(self): layer = mapscript.layerObj(self.map) assert layer.__class__.__name__ == "layerObj" assert layer.thisown == 1 - lyr = self.map.getLayer(self.map.numlayers-1) + lyr = self.map.getLayer(self.map.numlayers - 1) assert lyr is not None # assert str(layer) == str(lyr) # TODO - check why these are not equal assert layer.map is not None, layer.map class LayerItemDefinitionTestCase(MapLayerTestCase): - def setUp(self): MapTestCase.setUp(self) - self.layer = self.map.getLayerByName('POINT') + self.layer = self.map.getLayerByName("POINT") self.layer.open() def tearDown(self): @@ -94,7 +93,7 @@ def testLayerGetItemTypeClosedLayer(self): def testLayerGetNonDefinedItemType(self): """test getting layer item information for a layer with gml_types auto""" - layer = self.map.getLayerByName('POLYGON') + layer = self.map.getLayerByName("POLYGON") layer.open() item_type = layer.getItemType(0) assert item_type == "" @@ -102,7 +101,6 @@ def testLayerGetNonDefinedItemType(self): class LayerCloningTestCase(MapLayerTestCase): - def testLayerCloning(self): """check attributes of a cloned layer""" clone = self.layer.clone() @@ -115,10 +113,9 @@ def testLayerCloning(self): class LayerExtentTestCase(MapTestCase): - def setUp(self): MapTestCase.setUp(self) - self.layer = self.map.getLayerByName('POLYGON') + self.layer = self.map.getLayerByName("POLYGON") def testPolygonExtent(self): """retrieve the extent of a polygon layer""" @@ -142,13 +139,13 @@ def testGetPresetExtent(self): def testResetLayerExtent(self): """test resetting a layer's extent""" - layer = self.map.getLayerByName('POLYGON') + layer = self.map.getLayerByName("POLYGON") layer.setExtent() self.assertRectsEqual(layer.extent, mapscript.rectObj()) def testDirectExtentAccess(self): """direct access to a layer's extent works properly""" - pt_layer = self.map.getLayerByName('POINT') + pt_layer = self.map.getLayerByName("POINT") rect = pt_layer.extent assert str(pt_layer.extent) == str(rect), (pt_layer.extent, rect) e = mapscript.rectObj(-0.5, 51.0, 0.5, 52.0) @@ -156,28 +153,27 @@ def testDirectExtentAccess(self): class LayerRasterProcessingTestCase(MapLayerTestCase): - def testAddProcessing(self): """adding a layer's processing directive works""" - self.layer.addProcessing('directive0=foo') + self.layer.addProcessing("directive0=foo") assert self.layer.numprocessing == 1, self.layer.numprocessing - self.layer.addProcessing('directive1=bar') + self.layer.addProcessing("directive1=bar") assert self.layer.numprocessing == 2, self.layer.numprocessing - directives = [self.layer.getProcessing(i) - for i in range(self.layer.numprocessing)] - assert directives == ['directive0=foo', 'directive1=bar'] + directives = [ + self.layer.getProcessing(i) for i in range(self.layer.numprocessing) + ] + assert directives == ["directive0=foo", "directive1=bar"] def testClearProcessing(self): """clearing a self.layer's processing directive works""" - self.layer.addProcessing('directive0=foo') + self.layer.addProcessing("directive0=foo") assert self.layer.numprocessing == 1, self.layer.numprocessing - self.layer.addProcessing('directive1=bar') + self.layer.addProcessing("directive1=bar") assert self.layer.numprocessing == 2, self.layer.numprocessing assert self.layer.clearProcessing() == mapscript.MS_SUCCESS class RemoveClassTestCase(MapLayerTestCase): - def testRemoveClass1NumClasses(self): """RemoveClassTestCase.testRemoveClass1NumClasses: removing the layer's first class by index leaves one class left""" @@ -202,7 +198,7 @@ def testRemoveClass2NumClasses(self): def testRemoveClass2ClassName(self): """RemoveClassTestCase.testRemoveClass2ClassName: confirm removing the layer's second class reverts - the name of the first class""" + the name of the first class""" c1name = self.layer.getClass(0).name c = self.layer.removeClass(1) assert c is not None @@ -210,12 +206,11 @@ def testRemoveClass2ClassName(self): class InsertClassTestCase(MapLayerTestCase): - def testLayerInsertClass(self): """insert class at default index""" n = self.layer.numclasses new_class = mapscript.classObj() - new_class.name = 'foo' + new_class.name = "foo" new_index = self.layer.insertClass(new_class) assert new_index == n assert self.layer.numclasses == n + 1 @@ -227,7 +222,7 @@ def testLayerInsertClassAtZero(self): """insert class at index 0""" n = self.layer.numclasses new_class = mapscript.classObj() - new_class.name = 'foo' + new_class.name = "foo" new_index = self.layer.insertClass(new_class, 0) assert new_index == 0 assert self.layer.numclasses == n + 1 @@ -237,8 +232,7 @@ def testLayerInsertClassAtZero(self): def testInsertNULLClass(self): """inserting NULL class should raise an error""" - self.assertRaises(mapscript.MapServerChildError, - self.layer.insertClass, None) + self.assertRaises(mapscript.MapServerChildError, self.layer.insertClass, None) class LayerTestCase(MapTestCase): @@ -259,11 +253,11 @@ def testSetLayerOrder(self): order = self.map.getLayerOrder() assert order == ord, order + # Layer removal tests class RemoveLayerTestCase(MapTestCase): - def testRemoveLayer1NumLayers(self): """removing the first layer by index from the mapfile leaves three""" self.map.removeLayer(0) @@ -288,18 +282,17 @@ def testRemoveLayer2LayerName(self): class ExpressionTestCase(MapLayerTestCase): - def testClearExpression(self): """layer expression can be properly cleared""" - self.layer.setFilter('') + self.layer.setFilter("") fs = self.layer.getFilterString() assert fs is None, fs def testSetStringExpression(self): """layer expression can be set to string""" - self.layer.setFilter('foo') + self.layer.setFilter("foo") fs = self.layer.getFilterString() - self.layer.filteritem = 'fid' + self.layer.filteritem = "fid" assert fs == '"foo"', fs self.map.draw() @@ -307,23 +300,23 @@ def testSetQuotedStringExpression(self): """layer expression string can be quoted""" self.layer.setFilter('"foo"') fs = self.layer.getFilterString() - self.layer.filteritem = 'fid' + self.layer.filteritem = "fid" assert fs == '"foo"', fs self.map.draw() def testSetRegularExpression(self): """layer expression can be regular expression""" - self.layer.setFilter('/foo/') - self.layer.filteritem = 'fid' + self.layer.setFilter("/foo/") + self.layer.filteritem = "fid" fs = self.layer.getFilterString() - assert fs == '/foo/', fs + assert fs == "/foo/", fs self.map.draw() def testSetLogicalExpression(self): """layer expression can be logical expression""" - self.layer.setFilter('([fid] >= 2)') + self.layer.setFilter("([fid] >= 2)") fs = self.layer.getFilterString() - assert fs == '([fid] >= 2)', fs + assert fs == "([fid] >= 2)", fs self.map.draw() def testSetCompoundLogicalExpression(self): @@ -338,15 +331,13 @@ def testSetCompoundLogicalExpression(self): class LayerQueryTestCase(MapLayerTestCase): - def setUp(self): MapLayerTestCase.setUp(self) - self.layer = self.map.getLayerByName('POINT') - self.layer.template = 'foo' + self.layer = self.map.getLayerByName("POINT") + self.layer.template = "foo" class SpatialLayerQueryTestCase(LayerQueryTestCase): - def testRectQuery(self): qrect = mapscript.rectObj(-10.0, 45.0, 10.0, 55.0) self.layer.queryByRect(self.map, qrect) @@ -381,31 +372,34 @@ def testPointQueryNoResults(self): class AttributeLayerQueryTestCase(LayerQueryTestCase): - def testAttributeQuery(self): - self.layer.queryByAttributes(self.map, "FNAME", '"A Point"', - mapscript.MS_MULTIPLE) + self.layer.queryByAttributes( + self.map, "FNAME", '"A Point"', mapscript.MS_MULTIPLE + ) assert self.layer.getNumResults() == 1 def testLogicalAttributeQuery(self): - self.layer.queryByAttributes(self.map, None, '("[FNAME]" == "A Point")', - mapscript.MS_MULTIPLE) + self.layer.queryByAttributes( + self.map, None, '("[FNAME]" == "A Point")', mapscript.MS_MULTIPLE + ) assert self.layer.getNumResults() == 1 def testAttributeQueryNoResults(self): - self.layer.queryByAttributes(self.map, "FNAME", '"Bogus Point"', - mapscript.MS_MULTIPLE) + self.layer.queryByAttributes( + self.map, "FNAME", '"Bogus Point"', mapscript.MS_MULTIPLE + ) assert self.layer.getNumResults() == 0 class LayerVisibilityTestCase(MapLayerTestCase): - def setUp(self): MapLayerTestCase.setUp(self) self.layer.minscaledenom = 1000 self.layer.maxscaledenom = 2000 self.layer.status = mapscript.MS_ON - self.map.zoomScale(1500, mapscript.pointObj(100, 100), 200, 200, self.map.extent, None) + self.map.zoomScale( + 1500, mapscript.pointObj(100, 100), 200, 200, self.map.extent, None + ) def testInitialVisibility(self): """expect visibility""" @@ -418,12 +412,13 @@ def testStatusOffVisibility(self): def testZoomOutVisibility(self): """expect false visibility after zooming out beyond maximum""" - self.map.zoomScale(2500, mapscript.pointObj(100, 100), 200, 200, self.map.extent, None) + self.map.zoomScale( + 2500, mapscript.pointObj(100, 100), 200, 200, self.map.extent, None + ) assert self.layer.isVisible() == mapscript.MS_FALSE class InlineLayerTestCase(unittest.TestCase): - def setUp(self): # Inline feature layer self.ilayer = mapscript.layerObj() @@ -431,8 +426,8 @@ def setUp(self): self.ilayer.status = mapscript.MS_DEFAULT self.ilayer.connectiontype = mapscript.MS_INLINE - cs = 'f7fcfd, e5f5f9, ccece6, 99d8c9, 66c2a4, 41ae76, 238b45, 006d2c, 00441b' - colors = ['#' + h for h in cs.split(', ')] + cs = "f7fcfd, e5f5f9, ccece6, 99d8c9, 66c2a4, 41ae76, 238b45, 006d2c, 00441b" + colors = ["#" + h for h in cs.split(", ")] for i in range(9): # Make a class for feature @@ -443,15 +438,15 @@ def setUp(self): so.color.setHex(colors[i]) li = co.addLabel(mapscript.labelObj()) lbl = co.getLabel(li) - lbl.color.setHex('#000000') - lbl.outlinecolor.setHex('#FFFFFF') + lbl.color.setHex("#000000") + lbl.outlinecolor.setHex("#FFFFFF") lbl.type = mapscript.MS_BITMAP lbl.size = mapscript.MS_SMALL # The shape to add is randomly generated - xc = 4.0*(random() - 0.5) - yc = 4.0*(random() - 0.5) - r = mapscript.rectObj(xc-0.25, yc-0.25, xc+0.25, yc+0.25) + xc = 4.0 * (random() - 0.5) + yc = 4.0 * (random() - 0.5) + r = mapscript.rectObj(xc - 0.25, yc - 0.25, xc + 0.25, yc + 0.25) s = r.toPolygon() # Classify @@ -465,11 +460,11 @@ def testExternalClassification(self): mo = mapscript.mapObj() mo.setSize(400, 400) mo.setExtent(-2.5, -2.5, 2.5, 2.5) - mo.selectOutputFormat('image/png') + mo.selectOutputFormat("image/png") mo.insertLayer(self.ilayer) im = mo.draw() - im.save('testExternalClassification.png') + im.save("testExternalClassification.png") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/line_test.py b/mapscript/python/tests/cases/line_test.py index 417a5203ce..6af0c53388 100644 --- a/mapscript/python/tests/cases/line_test.py +++ b/mapscript/python/tests/cases/line_test.py @@ -26,7 +26,9 @@ import unittest + import mapscript + from .testing import MapPrimitivesTestCase @@ -35,8 +37,7 @@ class LineObjTestCase(MapPrimitivesTestCase): def setUp(self): """The test fixture is a line with two points""" - self.points = (mapscript.pointObj(0.0, 1.0), - mapscript.pointObj(2.0, 3.0)) + self.points = (mapscript.pointObj(0.0, 1.0), mapscript.pointObj(2.0, 3.0)) self.line = mapscript.lineObj() self.addPointToLine(self.line, self.points[0]) self.addPointToLine(self.line, self.points[1]) @@ -76,8 +77,11 @@ def xtestAlterNumPoints(self): def testLineGeoInterface(self): """return line using the __geo_interface__ protocol""" - assert self.line.__geo_interface__ == {"type": "LineString", "coordinates": [(0.0, 1.0, 0.0), (2.0, 3.0, 0.0)]} + assert self.line.__geo_interface__ == { + "type": "LineString", + "coordinates": [(0.0, 1.0, 0.0), (2.0, 3.0, 0.0)], + } -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/mapscript/python/tests/cases/map_test.py b/mapscript/python/tests/cases/map_test.py index a66e65e324..134ebbfce0 100644 --- a/mapscript/python/tests/cases/map_test.py +++ b/mapscript/python/tests/cases/map_test.py @@ -25,12 +25,13 @@ # =========================================================================== import unittest + import mapscript -from .testing import MapTestCase, TESTMAPFILE +from .testing import TESTMAPFILE, MapTestCase -class MapConstructorTestCase(unittest.TestCase): +class MapConstructorTestCase(unittest.TestCase): def testMapConstructorNoArg(self): """MapConstructorTestCase.testMapConstructorNoArg: test map constructor with no argument""" test_map = mapscript.mapObj() @@ -40,7 +41,7 @@ def testMapConstructorNoArg(self): def testMapConstructorEmptyStringArg(self): """MapConstructorTestCase.testMapConstructorEmptyStringArg: test map constructor with old-style empty string argument""" - test_map = mapscript.mapObj('') + test_map = mapscript.mapObj("") assert test_map.__class__.__name__ == "mapObj" assert test_map.thisown == 1 @@ -63,8 +64,9 @@ def testSetExtent(self): def testSetExtentBadly(self): """MapExtentTestCase.testSetExtentBadly: test that mapscript raises an error for an invalid mapObj extent""" test_map = mapscript.mapObj(TESTMAPFILE) - self.assertRaises(mapscript.MapServerError, test_map.setExtent, - 1.0, -2.0, -3.0, 4.0) + self.assertRaises( + mapscript.MapServerError, test_map.setExtent, 1.0, -2.0, -3.0, 4.0 + ) def testReBindingExtent(self): """test the rebinding of a map's extent""" @@ -78,20 +80,27 @@ def testReBindingExtent(self): class MapLayersTestCase(MapTestCase): - def testMapInsertLayer(self): """MapLayersTestCase.testMapInsertLayer: test insertion of a new layer at default (last) index""" n = self.map.numlayers layer = mapscript.layerObj() - layer.name = 'new' + layer.name = "new" assert layer.map is None, layer.map index = self.map.insertLayer(layer) assert layer.map is not None, layer.map assert index == n, index assert self.map.numlayers == n + 1 names = [self.map.getLayer(i).name for i in range(self.map.numlayers)] - assert names == ['RASTER', 'POLYGON', 'LINE', 'POINT', 'INLINE', - 'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT', 'new'] + assert names == [ + "RASTER", + "POLYGON", + "LINE", + "POINT", + "INLINE", + "INLINE-PIXMAP-RGBA", + "INLINE-PIXMAP-PCT", + "new", + ] order = self.map.getLayerOrder() assert order == (0, 1, 2, 3, 4, 5, 6, 7), order @@ -99,15 +108,23 @@ def testMapInsertLayerAtZero(self): """MapLayersTestCase.testMapInsertLayerAtZero: test insertion of a new layer at first index""" n = self.map.numlayers layer = mapscript.layerObj() - layer.name = 'new' + layer.name = "new" assert layer.map is None, layer.map index = self.map.insertLayer(layer, 0) assert layer.map is not None, layer.map assert index == 0, index assert self.map.numlayers == n + 1 names = [self.map.getLayer(i).name for i in range(self.map.numlayers)] - assert names == ['new', 'RASTER', 'POLYGON', 'LINE', 'POINT', 'INLINE', - 'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT'], names + assert names == [ + "new", + "RASTER", + "POLYGON", + "LINE", + "POINT", + "INLINE", + "INLINE-PIXMAP-RGBA", + "INLINE-PIXMAP-PCT", + ], names order = self.map.getLayerOrder() assert order == (0, 1, 2, 3, 4, 5, 6, 7), order @@ -121,7 +138,7 @@ def testMapInsertLayerDrawingOrder(self): self.map.setLayerOrder(o_start) # insert Layer layer = mapscript.layerObj() - layer.name = 'new' + layer.name = "new" index = self.map.insertLayer(layer, 1) assert index == 1, index # We expect our new layer to be at index 1 in drawing order as well @@ -131,20 +148,20 @@ def testMapInsertLayerDrawingOrder(self): def testMapInsertLayerBadIndex(self): """MapLayersTestCase.testMapInsertLayerBadIndex: expect an exception when index is too large""" layer = mapscript.layerObj() - self.assertRaises(mapscript.MapServerChildError, self.map.insertLayer, - layer, 1000) + self.assertRaises( + mapscript.MapServerChildError, self.map.insertLayer, layer, 1000 + ) def testMapInsertNULLLayer(self): """expect an exception on attempt to insert a NULL Layer""" - self.assertRaises(mapscript.MapServerChildError, self.map.insertLayer, - None) + self.assertRaises(mapscript.MapServerChildError, self.map.insertLayer, None) def testMapRemoveLayerAtTail(self): """removal of highest index (tail) layer""" n = self.map.numlayers - layer = self.map.removeLayer(n-1) - assert self.map.numlayers == n-1 - assert layer.name == 'INLINE-PIXMAP-PCT' + layer = self.map.removeLayer(n - 1) + assert self.map.numlayers == n - 1 + assert layer.name == "INLINE-PIXMAP-PCT" assert layer.thisown == 1 del layer order = self.map.getLayerOrder() @@ -154,8 +171,8 @@ def testMapRemoveLayerAtZero(self): """removal of lowest index (0) layer""" n = self.map.numlayers layer = self.map.removeLayer(0) - assert self.map.numlayers == n-1 - assert layer.name == 'RASTER' + assert self.map.numlayers == n - 1 + assert layer.name == "RASTER" order = self.map.getLayerOrder() assert order == (0, 1, 2, 3, 4, 5), order @@ -166,27 +183,31 @@ def testMapRemoveLayerDrawingOrder(self): o_start = (6, 5, 4, 3, 2, 1, 0) self.map.setLayerOrder(o_start) layer = self.map.removeLayer(1) - assert self.map.numlayers == n-1 - assert layer.name == 'POLYGON' + assert self.map.numlayers == n - 1 + assert layer.name == "POLYGON" order = self.map.getLayerOrder() assert order == (5, 4, 3, 2, 1, 0), order names = [self.map.getLayer(i).name for i in range(self.map.numlayers)] - assert names == ['RASTER', 'LINE', 'POINT', 'INLINE', - 'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT'], names + assert names == [ + "RASTER", + "LINE", + "POINT", + "INLINE", + "INLINE-PIXMAP-RGBA", + "INLINE-PIXMAP-PCT", + ], names class MapExceptionTestCase(MapTestCase): - def testDrawBadData(self): """MapExceptionTestCase.testDrawBadData: a bad data descriptor in a layer returns proper error""" - self.map.getLayerByName('POLYGON').data = 'foo' + self.map.getLayerByName("POLYGON").data = "foo" self.assertRaises(mapscript.MapServerError, self.map.draw) class EmptyMapExceptionTestCase(unittest.TestCase): - def setUp(self): - self.map = mapscript.mapObj('') + self.map = mapscript.mapObj("") def tearDown(self): self.map = None @@ -197,7 +218,6 @@ def testDrawEmptyMap(self): class NoFontSetTestCase(unittest.TestCase): - def testNoGetFontSetFile(self): """an empty map should have fontset filename == None""" self.map = mapscript.mapObj() @@ -205,15 +225,13 @@ def testNoGetFontSetFile(self): class MapFontSetTestCase(MapTestCase): - def testGetFontSetFile(self): """expect fontset file to be 'fonts.txt'""" file = self.map.fontset.filename - assert file == 'fonts.txt', file + assert file == "fonts.txt", file class MapSizeTestCase(MapTestCase): - def testDefaultSize(self): assert self.map.width == 200 assert self.map.height == 200 @@ -226,9 +244,9 @@ def testSetSize(self): class MapSetWKTTestCase(MapTestCase): - def testOGCWKT(self): - self.map.setWKTProjection('''PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984", + self.map.setWKTProjection( + """PROJCS["unnamed",GEOGCS["WGS 84",DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Degree",0.0174532925199433]], @@ -237,37 +255,41 @@ def testOGCWKT(self): PARAMETER["latitude_of_center", 0], PARAMETER["longitude_of_center", -153], PARAMETER["false_easting", -4943910.68], PARAMETER["false_northing", 0], UNIT["metre",1.0] - ]''') + ]""" + ) proj4 = self.map.getProjection() - assert proj4.find('+proj=aea') != -1 - assert proj4.find('+datum=WGS84') != -1 + assert proj4.find("+proj=aea") != -1 + assert proj4.find("+datum=WGS84") != -1 assert mapscript.projectionObj(proj4).getUnits() != mapscript.MS_DD def testESRIWKT(self): - self.map.setWKTProjection('ESRI::PROJCS["Pulkovo_1995_GK_Zone_2", GEOGCS["GCS_Pulkovo_1995", ' - 'DATUM["D_Pulkovo_1995", SPHEROID["Krasovsky_1940", 6378245, 298.3]], ' - 'PRIMEM["Greenwich", 0], ' - 'UNIT["Degree", 0.017453292519943295]], PROJECTION["Gauss_Kruger"], ' - 'PARAMETER["False_Easting", 2500000], ' - 'PARAMETER["False_Northing", 0], PARAMETER["Central_Meridian", 9], ' - 'PARAMETER["Scale_Factor", 1], ' - 'PARAMETER["Latitude_Of_Origin", 0], UNIT["Meter", 1]]') + self.map.setWKTProjection( + 'ESRI::PROJCS["Pulkovo_1995_GK_Zone_2", GEOGCS["GCS_Pulkovo_1995", ' + 'DATUM["D_Pulkovo_1995", SPHEROID["Krasovsky_1940", 6378245, 298.3]], ' + 'PRIMEM["Greenwich", 0], ' + 'UNIT["Degree", 0.017453292519943295]], PROJECTION["Gauss_Kruger"], ' + 'PARAMETER["False_Easting", 2500000], ' + 'PARAMETER["False_Northing", 0], PARAMETER["Central_Meridian", 9], ' + 'PARAMETER["Scale_Factor", 1], ' + 'PARAMETER["Latitude_Of_Origin", 0], UNIT["Meter", 1]]' + ) proj4 = self.map.getProjection() - assert proj4.find('+proj=tmerc') != -1 - assert proj4.find('+ellps=krass') != -1 + assert proj4.find("+proj=tmerc") != -1 + assert proj4.find("+ellps=krass") != -1 assert (mapscript.projectionObj(proj4)).getUnits() != mapscript.MS_DD def testWellKnownGEOGCS(self): - self.map.setWKTProjection('WGS84') + self.map.setWKTProjection("WGS84") proj4 = self.map.getProjection() - assert ('+proj=longlat' in proj4 and '+datum=WGS84' in proj4) or proj4 == '+init=epsg:4326', proj4 + assert ( + "+proj=longlat" in proj4 and "+datum=WGS84" in proj4 + ) or proj4 == "+init=epsg:4326", proj4 assert (mapscript.projectionObj(proj4)).getUnits() != mapscript.MS_METERS class MapRunSubTestCase(MapTestCase): - def testDefaultSubstitutions(self): s = """ MAP @@ -330,5 +352,5 @@ def test(self): assert result.startswith(' Line::constructor; -void Line::Initialize(Handle target) -{ +void Line::Initialize(Handle target) { HandleScope scope; Handle c = FunctionTemplate::New(Line::New); @@ -55,78 +54,66 @@ void Line::Initialize(Handle target) constructor.Reset(Isolate::GetCurrent(), c); } -void Line::Dispose() -{ +void Line::Dispose() { Line::constructor.Dispose(); Line::constructor.Clear(); } -Line::~Line() -{ +Line::~Line() { if (this->freeInternal) { msFree(this->this_->point); msFree(this->this_); } } -Handle Line::Constructor() -{ +Handle Line::Constructor() { return (*Line::constructor)->GetFunction(); } -void Line::New(const v8::FunctionCallbackInfo& args) -{ +void Line::New(const v8::FunctionCallbackInfo &args) { HandleScope scope; - if (args[0]->IsExternal()) - { + if (args[0]->IsExternal()) { Local ext = Local::Cast(args[0]); void *ptr = ext->Value(); - Line *line = static_cast(ptr); + Line *line = static_cast(ptr); Handle self = args.Holder(); line->Wrap(self); if (line->parent_) { self->SetHiddenValue(String::New("__parent__"), line->parent_->handle()); line->disableMemoryHandler(); } - } - else - { + } else { lineObj *l = (lineObj *)msSmallMalloc(sizeof(lineObj)); - l->numpoints=0; - l->point=NULL; + l->numpoints = 0; + l->point = NULL; Line *line = new Line(l); line->Wrap(args.Holder()); } - } -Line::Line(lineObj *l, ObjectWrap *p): - ObjectWrap() -{ +Line::Line(lineObj *l, ObjectWrap *p) : ObjectWrap() { this->this_ = l; this->parent_ = p; this->freeInternal = true; } void Line::getProp(Local property, - const PropertyCallbackInfo& info) -{ - HandleScope scope; - Line* l = ObjectWrap::Unwrap(info.Holder()); - std::string name = TOSTR(property); - Handle value = Undefined(); + const PropertyCallbackInfo &info) { + HandleScope scope; + Line *l = ObjectWrap::Unwrap(info.Holder()); + std::string name = TOSTR(property); + Handle value = Undefined(); - if (name == "numpoints") - value = Integer::New(l->get()->numpoints); + if (name == "numpoints") + value = Integer::New(l->get()->numpoints); - info.GetReturnValue().Set(value); + info.GetReturnValue().Set(value); } -void Line::getPoint(const v8::FunctionCallbackInfo& args) -{ +void Line::getPoint(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -134,13 +121,12 @@ void Line::getPoint(const v8::FunctionCallbackInfo& args) return; } - Line* l = ObjectWrap::Unwrap(args.Holder()); - lineObj* line = l->get(); + Line *l = ObjectWrap::Unwrap(args.Holder()); + lineObj *line = l->get(); int index = args[0]->Int32Value(); - if (index < 0 || index >= line->numpoints) - { + if (index < 0 || index >= line->numpoints) { ThrowException(String::New("Invalid point index.")); return; } @@ -150,8 +136,7 @@ void Line::getPoint(const v8::FunctionCallbackInfo& args) args.GetReturnValue().Set(Point::Constructor()->NewInstance(1, &ext)); } -void Line::addXY(const v8::FunctionCallbackInfo& args) -{ +void Line::addXY(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) { @@ -159,13 +144,14 @@ void Line::addXY(const v8::FunctionCallbackInfo& args) return; } - Line* l = ObjectWrap::Unwrap(args.Holder()); - lineObj* line = l->get(); + Line *l = ObjectWrap::Unwrap(args.Holder()); + lineObj *line = l->get(); - if(line->numpoints == 0) /* new */ + if (line->numpoints == 0) /* new */ line->point = (pointObj *)msSmallMalloc(sizeof(pointObj)); else /* extend array */ - line->point = (pointObj *)msSmallRealloc(line->point, sizeof(pointObj)*(line->numpoints+1)); + line->point = (pointObj *)msSmallRealloc( + line->point, sizeof(pointObj) * (line->numpoints + 1)); line->point[line->numpoints].x = args[0]->NumberValue(); line->point[line->numpoints].y = args[1]->NumberValue(); @@ -175,23 +161,23 @@ void Line::addXY(const v8::FunctionCallbackInfo& args) line->numpoints++; } -void Line::addXYZ(const v8::FunctionCallbackInfo& args) -{ +void Line::addXYZ(const v8::FunctionCallbackInfo &args) { HandleScope scope; - if (args.Length() < 3 || !args[0]->IsNumber() || - !args[1]->IsNumber() || !args[2]->IsNumber()) { + if (args.Length() < 3 || !args[0]->IsNumber() || !args[1]->IsNumber() || + !args[2]->IsNumber()) { ThrowException(String::New("Invalid argument")); return; } - Line* l = ObjectWrap::Unwrap(args.Holder()); - lineObj* line = l->get(); + Line *l = ObjectWrap::Unwrap(args.Holder()); + lineObj *line = l->get(); - if(line->numpoints == 0) /* new */ + if (line->numpoints == 0) /* new */ line->point = (pointObj *)msSmallMalloc(sizeof(pointObj)); else /* extend array */ - line->point = (pointObj *)msSmallRealloc(line->point, sizeof(pointObj)*(line->numpoints+1)); + line->point = (pointObj *)msSmallRealloc( + line->point, sizeof(pointObj) * (line->numpoints + 1)); line->point[line->numpoints].x = args[0]->NumberValue(); line->point[line->numpoints].y = args[1]->NumberValue(); @@ -201,25 +187,26 @@ void Line::addXYZ(const v8::FunctionCallbackInfo& args) line->numpoints++; } -void Line::addPoint(const v8::FunctionCallbackInfo& args) -{ +void Line::addPoint(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsObject() || - !args[0]->ToObject()->GetConstructorName()->Equals(String::New("pointObj"))) { + !args[0]->ToObject()->GetConstructorName()->Equals( + String::New("pointObj"))) { ThrowException(String::New("Invalid argument")); return; } - Line* l = ObjectWrap::Unwrap(args.Holder()); - lineObj* line = l->get(); - Point* p = ObjectWrap::Unwrap(args[0]->ToObject()); - pointObj* point = p->get(); + Line *l = ObjectWrap::Unwrap(args.Holder()); + lineObj *line = l->get(); + Point *p = ObjectWrap::Unwrap(args[0]->ToObject()); + pointObj *point = p->get(); - if(line->numpoints == 0) /* new */ + if (line->numpoints == 0) /* new */ line->point = (pointObj *)msSmallMalloc(sizeof(pointObj)); else /* extend array */ - line->point = (pointObj *)msSmallRealloc(line->point, sizeof(pointObj)*(line->numpoints+1)); + line->point = (pointObj *)msSmallRealloc( + line->point, sizeof(pointObj) * (line->numpoints + 1)); line->point[line->numpoints].x = point->x; line->point[line->numpoints].y = point->y; diff --git a/mapscript/v8/line.hpp b/mapscript/v8/line.hpp index b08016505f..a9c1342598 100644 --- a/mapscript/v8/line.hpp +++ b/mapscript/v8/line.hpp @@ -33,29 +33,28 @@ using namespace v8; -class Line: public ObjectWrap -{ +class Line : public ObjectWrap { public: static void Initialize(Handle target); - static void New(const v8::FunctionCallbackInfo& args); + static void New(const v8::FunctionCallbackInfo &args); static void Dispose(); static Handle Constructor(); Line(lineObj *l, ObjectWrap *p = NULL); ~Line(); - inline lineObj* get() { return this_; } + inline lineObj *get() { return this_; } inline void disableMemoryHandler() { this->freeInternal = false; } static void getProp(Local property, - const PropertyCallbackInfo& info); - static void setProp(Local property, - Local value, - const PropertyCallbackInfo& info); + const PropertyCallbackInfo &info); + static void setProp(Local property, Local value, + const PropertyCallbackInfo &info); + + static void getPoint(const v8::FunctionCallbackInfo &args); + static void addXY(const v8::FunctionCallbackInfo &args); + static void addXYZ(const v8::FunctionCallbackInfo &args); + static void addPoint(const v8::FunctionCallbackInfo &args); - static void getPoint(const v8::FunctionCallbackInfo& args); - static void addXY(const v8::FunctionCallbackInfo& args); - static void addXYZ(const v8::FunctionCallbackInfo& args); - static void addPoint(const v8::FunctionCallbackInfo& args); private: static Persistent constructor; lineObj *this_; diff --git a/mapscript/v8/point.cpp b/mapscript/v8/point.cpp index ce649b7d63..ba99792b60 100644 --- a/mapscript/v8/point.cpp +++ b/mapscript/v8/point.cpp @@ -35,8 +35,7 @@ using namespace v8; Persistent Point::constructor; -void Point::Initialize(Handle target) -{ +void Point::Initialize(Handle target) { HandleScope scope; Handle c = FunctionTemplate::New(Point::New); @@ -56,42 +55,35 @@ void Point::Initialize(Handle target) constructor.Reset(Isolate::GetCurrent(), c); } -void Point::Dispose() -{ +void Point::Dispose() { Point::constructor.Dispose(); Point::constructor.Clear(); } -Point::~Point() -{ +Point::~Point() { if (this->freeInternal) { msFree(this->get()); } } -Handle Point::Constructor() -{ +Handle Point::Constructor() { return (*Point::constructor)->GetFunction(); } -void Point::New(const v8::FunctionCallbackInfo& args) -{ +void Point::New(const v8::FunctionCallbackInfo &args) { HandleScope scope; - if (args[0]->IsExternal()) - { + if (args[0]->IsExternal()) { Local ext = Local::Cast(args[0]); void *ptr = ext->Value(); - Point *point = static_cast(ptr); + Point *point = static_cast(ptr); Handle self = args.Holder(); point->Wrap(self); if (point->parent_) { self->SetHiddenValue(String::New("__parent__"), point->parent_->handle()); point->disableMemoryHandler(); } - } - else - { + } else { pointObj *p = (pointObj *)msSmallMalloc(sizeof(pointObj)); p->x = 0; @@ -104,58 +96,51 @@ void Point::New(const v8::FunctionCallbackInfo& args) } } - Point::Point(pointObj *p, ObjectWrap *pa): - ObjectWrap() -{ - this->this_ = p; - this->parent_ = pa; - this->freeInternal = true; +Point::Point(pointObj *p, ObjectWrap *pa) : ObjectWrap() { + this->this_ = p; + this->parent_ = pa; + this->freeInternal = true; } void Point::getProp(Local property, - const PropertyCallbackInfo& info) -{ - HandleScope scope; - Point* p = ObjectWrap::Unwrap(info.Holder()); - std::string name = TOSTR(property); - Handle value = Undefined(); - - if (name == "x") - value = Number::New(p->get()->x); - else if (name == "y") - value = Number::New(p->get()->y); - else if (name == "z") - value = Number::New(p->get()->z); - else if (name == "m") - value = Number::New(p->get()->m); - - info.GetReturnValue().Set(value); + const PropertyCallbackInfo &info) { + HandleScope scope; + Point *p = ObjectWrap::Unwrap(info.Holder()); + std::string name = TOSTR(property); + Handle value = Undefined(); + + if (name == "x") + value = Number::New(p->get()->x); + else if (name == "y") + value = Number::New(p->get()->y); + else if (name == "z") + value = Number::New(p->get()->z); + else if (name == "m") + value = Number::New(p->get()->m); + + info.GetReturnValue().Set(value); } -void Point::setProp(Local property, - Local value, - const PropertyCallbackInfo& info) -{ - HandleScope scope; - Point* p = ObjectWrap::Unwrap(info.Holder()); - std::string name = TOSTR(property); - if (!value->IsNumber()) - ThrowException(Exception::TypeError( - String::New("point value must be a number"))); - if (name == "x") { - p->get()->x = value->NumberValue(); - } else if (name == "y") { - p->get()->y = value->NumberValue(); - } - else if (name == "z") { - p->get()->z = value->NumberValue(); - } else if (name == "m") { - p->get()->m = value->NumberValue(); - } +void Point::setProp(Local property, Local value, + const PropertyCallbackInfo &info) { + HandleScope scope; + Point *p = ObjectWrap::Unwrap(info.Holder()); + std::string name = TOSTR(property); + if (!value->IsNumber()) + ThrowException( + Exception::TypeError(String::New("point value must be a number"))); + if (name == "x") { + p->get()->x = value->NumberValue(); + } else if (name == "y") { + p->get()->y = value->NumberValue(); + } else if (name == "z") { + p->get()->z = value->NumberValue(); + } else if (name == "m") { + p->get()->m = value->NumberValue(); + } } -void Point::setXY(const v8::FunctionCallbackInfo& args) -{ +void Point::setXY(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) { @@ -163,24 +148,22 @@ void Point::setXY(const v8::FunctionCallbackInfo& args) return; } - Point* p = ObjectWrap::Unwrap(args.Holder()); + Point *p = ObjectWrap::Unwrap(args.Holder()); p->get()->x = args[0]->NumberValue(); p->get()->y = args[1]->NumberValue(); - } -void Point::setXYZ(const v8::FunctionCallbackInfo& args) -{ +void Point::setXYZ(const v8::FunctionCallbackInfo &args) { HandleScope scope; - if (args.Length() < 3 || - !args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { + if (args.Length() < 3 || !args[0]->IsNumber() || !args[1]->IsNumber() || + !args[2]->IsNumber()) { ThrowException(String::New("Invalid argument")); return; } - Point* p = ObjectWrap::Unwrap(args.Holder()); + Point *p = ObjectWrap::Unwrap(args.Holder()); p->get()->x = args[0]->NumberValue(); p->get()->y = args[1]->NumberValue(); diff --git a/mapscript/v8/point.hpp b/mapscript/v8/point.hpp index b8e173d551..c2d5317930 100644 --- a/mapscript/v8/point.hpp +++ b/mapscript/v8/point.hpp @@ -33,27 +33,26 @@ using namespace v8; -class Point: public ObjectWrap -{ +class Point : public ObjectWrap { public: static void Initialize(Handle target); - static void New(const v8::FunctionCallbackInfo& args); + static void New(const v8::FunctionCallbackInfo &args); static void Dispose(); static Handle Constructor(); Point(pointObj *p, ObjectWrap *pa = NULL); ~Point(); - inline pointObj* get() { return this_; } + inline pointObj *get() { return this_; } inline void disableMemoryHandler() { this->freeInternal = false; } static void getProp(Local property, - const PropertyCallbackInfo& info); - static void setProp(Local property, - Local value, - const PropertyCallbackInfo& info); + const PropertyCallbackInfo &info); + static void setProp(Local property, Local value, + const PropertyCallbackInfo &info); + + static void setXY(const v8::FunctionCallbackInfo &args); + static void setXYZ(const v8::FunctionCallbackInfo &args); - static void setXY(const v8::FunctionCallbackInfo& args); - static void setXYZ(const v8::FunctionCallbackInfo& args); private: static Persistent constructor; pointObj *this_; diff --git a/mapscript/v8/shape.cpp b/mapscript/v8/shape.cpp index dba22bc179..28939fdd3b 100644 --- a/mapscript/v8/shape.cpp +++ b/mapscript/v8/shape.cpp @@ -38,8 +38,7 @@ using std::string; Persistent Shape::constructor; -void Shape::Initialize(Handle target) -{ +void Shape::Initialize(Handle target) { HandleScope scope; Handle c = FunctionTemplate::New(Shape::New); @@ -59,28 +58,22 @@ void Shape::Initialize(Handle target) NODE_SET_PROTOTYPE_METHOD(c, "add", addLine); NODE_SET_PROTOTYPE_METHOD(c, "setGeometry", setGeometry); - NODE_DEFINE_CONSTANT(c->GetFunction(), - "Point",MS_SHAPE_POINT); - NODE_DEFINE_CONSTANT(c->GetFunction(), - "Line",MS_SHAPE_LINE); - NODE_DEFINE_CONSTANT(c->GetFunction(), - "Polygon",MS_SHAPE_POLYGON); - NODE_DEFINE_CONSTANT(c->GetFunction(), - "Null",MS_SHAPE_NULL); + NODE_DEFINE_CONSTANT(c->GetFunction(), "Point", MS_SHAPE_POINT); + NODE_DEFINE_CONSTANT(c->GetFunction(), "Line", MS_SHAPE_LINE); + NODE_DEFINE_CONSTANT(c->GetFunction(), "Polygon", MS_SHAPE_POLYGON); + NODE_DEFINE_CONSTANT(c->GetFunction(), "Null", MS_SHAPE_NULL); target->Set(String::NewSymbol("shapeObj"), c->GetFunction()); constructor.Reset(Isolate::GetCurrent(), c); } -void Shape::Dispose() -{ +void Shape::Dispose() { Shape::constructor.Dispose(); Shape::constructor.Clear(); } -Shape::~Shape() -{ +Shape::~Shape() { /* this is set to false if the shapeObj is owned by mapserver and not v8 */ if (freeInternal) { msFreeShape(this->get()); @@ -88,33 +81,27 @@ Shape::~Shape() } } -Handle Shape::Constructor() -{ +Handle Shape::Constructor() { return (*Shape::constructor)->GetFunction(); } -void Shape::New(const v8::FunctionCallbackInfo& args) -{ +void Shape::New(const v8::FunctionCallbackInfo &args) { HandleScope scope; Handle self = args.Holder(); Shape *shape; - if (args[0]->IsExternal()) - { + if (args[0]->IsExternal()) { Local ext = Local::Cast(args[0]); void *ptr = ext->Value(); - shape = static_cast(ptr); + shape = static_cast(ptr); shape->Wrap(args.Holder()); - } - else - { + } else { shapeObj *s = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); msInitShape(s); - if(args.Length() >= 1) { + if (args.Length() >= 1) { s->type = args[0]->Int32Value(); - } - else { + } else { s->type = MS_SHAPE_NULL; } @@ -130,11 +117,11 @@ void Shape::New(const v8::FunctionCallbackInfo& args) Handle attributes = attributes_templ->NewInstance(); map *attributes_map = new map(); attributes->SetInternalField(0, External::New(attributes_map)); - attributes->SetInternalField(1, External::New(shape->get()->values)); + attributes->SetInternalField(1, External::New(shape->get()->values)); attributes->SetHiddenValue(String::New("__parent__"), self); if (shape->layer) { - for (int i=0; ilayer->numitems; ++i) { + for (int i = 0; i < shape->layer->numitems; ++i) { (*attributes_map)[string(shape->layer->items[i])] = i; } } @@ -147,59 +134,53 @@ void Shape::New(const v8::FunctionCallbackInfo& args) self->Set(String::New("attributes"), attributes); } -Shape::Shape(shapeObj *s): - ObjectWrap() -{ +Shape::Shape(shapeObj *s) : ObjectWrap() { this->this_ = s; this->layer = NULL; this->freeInternal = true; } void Shape::getProp(Local property, - const PropertyCallbackInfo& info) -{ - HandleScope scope; - Shape* s = ObjectWrap::Unwrap(info.Holder()); - std::string name = TOSTR(property); - Handle value = Undefined(); - - if (name == "numvalues") - value = Integer::New(s->get()->numvalues); - else if (name == "numlines") - value = Integer::New(s->get()->numlines); - else if (name == "index") - value = Number::New(s->get()->index); - else if (name == "type") - value = Integer::New(s->get()->type); - else if (name == "tileindex") - value = Integer::New(s->get()->tileindex); - else if (name == "classindex") - value = Integer::New(s->get()->classindex); - else if (name == "text") - value = String::New(s->get()->text); - - info.GetReturnValue().Set(value); + const PropertyCallbackInfo &info) { + HandleScope scope; + Shape *s = ObjectWrap::Unwrap(info.Holder()); + std::string name = TOSTR(property); + Handle value = Undefined(); + + if (name == "numvalues") + value = Integer::New(s->get()->numvalues); + else if (name == "numlines") + value = Integer::New(s->get()->numlines); + else if (name == "index") + value = Number::New(s->get()->index); + else if (name == "type") + value = Integer::New(s->get()->type); + else if (name == "tileindex") + value = Integer::New(s->get()->tileindex); + else if (name == "classindex") + value = Integer::New(s->get()->classindex); + else if (name == "text") + value = String::New(s->get()->text); + + info.GetReturnValue().Set(value); } -void Shape::setProp(Local property, - Local value, - const PropertyCallbackInfo& info) -{ - HandleScope scope; - Shape* s = ObjectWrap::Unwrap(info.Holder()); - std::string name = TOSTR(property); - - if (name == "text") { - if (s->get()->text) - msFree(s->get()->text); - s->get()->text = getStringValue(value); - } +void Shape::setProp(Local property, Local value, + const PropertyCallbackInfo &info) { + HandleScope scope; + Shape *s = ObjectWrap::Unwrap(info.Holder()); + std::string name = TOSTR(property); + + if (name == "text") { + if (s->get()->text) + msFree(s->get()->text); + s->get()->text = getStringValue(value); + } } -void Shape::clone(const v8::FunctionCallbackInfo& args) -{ +void Shape::clone(const v8::FunctionCallbackInfo &args) { HandleScope scope; - Shape* s = ObjectWrap::Unwrap(args.Holder()); + Shape *s = ObjectWrap::Unwrap(args.Holder()); shapeObj *shape = s->get(); shapeObj *new_shape = (shapeObj *)msSmallMalloc(sizeof(shapeObj)); @@ -208,16 +189,19 @@ void Shape::clone(const v8::FunctionCallbackInfo& args) Shape *ns = new Shape(new_shape); Handle ext = External::New(ns); - Handle clone = Shape::Constructor()->NewInstance(1, &ext); + Handle clone = Shape::Constructor()->NewInstance(1, &ext); /* we need this to copy shape attributes */ Handle self = s->handle(); - Handle self_attributes = self->Get(String::New("attributes"))->ToObject(); - Local wrap = Local::Cast(self_attributes->GetInternalField(0)); + Handle self_attributes = + self->Get(String::New("attributes"))->ToObject(); + Local wrap = + Local::Cast(self_attributes->GetInternalField(0)); void *ptr = wrap->Value(); map *self_attributes_map = static_cast *>(ptr); - Handle clone_attributes = clone->Get(String::New("attributes"))->ToObject(); + Handle clone_attributes = + clone->Get(String::New("attributes"))->ToObject(); wrap = Local::Cast(clone_attributes->GetInternalField(0)); ptr = wrap->Value(); map *clone_attributes_map = static_cast *>(ptr); @@ -228,8 +212,7 @@ void Shape::clone(const v8::FunctionCallbackInfo& args) args.GetReturnValue().Set(clone); } -void Shape::getLine(const v8::FunctionCallbackInfo& args) -{ +void Shape::getLine(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -239,11 +222,10 @@ void Shape::getLine(const v8::FunctionCallbackInfo& args) int index = args[0]->Int32Value(); - Shape* s = ObjectWrap::Unwrap(args.Holder()); + Shape *s = ObjectWrap::Unwrap(args.Holder()); shapeObj *shape = s->get(); - if (index < 0 || index >= shape->numlines) - { + if (index < 0 || index >= shape->numlines) { ThrowException(String::New("Invalid line index.")); return; } @@ -253,45 +235,46 @@ void Shape::getLine(const v8::FunctionCallbackInfo& args) args.GetReturnValue().Set(Line::Constructor()->NewInstance(1, &ext)); } -void Shape::addLine(const v8::FunctionCallbackInfo& args) -{ +void Shape::addLine(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsObject() || - !args[0]->ToObject()->GetConstructorName()->Equals(String::New("lineObj"))) { + !args[0]->ToObject()->GetConstructorName()->Equals( + String::New("lineObj"))) { ThrowException(String::New("Invalid argument")); return; } - Shape* s = ObjectWrap::Unwrap(args.Holder()); + Shape *s = ObjectWrap::Unwrap(args.Holder()); shapeObj *shape = s->get(); - Line* l = ObjectWrap::Unwrap(args[0]->ToObject()); + Line *l = ObjectWrap::Unwrap(args[0]->ToObject()); lineObj *line = l->get(); msAddLine(shape, line); } -void Shape::setGeometry(const v8::FunctionCallbackInfo& args) -{ +void Shape::setGeometry(const v8::FunctionCallbackInfo &args) { HandleScope scope; if (args.Length() < 1 || !args[0]->IsObject() || - !args[0]->ToObject()->GetConstructorName()->Equals(String::New("shapeObj"))) { + !args[0]->ToObject()->GetConstructorName()->Equals( + String::New("shapeObj"))) { ThrowException(String::New("Invalid argument")); return; } - Shape* s = ObjectWrap::Unwrap(args.Holder()); + Shape *s = ObjectWrap::Unwrap(args.Holder()); shapeObj *shape = s->get(); - Shape* ns = ObjectWrap::Unwrap(args[0]->ToObject()); + Shape *ns = ObjectWrap::Unwrap(args[0]->ToObject()); shapeObj *new_shape = ns->get(); /* clean current shape */ for (int i = 0; i < shape->numlines; i++) { free(shape->line[i].point); } - if (shape->line) free(shape->line); + if (shape->line) + free(shape->line); shape->line = NULL; shape->numlines = 0; @@ -302,18 +285,17 @@ void Shape::setGeometry(const v8::FunctionCallbackInfo& args) return; } -void Shape::attributeWeakCallback(v8::Isolate* isolate, - v8::Persistent* pobj, - map *map) { - v8::HandleScope scope(isolate); - pobj->Dispose(); - pobj->Clear(); - delete map; +void Shape::attributeWeakCallback(v8::Isolate *isolate, + v8::Persistent *pobj, + map *map) { + v8::HandleScope scope(isolate); + pobj->Dispose(); + pobj->Clear(); + delete map; } void Shape::attributeGetValue(Local name, - const PropertyCallbackInfo &info) -{ + const PropertyCallbackInfo &info) { Local self = info.Holder(); Local wrap = Local::Cast(self->GetInternalField(0)); void *ptr = wrap->Value(); @@ -332,10 +314,8 @@ void Shape::attributeGetValue(Local name, } } -void Shape::attributeSetValue(Local name, - Local value, - const PropertyCallbackInfo &info) -{ +void Shape::attributeSetValue(Local name, Local value, + const PropertyCallbackInfo &info) { Local self = info.Holder(); Local wrap = Local::Cast(self->GetInternalField(0)); void *ptr = wrap->Value(); @@ -351,9 +331,7 @@ void Shape::attributeSetValue(Local name, if (iter == indexes->end()) { ThrowException(String::New("Invalid value name.")); - } - else - { + } else { const int &index = (*iter).second; msFree(values[index]); values[index] = msStrdup(*utf8_value); diff --git a/mapscript/v8/shape.hpp b/mapscript/v8/shape.hpp index 3f9bdc01ef..562bb01817 100644 --- a/mapscript/v8/shape.hpp +++ b/mapscript/v8/shape.hpp @@ -37,44 +37,41 @@ using namespace v8; using std::map; using std::string; -class Shape: public ObjectWrap -{ +class Shape : public ObjectWrap { public: static void Initialize(Handle target); - static void New(const v8::FunctionCallbackInfo& args); + static void New(const v8::FunctionCallbackInfo &args); static void Dispose(); static Handle Constructor(); Shape(shapeObj *p); - ~Shape(); - inline shapeObj* get() { return this_; } + ~Shape(); + inline shapeObj *get() { return this_; } inline void disableMemoryHandler() { this->freeInternal = false; } - + inline void setLayer(layerObj *layer) { this->layer = layer; }; - + static void getProp(Local property, - const PropertyCallbackInfo& info); - static void setProp(Local property, - Local value, - const PropertyCallbackInfo& info); + const PropertyCallbackInfo &info); + static void setProp(Local property, Local value, + const PropertyCallbackInfo &info); - static void clone(const v8::FunctionCallbackInfo& args); - static void getLine(const v8::FunctionCallbackInfo& args); - static void addLine(const v8::FunctionCallbackInfo& args); - static void setGeometry(const v8::FunctionCallbackInfo& args); + static void clone(const v8::FunctionCallbackInfo &args); + static void getLine(const v8::FunctionCallbackInfo &args); + static void addLine(const v8::FunctionCallbackInfo &args); + static void setGeometry(const v8::FunctionCallbackInfo &args); /* This could be generic in the future.. */ - static void attributeWeakCallback(v8::Isolate* isolate, - v8::Persistent* pobj, + static void attributeWeakCallback(v8::Isolate *isolate, + v8::Persistent *pobj, map *map); static void attributeGetValue(Local name, const PropertyCallbackInfo &info); - static void attributeSetValue(Local name, - Local value, + static void attributeSetValue(Local name, Local value, const PropertyCallbackInfo &info); - static void attributeMapDestroy(Isolate *isolate, - Persistent *object, - map *map); + static void attributeMapDestroy(Isolate *isolate, Persistent *object, + map *map); + private: static Persistent constructor; bool freeInternal; diff --git a/mapscript/v8/v8_mapscript.cpp b/mapscript/v8/v8_mapscript.cpp index ea3d8aadd8..a8bdb8b63f 100644 --- a/mapscript/v8/v8_mapscript.cpp +++ b/mapscript/v8/v8_mapscript.cpp @@ -32,15 +32,14 @@ #include "mapserver.h" #include "v8_mapscript.h" -char* getStringValue(Local value, const char *fallback) -{ +char *getStringValue(Local value, const char *fallback) { if (value->IsString()) { String::AsciiValue string(value); - char *str = (char *) malloc(string.length() + 1); + char *str = (char *)malloc(string.length() + 1); strcpy(str, *string); return str; } - char *str = (char *) malloc(strlen(fallback) + 1); + char *str = (char *)malloc(strlen(fallback) + 1); strcpy(str, fallback); return str; } diff --git a/mapscript/v8/v8_mapscript.h b/mapscript/v8/v8_mapscript.h index b38d36d9eb..654b5f3afe 100644 --- a/mapscript/v8/v8_mapscript.h +++ b/mapscript/v8/v8_mapscript.h @@ -48,28 +48,26 @@ using namespace v8; -using std::string; -using std::stack; using std::map; +using std::stack; +using std::string; -class V8Context -{ +class V8Context { public: - V8Context(Isolate *isolate) - : isolate(isolate) {} + V8Context(Isolate *isolate) : isolate(isolate) {} Isolate *isolate; stack paths; /* for relative paths and the require function */ - map > scripts; + map> scripts; Persistent context; layerObj *layer; /* current layer, used in geomtransform */ }; -#define V8CONTEXT(map) ((V8Context*) (map)->v8context) +#define V8CONTEXT(map) ((V8Context *)(map)->v8context) inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle recv, - const char* name, + const char *name, v8::FunctionCallback callback) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate *isolate = v8::Isolate::GetCurrent(); v8::HandleScope handle_scope(isolate); v8::Local t = v8::FunctionTemplate::New(callback); recv->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, name), @@ -79,29 +77,22 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle recv, #define TOSTR(obj) (*String::Utf8Value((obj)->ToString())) -#define SET(target, name, value) \ +#define SET(target, name, value) \ (target)->PrototypeTemplate()->Set(String::NewSymbol(name), value); -#define SET_ATTRIBUTE(t, name, get, set) \ +#define SET_ATTRIBUTE(t, name, get, set) \ t->InstanceTemplate()->SetAccessor(String::NewSymbol(name), get, set) -#define SET_ATTRIBUTE_RO(t, name, get) \ - t->InstanceTemplate()->SetAccessor( \ - String::NewSymbol(name), \ - get, 0, \ - Handle(), \ - DEFAULT, \ - static_cast( \ - ReadOnly|DontDelete)) - -#define NODE_DEFINE_CONSTANT(target, name, constant) \ - (target)->Set(String::NewSymbol(name), \ - Integer::New(constant), \ - static_cast( \ - ReadOnly|DontDelete)); +#define SET_ATTRIBUTE_RO(t, name, get) \ + t->InstanceTemplate()->SetAccessor( \ + String::NewSymbol(name), get, 0, Handle(), DEFAULT, \ + static_cast(ReadOnly | DontDelete)) -char* getStringValue(Local value, const char *fallback=""); +#define NODE_DEFINE_CONSTANT(target, name, constant) \ + (target)->Set(String::NewSymbol(name), Integer::New(constant), \ + static_cast(ReadOnly | DontDelete)); +char *getStringValue(Local value, const char *fallback = ""); #endif diff --git a/mapscript/v8/v8_object_wrap.hpp b/mapscript/v8/v8_object_wrap.hpp index b451266527..d040bd53f3 100644 --- a/mapscript/v8/v8_object_wrap.hpp +++ b/mapscript/v8/v8_object_wrap.hpp @@ -26,10 +26,8 @@ #include class ObjectWrap { - public: - ObjectWrap() { - refs_ = 0; - } +public: + ObjectWrap() { refs_ = 0; } virtual ~ObjectWrap() { if (persistent().IsEmpty()) @@ -39,35 +37,27 @@ class ObjectWrap { persistent().Dispose(); } - - template - static inline T* Unwrap(v8::Handle handle) { + template static inline T *Unwrap(v8::Handle handle) { assert(!handle.IsEmpty()); assert(handle->InternalFieldCount() > 0); // Cast to ObjectWrap before casting to T. A direct cast from void // to T won't work right when T has more than one base class. - void* ptr = handle->GetAlignedPointerFromInternalField(0); - ObjectWrap* wrap = static_cast(ptr); - return static_cast(wrap); + void *ptr = handle->GetAlignedPointerFromInternalField(0); + ObjectWrap *wrap = static_cast(ptr); + return static_cast(wrap); } - inline v8::Local handle() { return handle(v8::Isolate::GetCurrent()); } - - inline v8::Local handle(v8::Isolate* isolate) { + inline v8::Local handle(v8::Isolate *isolate) { return v8::Local::New(isolate, persistent()); } + inline v8::Persistent &persistent() { return handle_; } - inline v8::Persistent& persistent() { - return handle_; - } - - - protected: +protected: inline void Wrap(v8::Handle handle) { assert(persistent().IsEmpty()); assert(handle->InternalFieldCount() > 0); @@ -76,7 +66,6 @@ class ObjectWrap { MakeWeak(); } - inline void MakeWeak(void) { persistent().MakeWeak(this, WeakCallback); persistent().MarkIndependent(); @@ -109,12 +98,11 @@ class ObjectWrap { MakeWeak(); } - int refs_; // ro + int refs_; // ro - private: - static void WeakCallback(v8::Isolate* isolate, - v8::Persistent* pobj, - ObjectWrap* wrap) { +private: + static void WeakCallback(v8::Isolate *isolate, + v8::Persistent *pobj, ObjectWrap *wrap) { v8::HandleScope scope(isolate); assert(wrap->refs_ == 0); assert(*pobj == wrap->persistent()); @@ -125,5 +113,4 @@ class ObjectWrap { v8::Persistent handle_; }; - -#endif // v8_OBJECT_WRAP_H_ +#endif // v8_OBJECT_WRAP_H_ diff --git a/mapsearch.c b/mapsearch.c index d6615320a5..abb378b378 100644 --- a/mapsearch.c +++ b/mapsearch.c @@ -35,21 +35,22 @@ #include "mapserver.h" - - -#define LASTVERT(v,n) ((v) == 0 ? n-2 : v-1) -#define NEXTVERT(v,n) ((v) == n-2 ? 0 : v+1) +#define LASTVERT(v, n) ((v) == 0 ? n - 2 : v - 1) +#define NEXTVERT(v, n) ((v) == n - 2 ? 0 : v + 1) /* ** Returns MS_TRUE if rectangles a and b overlap */ -int msRectOverlap(const rectObj *a, const rectObj *b) -{ - if(a->minx > b->maxx) return(MS_FALSE); - if(a->maxx < b->minx) return(MS_FALSE); - if(a->miny > b->maxy) return(MS_FALSE); - if(a->maxy < b->miny) return(MS_FALSE); - return(MS_TRUE); +int msRectOverlap(const rectObj *a, const rectObj *b) { + if (a->minx > b->maxx) + return (MS_FALSE); + if (a->maxx < b->minx) + return (MS_FALSE); + if (a->miny > b->maxy) + return (MS_FALSE); + if (a->maxy < b->miny) + return (MS_FALSE); + return (MS_TRUE); } /* @@ -57,18 +58,17 @@ int msRectOverlap(const rectObj *a, const rectObj *b) ** to be only the intersection of the two. Returns MS_FALSE if ** the intersection is empty. */ -int msRectIntersect( rectObj *a, const rectObj *b ) -{ - if( a->maxx > b->maxx ) +int msRectIntersect(rectObj *a, const rectObj *b) { + if (a->maxx > b->maxx) a->maxx = b->maxx; - if( a->minx < b->minx ) + if (a->minx < b->minx) a->minx = b->minx; - if( a->maxy > b->maxy ) + if (a->maxy > b->maxy) a->maxy = b->maxy; - if( a->miny < b->miny ) + if (a->miny < b->miny) a->miny = b->miny; - if( a->maxx < a->minx || b->maxx < b->minx ) + if (a->maxx < a->minx || b->maxx < b->minx) return MS_FALSE; else return MS_TRUE; @@ -77,91 +77,108 @@ int msRectIntersect( rectObj *a, const rectObj *b ) /* ** Returns MS_TRUE if rectangle a is contained in rectangle b */ -int msRectContained(const rectObj *a, const rectObj *b) -{ - if(a->minx >= b->minx && a->maxx <= b->maxx) - if(a->miny >= b->miny && a->maxy <= b->maxy) - return(MS_TRUE); - return(MS_FALSE); +int msRectContained(const rectObj *a, const rectObj *b) { + if (a->minx >= b->minx && a->maxx <= b->maxx) + if (a->miny >= b->miny && a->maxy <= b->maxy) + return (MS_TRUE); + return (MS_FALSE); } /* ** Merges rect b into rect a. Rect a changes, b does not. */ -void msMergeRect(rectObj *a, rectObj *b) -{ +void msMergeRect(rectObj *a, rectObj *b) { a->minx = MS_MIN(a->minx, b->minx); a->maxx = MS_MAX(a->maxx, b->maxx); a->miny = MS_MIN(a->miny, b->miny); a->maxy = MS_MAX(a->maxy, b->maxy); } -int msPointInRect(const pointObj *p, const rectObj *rect) -{ - if(p->x < rect->minx) return(MS_FALSE); - if(p->x > rect->maxx) return(MS_FALSE); - if(p->y < rect->miny) return(MS_FALSE); - if(p->y > rect->maxy) return(MS_FALSE); - return(MS_TRUE); +int msPointInRect(const pointObj *p, const rectObj *rect) { + if (p->x < rect->minx) + return (MS_FALSE); + if (p->x > rect->maxx) + return (MS_FALSE); + if (p->y < rect->miny) + return (MS_FALSE); + if (p->y > rect->maxy) + return (MS_FALSE); + return (MS_TRUE); } -int msPolygonDirection(lineObj *c) -{ +int msPolygonDirection(lineObj *c) { double mx, my, area; - int i, v=0, lv, nv; + int i, v = 0, lv, nv; /* first find lowest, rightmost point of polygon */ mx = c->point[0].x; my = c->point[0].y; - for(i=0; inumpoints-1; i++) { - if((c->point[i].y < my) || ((c->point[i].y == my) && (c->point[i].x > mx))) { + for (i = 0; i < c->numpoints - 1; i++) { + if ((c->point[i].y < my) || + ((c->point[i].y == my) && (c->point[i].x > mx))) { v = i; mx = c->point[i].x; my = c->point[i].y; } } - lv = LASTVERT(v,c->numpoints); - nv = NEXTVERT(v,c->numpoints); + lv = LASTVERT(v, c->numpoints); + nv = NEXTVERT(v, c->numpoints); - area = c->point[lv].x*c->point[v].y - c->point[lv].y*c->point[v].x + c->point[lv].y*c->point[nv].x - c->point[lv].x*c->point[nv].y + c->point[v].x*c->point[nv].y - c->point[nv].x*c->point[v].y; - if(area > 0) - return(1); /* counter clockwise orientation */ - else if(area < 0) /* clockwise orientation */ - return(-1); + area = c->point[lv].x * c->point[v].y - c->point[lv].y * c->point[v].x + + c->point[lv].y * c->point[nv].x - c->point[lv].x * c->point[nv].y + + c->point[v].x * c->point[nv].y - c->point[nv].x * c->point[v].y; + if (area > 0) + return (1); /* counter clockwise orientation */ + else if (area < 0) /* clockwise orientation */ + return (-1); else - return(0); /* shouldn't happen unless the polygon is self intersecting */ + return (0); /* shouldn't happen unless the polygon is self intersecting */ } /* ** Copyright (c) 1970-2003, Wm. Randolph Franklin ** -** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -** associated documentation files (the "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +** Permission is hereby granted, free of charge, to any person obtaining a copy +*of this software and +** associated documentation files (the "Software"), to deal in the Software +*without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +*distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +*furnished to do so, subject to the ** following conditions: ** -** 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +** 1. Redistributions of source code must retain the above copyright notice, +*this list of conditions and the ** following disclaimers. -** 2. Redistributions in binary form must reproduce the above copyright notice in the documentation and/or +** 2. Redistributions in binary form must reproduce the above copyright notice +*in the documentation and/or ** other materials provided with the distribution. -** 3. The name of W. Randolph Franklin may not be used to endorse or promote products derived from this +** 3. The name of W. Randolph Franklin may not be used to endorse or promote +*products derived from this ** Software without specific prior written permission. ** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -** LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -** NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +*IMPLIED, INCLUDING BUT NOT +** LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +*PURPOSE AND NONINFRINGEMENT. IN +** NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +*DAMAGES OR OTHER LIABILITY, +** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +*IN CONNECTION WITH THE ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -int msPointInPolygon(pointObj *p, lineObj *c) -{ +int msPointInPolygon(pointObj *p, lineObj *c) { int i, j, status = MS_FALSE; - for (i = 0, j = c->numpoints-1; i < c->numpoints; j = i++) { - if ((((c->point[i].y<=p->y) && (p->ypoint[j].y)) || ((c->point[j].y<=p->y) && (p->ypoint[i].y))) && (p->x < (c->point[j].x - c->point[i].x) * (p->y - c->point[i].y) / (c->point[j].y - c->point[i].y) + c->point[i].x)) + for (i = 0, j = c->numpoints - 1; i < c->numpoints; j = i++) { + if ((((c->point[i].y <= p->y) && (p->y < c->point[j].y)) || + ((c->point[j].y <= p->y) && (p->y < c->point[i].y))) && + (p->x < (c->point[j].x - c->point[i].x) * (p->y - c->point[i].y) / + (c->point[j].y - c->point[i].y) + + c->point[i].x)) status = !status; } return status; @@ -173,44 +190,50 @@ int msPointInPolygon(pointObj *p, lineObj *c) ** cases. In due time... -SDL- */ -int msIntersectSegments(const pointObj *a, const pointObj *b, const pointObj *c, const pointObj *d) /* from comp.graphics.alogorithms FAQ */ +int msIntersectSegments( + const pointObj *a, const pointObj *b, const pointObj *c, + const pointObj *d) /* from comp.graphics.alogorithms FAQ */ { double r, s; double denominator, numerator; - numerator = ((a->y-c->y)*(d->x-c->x) - (a->x-c->x)*(d->y-c->y)); - denominator = ((b->x-a->x)*(d->y-c->y) - (b->y-a->y)*(d->x-c->x)); + numerator = ((a->y - c->y) * (d->x - c->x) - (a->x - c->x) * (d->y - c->y)); + denominator = ((b->x - a->x) * (d->y - c->y) - (b->y - a->y) * (d->x - c->x)); - if((denominator == 0) && (numerator == 0)) { /* lines are coincident, intersection is a line segement if it exists */ - if(a->y == c->y) { /* coincident horizontally, check x's */ - if(((a->x >= MS_MIN(c->x,d->x)) && (a->x <= MS_MAX(c->x,d->x))) || ((b->x >= MS_MIN(c->x,d->x)) && (b->x <= MS_MAX(c->x,d->x)))) - return(MS_TRUE); + if ((denominator == 0) && + (numerator == 0)) { /* lines are coincident, intersection is a line + segement if it exists */ + if (a->y == c->y) { /* coincident horizontally, check x's */ + if (((a->x >= MS_MIN(c->x, d->x)) && (a->x <= MS_MAX(c->x, d->x))) || + ((b->x >= MS_MIN(c->x, d->x)) && (b->x <= MS_MAX(c->x, d->x)))) + return (MS_TRUE); else - return(MS_FALSE); + return (MS_FALSE); } else { /* test for y's will work fine for remaining cases */ - if(((a->y >= MS_MIN(c->y,d->y)) && (a->y <= MS_MAX(c->y,d->y))) || ((b->y >= MS_MIN(c->y,d->y)) && (b->y <= MS_MAX(c->y,d->y)))) - return(MS_TRUE); + if (((a->y >= MS_MIN(c->y, d->y)) && (a->y <= MS_MAX(c->y, d->y))) || + ((b->y >= MS_MIN(c->y, d->y)) && (b->y <= MS_MAX(c->y, d->y)))) + return (MS_TRUE); else - return(MS_FALSE); + return (MS_FALSE); } } - if(denominator == 0) /* lines are parallel, can't intersect */ - return(MS_FALSE); + if (denominator == 0) /* lines are parallel, can't intersect */ + return (MS_FALSE); - r = numerator/denominator; + r = numerator / denominator; - if((r<0) || (r>1)) - return(MS_FALSE); /* no intersection */ + if ((r < 0) || (r > 1)) + return (MS_FALSE); /* no intersection */ - numerator = ((a->y-c->y)*(b->x-a->x) - (a->x-c->x)*(b->y-a->y)); - s = numerator/denominator; + numerator = ((a->y - c->y) * (b->x - a->x) - (a->x - c->x) * (b->y - a->y)); + s = numerator / denominator; - if((s<0) || (s>1)) - return(MS_FALSE); /* no intersection */ + if ((s < 0) || (s > 1)) + return (MS_FALSE); /* no intersection */ - return(MS_TRUE); + return (MS_TRUE); } /* @@ -218,160 +241,168 @@ int msIntersectSegments(const pointObj *a, const pointObj *b, const pointObj *c, ** point falls in. If odd the point is in the polygon, if 0 or even ** then the point is in a hole or completely outside. */ -int msIntersectPointPolygon(pointObj *point, shapeObj *poly) -{ +int msIntersectPointPolygon(pointObj *point, shapeObj *poly) { int i; - int status=MS_FALSE; + int status = MS_FALSE; - for(i=0; inumlines; i++) { - if(msPointInPolygon(point, &poly->line[i]) == MS_TRUE) /* ok, the point is in a line */ + for (i = 0; i < poly->numlines; i++) { + if (msPointInPolygon(point, &poly->line[i]) == + MS_TRUE) /* ok, the point is in a line */ status = !status; } - return(status); + return (status); } -int msIntersectMultipointPolygon(shapeObj *multipoint, shapeObj *poly) -{ - int i,j; +int msIntersectMultipointPolygon(shapeObj *multipoint, shapeObj *poly) { + int i, j; /* The change to loop through all the lines has been made for ticket * #2443 but is no more needed since ticket #2762. PostGIS now put all * points into a single line. */ - for(i=0; inumlines; i++ ) { + for (i = 0; i < multipoint->numlines; i++) { lineObj points = multipoint->line[i]; - for(j=0; jnumlines; c1++) - for(v1=1; v1line[c1].numpoints; v1++) - for(c2=0; c2numlines; c2++) - for(v2=1; v2line[c2].numpoints; v2++) - if(msIntersectSegments(&(line1->line[c1].point[v1-1]), &(line1->line[c1].point[v1]), - &(line2->line[c2].point[v2-1]), &(line2->line[c2].point[v2])) == MS_TRUE) - return(MS_TRUE); + for (c1 = 0; c1 < line1->numlines; c1++) + for (v1 = 1; v1 < line1->line[c1].numpoints; v1++) + for (c2 = 0; c2 < line2->numlines; c2++) + for (v2 = 1; v2 < line2->line[c2].numpoints; v2++) + if (msIntersectSegments(&(line1->line[c1].point[v1 - 1]), + &(line1->line[c1].point[v1]), + &(line2->line[c2].point[v2 - 1]), + &(line2->line[c2].point[v2])) == MS_TRUE) + return (MS_TRUE); - return(MS_FALSE); + return (MS_FALSE); } -int msIntersectPolylinePolygon(shapeObj *line, shapeObj *poly) -{ +int msIntersectPolylinePolygon(shapeObj *line, shapeObj *poly) { int i; - /* STEP 1: polygon might competely contain the polyline or one of it's parts (only need to check one point from each part) */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(line->line[i].point[0]), poly) == MS_TRUE) /* this considers holes and multiple parts */ - return(MS_TRUE); + /* STEP 1: polygon might competely contain the polyline or one of it's parts + * (only need to check one point from each part) */ + for (i = 0; i < line->numlines; i++) { + if (msIntersectPointPolygon(&(line->line[i].point[0]), poly) == + MS_TRUE) /* this considers holes and multiple parts */ + return (MS_TRUE); } /* STEP 2: look for intersecting line segments */ if (msIntersectPolylines(line, poly) == MS_TRUE) return (MS_TRUE); - return(MS_FALSE); + return (MS_FALSE); } -int msIntersectPolygons(shapeObj *p1, shapeObj *p2) -{ +int msIntersectPolygons(shapeObj *p1, shapeObj *p2) { int i; - /* STEP 1: polygon 1 completely contains 2 (only need to check one point from each part) */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(p2->line[i].point[0]), p1) == MS_TRUE) /* this considers holes and multiple parts */ - return(MS_TRUE); + /* STEP 1: polygon 1 completely contains 2 (only need to check one point from + * each part) */ + for (i = 0; i < p2->numlines; i++) { + if (msIntersectPointPolygon(&(p2->line[i].point[0]), p1) == + MS_TRUE) /* this considers holes and multiple parts */ + return (MS_TRUE); } - /* STEP 2: polygon 2 completely contains 1 (only need to check one point from each part) */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(p1->line[i].point[0]), p2) == MS_TRUE) /* this considers holes and multiple parts */ - return(MS_TRUE); + /* STEP 2: polygon 2 completely contains 1 (only need to check one point from + * each part) */ + for (i = 0; i < p1->numlines; i++) { + if (msIntersectPointPolygon(&(p1->line[i].point[0]), p2) == + MS_TRUE) /* this considers holes and multiple parts */ + return (MS_TRUE); } /* STEP 3: look for intersecting line segments */ if (msIntersectPolylines(p1, p2) == MS_TRUE) - return(MS_TRUE); + return (MS_TRUE); /* - ** At this point we know there are are no intersections between edges. There may be other tests necessary + ** At this point we know there are are no intersections between edges. There + *may be other tests necessary ** but I haven't run into any cases that require them. */ - return(MS_FALSE); + return (MS_FALSE); } - /* ** Distance computations */ -double msDistancePointToPoint(pointObj *a, pointObj *b) -{ +double msDistancePointToPoint(pointObj *a, pointObj *b) { double d; d = sqrt(msSquareDistancePointToPoint(a, b)); - return(d); + return (d); } /* -** Quickly compute the square of the distance; avoids expensive sqrt() call on each invocation +** Quickly compute the square of the distance; avoids expensive sqrt() call on +*each invocation */ -double msSquareDistancePointToPoint(pointObj *a, pointObj *b) -{ +double msSquareDistancePointToPoint(pointObj *a, pointObj *b) { double dx, dy; dx = a->x - b->x; dy = a->y - b->y; - return(dx*dx + dy*dy); + return (dx * dx + dy * dy); } -double msDistancePointToSegment(pointObj *p, pointObj *a, pointObj *b) -{ +double msDistancePointToSegment(pointObj *p, pointObj *a, pointObj *b) { return (sqrt(msSquareDistancePointToSegment(p, a, b))); } -double msSquareDistancePointToSegment(pointObj *p, pointObj *a, pointObj *b) -{ +double msSquareDistancePointToSegment(pointObj *p, pointObj *a, pointObj *b) { double l_squared; /* squared length of line ab */ - double r,s; + double r, s; - l_squared = msSquareDistancePointToPoint(a,b); + l_squared = msSquareDistancePointToPoint(a, b); - if(l_squared == 0.0) /* a = b */ - return(msSquareDistancePointToPoint(a,p)); + if (l_squared == 0.0) /* a = b */ + return (msSquareDistancePointToPoint(a, p)); - r = ((a->y - p->y)*(a->y - b->y) - (a->x - p->x)*(b->x - a->x))/(l_squared); + r = ((a->y - p->y) * (a->y - b->y) - (a->x - p->x) * (b->x - a->x)) / + (l_squared); - if(r > 1) /* perpendicular projection of P is on the forward extention of AB */ - return(MS_MIN(msSquareDistancePointToPoint(p, b),msSquareDistancePointToPoint(p, a))); - if(r < 0) /* perpendicular projection of P is on the backward extention of AB */ - return(MS_MIN(msSquareDistancePointToPoint(p, b),msSquareDistancePointToPoint(p, a))); + if (r > + 1) /* perpendicular projection of P is on the forward extention of AB */ + return (MS_MIN(msSquareDistancePointToPoint(p, b), + msSquareDistancePointToPoint(p, a))); + if (r < + 0) /* perpendicular projection of P is on the backward extention of AB */ + return (MS_MIN(msSquareDistancePointToPoint(p, b), + msSquareDistancePointToPoint(p, a))); - s = ((a->y - p->y)*(b->x - a->x) - (a->x - p->x)*(b->y - a->y))/l_squared; + s = ((a->y - p->y) * (b->x - a->x) - (a->x - p->x) * (b->y - a->y)) / + l_squared; - return(fabs(s*s*l_squared)); + return (fabs(s * s * l_squared)); } #define SMALL_NUMBER 0.00000001 -#define dot(u,v) ((u).x *(v).x + (u).y *(v).y) /* vector dot product */ -#define norm(v) sqrt(dot(v,v)) +#define dot(u, v) ((u).x * (v).x + (u).y * (v).y) /* vector dot product */ +#define norm(v) sqrt(dot(v, v)) -#define slope(a,b) (((a)->y - (b)->y)/((a)->x - (b)->x)) +#define slope(a, b) (((a)->y - (b)->y) / ((a)->x - (b)->x)) /* Segment to segment distance code is a modified version of that found at: */ /* */ -/* http://www.geometryalgorithms.com/Archive/algorithm_0106/algorithm_0106.htm */ +/* http://www.geometryalgorithms.com/Archive/algorithm_0106/algorithm_0106.htm + */ /* */ /* Copyright 2001, softSurfer (www.softsurfer.com) */ /* This code may be freely used and modified for any purpose */ @@ -380,12 +411,13 @@ double msSquareDistancePointToSegment(pointObj *p, pointObj *a, pointObj *b) /* liable for any real or imagined damage resulting from its use. */ /* Users of this code must verify correctness for their application. */ -double msDistanceSegmentToSegment(pointObj *pa, pointObj *pb, pointObj *pc, pointObj *pd) -{ +double msDistanceSegmentToSegment(pointObj *pa, pointObj *pb, pointObj *pc, + pointObj *pd) { vectorObj u, v, w; /* check for strictly parallel segments first */ - /* if(((pa->x == pb->x) && (pc->x == pd->x)) || (slope(pa,pb) == slope(pc,pd))) { // vertical (infinite slope) || otherwise parallel */ + /* if(((pa->x == pb->x) && (pc->x == pd->x)) || (slope(pa,pb) == + * slope(pc,pd))) { // vertical (infinite slope) || otherwise parallel */ /* D = msDistancePointToSegment(pa, pc, pd); */ /* D = MS_MIN(D, msDistancePointToSegment(pb, pc, pd)); */ /* D = MS_MIN(D, msDistancePointToSegment(pc, pa, pb)); */ @@ -399,13 +431,13 @@ double msDistanceSegmentToSegment(pointObj *pa, pointObj *pb, pointObj *pc, poin w.x = pa->x - pc->x; /* w = pa - pc */ w.y = pa->y - pc->y; - const double a = dot(u,u); - const double b = dot(u,v); - const double c = dot(v,v); - const double d = dot(u,w); - const double e = dot(v,w); + const double a = dot(u, u); + const double b = dot(u, v); + const double c = dot(v, v); + const double d = dot(u, w); + const double e = dot(v, w); - const double D = a*c - b*b; + const double D = a * c - b * b; /* N=numerator, D=demoninator */ double sN = 0; double sD = D; @@ -413,41 +445,39 @@ double msDistanceSegmentToSegment(pointObj *pa, pointObj *pb, pointObj *pc, poin double tN = D; /* compute the line parameters of the two closest points */ - if(D < SMALL_NUMBER) { /* lines are parallel or almost parallel */ + if (D < SMALL_NUMBER) { /* lines are parallel or almost parallel */ sD = 1.0; tN = e; tD = c; } else { /* get the closest points on the infinite lines */ - sN = b*e - c*d; - tN = a*e - b*d; - if(sN < 0) { + sN = b * e - c * d; + tN = a * e - b * d; + if (sN < 0) { sN = 0.0; tN = e; tD = c; - } else if(sN > sD) { + } else if (sN > sD) { sN = sD; tN = e + b; tD = c; } } - if(tN < 0) { + if (tN < 0) { tN = 0.0; - if(-d < 0) { + if (-d < 0) { /* sN = 0.0 */ - } - else if(-d > a) + } else if (-d > a) sN = sD; else { sN = -d; sD = a; } - } else if(tN > tD) { + } else if (tN > tD) { tN = tD; - if((-d + b) < 0) { + if ((-d + b) < 0) { /* sN = 0.0 */ - } - else if((-d + b) > a) + } else if ((-d + b) > a) sN = sD; else { sN = (-d + b); @@ -456,213 +486,248 @@ double msDistanceSegmentToSegment(pointObj *pa, pointObj *pb, pointObj *pc, poin } /* finally do the division to get sc and tc */ - const double sc = sN/sD; - const double tc = tN/tD; + const double sc = sN / sD; + const double tc = tN / tD; vectorObj dP; - dP.x = w.x + (sc*u.x) - (tc*v.x); - dP.y = w.y + (sc*u.y) - (tc*v.y); + dP.x = w.x + (sc * u.x) - (tc * v.x); + dP.y = w.y + (sc * u.y) - (tc * v.y); - return(norm(dP)); + return (norm(dP)); } -double msDistancePointToShape(pointObj *point, shapeObj *shape) -{ +double msDistancePointToShape(pointObj *point, shapeObj *shape) { double d; d = msSquareDistancePointToShape(point, shape); - return(sqrt(d)); + return (sqrt(d)); } /* ** As msDistancePointToShape; avoid expensive sqrt calls */ -double msSquareDistancePointToShape(pointObj *point, shapeObj *shape) -{ +double msSquareDistancePointToShape(pointObj *point, shapeObj *shape) { int i, j; - double dist, minDist=-1; - - switch(shape->type) { - case(MS_SHAPE_POINT): - for(j=0; jnumlines; j++) { - for(i=0; iline[j].numpoints; i++) { - dist = msSquareDistancePointToPoint(point, &(shape->line[j].point[i])); - if((dist < minDist) || (minDist < 0)) minDist = dist; - } + double dist, minDist = -1; + + switch (shape->type) { + case (MS_SHAPE_POINT): + for (j = 0; j < shape->numlines; j++) { + for (i = 0; i < shape->line[j].numpoints; i++) { + dist = msSquareDistancePointToPoint(point, &(shape->line[j].point[i])); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; } - break; - case(MS_SHAPE_LINE): - for(j=0; jnumlines; j++) { - for(i=1; iline[j].numpoints; i++) { - dist = msSquareDistancePointToSegment(point, &(shape->line[j].point[i-1]), &(shape->line[j].point[i])); - if((dist < minDist) || (minDist < 0)) minDist = dist; - } + } + break; + case (MS_SHAPE_LINE): + for (j = 0; j < shape->numlines; j++) { + for (i = 1; i < shape->line[j].numpoints; i++) { + dist = msSquareDistancePointToSegment( + point, &(shape->line[j].point[i - 1]), &(shape->line[j].point[i])); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; } - break; - case(MS_SHAPE_POLYGON): - if(msIntersectPointPolygon(point, shape)) - minDist = 0; /* point is IN the shape */ - else { /* treat shape just like a line */ - for(j=0; jnumlines; j++) { - for(i=1; iline[j].numpoints; i++) { - dist = msSquareDistancePointToSegment(point, &(shape->line[j].point[i-1]), &(shape->line[j].point[i])); - if((dist < minDist) || (minDist < 0)) minDist = dist; - } + } + break; + case (MS_SHAPE_POLYGON): + if (msIntersectPointPolygon(point, shape)) + minDist = 0; /* point is IN the shape */ + else { /* treat shape just like a line */ + for (j = 0; j < shape->numlines; j++) { + for (i = 1; i < shape->line[j].numpoints; i++) { + dist = msSquareDistancePointToSegment(point, + &(shape->line[j].point[i - 1]), + &(shape->line[j].point[i])); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; } } - break; - default: - break; + } + break; + default: + break; } - return(minDist); + return (minDist); } -double msDistanceShapeToShape(shapeObj *shape1, shapeObj *shape2) -{ - int i,j,k,l; - double dist, minDist=-1; - - switch(shape1->type) { - case(MS_SHAPE_POINT): /* shape1 */ - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - dist = msSquareDistancePointToShape(&(shape1->line[i].point[j]), shape2); - if((dist < minDist) || (minDist < 0)) +double msDistanceShapeToShape(shapeObj *shape1, shapeObj *shape2) { + int i, j, k, l; + double dist, minDist = -1; + + switch (shape1->type) { + case (MS_SHAPE_POINT): /* shape1 */ + for (i = 0; i < shape1->numlines; i++) { + for (j = 0; j < shape1->line[i].numpoints; j++) { + dist = + msSquareDistancePointToShape(&(shape1->line[i].point[j]), shape2); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; + } + } + minDist = sqrt(minDist); + break; + case (MS_SHAPE_LINE): /* shape1 */ + switch (shape2->type) { + case (MS_SHAPE_POINT): + for (i = 0; i < shape2->numlines; i++) { + for (j = 0; j < shape2->line[i].numpoints; j++) { + dist = + msSquareDistancePointToShape(&(shape2->line[i].point[j]), shape1); + if ((dist < minDist) || (minDist < 0)) minDist = dist; } } minDist = sqrt(minDist); break; - case(MS_SHAPE_LINE): /* shape1 */ - switch(shape2->type) { - case(MS_SHAPE_POINT): - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - dist = msSquareDistancePointToShape(&(shape2->line[i].point[j]), shape1); - if((dist < minDist) || (minDist < 0)) + case (MS_SHAPE_LINE): + for (i = 0; i < shape1->numlines; i++) { + for (j = 1; j < shape1->line[i].numpoints; j++) { + for (k = 0; k < shape2->numlines; k++) { + for (l = 1; l < shape2->line[k].numpoints; l++) { + /* check intersection (i.e. dist=0) */ + if (msIntersectSegments(&(shape1->line[i].point[j - 1]), + &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), + &(shape2->line[k].point[l])) == MS_TRUE) + return (0); + + /* no intersection, compute distance */ + dist = msDistanceSegmentToSegment( + &(shape1->line[i].point[j - 1]), &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), &(shape2->line[k].point[l])); + if ((dist < minDist) || (minDist < 0)) minDist = dist; } } - minDist = sqrt(minDist); - break; - case(MS_SHAPE_LINE): - for(i=0; inumlines; i++) { - for(j=1; jline[i].numpoints; j++) { - for(k=0; knumlines; k++) { - for(l=1; lline[k].numpoints; l++) { - /* check intersection (i.e. dist=0) */ - if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) - return(0); - - /* no intersection, compute distance */ - dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])); - if((dist < minDist) || (minDist < 0)) - minDist = dist; - } - } - } - } - break; - case(MS_SHAPE_POLYGON): - /* shape2 (the polygon) could contain shape1 or one of it's parts */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(shape1->line[0].point[0]), shape2) == MS_TRUE) /* this considers holes and multiple parts */ - return(0); - } - - /* check segment intersection and, if necessary, distance between segments */ - for(i=0; inumlines; i++) { - for(j=1; jline[i].numpoints; j++) { - for(k=0; knumlines; k++) { - for(l=1; lline[k].numpoints; l++) { - /* check intersection (i.e. dist=0) */ - if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) - return(0); - - /* no intersection, compute distance */ - dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])); - if((dist < minDist) || (minDist < 0)) - minDist = dist; - } - } - } - } - break; + } } break; - case(MS_SHAPE_POLYGON): /* shape1 */ - switch(shape2->type) { - case(MS_SHAPE_POINT): - for(i=0; inumlines; i++) { - for(j=0; jline[i].numpoints; j++) { - dist = msSquareDistancePointToShape(&(shape2->line[i].point[j]), shape1); - if((dist < minDist) || (minDist < 0)) + case (MS_SHAPE_POLYGON): + /* shape2 (the polygon) could contain shape1 or one of it's parts */ + for (i = 0; i < shape1->numlines; i++) { + if (msIntersectPointPolygon(&(shape1->line[0].point[0]), shape2) == + MS_TRUE) /* this considers holes and multiple parts */ + return (0); + } + + /* check segment intersection and, if necessary, distance between segments + */ + for (i = 0; i < shape1->numlines; i++) { + for (j = 1; j < shape1->line[i].numpoints; j++) { + for (k = 0; k < shape2->numlines; k++) { + for (l = 1; l < shape2->line[k].numpoints; l++) { + /* check intersection (i.e. dist=0) */ + if (msIntersectSegments(&(shape1->line[i].point[j - 1]), + &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), + &(shape2->line[k].point[l])) == MS_TRUE) + return (0); + + /* no intersection, compute distance */ + dist = msDistanceSegmentToSegment( + &(shape1->line[i].point[j - 1]), &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), &(shape2->line[k].point[l])); + if ((dist < minDist) || (minDist < 0)) minDist = dist; } } - minDist = sqrt(minDist); - break; - case(MS_SHAPE_LINE): - /* shape1 (the polygon) could contain shape2 or one of it's parts */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == MS_TRUE) /* this considers holes and multiple parts */ - return(0); - } + } + } + break; + } + break; + case (MS_SHAPE_POLYGON): /* shape1 */ + switch (shape2->type) { + case (MS_SHAPE_POINT): + for (i = 0; i < shape2->numlines; i++) { + for (j = 0; j < shape2->line[i].numpoints; j++) { + dist = + msSquareDistancePointToShape(&(shape2->line[i].point[j]), shape1); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; + } + } + minDist = sqrt(minDist); + break; + case (MS_SHAPE_LINE): + /* shape1 (the polygon) could contain shape2 or one of it's parts */ + for (i = 0; i < shape2->numlines; i++) { + if (msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == + MS_TRUE) /* this considers holes and multiple parts */ + return (0); + } - /* check segment intersection and, if necessary, distance between segments */ - for(i=0; inumlines; i++) { - for(j=1; jline[i].numpoints; j++) { - for(k=0; knumlines; k++) { - for(l=1; lline[k].numpoints; l++) { - /* check intersection (i.e. dist=0) */ - if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) - return(0); - - /* no intersection, compute distance */ - dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])); - if((dist < minDist) || (minDist < 0)) - minDist = dist; - } - } + /* check segment intersection and, if necessary, distance between segments + */ + for (i = 0; i < shape1->numlines; i++) { + for (j = 1; j < shape1->line[i].numpoints; j++) { + for (k = 0; k < shape2->numlines; k++) { + for (l = 1; l < shape2->line[k].numpoints; l++) { + /* check intersection (i.e. dist=0) */ + if (msIntersectSegments(&(shape1->line[i].point[j - 1]), + &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), + &(shape2->line[k].point[l])) == MS_TRUE) + return (0); + + /* no intersection, compute distance */ + dist = msDistanceSegmentToSegment( + &(shape1->line[i].point[j - 1]), &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), &(shape2->line[k].point[l])); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; } } - break; - case(MS_SHAPE_POLYGON): - /* shape1 completely contains shape2 (only need to check one point from each part) */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == MS_TRUE) /* this considers holes and multiple parts */ - return(0); - } + } + } + break; + case (MS_SHAPE_POLYGON): + /* shape1 completely contains shape2 (only need to check one point from + * each part) */ + for (i = 0; i < shape2->numlines; i++) { + if (msIntersectPointPolygon(&(shape2->line[i].point[0]), shape1) == + MS_TRUE) /* this considers holes and multiple parts */ + return (0); + } - /* shape2 completely contains shape1 (only need to check one point from each part) */ - for(i=0; inumlines; i++) { - if(msIntersectPointPolygon(&(shape1->line[i].point[0]), shape2) == MS_TRUE) /* this considers holes and multiple parts */ - return(0); - } + /* shape2 completely contains shape1 (only need to check one point from + * each part) */ + for (i = 0; i < shape1->numlines; i++) { + if (msIntersectPointPolygon(&(shape1->line[i].point[0]), shape2) == + MS_TRUE) /* this considers holes and multiple parts */ + return (0); + } - /* check segment intersection and, if necessary, distance between segments */ - for(i=0; inumlines; i++) { - for(j=1; jline[i].numpoints; j++) { - for(k=0; knumlines; k++) { - for(l=1; lline[k].numpoints; l++) { - /* check intersection (i.e. dist=0) */ - if(msIntersectSegments(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])) == MS_TRUE) - return(0); - - /* no intersection, compute distance */ - dist = msDistanceSegmentToSegment(&(shape1->line[i].point[j-1]), &(shape1->line[i].point[j]), &(shape2->line[k].point[l-1]), &(shape2->line[k].point[l])); - if((dist < minDist) || (minDist < 0)) - minDist = dist; - } - } + /* check segment intersection and, if necessary, distance between segments + */ + for (i = 0; i < shape1->numlines; i++) { + for (j = 1; j < shape1->line[i].numpoints; j++) { + for (k = 0; k < shape2->numlines; k++) { + for (l = 1; l < shape2->line[k].numpoints; l++) { + /* check intersection (i.e. dist=0) */ + if (msIntersectSegments(&(shape1->line[i].point[j - 1]), + &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), + &(shape2->line[k].point[l])) == MS_TRUE) + return (0); + + /* no intersection, compute distance */ + dist = msDistanceSegmentToSegment( + &(shape1->line[i].point[j - 1]), &(shape1->line[i].point[j]), + &(shape2->line[k].point[l - 1]), &(shape2->line[k].point[l])); + if ((dist < minDist) || (minDist < 0)) + minDist = dist; } } - break; + } } break; + } + break; } - return(minDist); + return (minDist); } diff --git a/mapserv-config.cpp b/mapserv-config.cpp index d7a0b20ded..7095c44f45 100644 --- a/mapserv-config.cpp +++ b/mapserv-config.cpp @@ -6,7 +6,7 @@ * Author: Steve Lime and the MapServer team. * ********************************************************************** - * Copyright (c) 1996-2005 Regents of the University of Minnesota. + * Copyright (c) 1996-2005 Regents of the University of Minnesota. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -40,82 +40,91 @@ extern "C" int msyystate; extern "C" int msyylineno; extern "C" char *msyystring_buffer; -static int initConfig(configObj *config) -{ +static int initConfig(configObj *config) { if (config == NULL) { msSetError(MS_MEMERR, "Config object is NULL.", "initConfig()"); return MS_FAILURE; } - if(initHashTable(&(config->env)) != MS_SUCCESS) return MS_FAILURE; - if(initHashTable(&(config->maps)) != MS_SUCCESS) return MS_FAILURE; - if(initHashTable(&(config->plugins)) != MS_SUCCESS) return MS_FAILURE; + if (initHashTable(&(config->env)) != MS_SUCCESS) + return MS_FAILURE; + if (initHashTable(&(config->maps)) != MS_SUCCESS) + return MS_FAILURE; + if (initHashTable(&(config->plugins)) != MS_SUCCESS) + return MS_FAILURE; return MS_SUCCESS; } -void msFreeConfig(configObj *config) -{ - if(config == NULL) return; - if(&(config->env)) msFreeHashItems(&(config->env)); - if(&(config->maps)) msFreeHashItems(&(config->maps)); - if(&(config->plugins)) msFreeHashItems(&(config->plugins)); +void msFreeConfig(configObj *config) { + if (config == NULL) + return; + if (&(config->env)) + msFreeHashItems(&(config->env)); + if (&(config->maps)) + msFreeHashItems(&(config->maps)); + if (&(config->plugins)) + msFreeHashItems(&(config->plugins)); msFree(config); } -static int loadConfig(configObj *config) -{ +static int loadConfig(configObj *config) { int token; - if(config == NULL) return MS_FAILURE; + if (config == NULL) + return MS_FAILURE; token = msyylex(); - if(token != MS_CONFIG_SECTION) { - msSetError(MS_IDENTERR, "First token must be CONFIG, this doesn't look like a mapserver config file.", "msLoadConfig()"); + if (token != MS_CONFIG_SECTION) { + msSetError(MS_IDENTERR, + "First token must be CONFIG, this doesn't look like a mapserver " + "config file.", + "msLoadConfig()"); return MS_FAILURE; } - for(;;) { - switch(msyylex()) { - case(MS_CONFIG_SECTION_ENV): { - if(loadHashTable(&(config->env)) != MS_SUCCESS) return MS_FAILURE; + for (;;) { + switch (msyylex()) { + case (MS_CONFIG_SECTION_ENV): { + if (loadHashTable(&(config->env)) != MS_SUCCESS) + return MS_FAILURE; break; } - case(MS_CONFIG_SECTION_MAPS): - if(loadHashTable(&config->maps) != MS_SUCCESS) return MS_FAILURE; + case (MS_CONFIG_SECTION_MAPS): + if (loadHashTable(&config->maps) != MS_SUCCESS) + return MS_FAILURE; break; - case(MS_CONFIG_SECTION_PLUGINS): - if(loadHashTable(&config->plugins) != MS_SUCCESS) return MS_FAILURE; + case (MS_CONFIG_SECTION_PLUGINS): + if (loadHashTable(&config->plugins) != MS_SUCCESS) + return MS_FAILURE; break; - case(EOF): + case (EOF): msSetError(MS_EOFERR, NULL, "msLoadConfig()"); return MS_FAILURE; - case(END): - if(msyyin) { - fclose(msyyin); - msyyin = NULL; + case (END): + if (msyyin) { + fclose(msyyin); + msyyin = NULL; } return MS_SUCCESS; break; default: - msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "msLoadConfig()", msyystring_buffer, msyylineno); + msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", + "msLoadConfig()", msyystring_buffer, msyylineno); return MS_FAILURE; } } } -static void msConfigSetConfigOption(const char* key, const char* value) -{ +static void msConfigSetConfigOption(const char *key, const char *value) { CPLSetConfigOption(key, value); - if( strcasecmp(key,"PROJ_DATA") == 0 || - strcasecmp(key,"PROJ_LIB") == 0 ) { - msSetPROJ_DATA( value, nullptr ); + if (strcasecmp(key, "PROJ_DATA") == 0 || strcasecmp(key, "PROJ_LIB") == 0) { + msSetPROJ_DATA(value, nullptr); } } -configObj *msLoadConfig(const char* ms_config_file) -{ +configObj *msLoadConfig(const char *ms_config_file) { configObj *config = NULL; if (ms_config_file == NULL) { @@ -123,12 +132,12 @@ configObj *msLoadConfig(const char* ms_config_file) ms_config_file = getenv("MAPSERVER_CONFIG_FILE"); } - if(ms_config_file == NULL && MAPSERVER_CONFIG_FILE[0] != '\0') { + if (ms_config_file == NULL && MAPSERVER_CONFIG_FILE[0] != '\0') { // Fallback to hardcoded file name ms_config_file = MAPSERVER_CONFIG_FILE; } - if(ms_config_file == NULL) { + if (ms_config_file == NULL) { msSetError(MS_MISCERR, "No config file set.", "msLoadConfig()"); return NULL; } @@ -136,16 +145,18 @@ configObj *msLoadConfig(const char* ms_config_file) config = (configObj *)calloc(sizeof(configObj), 1); MS_CHECK_ALLOC(config, sizeof(configObj), NULL); - if(initConfig(config) != MS_SUCCESS) { + if (initConfig(config) != MS_SUCCESS) { msFreeConfig(config); return NULL; } msAcquireLock(TLOCK_PARSER); - if((msyyin = fopen(ms_config_file, "r")) == NULL) { + if ((msyyin = fopen(ms_config_file, "r")) == NULL) { msDebug("Cannot open configuration file %s.\n", ms_config_file); - msSetError(MS_IOERR, "See mapserver.org/mapfile/config.html for more information.", "msLoadConfig()"); + msSetError(MS_IOERR, + "See mapserver.org/mapfile/config.html for more information.", + "msLoadConfig()"); msReleaseLock(TLOCK_PARSER); msFreeConfig(config); return NULL; @@ -157,10 +168,10 @@ configObj *msLoadConfig(const char* ms_config_file) msyyrestart(msyyin); // start at line 1 msyylineno = 1; - if(loadConfig(config) != MS_SUCCESS) { + if (loadConfig(config) != MS_SUCCESS) { msFreeConfig(config); msReleaseLock(TLOCK_PARSER); - if(msyyin) { + if (msyyin) { fclose(msyyin); msyyin = NULL; } @@ -168,35 +179,36 @@ configObj *msLoadConfig(const char* ms_config_file) } msReleaseLock(TLOCK_PARSER); - // load all env key/values using CPLSetConfigOption() - only do this *after* we have a good config + // load all env key/values using CPLSetConfigOption() - only do this *after* + // we have a good config const char *key = msFirstKeyFromHashTable(&config->env); - if(key != NULL) { + if (key != NULL) { msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); const char *last_key = key; - while((key = msNextKeyFromHashTable(&config->env, last_key)) != NULL) { + while ((key = msNextKeyFromHashTable(&config->env, last_key)) != NULL) { msConfigSetConfigOption(key, msLookupHashTable(&config->env, key)); last_key = key; } } - return config; + return config; } -const char *msConfigGetEnv(const configObj *config, const char *key) -{ - if(config == NULL || key == NULL) return NULL; +const char *msConfigGetEnv(const configObj *config, const char *key) { + if (config == NULL || key == NULL) + return NULL; return msLookupHashTable(&config->env, key); } -const char *msConfigGetMap(const configObj *config, const char *key) -{ - if(config == NULL || key == NULL) return NULL; +const char *msConfigGetMap(const configObj *config, const char *key) { + if (config == NULL || key == NULL) + return NULL; return msLookupHashTable(&config->maps, key); } -const char *msConfigGetPlugin(const configObj *config, const char *key) -{ - if(config == NULL || key == NULL) return NULL; +const char *msConfigGetPlugin(const configObj *config, const char *key) { + if (config == NULL || key == NULL) + return NULL; return msLookupHashTable(&config->plugins, key); } diff --git a/mapserv-config.h b/mapserv-config.h index 7d8f9e9a69..2c4e5f81fd 100644 --- a/mapserv-config.h +++ b/mapserv-config.h @@ -7,25 +7,33 @@ extern "C" { #endif -enum MS_CONFIG_SECTIONS { MS_CONFIG_SECTION=3000, MS_CONFIG_SECTION_ENV, MS_CONFIG_SECTION_MAPS, MS_CONFIG_SECTION_PLUGINS }; +enum MS_CONFIG_SECTIONS { + MS_CONFIG_SECTION = 3000, + MS_CONFIG_SECTION_ENV, + MS_CONFIG_SECTION_MAPS, + MS_CONFIG_SECTION_PLUGINS +}; /** The :ref:`CONFIG ` object */ typedef struct { - hashTableObj env; ///< Key-value pairs of environment variables and values - hashTableObj maps; ///< Key-value pairs of Mapfile names and paths + hashTableObj env; ///< Key-value pairs of environment variables and values + hashTableObj maps; ///< Key-value pairs of Mapfile names and paths hashTableObj plugins; ///< Key-value pairs of plugin names and paths } configObj; -MS_DLL_EXPORT configObj *msLoadConfig(const char* ms_config_file); +MS_DLL_EXPORT configObj *msLoadConfig(const char *ms_config_file); MS_DLL_EXPORT void msFreeConfig(configObj *config); -MS_DLL_EXPORT const char *msConfigGetEnv(const configObj *config, const char *key); -MS_DLL_EXPORT const char *msConfigGetMap(const configObj *config, const char *key); -MS_DLL_EXPORT const char *msConfigGetPlugin(const configObj *config, const char *key); +MS_DLL_EXPORT const char *msConfigGetEnv(const configObj *config, + const char *key); +MS_DLL_EXPORT const char *msConfigGetMap(const configObj *config, + const char *key); +MS_DLL_EXPORT const char *msConfigGetPlugin(const configObj *config, + const char *key); #ifdef __cplusplus } /* extern C */ #endif -#endif +#endif diff --git a/mapserv.c b/mapserv.c index 55944ace66..4f5ad10c29 100644 --- a/mapserv.c +++ b/mapserv.c @@ -50,7 +50,6 @@ #include #endif - /************************************************************************/ /* FastCGI cleanup functions. */ /************************************************************************/ @@ -58,18 +57,14 @@ static int finish_process = 0; #ifndef _WIN32 -static void msCleanupOnSignal( int nInData ) -{ +static void msCleanupOnSignal(int nInData) { (void)nInData; finish_process = 1; } #endif #ifdef _WIN32 -static void msCleanupOnExit( void ) -{ - finish_process = 1; -} +static void msCleanupOnExit(void) { finish_process = 1; } #endif #ifdef USE_FASTCGI @@ -80,10 +75,10 @@ static void msCleanupOnExit( void ) /* This is the default implementation via stdio. */ /************************************************************************/ -static int msIO_fcgiRead( void *cbData, void *data, int byteCount ) +static int msIO_fcgiRead(void *cbData, void *data, int byteCount) { - return (int) FCGI_fread( data, 1, byteCount, (FCGI_FILE *) cbData ); + return (int)FCGI_fread(data, 1, byteCount, (FCGI_FILE *)cbData); } /************************************************************************/ @@ -92,10 +87,10 @@ static int msIO_fcgiRead( void *cbData, void *data, int byteCount ) /* This is the default implementation via stdio. */ /************************************************************************/ -static int msIO_fcgiWrite( void *cbData, void *data, int byteCount ) +static int msIO_fcgiWrite(void *cbData, void *data, int byteCount) { - return (int) FCGI_fwrite( data, 1, byteCount, (FCGI_FILE *) cbData ); + return (int)FCGI_fwrite(data, 1, byteCount, (FCGI_FILE *)cbData); } /************************************************************************/ @@ -109,19 +104,19 @@ static int msIO_installFastCGIRedirect() stdin_ctx.label = "fcgi"; stdin_ctx.write_channel = MS_FALSE; stdin_ctx.readWriteFunc = msIO_fcgiRead; - stdin_ctx.cbData = (void *) FCGI_stdin; + stdin_ctx.cbData = (void *)FCGI_stdin; stdout_ctx.label = "fcgi"; stdout_ctx.write_channel = MS_TRUE; stdout_ctx.readWriteFunc = msIO_fcgiWrite; - stdout_ctx.cbData = (void *) FCGI_stdout; + stdout_ctx.cbData = (void *)FCGI_stdout; stderr_ctx.label = "fcgi"; stderr_ctx.write_channel = MS_TRUE; stderr_ctx.readWriteFunc = msIO_fcgiWrite; - stderr_ctx.cbData = (void *) FCGI_stderr; + stderr_ctx.cbData = (void *)FCGI_stderr; - msIO_installHandlers( &stdin_ctx, &stdout_ctx, &stderr_ctx ); + msIO_installHandlers(&stdin_ctx, &stdout_ctx, &stderr_ctx); return MS_TRUE; } @@ -130,59 +125,65 @@ static int msIO_installFastCGIRedirect() /************************************************************************/ /* main() */ /************************************************************************/ -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { int sendheaders = MS_TRUE; struct mstimeval execstarttime, execendtime; struct mstimeval requeststarttime, requestendtime; - mapservObj *mapserv = NULL; + mapservObj *mapserv = NULL; configObj *config = NULL; - /* - ** Process -v and -h command line arguments first end exit. We want to avoid any error messages + /* + ** Process -v and -h command line arguments first end exit. We want to avoid + *any error messages ** associated with msLoadConfig() or msSetup(). */ - const char* config_filename = NULL; + const char *config_filename = NULL; const bool use_command_line_options = getenv("QUERY_STRING") == NULL; if (use_command_line_options) { /* WARNING: * Do not parse command line arguments (especially those that could have - * dangerous consequences if controlled through a web request), without checking - * that the QUERY_STRING environment variable is *not* set, because in a - * CGI context, command line arguments can be generated from the content - * of the QUERY_STRING, and thus cause a security problem. - * For ex, "http://example.com/mapserv.cgi?-conf+bar - * would result in "mapserv.cgi -conf bar" being invoked. - * See https://github.com/MapServer/MapServer/pull/6429#issuecomment-952533589 + * dangerous consequences if controlled through a web request), without + * checking that the QUERY_STRING environment variable is *not* set, because + * in a CGI context, command line arguments can be generated from the + * content of the QUERY_STRING, and thus cause a security problem. For ex, + * "http://example.com/mapserv.cgi?-conf+bar would result in "mapserv.cgi + * -conf bar" being invoked. See + * https://github.com/MapServer/MapServer/pull/6429#issuecomment-952533589 * and https://datatracker.ietf.org/doc/html/rfc3875#section-4.4 - */ - for( int iArg = 1; iArg < argc; iArg++ ) { - if( strcmp(argv[iArg],"-v") == 0 ) { + */ + for (int iArg = 1; iArg < argc; iArg++) { + if (strcmp(argv[iArg], "-v") == 0) { printf("%s\n", msGetVersion()); fflush(stdout); exit(0); - } else if (strcmp(argv[iArg], "-h") == 0 || strcmp(argv[iArg], "--help") == 0) { - printf("Usage: mapserv [--help] [-v] [-nh] [QUERY_STRING=value] [PATH_INFO=value]\n"); + } else if (strcmp(argv[iArg], "-h") == 0 || + strcmp(argv[iArg], "--help") == 0) { + printf("Usage: mapserv [--help] [-v] [-nh] [QUERY_STRING=value] " + "[PATH_INFO=value]\n"); printf(" [-conf filename]\n"); printf("\n"); printf("Options :\n"); printf(" -h, --help Display this help message.\n"); printf(" -v Display version and exit.\n"); - printf(" -nh Suppress HTTP headers in CGI mode.\n"); - printf(" -conf filename Filename of the MapServer configuration file.\n"); - printf(" QUERY_STRING=value Set the QUERY_STRING in GET request mode.\n"); - printf(" PATH_INFO=value Set the PATH_INFO for an API request.\n"); + printf( + " -nh Suppress HTTP headers in CGI mode.\n"); + printf(" -conf filename Filename of the MapServer " + "configuration file.\n"); + printf(" QUERY_STRING=value Set the QUERY_STRING in GET request " + "mode.\n"); + printf(" PATH_INFO=value Set the PATH_INFO for an API " + "request.\n"); fflush(stdout); exit(0); - } else if( iArg < argc-1 && strcmp(argv[iArg], "-conf") == 0) { - config_filename = argv[iArg+1]; + } else if (iArg < argc - 1 && strcmp(argv[iArg], "-conf") == 0) { + config_filename = argv[iArg + 1]; ++iArg; } } } config = msLoadConfig(config_filename); // first thing - if(config == NULL) { + if (config == NULL) { #ifdef USE_FASTCGI msIO_installFastCGIRedirect(); // FastCGI setup for error handling here FCGI_Accept(); @@ -195,7 +196,7 @@ int main(int argc, char *argv[]) /* Initialize mapserver. This sets up threads, GD and GEOS as */ /* well as using MS_ERRORFILE and MS_DEBUGLEVEL env vars if set. */ /* -------------------------------------------------------------------- */ - if( msSetup() != MS_SUCCESS ) { + if (msSetup() != MS_SUCCESS) { #ifdef USE_FASTCGI msIO_installFastCGIRedirect(); // FastCGI setup for error handling here FCGI_Accept(); @@ -206,7 +207,7 @@ int main(int argc, char *argv[]) exit(0); } - if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) + if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&execstarttime, NULL); /* -------------------------------------------------------------------- */ @@ -214,21 +215,22 @@ int main(int argc, char *argv[]) /* commandline switches, but we provide a few for test/debug */ /* purposes. */ /* -------------------------------------------------------------------- */ - if(use_command_line_options) { - for( int iArg = 1; iArg < argc; iArg++ ) { - if(strcmp(argv[iArg], "-nh") == 0) { + if (use_command_line_options) { + for (int iArg = 1; iArg < argc; iArg++) { + if (strcmp(argv[iArg], "-nh") == 0) { sendheaders = MS_FALSE; - msIO_setHeaderEnabled( MS_FALSE ); - } else if( strncmp(argv[iArg], "QUERY_STRING=", 13) == 0 ) { + msIO_setHeaderEnabled(MS_FALSE); + } else if (strncmp(argv[iArg], "QUERY_STRING=", 13) == 0) { /* Debugging hook... pass "QUERY_STRING=..." on the command-line */ - putenv( "REQUEST_METHOD=GET" ); + putenv("REQUEST_METHOD=GET"); /* coverity[tainted_string] */ - putenv( argv[iArg] ); - } else if( strncmp(argv[iArg], "PATH_INFO=", 10) == 0 ) { - /* Debugging hook for APIs... pass "PATH_INFO=..." on the command-line */ - putenv( "REQUEST_METHOD=GET" ); + putenv(argv[iArg]); + } else if (strncmp(argv[iArg], "PATH_INFO=", 10) == 0) { + /* Debugging hook for APIs... pass "PATH_INFO=..." on the command-line + */ + putenv("REQUEST_METHOD=GET"); /* coverity[tainted_string] */ - putenv( argv[iArg] ); + putenv(argv[iArg]); } } } @@ -237,8 +239,8 @@ int main(int argc, char *argv[]) /* Setup cleanup magic, mainly for FastCGI case. */ /* -------------------------------------------------------------------- */ #ifndef _WIN32 - signal( SIGUSR1, msCleanupOnSignal ); - signal( SIGTERM, msCleanupOnSignal ); + signal(SIGUSR1, msCleanupOnSignal); + signal(SIGTERM, msCleanupOnSignal); #endif #ifdef USE_FASTCGI @@ -246,55 +248,58 @@ int main(int argc, char *argv[]) /* In FastCGI case we loop accepting multiple requests. In normal CGI */ /* use we only accept and process one request. */ - while( !finish_process && FCGI_Accept() >= 0 ) { + while (!finish_process && FCGI_Accept() >= 0) { #endif /* def USE_FASTCGI */ /* -------------------------------------------------------------------- */ /* Process a request. */ /* -------------------------------------------------------------------- */ mapserv = msAllocMapServObj(); - mapserv->sendheaders = sendheaders; /* override the default if necessary (via command line -nh switch) */ + mapserv->sendheaders = sendheaders; /* override the default if necessary + (via command line -nh switch) */ - mapserv->request->NumParams = loadParams(mapserv->request, NULL, NULL, 0, NULL); - if(msCGIIsAPIRequest(mapserv) == MS_FALSE && mapserv->request->NumParams == -1) { /* no QUERY_STRING or PATH_INFO */ + mapserv->request->NumParams = + loadParams(mapserv->request, NULL, NULL, 0, NULL); + if (msCGIIsAPIRequest(mapserv) == MS_FALSE && + mapserv->request->NumParams == -1) { /* no QUERY_STRING or PATH_INFO */ msCGIWriteError(mapserv); goto end_request; } mapserv->map = msCGILoadMap(mapserv, config); - if(!mapserv->map) { + if (!mapserv->map) { msCGIWriteError(mapserv); goto end_request; } - if( mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) + if (mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) msGettimeofday(&requeststarttime, NULL); #ifdef USE_FASTCGI - if( mapserv->map->debug ) { + if (mapserv->map->debug) { static int nRequestCounter = 1; - msDebug( "CGI Request %d on process %d\n", nRequestCounter, getpid() ); + msDebug("CGI Request %d on process %d\n", nRequestCounter, getpid()); nRequestCounter++; } #endif - if(mapserv->request->api_path != NULL) { - if(msCGIDispatchAPIRequest(mapserv) != MS_SUCCESS) { - msCGIWriteError(mapserv); - goto end_request; + if (mapserv->request->api_path != NULL) { + if (msCGIDispatchAPIRequest(mapserv) != MS_SUCCESS) { + msCGIWriteError(mapserv); + goto end_request; } - } else if(msCGIDispatchRequest(mapserv) != MS_SUCCESS) { + } else if (msCGIDispatchRequest(mapserv) != MS_SUCCESS) { msCGIWriteError(mapserv); goto end_request; } -end_request: - if(mapserv->map && mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) { + end_request: + if (mapserv->map && mapserv->map->debug >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&requestendtime, NULL); msDebug("mapserv request processing time (msLoadMap not incl.): %.3fs\n", - (requestendtime.tv_sec+requestendtime.tv_usec/1.0e6)- - (requeststarttime.tv_sec+requeststarttime.tv_usec/1.0e6) ); + (requestendtime.tv_sec + requestendtime.tv_usec / 1.0e6) - + (requeststarttime.tv_sec + requeststarttime.tv_usec / 1.0e6)); } msFreeMapServObj(mapserv); #ifdef USE_FASTCGI @@ -305,11 +310,11 @@ int main(int argc, char *argv[]) #endif /* normal case, processing is complete */ - if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { + if (msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) { msGettimeofday(&execendtime, NULL); msDebug("mapserv total execution time: %.3fs\n", - (execendtime.tv_sec+execendtime.tv_usec/1.0e6)- - (execstarttime.tv_sec+execstarttime.tv_usec/1.0e6) ); + (execendtime.tv_sec + execendtime.tv_usec / 1.0e6) - + (execstarttime.tv_sec + execstarttime.tv_usec / 1.0e6)); } msCleanup(); msFreeConfig(config); @@ -319,5 +324,5 @@ int main(int argc, char *argv[]) fflush(stdout); #endif - exit( 0 ); + exit(0); } diff --git a/mapserv.h b/mapserv.h index 249d1adad9..55d87b8877 100644 --- a/mapserv.h +++ b/mapserv.h @@ -51,7 +51,11 @@ /* ** Macros */ -#define TEMPLATE_TYPE(s) (((strncmp("http://", s, 7) == 0) || (strncmp("https://", s, 8) == 0) || (strncmp("ftp://", s, 6)) == 0) ? MS_URL : MS_FILE) +#define TEMPLATE_TYPE(s) \ + (((strncmp("http://", s, 7) == 0) || (strncmp("https://", s, 8) == 0) || \ + (strncmp("ftp://", s, 6)) == 0) \ + ? MS_URL \ + : MS_FILE) MS_DLL_EXPORT void msCGIWriteError(mapservObj *mapserv); MS_DLL_EXPORT mapObj *msCGILoadMap(mapservObj *mapserv, configObj *context); diff --git a/mapserver-api.c b/mapserver-api.c index e1ec1fdec0..4f9f5d3005 100644 --- a/mapserver-api.c +++ b/mapserver-api.c @@ -1,20 +1,19 @@ #include "mapserver.h" - -mapObj* umnms_new_map(char *filename) { +mapObj *umnms_new_map(char *filename) { mapObj *map = NULL; - if(filename) { - map = msLoadMap(filename,NULL); + if (filename) { + map = msLoadMap(filename, NULL); } else { - map = (mapObj *)msSmallCalloc(sizeof(mapObj),1); - if(initMap(map) == -1) { + map = (mapObj *)msSmallCalloc(sizeof(mapObj), 1); + if (initMap(map) == -1) { free(map); return NULL; } } return map; } -layerObj* umnms_new_layer(mapObj *map); -classObj* umnms_new_class(layerObj *layer); -styleObj* umnms_new_style(classObj *theclass); -labelObj* umnms_new_label(classObj *theclass); +layerObj *umnms_new_layer(mapObj *map); +classObj *umnms_new_class(layerObj *layer); +styleObj *umnms_new_style(classObj *theclass); +labelObj *umnms_new_label(classObj *theclass); diff --git a/mapserver-api.h b/mapserver-api.h index 3be93bc9a4..80c1b44708 100644 --- a/mapserver-api.h +++ b/mapserver-api.h @@ -1,4 +1,4 @@ -/* +/* * File: mapserver-api.h * Author: tbonfort * @@ -6,11 +6,11 @@ */ #ifndef MAPSERVER_API_H -#define MAPSERVER_API_H +#define MAPSERVER_API_H #include "mapserver-version.h" -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -22,18 +22,14 @@ typedef struct labelObj labelObj; typedef struct symbolObj symbolObj; typedef struct imageObj imageObj; -mapObj* umnms_new_map(char *filename); -layerObj* umnms_new_layer(mapObj *map); -classObj* umnms_new_class(layerObj *layer); -styleObj* umnms_new_style(classObj *theclass); -labelObj* umnms_new_label(classObj *theclass); +mapObj *umnms_new_map(char *filename); +layerObj *umnms_new_layer(mapObj *map); +classObj *umnms_new_class(layerObj *layer); +styleObj *umnms_new_style(classObj *theclass); +labelObj *umnms_new_label(classObj *theclass); - - - -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* MAPSERVER_API_H */ - +#endif /* MAPSERVER_API_H */ diff --git a/mapserver.h b/mapserver.h old mode 100755 new mode 100644 index 586ed07fad..e24bc826b2 --- a/mapserver.h +++ b/mapserver.h @@ -56,16 +56,16 @@ #endif #if defined(_WIN32) && !defined(__CYGWIN__) -# define MS_DLL_EXPORT __declspec(dllexport) +#define MS_DLL_EXPORT __declspec(dllexport) #define USE_MSFREE #else -#define MS_DLL_EXPORT +#define MS_DLL_EXPORT #endif #if defined(__GNUC__) #define WARN_UNUSED __attribute__((warn_unused_result)) -#define MS_LIKELY(x) __builtin_expect((x),1) -#define MS_UNLIKELY(x) __builtin_expect((x),0) +#define MS_LIKELY(x) __builtin_expect((x), 1) +#define MS_UNLIKELY(x) __builtin_expect((x), 0) #else #define WARN_UNUSED #define MS_LIKELY(x) (x) @@ -89,14 +89,14 @@ #endif #if ULONG_MAX == 0xffffffff -typedef long ms_int32; -typedef unsigned long ms_uint32; +typedef long ms_int32; +typedef unsigned long ms_uint32; #elif UINT_MAX == 0xffffffff -typedef int ms_int32; -typedef unsigned int ms_uint32; +typedef int ms_int32; +typedef unsigned int ms_uint32; #else -typedef int32_t ms_int32; -typedef uint32_t ms_uint32; +typedef int32_t ms_int32; +typedef uint32_t ms_uint32; #endif #if defined(_WIN32) && !defined(__CYGWIN__) @@ -116,7 +116,6 @@ typedef struct glyph_element glyph_element; typedef struct face_element face_element; #endif - /* ms_bitarray is used by the bit mask in mapbit.c */ typedef ms_uint32 *ms_bitarray; typedef const ms_uint32 *ms_const_bitarray; @@ -141,30 +140,28 @@ typedef const ms_uint32 *ms_const_bitarray; */ #include "mapregex.h" - #define CPL_SUPRESS_CPLUSPLUS #include "ogr_api.h" - -/* EQUAL and EQUALN are defined in cpl_port.h, so add them in here if ogr was not included */ +/* EQUAL and EQUALN are defined in cpl_port.h, so add them in here if ogr was + * not included */ #ifndef EQUAL #if defined(_WIN32) || defined(WIN32CE) -# define EQUAL(a,b) (stricmp(a,b)==0) +#define EQUAL(a, b) (stricmp(a, b) == 0) #else -# define EQUAL(a,b) (strcasecmp(a,b)==0) +#define EQUAL(a, b) (strcasecmp(a, b) == 0) #endif #endif #ifndef EQUALN #if defined(_WIN32) || defined(WIN32CE) -# define EQUALN(a,b,n) (strnicmp(a,b,n)==0) +#define EQUALN(a, b, n) (strnicmp(a, b, n) == 0) #else -# define EQUALN(a,b,n) (strncasecmp(a,b,n)==0) +#define EQUALN(a, b, n) (strncasecmp(a, b, n) == 0) #endif #endif - #if defined(_WIN32) && !defined(__CYGWIN__) #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || !defined(_MSC_VER) #define snprintf _snprintf @@ -179,27 +176,27 @@ extern "C" { // hide from swig or ruby will choke on the __FUNCTION__ name #ifndef SWIG - /* Memory allocation check utility */ +/* Memory allocation check utility */ #ifndef __FUNCTION__ -# define __FUNCTION__ "MapServer" +#define __FUNCTION__ "MapServer" #endif #endif -#define MS_CHECK_ALLOC(var, size, retval) \ - if (!var) { \ - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", __FUNCTION__, \ - __FILE__, __LINE__, (unsigned int)(size)); \ - return retval; \ - } +#define MS_CHECK_ALLOC(var, size, retval) \ + if (!var) { \ + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", \ + __FUNCTION__, __FILE__, __LINE__, (unsigned int)(size)); \ + return retval; \ + } -#define MS_CHECK_ALLOC_NO_RET(var, size) \ - if (!var) { \ - msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", __FUNCTION__, \ - __FILE__, __LINE__, (unsigned int)(size)); \ - return; \ - } +#define MS_CHECK_ALLOC_NO_RET(var, size) \ + if (!var) { \ + msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", \ + __FUNCTION__, __FILE__, __LINE__, (unsigned int)(size)); \ + return; \ + } - /* General defines, wrapable */ +/* General defines, wrapable */ #define MS_TRUE 1 /* logical control variables */ #define MS_FALSE 0 @@ -212,21 +209,20 @@ extern "C" { #define MS_YES 1 #define MS_NO 0 - - /* Number of layer, class and style ptrs to alloc at once in the - corresponding msGrow...() functions. Replaces former MS_MAXLAYERS, - MS_MAXCLASSES and MS_MAXSTYLES with dynamic allocation (see RFC-17). */ +/* Number of layer, class and style ptrs to alloc at once in the + corresponding msGrow...() functions. Replaces former MS_MAXLAYERS, + MS_MAXCLASSES and MS_MAXSTYLES with dynamic allocation (see RFC-17). */ #define MS_LAYER_ALLOCSIZE 64 #define MS_CLASS_ALLOCSIZE 8 #define MS_STYLE_ALLOCSIZE 4 #define MS_LABEL_ALLOCSIZE 2 /* not too common */ -#define MS_MAX_LABEL_PRIORITY 10 -#define MS_MAX_LABEL_FONTS 5 +#define MS_MAX_LABEL_PRIORITY 10 +#define MS_MAX_LABEL_FONTS 5 #define MS_DEFAULT_LABEL_PRIORITY 1 #define MS_LABEL_FORCE_GROUP 2 /* other values are MS_ON/MS_OFF */ - /* General defines, not wrapable */ +/* General defines, not wrapable */ #ifndef SWIG #ifdef USE_XMLMAPFILE #define MS_DEFAULT_MAPFILE_PATTERN "\\.(map|xml)$" @@ -245,7 +241,7 @@ extern "C" { #define MS_QUERY_EXTENSION ".qy" #define MS_DEG_TO_RAD .0174532925199432958 -#define MS_RAD_TO_DEG 57.29577951 +#define MS_RAD_TO_DEG 57.29577951 #define MS_DEFAULT_RESOLUTION 72 @@ -270,10 +266,10 @@ extern "C" { #define MS_ITEMNAMELEN 32 #define MS_NAMELEN 20 -#define MS_MINSYMBOLSIZE 0 /* in pixels */ +#define MS_MINSYMBOLSIZE 0 /* in pixels */ #define MS_MAXSYMBOLSIZE 500 -#define MS_MINSYMBOLWIDTH 0 /* in pixels */ +#define MS_MINSYMBOLWIDTH 0 /* in pixels */ #define MS_MAXSYMBOLWIDTH 32 #define MS_URL 0 /* template types */ @@ -288,7 +284,9 @@ extern "C" { #define MS_RESULTCACHEINITSIZE 10 #define MS_RESULTCACHEINCREMENT 10 -#define MS_FEATUREINITSIZE 10 /* how many points initially can a feature have */ +#define MS_FEATUREINITSIZE \ + 10 /* how many points initially can a feature have \ + */ #define MS_FEATUREINCREMENT 10 #define MS_EXPRESSION 2000 /* todo: make this an enum */ @@ -301,26 +299,27 @@ extern "C" { #define MS_BINDING 2007 #define MS_LIST 2008 - /* string split flags */ -#define MS_HONOURSTRINGS 0x0001 -#define MS_ALLOWEMPTYTOKENS 0x0002 -#define MS_PRESERVEQUOTES 0x0004 -#define MS_PRESERVEESCAPES 0x0008 -#define MS_STRIPLEADSPACES 0x0010 -#define MS_STRIPENDSPACES 0x0020 +/* string split flags */ +#define MS_HONOURSTRINGS 0x0001 +#define MS_ALLOWEMPTYTOKENS 0x0002 +#define MS_PRESERVEQUOTES 0x0004 +#define MS_PRESERVEESCAPES 0x0008 +#define MS_STRIPLEADSPACES 0x0010 +#define MS_STRIPENDSPACES 0x0020 - /* boolean options for the expression object. */ +/* boolean options for the expression object. */ #define MS_EXP_INSENSITIVE 1 - /* General macro definitions */ -#define MS_MIN(a,b) (((a)<(b))?(a):(b)) -#define MS_MAX(a,b) (((a)>(b))?(a):(b)) -#define MS_ABS(a) (((a)<0) ? -(a) : (a)) -#define MS_SGN(a) (((a)<0) ? -1 : 1) +/* General macro definitions */ +#define MS_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MS_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MS_ABS(a) (((a) < 0) ? -(a) : (a)) +#define MS_SGN(a) (((a) < 0) ? -1 : 1) -#define MS_STRING_IS_NULL_OR_EMPTY(s) ((!s || s[0] == '\0') ? MS_TRUE:MS_FALSE) +#define MS_STRING_IS_NULL_OR_EMPTY(s) \ + ((!s || s[0] == '\0') ? MS_TRUE : MS_FALSE) -#define MS_NINT_GENERIC(x) ((x) >= 0.0 ? ((long) ((x)+.5)) : ((long) ((x)-.5))) +#define MS_NINT_GENERIC(x) ((x) >= 0.0 ? ((long)((x) + .5)) : ((long)((x)-.5))) #ifdef _MSC_VER #define msIsNan(x) _isnan(x) @@ -328,74 +327,104 @@ extern "C" { #define msIsNan(x) isnan(x) #endif - /* see http://mega-nerd.com/FPcast/ for some discussion of fast - conversion to nearest int. We avoid lrint() for now because it - would be hard to include math.h "properly". */ +/* see http://mega-nerd.com/FPcast/ for some discussion of fast + conversion to nearest int. We avoid lrint() for now because it + would be hard to include math.h "properly". */ #if defined(HAVE_LRINT) && !defined(USE_GENERIC_MS_NINT) -# define MS_NINT(x) lrint(x) - /*# define MS_NINT(x) lround(x) */ -/* note that lrint rounds .5 to the nearest *even* integer, i.e. lrint(0.5)=0,lrint(1.5)=2 */ +#define MS_NINT(x) lrint(x) +/*# define MS_NINT(x) lround(x) */ +/* note that lrint rounds .5 to the nearest *even* integer, i.e. + * lrint(0.5)=0,lrint(1.5)=2 */ #elif defined(_MSC_VER) && defined(_WIN32) && !defined(USE_GENERIC_MS_NINT) - static __inline long int MS_NINT (double flt) - { - int intgr; +static __inline long int MS_NINT(double flt) { + int intgr; - _asm { + _asm { fld flt fistp intgr - } ; - - return intgr ; } + ; + + return intgr; +} #elif defined(i386) && defined(__GNUC_PREREQ) && !defined(USE_GENERIC_MS_NINT) - static __inline long int MS_NINT( double __x ) - { - long int __lrintres; - __asm__ __volatile__ - ("fistpl %0" - : "=m" (__lrintres) : "t" (__x) : "st"); - return __lrintres; - } +static __inline long int MS_NINT(double __x) { + long int __lrintres; + __asm__ __volatile__("fistpl %0" : "=m"(__lrintres) : "t"(__x) : "st"); + return __lrintres; +} #else -# define MS_NINT(x) MS_NINT_GENERIC(x) -#endif - - /* #define MS_VALID_EXTENT(minx, miny, maxx, maxy) (((minxmimetype ? format->mimetype : "unknown") -#define MS_IMAGE_EXTENSION(format) (format->extension ? format->extension : "unknown") -#define MS_DRIVER_SWF(format) (strncasecmp((format)->driver,"swf",3)==0) -#define MS_DRIVER_GDAL(format) (strncasecmp((format)->driver,"gdal/",5)==0) -#define MS_DRIVER_IMAGEMAP(format) (strncasecmp((format)->driver,"imagemap",8)==0) -#define MS_DRIVER_AGG(format) (strncasecmp((format)->driver,"agg/",4)==0) -#define MS_DRIVER_MVT(format) (strncasecmp((format)->driver,"mvt",3)==0) -#define MS_DRIVER_CAIRO(format) (strncasecmp((format)->driver,"cairo/",6)==0) -#define MS_DRIVER_OGL(format) (strncasecmp((format)->driver,"ogl/",4)==0) -#define MS_DRIVER_TEMPLATE(format) (strncasecmp((format)->driver,"template",8)==0) +#define MS_NINT(x) MS_NINT_GENERIC(x) +#endif + +/* #define MS_VALID_EXTENT(minx, miny, maxx, maxy) (((minxmimetype ? format->mimetype : "unknown") +#define MS_IMAGE_EXTENSION(format) \ + (format->extension ? format->extension : "unknown") +#define MS_DRIVER_SWF(format) (strncasecmp((format)->driver, "swf", 3) == 0) +#define MS_DRIVER_GDAL(format) (strncasecmp((format)->driver, "gdal/", 5) == 0) +#define MS_DRIVER_IMAGEMAP(format) \ + (strncasecmp((format)->driver, "imagemap", 8) == 0) +#define MS_DRIVER_AGG(format) (strncasecmp((format)->driver, "agg/", 4) == 0) +#define MS_DRIVER_MVT(format) (strncasecmp((format)->driver, "mvt", 3) == 0) +#define MS_DRIVER_CAIRO(format) \ + (strncasecmp((format)->driver, "cairo/", 6) == 0) +#define MS_DRIVER_OGL(format) (strncasecmp((format)->driver, "ogl/", 4) == 0) +#define MS_DRIVER_TEMPLATE(format) \ + (strncasecmp((format)->driver, "template", 8) == 0) #endif /*SWIG*/ -#define MS_RENDER_WITH_SWF 2 -#define MS_RENDER_WITH_RAWDATA 3 +#define MS_RENDER_WITH_SWF 2 +#define MS_RENDER_WITH_RAWDATA 3 #define MS_RENDER_WITH_IMAGEMAP 5 #define MS_RENDER_WITH_TEMPLATE 8 /* query results only */ #define MS_RENDER_WITH_OGR 16 #define MS_RENDER_WITH_PLUGIN 100 -#define MS_RENDER_WITH_CAIRO_RASTER 101 +#define MS_RENDER_WITH_CAIRO_RASTER 101 #define MS_RENDER_WITH_CAIRO_PDF 102 #define MS_RENDER_WITH_CAIRO_SVG 103 -#define MS_RENDER_WITH_OGL 104 +#define MS_RENDER_WITH_OGL 104 #define MS_RENDER_WITH_AGG 105 #define MS_RENDER_WITH_KML 106 #define MS_RENDER_WITH_UTFGRID 107 @@ -404,41 +433,50 @@ extern "C" { #ifndef SWIG #define MS_RENDERER_SWF(format) ((format)->renderer == MS_RENDER_WITH_SWF) -#define MS_RENDERER_RAWDATA(format) ((format)->renderer == MS_RENDER_WITH_RAWDATA) -#define MS_RENDERER_IMAGEMAP(format) ((format)->renderer == MS_RENDER_WITH_IMAGEMAP) -#define MS_RENDERER_TEMPLATE(format) ((format)->renderer == MS_RENDER_WITH_TEMPLATE) +#define MS_RENDERER_RAWDATA(format) \ + ((format)->renderer == MS_RENDER_WITH_RAWDATA) +#define MS_RENDERER_IMAGEMAP(format) \ + ((format)->renderer == MS_RENDER_WITH_IMAGEMAP) +#define MS_RENDERER_TEMPLATE(format) \ + ((format)->renderer == MS_RENDER_WITH_TEMPLATE) #define MS_RENDERER_KML(format) ((format)->renderer == MS_RENDER_WITH_KML) #define MS_RENDERER_OGR(format) ((format)->renderer == MS_RENDER_WITH_OGR) #define MS_RENDERER_MVT(format) ((format)->renderer == MS_RENDER_WITH_MVT) #define MS_RENDERER_PLUGIN(format) ((format)->renderer > MS_RENDER_WITH_PLUGIN) -#define MS_CELLSIZE(min,max,d) (((max) - (min))/((d)-1)) /* where min/max are from an MapServer pixel center-to-pixel center extent */ -#define MS_OWS_CELLSIZE(min,max,d) (((max) - (min))/(d)) /* where min/max are from an OGC pixel outside edge-to-pixel outside edge extent */ -#define MS_MAP2IMAGE_X(x,minx,cx) (MS_NINT(((x) - (minx))/(cx))) -#define MS_MAP2IMAGE_Y(y,maxy,cy) (MS_NINT(((maxy) - (y))/(cy))) -#define MS_IMAGE2MAP_X(x,minx,cx) ((minx) + (cx)*(x)) -#define MS_IMAGE2MAP_Y(y,maxy,cy) ((maxy) - (cy)*(y)) - - /* these versions of MS_MAP2IMAGE takes 1/cellsize and is much faster */ -#define MS_MAP2IMAGE_X_IC(x,minx,icx) (MS_NINT(((x) - (minx))*(icx))) -#define MS_MAP2IMAGE_Y_IC(y,maxy,icy) (MS_NINT(((maxy) - (y))*(icy))) -#define MS_MAP2IMAGE_XCELL_IC(x,minx,icx) ((int)(((x) - (minx))*(icx))) -#define MS_MAP2IMAGE_YCELL_IC(y,maxy,icy) ((int)(((maxy) - (y))*(icy))) - -#define MS_MAP2IMAGE_X_IC_DBL(x,minx,icx) (((x) - (minx))*(icx)) -#define MS_MAP2IMAGE_Y_IC_DBL(y,maxy,icy) (((maxy) - (y))*(icy)) - -#define MS_MAP2IMAGE_X_IC_SNAP(x,minx,icx,res) ((MS_NINT(((x) - (minx))*(icx)*(res)))/(res)) -#define MS_MAP2IMAGE_Y_IC_SNAP(y,maxy,icy,res) ((MS_NINT(((maxy) - (y))*(icy)*(res)))/(res)) - - /* For CARTO symbols */ -#define MS_PI 3.14159265358979323846 -#define MS_PI2 1.57079632679489661923 /* (MS_PI / 2) */ -#define MS_3PI2 4.71238898038468985769 /* (3 * MS_PI2) */ -#define MS_2PI 6.28318530717958647693 /* (2 * MS_PI) */ - -#define MS_ENCRYPTION_KEY_SIZE 16 /* Key size: 128 bits = 16 bytes */ +#define MS_CELLSIZE(min, max, d) \ + (((max) - (min)) / ((d)-1)) /* where min/max are from an MapServer pixel \ + center-to-pixel center extent */ +#define MS_OWS_CELLSIZE(min, max, d) \ + (((max) - (min)) / (d)) /* where min/max are from an OGC pixel outside \ + edge-to-pixel outside edge extent */ +#define MS_MAP2IMAGE_X(x, minx, cx) (MS_NINT(((x) - (minx)) / (cx))) +#define MS_MAP2IMAGE_Y(y, maxy, cy) (MS_NINT(((maxy) - (y)) / (cy))) +#define MS_IMAGE2MAP_X(x, minx, cx) ((minx) + (cx) * (x)) +#define MS_IMAGE2MAP_Y(y, maxy, cy) ((maxy) - (cy) * (y)) + +/* these versions of MS_MAP2IMAGE takes 1/cellsize and is much faster */ +#define MS_MAP2IMAGE_X_IC(x, minx, icx) (MS_NINT(((x) - (minx)) * (icx))) +#define MS_MAP2IMAGE_Y_IC(y, maxy, icy) (MS_NINT(((maxy) - (y)) * (icy))) +#define MS_MAP2IMAGE_XCELL_IC(x, minx, icx) ((int)(((x) - (minx)) * (icx))) +#define MS_MAP2IMAGE_YCELL_IC(y, maxy, icy) ((int)(((maxy) - (y)) * (icy))) + +#define MS_MAP2IMAGE_X_IC_DBL(x, minx, icx) (((x) - (minx)) * (icx)) +#define MS_MAP2IMAGE_Y_IC_DBL(y, maxy, icy) (((maxy) - (y)) * (icy)) + +#define MS_MAP2IMAGE_X_IC_SNAP(x, minx, icx, res) \ + ((MS_NINT(((x) - (minx)) * (icx) * (res))) / (res)) +#define MS_MAP2IMAGE_Y_IC_SNAP(y, maxy, icy, res) \ + ((MS_NINT(((maxy) - (y)) * (icy) * (res))) / (res)) + +/* For CARTO symbols */ +#define MS_PI 3.14159265358979323846 +#define MS_PI2 1.57079632679489661923 /* (MS_PI / 2) */ +#define MS_3PI2 4.71238898038468985769 /* (3 * MS_PI2) */ +#define MS_2PI 6.28318530717958647693 /* (2 * MS_PI) */ + +#define MS_ENCRYPTION_KEY_SIZE 16 /* Key size: 128 bits = 16 bytes */ #define GET_LAYER(map, pos) map->layers[pos] #define GET_CLASS(map, lid, cid) map->layers[lid]->class[cid] @@ -447,1448 +485,1858 @@ extern "C" { #if defined(HAVE_SYNC_FETCH_AND_ADD) #define MS_REFCNT_INCR(obj) __sync_fetch_and_add(&obj->refcount, +1) #define MS_REFCNT_DECR(obj) __sync_sub_and_fetch(&obj->refcount, +1) -#define MS_REFCNT_INIT(obj) obj->refcount=1, __sync_synchronize() +#define MS_REFCNT_INIT(obj) obj->refcount = 1, __sync_synchronize() #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #include -#pragma intrinsic (_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedExchangeAdd) #if defined(_MSC_VER) && (_MSC_VER <= 1200) -#define MS_REFCNT_INCR(obj) ( _InterlockedExchangeAdd((long*)(&obj->refcount), (long)(+1)) +1 ) -#define MS_REFCNT_DECR(obj) ( _InterlockedExchangeAdd((long*)(&obj->refcount), (long)(-1)) -1 ) -#define MS_REFCNT_INIT(obj) obj->refcount=1 +#define MS_REFCNT_INCR(obj) \ + (_InterlockedExchangeAdd((long *)(&obj->refcount), (long)(+1)) + 1) +#define MS_REFCNT_DECR(obj) \ + (_InterlockedExchangeAdd((long *)(&obj->refcount), (long)(-1)) - 1) +#define MS_REFCNT_INIT(obj) obj->refcount = 1 #else -#define MS_REFCNT_INCR(obj) ( _InterlockedExchangeAdd((volatile long*)(&obj->refcount), (long)(+1)) +1 ) -#define MS_REFCNT_DECR(obj) ( _InterlockedExchangeAdd((volatile long*)(&obj->refcount), (long)(-1)) -1 ) -#define MS_REFCNT_INIT(obj) obj->refcount=1 +#define MS_REFCNT_INCR(obj) \ + (_InterlockedExchangeAdd((volatile long *)(&obj->refcount), (long)(+1)) + 1) +#define MS_REFCNT_DECR(obj) \ + (_InterlockedExchangeAdd((volatile long *)(&obj->refcount), (long)(-1)) - 1) +#define MS_REFCNT_INIT(obj) obj->refcount = 1 #endif #elif defined(__MINGW32__) && defined(__i386__) -#define MS_REFCNT_INCR(obj) ( InterlockedExchangeAdd((long*)(&obj->refcount), (long)(+1)) +1 ) -#define MS_REFCNT_DECR(obj) ( InterlockedExchangeAdd((long*)(&obj->refcount), (long)(-1)) -1 ) -#define MS_REFCNT_INIT(obj) obj->refcount=1 +#define MS_REFCNT_INCR(obj) \ + (InterlockedExchangeAdd((long *)(&obj->refcount), (long)(+1)) + 1) +#define MS_REFCNT_DECR(obj) \ + (InterlockedExchangeAdd((long *)(&obj->refcount), (long)(-1)) - 1) +#define MS_REFCNT_INIT(obj) obj->refcount = 1 #else - // unsafe fallback +// unsafe fallback #define MS_REFCNT_INCR(obj) obj->refcount++ #define MS_REFCNT_DECR(obj) (--(obj->refcount)) -#define MS_REFCNT_INIT(obj) obj->refcount=1 +#define MS_REFCNT_INIT(obj) obj->refcount = 1 #endif // close if defined(_MSC.. -#else /*USE_THREAD*/ +#else /*USE_THREAD*/ #define MS_REFCNT_INCR(obj) obj->refcount++ #define MS_REFCNT_DECR(obj) (--(obj->refcount)) -#define MS_REFCNT_INIT(obj) obj->refcount=1 +#define MS_REFCNT_INIT(obj) obj->refcount = 1 #endif /*USE_THREAD*/ -#define MS_REFCNT_DECR_IS_NOT_ZERO(obj) (MS_REFCNT_DECR(obj))>0 -#define MS_REFCNT_DECR_IS_ZERO(obj) (MS_REFCNT_DECR(obj))<=0 +#define MS_REFCNT_DECR_IS_NOT_ZERO(obj) (MS_REFCNT_DECR(obj)) > 0 +#define MS_REFCNT_DECR_IS_ZERO(obj) (MS_REFCNT_DECR(obj)) <= 0 -#define MS_IS_VALID_ARRAY_INDEX(index, size) ((index<0 || index>=size)?MS_FALSE:MS_TRUE) +#define MS_IS_VALID_ARRAY_INDEX(index, size) \ + ((index < 0 || index >= size) ? MS_FALSE : MS_TRUE) -#define MS_CONVERT_UNIT(src_unit, dst_unit, value) (value * msInchesPerUnit(src_unit,0) / msInchesPerUnit(dst_unit,0)) +#define MS_CONVERT_UNIT(src_unit, dst_unit, value) \ + (value * msInchesPerUnit(src_unit, 0) / msInchesPerUnit(dst_unit, 0)) -#define MS_INIT_INVALID_RECT { -1e300, -1e300, 1e300, 1e300 } +#define MS_INIT_INVALID_RECT \ + { -1e300, -1e300, 1e300, 1e300 } #endif - enum MS_NUM_CHECK_TYPES { MS_NUM_CHECK_NONE=0, MS_NUM_CHECK_RANGE, MS_NUM_CHECK_GT, MS_NUM_CHECK_GTE }; +enum MS_NUM_CHECK_TYPES { + MS_NUM_CHECK_NONE = 0, + MS_NUM_CHECK_RANGE, + MS_NUM_CHECK_GT, + MS_NUM_CHECK_GTE +}; - /* General enumerated types - needed by scripts */ - enum MS_FILE_TYPE {MS_FILE_MAP, MS_FILE_SYMBOL}; - enum MS_UNITS {MS_INCHES, MS_FEET, MS_MILES, MS_METERS, MS_KILOMETERS, MS_DD, MS_PIXELS, MS_PERCENTAGES, MS_NAUTICALMILES, MS_INHERIT = -1}; - enum MS_SHAPE_TYPE {MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON, MS_SHAPE_NULL}; - enum MS_LAYER_TYPE {MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON, MS_LAYER_RASTER, MS_LAYER_ANNOTATION /* only used for parser backwards compatibility */, MS_LAYER_QUERY, MS_LAYER_CIRCLE, MS_LAYER_TILEINDEX, MS_LAYER_CHART}; - enum MS_FONT_TYPE {MS_TRUETYPE, MS_BITMAP}; - enum MS_RENDER_MODE {MS_FIRST_MATCHING_CLASS, MS_ALL_MATCHING_CLASSES}; +/* General enumerated types - needed by scripts */ +enum MS_FILE_TYPE { MS_FILE_MAP, MS_FILE_SYMBOL }; +enum MS_UNITS { + MS_INCHES, + MS_FEET, + MS_MILES, + MS_METERS, + MS_KILOMETERS, + MS_DD, + MS_PIXELS, + MS_PERCENTAGES, + MS_NAUTICALMILES, + MS_INHERIT = -1 +}; +enum MS_SHAPE_TYPE { + MS_SHAPE_POINT, + MS_SHAPE_LINE, + MS_SHAPE_POLYGON, + MS_SHAPE_NULL +}; +enum MS_LAYER_TYPE { + MS_LAYER_POINT, + MS_LAYER_LINE, + MS_LAYER_POLYGON, + MS_LAYER_RASTER, + MS_LAYER_ANNOTATION /* only used for parser backwards compatibility */, + MS_LAYER_QUERY, + MS_LAYER_CIRCLE, + MS_LAYER_TILEINDEX, + MS_LAYER_CHART +}; +enum MS_FONT_TYPE { MS_TRUETYPE, MS_BITMAP }; +enum MS_RENDER_MODE { MS_FIRST_MATCHING_CLASS, MS_ALL_MATCHING_CLASSES }; #define MS_POSITIONS_LENGTH 14 - enum MS_POSITIONS_ENUM {MS_UL=101, MS_LR, MS_UR, MS_LL, MS_CR, MS_CL, MS_UC, MS_LC, MS_CC, MS_AUTO, MS_XY, MS_NONE, MS_AUTO2,MS_FOLLOW}; +enum MS_POSITIONS_ENUM { + MS_UL = 101, + MS_LR, + MS_UR, + MS_LL, + MS_CR, + MS_CL, + MS_UC, + MS_LC, + MS_CC, + MS_AUTO, + MS_XY, + MS_NONE, + MS_AUTO2, + MS_FOLLOW +}; #define MS_TINY 5 #define MS_SMALL 7 #define MS_MEDIUM 10 #define MS_LARGE 13 #define MS_GIANT 16 - enum MS_QUERYMAP_STYLES {MS_NORMAL, MS_HILITE, MS_SELECTED}; - enum MS_CONNECTION_TYPE {MS_INLINE, MS_SHAPEFILE, MS_TILED_SHAPEFILE, MS_UNUSED_2, MS_OGR, MS_UNUSED_1, MS_POSTGIS, MS_WMS, MS_ORACLESPATIAL, MS_WFS, MS_GRATICULE, MS_MYSQL, MS_RASTER, MS_PLUGIN, MS_UNION, MS_UVRASTER, MS_CONTOUR, MS_KERNELDENSITY, MS_IDW, MS_FLATGEOBUF }; -#define IS_THIRDPARTY_LAYER_CONNECTIONTYPE(type) ((type) == MS_UNION || (type) == MS_KERNELDENSITY || (type) == MS_IDW) - enum MS_JOIN_CONNECTION_TYPE {MS_DB_XBASE, MS_DB_CSV, MS_DB_MYSQL, MS_DB_ORACLE, MS_DB_POSTGRES}; - enum MS_JOIN_TYPE {MS_JOIN_ONE_TO_ONE, MS_JOIN_ONE_TO_MANY}; +enum MS_QUERYMAP_STYLES { MS_NORMAL, MS_HILITE, MS_SELECTED }; +enum MS_CONNECTION_TYPE { + MS_INLINE, + MS_SHAPEFILE, + MS_TILED_SHAPEFILE, + MS_UNUSED_2, + MS_OGR, + MS_UNUSED_1, + MS_POSTGIS, + MS_WMS, + MS_ORACLESPATIAL, + MS_WFS, + MS_GRATICULE, + MS_MYSQL, + MS_RASTER, + MS_PLUGIN, + MS_UNION, + MS_UVRASTER, + MS_CONTOUR, + MS_KERNELDENSITY, + MS_IDW, + MS_FLATGEOBUF +}; +#define IS_THIRDPARTY_LAYER_CONNECTIONTYPE(type) \ + ((type) == MS_UNION || (type) == MS_KERNELDENSITY || (type) == MS_IDW) +enum MS_JOIN_CONNECTION_TYPE { + MS_DB_XBASE, + MS_DB_CSV, + MS_DB_MYSQL, + MS_DB_ORACLE, + MS_DB_POSTGRES +}; +enum MS_JOIN_TYPE { MS_JOIN_ONE_TO_ONE, MS_JOIN_ONE_TO_MANY }; #define MS_SINGLE 0 /* modes for searching (spatial/database) */ #define MS_MULTIPLE 1 - enum MS_QUERY_MODE {MS_QUERY_SINGLE, MS_QUERY_MULTIPLE}; - enum MS_QUERY_TYPE {MS_QUERY_IS_NULL, MS_QUERY_BY_POINT, MS_QUERY_BY_RECT, MS_QUERY_BY_SHAPE, MS_QUERY_BY_ATTRIBUTE, MS_QUERY_BY_INDEX, MS_QUERY_BY_FILTER}; +enum MS_QUERY_MODE { MS_QUERY_SINGLE, MS_QUERY_MULTIPLE }; +enum MS_QUERY_TYPE { + MS_QUERY_IS_NULL, + MS_QUERY_BY_POINT, + MS_QUERY_BY_RECT, + MS_QUERY_BY_SHAPE, + MS_QUERY_BY_ATTRIBUTE, + MS_QUERY_BY_INDEX, + MS_QUERY_BY_FILTER +}; - enum MS_ALIGN_VALUE {MS_ALIGN_DEFAULT, MS_ALIGN_LEFT, MS_ALIGN_CENTER, MS_ALIGN_RIGHT}; +enum MS_ALIGN_VALUE { + MS_ALIGN_DEFAULT, + MS_ALIGN_LEFT, + MS_ALIGN_CENTER, + MS_ALIGN_RIGHT +}; - enum MS_CAPS_JOINS_AND_CORNERS {MS_CJC_NONE, MS_CJC_BEVEL, MS_CJC_BUTT, MS_CJC_MITER, MS_CJC_ROUND, MS_CJC_SQUARE, MS_CJC_TRIANGLE}; +enum MS_CAPS_JOINS_AND_CORNERS { + MS_CJC_NONE, + MS_CJC_BEVEL, + MS_CJC_BUTT, + MS_CJC_MITER, + MS_CJC_ROUND, + MS_CJC_SQUARE, + MS_CJC_TRIANGLE +}; #define MS_CJC_DEFAULT_CAPS MS_CJC_ROUND #define MS_CJC_DEFAULT_JOINS MS_CJC_NONE #define MS_CJC_DEFAULT_JOIN_MAXSIZE 3 - enum MS_RETURN_VALUE {MS_SUCCESS, MS_FAILURE, MS_DONE}; - enum MS_IMAGEMODE { MS_IMAGEMODE_PC256, MS_IMAGEMODE_RGB, MS_IMAGEMODE_RGBA, MS_IMAGEMODE_INT16, MS_IMAGEMODE_FLOAT32, MS_IMAGEMODE_BYTE, MS_IMAGEMODE_FEATURE, MS_IMAGEMODE_NULL }; +enum MS_RETURN_VALUE { MS_SUCCESS, MS_FAILURE, MS_DONE }; +enum MS_IMAGEMODE { + MS_IMAGEMODE_PC256, + MS_IMAGEMODE_RGB, + MS_IMAGEMODE_RGBA, + MS_IMAGEMODE_INT16, + MS_IMAGEMODE_FLOAT32, + MS_IMAGEMODE_BYTE, + MS_IMAGEMODE_FEATURE, + MS_IMAGEMODE_NULL +}; - enum MS_GEOS_OPERATOR {MS_GEOS_EQUALS, MS_GEOS_DISJOINT, MS_GEOS_TOUCHES, MS_GEOS_OVERLAPS, MS_GEOS_CROSSES, MS_GEOS_INTERSECTS, MS_GEOS_WITHIN, MS_GEOS_CONTAINS, MS_GEOS_BEYOND, MS_GEOS_DWITHIN}; +enum MS_GEOS_OPERATOR { + MS_GEOS_EQUALS, + MS_GEOS_DISJOINT, + MS_GEOS_TOUCHES, + MS_GEOS_OVERLAPS, + MS_GEOS_CROSSES, + MS_GEOS_INTERSECTS, + MS_GEOS_WITHIN, + MS_GEOS_CONTAINS, + MS_GEOS_BEYOND, + MS_GEOS_DWITHIN +}; #define MS_FILE_DEFAULT MS_FILE_MAP #if defined(_MSC_VER) && (_MSC_VER <= 1310) #define MS_DEBUG msDebug2 #else #ifdef USE_EXTENDED_DEBUG -#define MS_DEBUG(level,elt,fmt, ...) if((elt)->debug >= (level)) msDebug(fmt,##__VA_ARGS__) +#define MS_DEBUG(level, elt, fmt, ...) \ + if ((elt)->debug >= (level)) \ + msDebug(fmt, ##__VA_ARGS__) #else -#define MS_DEBUG(level,elt,fmt, ...) /* no-op */ -#endif -#endif - - /* coordinate to pixel simplification modes, used in msTransformShape */ - enum MS_TRANSFORM_MODE { - MS_TRANSFORM_NONE, /* no geographic to pixel transformation */ - MS_TRANSFORM_ROUND, /* round to integer, might create degenerate geometries (used for GD)*/ - MS_TRANSFORM_SNAPTOGRID, /* snap to a grid, should be user configurable in the future*/ - MS_TRANSFORM_FULLRESOLUTION, /* keep full resolution */ - MS_TRANSFORM_SIMPLIFY /* keep full resolution */ - }; - - typedef enum { - MS_COMPOP_CLEAR, - MS_COMPOP_SRC, - MS_COMPOP_DST, - MS_COMPOP_SRC_OVER, - MS_COMPOP_DST_OVER, - MS_COMPOP_SRC_IN, - MS_COMPOP_DST_IN, - MS_COMPOP_SRC_OUT, - MS_COMPOP_DST_OUT, - MS_COMPOP_SRC_ATOP, - MS_COMPOP_DST_ATOP, - MS_COMPOP_XOR, - MS_COMPOP_PLUS, - MS_COMPOP_MINUS, - MS_COMPOP_MULTIPLY, - MS_COMPOP_SCREEN, - MS_COMPOP_OVERLAY, - MS_COMPOP_DARKEN, - MS_COMPOP_LIGHTEN, - MS_COMPOP_COLOR_DODGE, - MS_COMPOP_COLOR_BURN, - MS_COMPOP_HARD_LIGHT, - MS_COMPOP_SOFT_LIGHT, - MS_COMPOP_DIFFERENCE, - MS_COMPOP_EXCLUSION, - MS_COMPOP_CONTRAST, - MS_COMPOP_INVERT, - MS_COMPOP_INVERT_RGB - } CompositingOperation; - - typedef struct _CompositingFilter{ - char *filter; - struct _CompositingFilter *next; - } CompositingFilter; - - typedef struct _LayerCompositer{ - CompositingOperation comp_op; - int opacity; - CompositingFilter *filter; - struct _LayerCompositer *next; - } LayerCompositer; +#define MS_DEBUG(level, elt, fmt, ...) /* no-op */ +#endif +#endif + +/* coordinate to pixel simplification modes, used in msTransformShape */ +enum MS_TRANSFORM_MODE { + MS_TRANSFORM_NONE, /* no geographic to pixel transformation */ + MS_TRANSFORM_ROUND, /* round to integer, might create degenerate geometries + (used for GD)*/ + MS_TRANSFORM_SNAPTOGRID, /* snap to a grid, should be user configurable in the + future*/ + MS_TRANSFORM_FULLRESOLUTION, /* keep full resolution */ + MS_TRANSFORM_SIMPLIFY /* keep full resolution */ +}; + +typedef enum { + MS_COMPOP_CLEAR, + MS_COMPOP_SRC, + MS_COMPOP_DST, + MS_COMPOP_SRC_OVER, + MS_COMPOP_DST_OVER, + MS_COMPOP_SRC_IN, + MS_COMPOP_DST_IN, + MS_COMPOP_SRC_OUT, + MS_COMPOP_DST_OUT, + MS_COMPOP_SRC_ATOP, + MS_COMPOP_DST_ATOP, + MS_COMPOP_XOR, + MS_COMPOP_PLUS, + MS_COMPOP_MINUS, + MS_COMPOP_MULTIPLY, + MS_COMPOP_SCREEN, + MS_COMPOP_OVERLAY, + MS_COMPOP_DARKEN, + MS_COMPOP_LIGHTEN, + MS_COMPOP_COLOR_DODGE, + MS_COMPOP_COLOR_BURN, + MS_COMPOP_HARD_LIGHT, + MS_COMPOP_SOFT_LIGHT, + MS_COMPOP_DIFFERENCE, + MS_COMPOP_EXCLUSION, + MS_COMPOP_CONTRAST, + MS_COMPOP_INVERT, + MS_COMPOP_INVERT_RGB +} CompositingOperation; + +typedef struct _CompositingFilter { + char *filter; + struct _CompositingFilter *next; +} CompositingFilter; + +typedef struct _LayerCompositer { + CompositingOperation comp_op; + int opacity; + CompositingFilter *filter; + struct _LayerCompositer *next; +} LayerCompositer; #ifndef SWIG - /* Filter object */ - typedef enum { - FILTER_NODE_TYPE_UNDEFINED = -1, - FILTER_NODE_TYPE_LOGICAL = 0, - FILTER_NODE_TYPE_SPATIAL = 1, - FILTER_NODE_TYPE_COMPARISON = 2, - FILTER_NODE_TYPE_PROPERTYNAME = 3, - FILTER_NODE_TYPE_BBOX = 4, - FILTER_NODE_TYPE_LITERAL = 5, - FILTER_NODE_TYPE_BOUNDARY = 6, - FILTER_NODE_TYPE_GEOMETRY_POINT = 7, - FILTER_NODE_TYPE_GEOMETRY_LINE = 8, - FILTER_NODE_TYPE_GEOMETRY_POLYGON = 9, - FILTER_NODE_TYPE_FEATUREID = 10, - FILTER_NODE_TYPE_TEMPORAL = 11, - FILTER_NODE_TYPE_TIME_PERIOD = 12 - } FilterNodeType; - - - /************************************************************************/ - /* FilterEncodingNode */ - /************************************************************************/ - - typedef struct _FilterNode { - FilterNodeType eType; - char *pszValue; - void *pOther; - char *pszSRS; - struct _FilterNode *psLeftNode; - struct _FilterNode *psRightNode; - } FilterEncodingNode; +/* Filter object */ +typedef enum { + FILTER_NODE_TYPE_UNDEFINED = -1, + FILTER_NODE_TYPE_LOGICAL = 0, + FILTER_NODE_TYPE_SPATIAL = 1, + FILTER_NODE_TYPE_COMPARISON = 2, + FILTER_NODE_TYPE_PROPERTYNAME = 3, + FILTER_NODE_TYPE_BBOX = 4, + FILTER_NODE_TYPE_LITERAL = 5, + FILTER_NODE_TYPE_BOUNDARY = 6, + FILTER_NODE_TYPE_GEOMETRY_POINT = 7, + FILTER_NODE_TYPE_GEOMETRY_LINE = 8, + FILTER_NODE_TYPE_GEOMETRY_POLYGON = 9, + FILTER_NODE_TYPE_FEATUREID = 10, + FILTER_NODE_TYPE_TEMPORAL = 11, + FILTER_NODE_TYPE_TIME_PERIOD = 12 +} FilterNodeType; + +/************************************************************************/ +/* FilterEncodingNode */ +/************************************************************************/ + +typedef struct _FilterNode { + FilterNodeType eType; + char *pszValue; + void *pOther; + char *pszSRS; + struct _FilterNode *psLeftNode; + struct _FilterNode *psRightNode; +} FilterEncodingNode; #endif /*SWIG*/ - /* Define supported bindings here (only covers existing bindings at first). Not accessible directly using MapScript. */ +/* Define supported bindings here (only covers existing bindings at first). Not + * accessible directly using MapScript. */ #define MS_STYLE_BINDING_LENGTH 12 - enum MS_STYLE_BINDING_ENUM { MS_STYLE_BINDING_SIZE, MS_STYLE_BINDING_WIDTH, MS_STYLE_BINDING_ANGLE, MS_STYLE_BINDING_COLOR, MS_STYLE_BINDING_OUTLINECOLOR, MS_STYLE_BINDING_SYMBOL, MS_STYLE_BINDING_OUTLINEWIDTH, MS_STYLE_BINDING_OPACITY, MS_STYLE_BINDING_OFFSET_X, MS_STYLE_BINDING_OFFSET_Y, MS_STYLE_BINDING_POLAROFFSET_PIXEL, MS_STYLE_BINDING_POLAROFFSET_ANGLE }; +enum MS_STYLE_BINDING_ENUM { + MS_STYLE_BINDING_SIZE, + MS_STYLE_BINDING_WIDTH, + MS_STYLE_BINDING_ANGLE, + MS_STYLE_BINDING_COLOR, + MS_STYLE_BINDING_OUTLINECOLOR, + MS_STYLE_BINDING_SYMBOL, + MS_STYLE_BINDING_OUTLINEWIDTH, + MS_STYLE_BINDING_OPACITY, + MS_STYLE_BINDING_OFFSET_X, + MS_STYLE_BINDING_OFFSET_Y, + MS_STYLE_BINDING_POLAROFFSET_PIXEL, + MS_STYLE_BINDING_POLAROFFSET_ANGLE +}; #define MS_LABEL_BINDING_LENGTH 12 - enum MS_LABEL_BINDING_ENUM { MS_LABEL_BINDING_SIZE, MS_LABEL_BINDING_ANGLE, MS_LABEL_BINDING_COLOR, MS_LABEL_BINDING_OUTLINECOLOR, MS_LABEL_BINDING_FONT, MS_LABEL_BINDING_PRIORITY, MS_LABEL_BINDING_POSITION, MS_LABEL_BINDING_SHADOWSIZEX, MS_LABEL_BINDING_SHADOWSIZEY, MS_LABEL_BINDING_OFFSET_X, MS_LABEL_BINDING_OFFSET_Y,MS_LABEL_BINDING_ALIGN }; +enum MS_LABEL_BINDING_ENUM { + MS_LABEL_BINDING_SIZE, + MS_LABEL_BINDING_ANGLE, + MS_LABEL_BINDING_COLOR, + MS_LABEL_BINDING_OUTLINECOLOR, + MS_LABEL_BINDING_FONT, + MS_LABEL_BINDING_PRIORITY, + MS_LABEL_BINDING_POSITION, + MS_LABEL_BINDING_SHADOWSIZEX, + MS_LABEL_BINDING_SHADOWSIZEY, + MS_LABEL_BINDING_OFFSET_X, + MS_LABEL_BINDING_OFFSET_Y, + MS_LABEL_BINDING_ALIGN +}; - /************************************************************************/ - /* attributeBindingObj */ - /************************************************************************/ +/************************************************************************/ +/* attributeBindingObj */ +/************************************************************************/ #ifndef SWIG - typedef struct { - char *item; - int index; - } attributeBindingObj; +typedef struct { + char *item; + int index; +} attributeBindingObj; #endif /*SWIG*/ - /************************************************************************/ - /* labelPathObj */ - /* */ - /* Label path object - used to hold path and bounds of curved */ - /* labels - Bug #1620 implementation. */ - /************************************************************************/ +/************************************************************************/ +/* labelPathObj */ +/* */ +/* Label path object - used to hold path and bounds of curved */ +/* labels - Bug #1620 implementation. */ +/************************************************************************/ #ifndef SWIG - typedef struct { - multipointObj path; - shapeObj bounds; - double *angles; - } labelPathObj; +typedef struct { + multipointObj path; + shapeObj bounds; + double *angles; +} labelPathObj; #endif /*SWIG*/ - /************************************************************************/ - /* fontSetObj */ - /* */ - /* used to hold aliases for TRUETYPE fonts */ - /************************************************************************/ +/************************************************************************/ +/* fontSetObj */ +/* */ +/* used to hold aliases for TRUETYPE fonts */ +/************************************************************************/ - /** - The :ref:`FONTSET ` object - */ - typedef struct { +/** +The :ref:`FONTSET ` object +*/ +typedef struct { #ifdef SWIG %immutable; #endif - char *filename; ///< The filename of the fonset - int numfonts; ///< The number of fonts in the fontset - hashTableObj fonts; ///< Key, value pairs of font name and font file + char *filename; ///< The filename of the fonset + int numfonts; ///< The number of fonts in the fontset + hashTableObj fonts; ///< Key, value pairs of font name and font file #ifdef SWIG %mutable; #endif #ifndef SWIG - struct mapObj *map; + struct mapObj *map; #endif - } fontSetObj; +} fontSetObj; - /************************************************************************/ - /* featureListNodeObj */ - /* */ - /* for inline features, shape caches and queries */ - /************************************************************************/ +/************************************************************************/ +/* featureListNodeObj */ +/* */ +/* for inline features, shape caches and queries */ +/************************************************************************/ #ifndef SWIG - typedef struct listNode { - shapeObj shape; - struct listNode *next; - struct listNode *tailifhead; /* this is the tail node in the list, if this is the head element, otherwise NULL */ - } featureListNodeObj; - - typedef featureListNodeObj * featureListNodeObjPtr; +typedef struct listNode { + shapeObj shape; + struct listNode *next; + struct listNode *tailifhead; /* this is the tail node in the list, if this is + the head element, otherwise NULL */ +} featureListNodeObj; + +typedef featureListNodeObj *featureListNodeObjPtr; #endif - /************************************************************************/ - /* paletteObj */ - /* */ - /* used to hold colors while a map file is read */ - /************************************************************************/ +/************************************************************************/ +/* paletteObj */ +/* */ +/* used to hold colors while a map file is read */ +/************************************************************************/ #ifndef SWIG - typedef struct { - colorObj colors[MS_MAXCOLORS-1]; - int colorvalue[MS_MAXCOLORS-1]; - int numcolors; - } paletteObj; -#endif - - /************************************************************************/ - /* expressionObj & tokenObj */ - /************************************************************************/ - - enum MS_TOKEN_LOGICAL_ENUM { MS_TOKEN_LOGICAL_AND=300, MS_TOKEN_LOGICAL_OR, MS_TOKEN_LOGICAL_NOT }; - enum MS_TOKEN_LITERAL_ENUM { MS_TOKEN_LITERAL_NUMBER=310, MS_TOKEN_LITERAL_STRING, MS_TOKEN_LITERAL_TIME, MS_TOKEN_LITERAL_SHAPE, MS_TOKEN_LITERAL_BOOLEAN }; - enum MS_TOKEN_COMPARISON_ENUM { - MS_TOKEN_COMPARISON_EQ=320, MS_TOKEN_COMPARISON_NE, MS_TOKEN_COMPARISON_GT, MS_TOKEN_COMPARISON_LT, MS_TOKEN_COMPARISON_LE, MS_TOKEN_COMPARISON_GE, MS_TOKEN_COMPARISON_IEQ, - MS_TOKEN_COMPARISON_RE, MS_TOKEN_COMPARISON_IRE, - MS_TOKEN_COMPARISON_IN, MS_TOKEN_COMPARISON_LIKE, - MS_TOKEN_COMPARISON_INTERSECTS, MS_TOKEN_COMPARISON_DISJOINT, MS_TOKEN_COMPARISON_TOUCHES, MS_TOKEN_COMPARISON_OVERLAPS, MS_TOKEN_COMPARISON_CROSSES, MS_TOKEN_COMPARISON_WITHIN, MS_TOKEN_COMPARISON_CONTAINS, MS_TOKEN_COMPARISON_EQUALS, MS_TOKEN_COMPARISON_BEYOND, MS_TOKEN_COMPARISON_DWITHIN - }; - enum MS_TOKEN_FUNCTION_ENUM { - MS_TOKEN_FUNCTION_LENGTH=350, MS_TOKEN_FUNCTION_TOSTRING, MS_TOKEN_FUNCTION_COMMIFY, MS_TOKEN_FUNCTION_AREA, MS_TOKEN_FUNCTION_ROUND, MS_TOKEN_FUNCTION_FROMTEXT, - MS_TOKEN_FUNCTION_BUFFER, MS_TOKEN_FUNCTION_DIFFERENCE, MS_TOKEN_FUNCTION_SIMPLIFY, MS_TOKEN_FUNCTION_SIMPLIFYPT, MS_TOKEN_FUNCTION_GENERALIZE, MS_TOKEN_FUNCTION_SMOOTHSIA, - MS_TOKEN_FUNCTION_CENTERLINE, MS_TOKEN_FUNCTION_DENSIFY, MS_TOKEN_FUNCTION_OUTER, MS_TOKEN_FUNCTION_INNER, - MS_TOKEN_FUNCTION_JAVASCRIPT, MS_TOKEN_FUNCTION_UPPER, MS_TOKEN_FUNCTION_LOWER, MS_TOKEN_FUNCTION_INITCAP, MS_TOKEN_FUNCTION_FIRSTCAP - }; - enum MS_TOKEN_BINDING_ENUM { MS_TOKEN_BINDING_DOUBLE=380, MS_TOKEN_BINDING_INTEGER, MS_TOKEN_BINDING_STRING, MS_TOKEN_BINDING_TIME, MS_TOKEN_BINDING_SHAPE, MS_TOKEN_BINDING_MAP_CELLSIZE, MS_TOKEN_BINDING_DATA_CELLSIZE }; - enum MS_PARSE_TYPE_ENUM { MS_PARSE_TYPE_BOOLEAN, MS_PARSE_TYPE_STRING, MS_PARSE_TYPE_SHAPE, MS_PARSE_TYPE_SLD }; +typedef struct { + colorObj colors[MS_MAXCOLORS - 1]; + int colorvalue[MS_MAXCOLORS - 1]; + int numcolors; +} paletteObj; +#endif + +/************************************************************************/ +/* expressionObj & tokenObj */ +/************************************************************************/ + +enum MS_TOKEN_LOGICAL_ENUM { + MS_TOKEN_LOGICAL_AND = 300, + MS_TOKEN_LOGICAL_OR, + MS_TOKEN_LOGICAL_NOT +}; +enum MS_TOKEN_LITERAL_ENUM { + MS_TOKEN_LITERAL_NUMBER = 310, + MS_TOKEN_LITERAL_STRING, + MS_TOKEN_LITERAL_TIME, + MS_TOKEN_LITERAL_SHAPE, + MS_TOKEN_LITERAL_BOOLEAN +}; +enum MS_TOKEN_COMPARISON_ENUM { + MS_TOKEN_COMPARISON_EQ = 320, + MS_TOKEN_COMPARISON_NE, + MS_TOKEN_COMPARISON_GT, + MS_TOKEN_COMPARISON_LT, + MS_TOKEN_COMPARISON_LE, + MS_TOKEN_COMPARISON_GE, + MS_TOKEN_COMPARISON_IEQ, + MS_TOKEN_COMPARISON_RE, + MS_TOKEN_COMPARISON_IRE, + MS_TOKEN_COMPARISON_IN, + MS_TOKEN_COMPARISON_LIKE, + MS_TOKEN_COMPARISON_INTERSECTS, + MS_TOKEN_COMPARISON_DISJOINT, + MS_TOKEN_COMPARISON_TOUCHES, + MS_TOKEN_COMPARISON_OVERLAPS, + MS_TOKEN_COMPARISON_CROSSES, + MS_TOKEN_COMPARISON_WITHIN, + MS_TOKEN_COMPARISON_CONTAINS, + MS_TOKEN_COMPARISON_EQUALS, + MS_TOKEN_COMPARISON_BEYOND, + MS_TOKEN_COMPARISON_DWITHIN +}; +enum MS_TOKEN_FUNCTION_ENUM { + MS_TOKEN_FUNCTION_LENGTH = 350, + MS_TOKEN_FUNCTION_TOSTRING, + MS_TOKEN_FUNCTION_COMMIFY, + MS_TOKEN_FUNCTION_AREA, + MS_TOKEN_FUNCTION_ROUND, + MS_TOKEN_FUNCTION_FROMTEXT, + MS_TOKEN_FUNCTION_BUFFER, + MS_TOKEN_FUNCTION_DIFFERENCE, + MS_TOKEN_FUNCTION_SIMPLIFY, + MS_TOKEN_FUNCTION_SIMPLIFYPT, + MS_TOKEN_FUNCTION_GENERALIZE, + MS_TOKEN_FUNCTION_SMOOTHSIA, + MS_TOKEN_FUNCTION_CENTERLINE, + MS_TOKEN_FUNCTION_DENSIFY, + MS_TOKEN_FUNCTION_OUTER, + MS_TOKEN_FUNCTION_INNER, + MS_TOKEN_FUNCTION_JAVASCRIPT, + MS_TOKEN_FUNCTION_UPPER, + MS_TOKEN_FUNCTION_LOWER, + MS_TOKEN_FUNCTION_INITCAP, + MS_TOKEN_FUNCTION_FIRSTCAP +}; +enum MS_TOKEN_BINDING_ENUM { + MS_TOKEN_BINDING_DOUBLE = 380, + MS_TOKEN_BINDING_INTEGER, + MS_TOKEN_BINDING_STRING, + MS_TOKEN_BINDING_TIME, + MS_TOKEN_BINDING_SHAPE, + MS_TOKEN_BINDING_MAP_CELLSIZE, + MS_TOKEN_BINDING_DATA_CELLSIZE +}; +enum MS_PARSE_TYPE_ENUM { + MS_PARSE_TYPE_BOOLEAN, + MS_PARSE_TYPE_STRING, + MS_PARSE_TYPE_SHAPE, + MS_PARSE_TYPE_SLD +}; #ifndef SWIG - typedef union { - int intval; - char *strval; - shapeObj *shpval; - } parseResultObj; - - typedef union { - double dblval; - int intval; - char *strval; - struct tm tmval; - shapeObj *shpval; - attributeBindingObj bindval; - } tokenValueObj; - - typedef struct tokenListNode { - int token; - tokenValueObj tokenval; - char *tokensrc; /* on occassion we may want to access to the original source string (e.g. date/time) */ - struct tokenListNode *next; - struct tokenListNode *tailifhead; /* this is the tail node in the list if this is the head element, otherwise NULL */ - } tokenListNodeObj; - - typedef tokenListNodeObj * tokenListNodeObjPtr; - - typedef struct { - char *string; - int type; - /* container for expression options such as case-insensitiveness */ - /* This is a boolean container. */ - int flags; - - /* logical expression options */ - tokenListNodeObjPtr tokens; - tokenListNodeObjPtr curtoken; - - /* regular expression options */ - ms_regex_t regex; /* compiled regular expression to be matched */ - int compiled; - - char *native_string; /* RFC 91 */ - } expressionObj; - - typedef struct { - colorObj *pixel; /* for raster layers */ - shapeObj *shape; /* for vector layers */ - double dblval; /* for map cellsize used by simplify */ - double dblval2; /* for data cellsize */ - expressionObj *expr; /* expression to be evaluated (contains tokens) */ - int type; /* type of parse: boolean, string/text or shape/geometry */ - parseResultObj result; /* parse result */ - } parseObj; -#endif - - /************************************************************************/ - /* clusterObj */ - /************************************************************************/ +typedef union { + int intval; + char *strval; + shapeObj *shpval; +} parseResultObj; + +typedef union { + double dblval; + int intval; + char *strval; + struct tm tmval; + shapeObj *shpval; + attributeBindingObj bindval; +} tokenValueObj; + +typedef struct tokenListNode { + int token; + tokenValueObj tokenval; + char *tokensrc; /* on occassion we may want to access to the original source + string (e.g. date/time) */ + struct tokenListNode *next; + struct tokenListNode *tailifhead; /* this is the tail node in the list if this + is the head element, otherwise NULL */ +} tokenListNodeObj; + +typedef tokenListNodeObj *tokenListNodeObjPtr; + +typedef struct { + char *string; + int type; + /* container for expression options such as case-insensitiveness */ + /* This is a boolean container. */ + int flags; + + /* logical expression options */ + tokenListNodeObjPtr tokens; + tokenListNodeObjPtr curtoken; + + /* regular expression options */ + ms_regex_t regex; /* compiled regular expression to be matched */ + int compiled; + + char *native_string; /* RFC 91 */ +} expressionObj; + +typedef struct { + colorObj *pixel; /* for raster layers */ + shapeObj *shape; /* for vector layers */ + double dblval; /* for map cellsize used by simplify */ + double dblval2; /* for data cellsize */ + expressionObj *expr; /* expression to be evaluated (contains tokens) */ + int type; /* type of parse: boolean, string/text or shape/geometry */ + parseResultObj result; /* parse result */ +} parseObj; +#endif + +/************************************************************************/ +/* clusterObj */ +/************************************************************************/ /** The :ref:`CLUSTER ` object. See :ref:`RFC 69 `. */ - typedef struct { - double maxdistance; ///< Maximum distance between clusters - see :ref:`MAXDISTANCE ` - double buffer; ///< The buffer size around the selection area - see :ref:`BUFFER ` - char* region; ///< The type of the cluster region (rectangle or ellipse) - see :ref:`REGION ` +typedef struct { + double maxdistance; ///< Maximum distance between clusters - see + ///< :ref:`MAXDISTANCE ` + double buffer; ///< The buffer size around the selection area - see + ///< :ref:`BUFFER ` + char *region; ///< The type of the cluster region (rectangle or ellipse) - see + ///< :ref:`REGION ` #ifndef SWIG - expressionObj group; /* expression to identify the groups */ - expressionObj filter; /* expression for filtering the shapes */ + expressionObj group; /* expression to identify the groups */ + expressionObj filter; /* expression for filtering the shapes */ #endif - } clusterObj; +} clusterObj; - /************************************************************************/ - /* processingParams */ - /************************************************************************/ +/************************************************************************/ +/* processingParams */ +/************************************************************************/ #ifndef SWIG /* Used by idw.c and kerneldensity.c */ - typedef struct { - float normalization_scale; - int expand_searchrect; - int radius; - float power; - } interpolationProcessingParams; +typedef struct { + float normalization_scale; + int expand_searchrect; + int radius; + float power; +} interpolationProcessingParams; #endif - /************************************************************************/ - /* joinObj */ - /* */ - /* simple way to access other XBase files, one-to-one or */ - /* one-to-many supported */ - /************************************************************************/ +/************************************************************************/ +/* joinObj */ +/* */ +/* simple way to access other XBase files, one-to-one or */ +/* one-to-many supported */ +/************************************************************************/ #ifndef SWIG - typedef struct { - char *name; - char **items, **values; /* items/values (process 1 record at a time) */ - int numitems; +typedef struct { + char *name; + char **items, **values; /* items/values (process 1 record at a time) */ + int numitems; - char *table; - char *from, *to; /* item names */ + char *table; + char *from, *to; /* item names */ - void *joininfo; /* vendor specific (i.e. XBase, MySQL, etc.) stuff to allow for persistent access */ + void *joininfo; /* vendor specific (i.e. XBase, MySQL, etc.) stuff to allow + for persistent access */ - char *header, *footer; + char *header, *footer; #ifndef __cplusplus - char *template; + char *template; #else - char *_template; + char *_template; #endif - enum MS_JOIN_TYPE type; - char *connection; - enum MS_JOIN_CONNECTION_TYPE connectiontype; - } joinObj; + enum MS_JOIN_TYPE type; + char *connection; + enum MS_JOIN_CONNECTION_TYPE connectiontype; +} joinObj; #endif - /************************************************************************/ - /* outputFormatObj */ - /* */ - /* see mapoutput.c for most related code. */ - /************************************************************************/ - +/************************************************************************/ +/* outputFormatObj */ +/* */ +/* see mapoutput.c for most related code. */ +/************************************************************************/ + /** The :ref:`OUTPUTFORMAT ` object */ - typedef struct { +typedef struct { #ifndef SWIG - int refcount; - char **formatoptions; - rendererVTableObj *vtable; - void *device; /* for supporting direct rendering onto a device context */ -#endif /* SWIG */ + int refcount; + char **formatoptions; + rendererVTableObj *vtable; + void *device; /* for supporting direct rendering onto a device context */ +#endif /* SWIG */ #ifdef SWIG %immutable; #endif /* SWIG */ - /** - The number of option values set on this format - can be used to - iterate over the options array in conjunction with :func:`outputFormatObj.getOptionAt` - */ - int numformatoptions; + /** + The number of option values set on this format - can be used to + iterate over the options array in conjunction with + :func:`outputFormatObj.getOptionAt` + */ + int numformatoptions; #ifdef SWIG %mutable; -#endif /* SWIG */ - char *name; ///< See :ref:`NAME ` - char *mimetype; ///< See :ref:`MIMETYPE ` - char *driver; ///< See :ref:`DRIVER ` - char *extension; ///< See :ref:`EXTENSION ` - int renderer; ///< A :ref:`render mode constant` - normally set internally based on the driver and some other setting in the constructor. - int imagemode; ///< An :ref:`Image mode constant` - see :ref:`IMAGEMODE ` - int transparent; ///< See :ref:`TRANSPARENT ` - int bands; ///< The number of bands in the raster, normally set via the BAND_COUNT formatoption - this field should be considered read-only - ///< Only used for the "raw" modes, MS_IMAGEMODE_BYTE, MS_IMAGEMODE_INT16, and MS_IMAGEMODE_FLOAT32 - int inmapfile; ///< Boolean value indicating if the format is in the Mapfile - } outputFormatObj; - - /* The following is used for "don't care" values in transparent, interlace and - imagequality values. */ -#define MS_NOOVERRIDE -1111 - - /************************************************************************/ - /* queryObj */ - /* */ - /* encapsulates the information necessary to perform a query */ - /************************************************************************/ +#endif /* SWIG */ + char *name; ///< See :ref:`NAME ` + char *mimetype; ///< See :ref:`MIMETYPE ` + char *driver; ///< See :ref:`DRIVER ` + char *extension; ///< See :ref:`EXTENSION ` + int renderer; ///< A :ref:`render mode constant` - + ///< normally set internally based on the driver and some other + ///< setting in the constructor. + int imagemode; ///< An :ref:`Image mode constant` + ///< - see :ref:`IMAGEMODE ` + int transparent; ///< See :ref:`TRANSPARENT + ///< ` + int bands; ///< The number of bands in the raster, normally set via the + ///< BAND_COUNT formatoption - this field should be considered + ///< read-only Only used for the "raw" modes, MS_IMAGEMODE_BYTE, + ///< MS_IMAGEMODE_INT16, and MS_IMAGEMODE_FLOAT32 + int inmapfile; ///< Boolean value indicating if the format is in the Mapfile +} outputFormatObj; + +/* The following is used for "don't care" values in transparent, interlace and + imagequality values. */ +#define MS_NOOVERRIDE -1111 + +/************************************************************************/ +/* queryObj */ +/* */ +/* encapsulates the information necessary to perform a query */ +/************************************************************************/ #ifndef SWIG - typedef struct { - int type; /* MS_QUERY_TYPE */ - int mode; /* MS_QUERY_MODE */ +typedef struct { + int type; /* MS_QUERY_TYPE */ + int mode; /* MS_QUERY_MODE */ - int layer; + int layer; - pointObj point; /* by point */ - double buffer; - int maxresults; + pointObj point; /* by point */ + double buffer; + int maxresults; - rectObj rect; /* by rect */ - shapeObj *shape; /* by shape & operator (OGC filter) */ + rectObj rect; /* by rect */ + shapeObj *shape; /* by shape & operator (OGC filter) */ - long shapeindex; /* by index */ - long tileindex; - int clear_resultcache; + long shapeindex; /* by index */ + long tileindex; + int clear_resultcache; - int maxfeatures; /* global maxfeatures */ - int startindex; - int only_cache_result_count; /* set to 1 sometimes by WFS 2.0 GetFeature request */ + int maxfeatures; /* global maxfeatures */ + int startindex; + int only_cache_result_count; /* set to 1 sometimes by WFS 2.0 GetFeature + request */ - expressionObj filter; /* by filter */ - char *filteritem; + expressionObj filter; /* by filter */ + char *filteritem; - int slayer; /* selection layer, used for msQueryByFeatures() (note this is not a query mode per se) */ + int slayer; /* selection layer, used for msQueryByFeatures() (note this is not + a query mode per se) */ - int cache_shapes; /* whether to cache shapes in resultCacheObj */ - int max_cached_shape_count; /* maximum number of shapes cached in the total number of resultCacheObj */ - int max_cached_shape_ram_amount; /* maximum number of bytes taken by shapes cached in the total number of resultCacheObj */ - } queryObj; + int cache_shapes; /* whether to cache shapes in resultCacheObj */ + int max_cached_shape_count; /* maximum number of shapes cached in the total + number of resultCacheObj */ + int max_cached_shape_ram_amount; /* maximum number of bytes taken by shapes + cached in the total number of + resultCacheObj */ +} queryObj; #endif - /************************************************************************/ - /* queryMapObj */ - /* */ - /* used to visualize query results */ - /************************************************************************/ +/************************************************************************/ +/* queryMapObj */ +/* */ +/* used to visualize query results */ +/************************************************************************/ /** The :ref:`QUERYMAP ` object. -Instances of querymapObj are always are always embedded inside the :class:`mapObj`. +Instances of querymapObj are always are always embedded inside the +:class:`mapObj`. */ - typedef struct { +typedef struct { #ifdef SWIG %immutable; -#endif /* SWIG */ - struct mapObj *map; ///< Reference to parent :class:`mapObj` +#endif /* SWIG */ + struct mapObj *map; ///< Reference to parent :class:`mapObj` #ifdef SWIG %mutable; -#endif /* SWIG */ - int height; ///< See :ref:`SIZE ` - int width; ///< See :ref:`SIZE ` - int status; ///< See :ref:`STATUS ` - int style; ///< ``HILITE``, ``SELECTED`` or ``NORMAL`` - see :ref:`STYLE ` - colorObj color; ///< See :ref:`COLOR ` - } queryMapObj; - - /************************************************************************/ - /* webObj */ - /* */ - /* holds parameters for a mapserver/mapscript interface */ - /************************************************************************/ +#endif /* SWIG */ + int height; ///< See :ref:`SIZE ` + int width; ///< See :ref:`SIZE ` + int status; ///< See :ref:`STATUS ` + int style; ///< ``HILITE``, ``SELECTED`` or ``NORMAL`` - see :ref:`STYLE + ///< ` + colorObj color; ///< See :ref:`COLOR ` +} queryMapObj; + +/************************************************************************/ +/* webObj */ +/* */ +/* holds parameters for a mapserver/mapscript interface */ +/************************************************************************/ /** The :ref:`WEB ` object. -Has no other existence than as an attribute of a :class:`mapObj`. -Serves as a container for various run-time web application definitions like temporary file paths, template paths, etc. +Has no other existence than as an attribute of a :class:`mapObj`. +Serves as a container for various run-time web application definitions like +temporary file paths, template paths, etc. */ - typedef struct { +typedef struct { #ifdef SWIG %immutable; -#endif /* SWIG */ - hashTableObj metadata; ///< Metadata hash table - see :ref:`METADATA ` - hashTableObj validation; ///< See :ref:`VALIDATION ` - struct mapObj *map; ///< Reference to parent :class:`mapObj` +#endif /* SWIG */ + hashTableObj metadata; ///< Metadata hash table - see :ref:`METADATA + ///< ` + hashTableObj validation; ///< See :ref:`VALIDATION ` + struct mapObj *map; ///< Reference to parent :class:`mapObj` #ifdef SWIG %mutable; #endif /* SWIG */ - char *imagepath; ///< Filesystem path to temporary image location - see :ref:`IMAGEPATH ` - char *imageurl; ///< URL to temporary image location - see :ref:`IMAGEURL ` - char *temppath; ///< See :ref:`TEMPPATH ` - char *header; ///< Path to header document - see :ref:`HEADER ` - char *footer; ///< Path to footer document - see :ref:`FOOTER ` - char *empty; ///< See :ref:`EMPTY ` - char *error; ///< Error handling - see :ref:`ERROR ` - - double minscaledenom; ///< Maximum map scale - see :ref:`MINSCALEDENOM ` - double maxscaledenom; ///< Minimum map scale - see :ref:`MAXSCALEDENOM ` - char *mintemplate; ///< See :ref:`MINTEMPLATE ` - char *maxtemplate; ///< See :ref:`MAXTEMPLATE ` - - char *queryformat; ///< See :ref:`QUERYFORMAT ` /* what format is the query to be returned, given as a MIME type */ - char *legendformat; ///< See :ref:`LEGENDFORMAT ` - char *browseformat; ///< See :ref:`BROWSEFORMAT ` + char *imagepath; ///< Filesystem path to temporary image location - see + ///< :ref:`IMAGEPATH ` + char *imageurl; ///< URL to temporary image location - see :ref:`IMAGEURL + ///< ` + char *temppath; ///< See :ref:`TEMPPATH ` + char *header; ///< Path to header document - see :ref:`HEADER + ///< ` + char *footer; ///< Path to footer document - see :ref:`FOOTER + ///< ` + char *empty; ///< See :ref:`EMPTY ` + char *error; ///< Error handling - see :ref:`ERROR ` + + double minscaledenom; ///< Maximum map scale - see :ref:`MINSCALEDENOM + ///< ` + double maxscaledenom; ///< Minimum map scale - see :ref:`MAXSCALEDENOM + ///< ` + char *mintemplate; ///< See :ref:`MINTEMPLATE ` + char *maxtemplate; ///< See :ref:`MAXTEMPLATE ` + + char *queryformat; ///< See :ref:`QUERYFORMAT ` /* + ///< what format is the query to be returned, given as a + ///< MIME type */ + char *legendformat; ///< See :ref:`LEGENDFORMAT ` + char *browseformat; ///< See :ref:`BROWSEFORMAT ` #ifndef __cplusplus - char *template; ///< Path to template document - see :ref:`TEMPLATE ` + char *template; ///< Path to template document - see :ref:`TEMPLATE + ///< ` #else - char *_template; + char *_template; #endif - } webObj; +} webObj; - /************************************************************************/ - /* styleObj */ - /* */ - /* holds parameters for symbolization, multiple styles may be */ - /* applied within a classObj */ - /************************************************************************/ +/************************************************************************/ +/* styleObj */ +/* */ +/* holds parameters for symbolization, multiple styles may be */ +/* applied within a classObj */ +/************************************************************************/ /** -The :ref:`STYLE \n"); - } else if(nVersion >= OWS_1_1_0) { + } else if (nVersion >= OWS_1_1_0) { if (pszLegendURL) { /* First, print the style block */ msIO_fprintf(stdout, " \n"); } else { if (script_url_encoded) { - if (lp->connectiontype != MS_WMS && - lp->connectiontype != MS_WFS && - lp->connectiontype != MS_UNUSED_1 && - lp->numclasses > 0) { + if (lp->connectiontype != MS_WMS && lp->connectiontype != MS_WFS && + lp->connectiontype != MS_UNUSED_1 && lp->numclasses > 0) { bool classnameset = false; - for (int i=0; inumclasses; i++) { - if (lp->_class[i]->name && - strlen(lp->_class[i]->name) > 0) { + for (int i = 0; i < lp->numclasses; i++) { + if (lp->_class[i]->name && strlen(lp->_class[i]->name) > 0) { classnameset = true; break; } } if (classnameset) { - int size_x=0, size_y=0; + int size_x = 0, size_y = 0; std::vector group_layers; group_layers.reserve(map->numlayers); - char ***nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**)); - int *numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int)); - int* isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int)); - msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup); + char ***nestedGroups = + (char ***)msSmallCalloc(map->numlayers, sizeof(char **)); + int *numNestedGroups = + (int *)msSmallCalloc(map->numlayers, sizeof(int)); + int *isUsedInNestedGroup = + (int *)msSmallCalloc(map->numlayers, sizeof(int)); + msWMSPrepareNestedGroups(map, nVersion, nestedGroups, + numNestedGroups, isUsedInNestedGroup); group_layers.push_back(lp->index); if (isUsedInNestedGroup[lp->index]) { - for (int j=0; j < map->numlayers; j++) { + for (int j = 0; j < map->numlayers; j++) { if (j == lp->index) - continue; - for(int k = 0; k < numNestedGroups[j]; k++) { + continue; + for (int k = 0; k < numNestedGroups[j]; k++) { if (strcasecmp(lp->name, nestedGroups[j][k]) == 0) { group_layers.push_back(j); break; @@ -2449,11 +2668,13 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, } } - if (msLegendCalcSize(map, 1, &size_x, &size_y, group_layers.data(), static_cast(group_layers.size()), NULL, 1) == MS_SUCCESS) { + if (msLegendCalcSize(map, 1, &size_x, &size_y, group_layers.data(), + static_cast(group_layers.size()), NULL, + 1) == MS_SUCCESS) { const std::string width(std::to_string(size_x)); const std::string height(std::to_string(size_y)); - char* mimetype = NULL; + char *mimetype = NULL; #if defined USE_PNG mimetype = msEncodeHTMLEntities("image/png"); #endif @@ -2463,36 +2684,48 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, mimetype = msEncodeHTMLEntities("image/jpeg"); #endif if (!mimetype) - mimetype = msEncodeHTMLEntities(MS_IMAGE_MIME_TYPE(map->outputformat)); - - /* -------------------------------------------------------------------- */ - /* check if the group parameters for the classes are set. We */ - /* should then publish the different class groups as different styles.*/ - /* -------------------------------------------------------------------- */ + mimetype = + msEncodeHTMLEntities(MS_IMAGE_MIME_TYPE(map->outputformat)); + + /* -------------------------------------------------------------------- + */ + /* check if the group parameters for the classes are set. We + */ + /* should then publish the different class groups as + * different styles.*/ + /* -------------------------------------------------------------------- + */ iclassgroups = 0; classgroups = NULL; - const char* styleName = msOWSLookupMetadata(&(map->web.metadata), "MO", "style_name"); + const char *styleName = + msOWSLookupMetadata(&(map->web.metadata), "MO", "style_name"); if (styleName == NULL) styleName = "default"; - char* pszEncodedStyleName = msEncodeHTMLEntities(styleName); + char *pszEncodedStyleName = msEncodeHTMLEntities(styleName); - for (int i=0; inumclasses; i++) { + for (int i = 0; i < lp->numclasses; i++) { if (lp->_class[i]->name && lp->_class[i]->group) { - /* Check that style is not inherited from root layer (#4442). */ - if (strcasecmp(pszEncodedStyleName, lp->_class[i]->group) == 0) + /* Check that style is not inherited from root layer (#4442). + */ + if (strcasecmp(pszEncodedStyleName, lp->_class[i]->group) == + 0) continue; - /* Check that style is not inherited from group layer(s) (#4442). */ + /* Check that style is not inherited from group layer(s) + * (#4442). */ if (numNestedGroups[lp->index] > 0) { - int j=0; + int j = 0; layerObj *lp2 = NULL; - for (; jindex]; j++) { + for (; j < numNestedGroups[lp->index]; j++) { int l = 0; - for (int k=0; k < map->numlayers; k++) { - if (GET_LAYER(map, k)->name && strcasecmp(GET_LAYER(map, k)->name, nestedGroups[lp->index][j]) == 0) { + for (int k = 0; k < map->numlayers; k++) { + if (GET_LAYER(map, k)->name && + strcasecmp(GET_LAYER(map, k)->name, + nestedGroups[lp->index][j]) == 0) { lp2 = (GET_LAYER(map, k)); - for (l=0; l < lp2->numclasses; l++) { - if (strcasecmp(lp2->_class[l]->group, lp->_class[i]->group) == 0) + for (l = 0; l < lp2->numclasses; l++) { + if (strcasecmp(lp2->_class[l]->group, + lp->_class[i]->group) == 0) break; } break; @@ -2506,20 +2739,24 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, } if (!classgroups) { classgroups = (char **)msSmallMalloc(sizeof(char *)); - classgroups[iclassgroups++]= msStrdup(lp->_class[i]->group); + classgroups[iclassgroups++] = + msStrdup(lp->_class[i]->group); } else { /* Output style only once. */ bool found = false; - for (int j=0; j_class[i]->group) == 0) { + for (int j = 0; j < iclassgroups; j++) { + if (strcasecmp(classgroups[j], lp->_class[i]->group) == + 0) { found = true; break; } } if (!found) { iclassgroups++; - classgroups = (char **)msSmallRealloc(classgroups, sizeof(char *)*iclassgroups); - classgroups[iclassgroups-1]= msStrdup(lp->_class[i]->group); + classgroups = (char **)msSmallRealloc( + classgroups, sizeof(char *) * iclassgroups); + classgroups[iclassgroups - 1] = + msStrdup(lp->_class[i]->group); } } } @@ -2527,22 +2764,22 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, msFree(pszEncodedStyleName); if (classgroups == NULL) { classgroups = (char **)msSmallMalloc(sizeof(char *)); - classgroups[0]= msStrdup("default"); + classgroups[0] = msStrdup("default"); iclassgroups = 1; } - for (int i=0; iname); char *classgroup_encoded = msEncodeHTMLEntities(classgroups[i]); std::string legendurl(script_url_encoded); legendurl += "version="; char szVersionBuf[OWS_VERSION_MAXLEN]; legendurl += msOWSGetVersionString(nVersion, szVersionBuf); - legendurl += "&service=WMS&request=GetLegendGraphic&"; + legendurl += + "&service=WMS&request=GetLegendGraphic&"; if (nVersion >= OWS_1_3_0) { legendurl += "sld_version=1.1.0&layer="; - } - else { + } else { legendurl += "layer="; } legendurl += name_encoded; @@ -2555,43 +2792,45 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, msFree(classgroup_encoded); msIO_fprintf(stdout, " \n"); } @@ -2614,12 +2853,14 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, } /* print Min/Max ScaleDenominator */ - if (nVersion < OWS_1_3_0) - msWMSPrintScaleHint(" ", lp->minscaledenom, lp->maxscaledenom, map->resolution); + if (nVersion < OWS_1_3_0) + msWMSPrintScaleHint(" ", lp->minscaledenom, lp->maxscaledenom, + map->resolution); else - msWMSPrintScaleDenominator(" ", lp->minscaledenom, lp->maxscaledenom); + msWMSPrintScaleDenominator(" ", lp->minscaledenom, + lp->maxscaledenom); - if ( grouplayer == MS_FALSE ) + if (grouplayer == MS_FALSE) msIO_printf("%s \n", indent); return MS_SUCCESS; @@ -2628,8 +2869,8 @@ int msDumpLayer(mapObj *map, layerObj *lp, int nVersion, /* * msWMSIsSubGroup */ -static bool msWMSIsSubGroup(char** currentGroups, int currentLevel, char** otherGroups, int numOtherGroups) -{ +static bool msWMSIsSubGroup(char **currentGroups, int currentLevel, + char **otherGroups, int numOtherGroups) { /* no match if otherGroups[] has less levels than currentLevel */ if (numOtherGroups <= currentLevel) { return false; @@ -2646,37 +2887,39 @@ static bool msWMSIsSubGroup(char** currentGroups, int currentLevel, char** other /* * msWMSHasQueryableSubLayers */ -static int msWMSHasQueryableSubLayers(mapObj* map, int index, int level, - char*** nestedGroups, int* numNestedGroups) -{ - for (int j = index; j < map->numlayers; j++) { - if (msWMSIsSubGroup(nestedGroups[index], level, nestedGroups[j], numNestedGroups[j])) { - if( msIsLayerQueryable( GET_LAYER(map,j) ) ) - return MS_TRUE; - } +static int msWMSHasQueryableSubLayers(mapObj *map, int index, int level, + char ***nestedGroups, + int *numNestedGroups) { + for (int j = index; j < map->numlayers; j++) { + if (msWMSIsSubGroup(nestedGroups[index], level, nestedGroups[j], + numNestedGroups[j])) { + if (msIsLayerQueryable(GET_LAYER(map, j))) + return MS_TRUE; } - return MS_FALSE; + } + return MS_FALSE; } /*********************************************************************************** - * msWMSPrintNestedGroups() * + * msWMSPrintNestedGroups() * * * - * purpose: Writes the layers to the capabilities that have the * - * "WMS_LAYER_GROUP" metadata set. * + * purpose: Writes the layers to the capabilities that have the * + * "WMS_LAYER_GROUP" metadata set. * * * - * params: * - * -map: The main map object * - * -nVersion: OGC WMS version * - * -pabLayerProcessed: boolean array indicating which layers have been dealt with. * - * -index: the index of the current layer. * - * -level: the level of depth in the group tree (root = 0) * - * -nestedGroups: This array holds the arrays of groups that have * - * been set through the WMS_LAYER_GROUP metadata * - * -numNestedGroups: This array holds the number of nested groups for each layer * + * params: * -map: The main map object * -nVersion: OGC WMS version * + * -pabLayerProcessed: boolean array indicating which layers have been dealt + *with. * -index: the index of the current layer. * -level: the level of depth + *in the group tree (root = 0) * -nestedGroups: This + *array holds the arrays of groups that have * been set through + *the WMS_LAYER_GROUP metadata * + * -numNestedGroups: This array holds the number of nested groups for each layer + ** ***********************************************************************************/ -void msWMSPrintNestedGroups(mapObj* map, int nVersion, char* pabLayerProcessed, - int index, int level, char*** nestedGroups, int* numNestedGroups, int* isUsedInNestedGroup, const char *script_url_encoded, const char *validated_language) -{ +void msWMSPrintNestedGroups(mapObj *map, int nVersion, char *pabLayerProcessed, + int index, int level, char ***nestedGroups, + int *numNestedGroups, int *isUsedInNestedGroup, + const char *script_url_encoded, + const char *validated_language) { bool groupAdded = false; std::string indent; for (int i = 0; i < level; i++) { @@ -2685,57 +2928,67 @@ void msWMSPrintNestedGroups(mapObj* map, int nVersion, char* pabLayerProcessed, if (numNestedGroups[index] <= level) { /* no more subgroups */ if ((!pabLayerProcessed[index]) && (!isUsedInNestedGroup[index])) { - /* we are at the deepest level of the group branchings, so add layer now. */ - msDumpLayer(map, GET_LAYER(map, index), nVersion, script_url_encoded, indent.c_str(), validated_language, MS_FALSE, MS_FALSE); + /* we are at the deepest level of the group branchings, so add layer now. + */ + msDumpLayer(map, GET_LAYER(map, index), nVersion, script_url_encoded, + indent.c_str(), validated_language, MS_FALSE, MS_FALSE); pabLayerProcessed[index] = 1; /* done */ } - } else { /* not yet there, we have to deal with this group and possible subgroups and layers. */ + } else { /* not yet there, we have to deal with this group and possible + subgroups and layers. */ int j; for (j = 0; j < map->numlayers; j++) { - if ( GET_LAYER(map, j)->name && strcasecmp(GET_LAYER(map, j)->name, nestedGroups[index][level]) == 0 ) { + if (GET_LAYER(map, j)->name && + strcasecmp(GET_LAYER(map, j)->name, nestedGroups[index][level]) == + 0) { break; } } /* Beginning of a new group... enclose the group in a layer block */ - if ( j < map->numlayers ) { + if (j < map->numlayers) { if (!pabLayerProcessed[j]) { msDumpLayer(map, GET_LAYER(map, j), nVersion, script_url_encoded, indent.c_str(), validated_language, MS_TRUE, - msWMSHasQueryableSubLayers(map, index, level, - nestedGroups, numNestedGroups)); + msWMSHasQueryableSubLayers(map, index, level, nestedGroups, + numNestedGroups)); pabLayerProcessed[j] = 1; /* done */ groupAdded = true; } } else { msIO_printf("%s \n", indent.c_str(), - msWMSHasQueryableSubLayers(map, index, level, - nestedGroups, numNestedGroups) ? " queryable=\"1\"" : ""); - msIO_printf("%s %s\n", indent.c_str(), nestedGroups[index][level]); - msIO_printf("%s %s\n", indent.c_str(), nestedGroups[index][level]); + msWMSHasQueryableSubLayers(map, index, level, nestedGroups, + numNestedGroups) + ? " queryable=\"1\"" + : ""); + msIO_printf("%s %s\n", indent.c_str(), + nestedGroups[index][level]); + msIO_printf("%s %s\n", indent.c_str(), + nestedGroups[index][level]); groupAdded = true; } /* Look for one group deeper in the current layer */ if (!pabLayerProcessed[index]) { - msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed, - index, level + 1, nestedGroups, - numNestedGroups, isUsedInNestedGroup, + msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed, index, level + 1, + nestedGroups, numNestedGroups, isUsedInNestedGroup, script_url_encoded, validated_language); } /* look for subgroups in other layers. */ for (j = index + 1; j < map->numlayers; j++) { - if (msWMSIsSubGroup(nestedGroups[index], level, nestedGroups[j], numNestedGroups[j])) { + if (msWMSIsSubGroup(nestedGroups[index], level, nestedGroups[j], + numNestedGroups[j])) { if (!pabLayerProcessed[j]) { - msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed, - j, level + 1, nestedGroups, - numNestedGroups, isUsedInNestedGroup, - script_url_encoded, validated_language); + msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed, j, level + 1, + nestedGroups, numNestedGroups, + isUsedInNestedGroup, script_url_encoded, + validated_language); } } else { /* TODO: if we would sort all layers on "WMS_LAYER_GROUP" beforehand */ - /* we could break out of this loop at this point, which would increase */ + /* we could break out of this loop at this point, which would increase + */ /* performance. */ } } @@ -2748,38 +3001,49 @@ void msWMSPrintNestedGroups(mapObj* map, int nVersion, char* pabLayerProcessed, /* ** msWMSGetCapabilities() */ -static -int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsRequestObj *ows_request, - const char *requested_updatesequence, const char *wms_exception_format, const char *requested_language) -{ - const char* updatesequence = msOWSLookupMetadata(&(map->web.metadata), "MO", "updatesequence"); +static int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, + owsRequestObj *ows_request, + const char *requested_updatesequence, + const char *wms_exception_format, + const char *requested_language) { + const char *updatesequence = + msOWSLookupMetadata(&(map->web.metadata), "MO", "updatesequence"); - const char* sldenabled = msOWSLookupMetadata(&(map->web.metadata), "MO", "sld_enabled"); + const char *sldenabled = + msOWSLookupMetadata(&(map->web.metadata), "MO", "sld_enabled"); if (sldenabled == NULL) sldenabled = "true"; if (requested_updatesequence != NULL) { - int i = msOWSNegotiateUpdateSequence(requested_updatesequence, updatesequence); + int i = + msOWSNegotiateUpdateSequence(requested_updatesequence, updatesequence); if (i == 0) { /* current */ - msSetError(MS_WMSERR, "UPDATESEQUENCE parameter (%s) is equal to server (%s)", "msWMSGetCapabilities()", requested_updatesequence, updatesequence); - return msWMSException(map, nVersion, "CurrentUpdateSequence", wms_exception_format); + msSetError( + MS_WMSERR, "UPDATESEQUENCE parameter (%s) is equal to server (%s)", + "msWMSGetCapabilities()", requested_updatesequence, updatesequence); + return msWMSException(map, nVersion, "CurrentUpdateSequence", + wms_exception_format); } if (i > 0) { /* invalid */ - msSetError(MS_WMSERR, "UPDATESEQUENCE parameter (%s) is higher than server (%s)", "msWMSGetCapabilities()", requested_updatesequence, updatesequence); - return msWMSException(map, nVersion, "InvalidUpdateSequence", wms_exception_format); + msSetError( + MS_WMSERR, "UPDATESEQUENCE parameter (%s) is higher than server (%s)", + "msWMSGetCapabilities()", requested_updatesequence, updatesequence); + return msWMSException(map, nVersion, "InvalidUpdateSequence", + wms_exception_format); } } std::string schemalocation; { - char* pszSchemalocation = msEncodeHTMLEntities( msOWSGetSchemasLocation(map) ); - schemalocation = pszSchemalocation; - msFree(pszSchemalocation); + char *pszSchemalocation = + msEncodeHTMLEntities(msOWSGetSchemasLocation(map)); + schemalocation = pszSchemalocation; + msFree(pszSchemalocation); } if (nVersion < 0) - nVersion = OWS_1_3_0; /* Default to 1.3.0 */ + nVersion = OWS_1_3_0; /* Default to 1.3.0 */ /* Decide which version we're going to return. */ std::string dtd_url; @@ -2811,11 +3075,11 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque /* This function owns validated_language, so remember to free it later*/ std::string validated_language; { - char* pszValidated_language = msOWSGetLanguageFromList(map, "MO", requested_language); - if( pszValidated_language ) - { - validated_language = pszValidated_language; - msMapSetLanguageSpecificConnection(map, pszValidated_language); + char *pszValidated_language = + msOWSGetLanguageFromList(map, "MO", requested_language); + if (pszValidated_language) { + validated_language = pszValidated_language; + msMapSetLanguageSpecificConnection(map, pszValidated_language); } msFree(pszValidated_language); } @@ -2824,9 +3088,10 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque /* Default to use the value of the "onlineresource" metadata, and if not */ /* set then build it: "http://$(SERVER_NAME):$(SERVER_PORT)$(SCRIPT_NAME)?" */ /* the returned string should be freed once we're done with it. */ - char *script_url_encoded=NULL; + char *script_url_encoded = NULL; { - char *script_url = msOWSGetOnlineResource2(map, "MO", "onlineresource", req, validated_language.c_str()); + char *script_url = msOWSGetOnlineResource2(map, "MO", "onlineresource", req, + validated_language.c_str()); if (script_url == NULL || (script_url_encoded = msEncodeHTMLEntities(script_url)) == NULL) { free(script_url); @@ -2835,25 +3100,174 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque free(script_url); } - if (nVersion <= OWS_1_0_7 || nVersion >= OWS_1_3_0) /* 1.0.0 to 1.0.7 and >=1.3.0*/ - msIO_setHeader("Content-Type","text/xml; charset=UTF-8"); + if (nVersion <= OWS_1_0_7 || + nVersion >= OWS_1_3_0) /* 1.0.0 to 1.0.7 and >=1.3.0*/ + msIO_setHeader("Content-Type", "text/xml; charset=UTF-8"); else /* 1.1.0 and later */ - msIO_setHeader("Content-Type","application/vnd.ogc.wms_xml; charset=UTF-8"); + msIO_setHeader("Content-Type", + "application/vnd.ogc.wms_xml; charset=UTF-8"); msIO_sendHeaders(); msIO_printf("\n"); /*TODO review wms1.3.0*/ - if ( nVersion < OWS_1_3_0) { - msIO_printf("web.metadata), "MO", "inspire_capabilities") ) { - msIO_printf("" - " " - "" - "" - "\n"); + if (nVersion == OWS_1_1_1 && msOWSLookupMetadata(&(map->web.metadata), "MO", + "inspire_capabilities")) { + msIO_printf( + "" + " " + "" + "" + "\n"); } else { /* some mapserver specific declarations will go here */ msIO_printf(" \n"); @@ -2863,39 +3277,48 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque } char szVersionBuf[OWS_VERSION_MAXLEN]; - const char* pszVersion = msOWSGetVersionString(nVersion, szVersionBuf); - if ( nVersion >= OWS_1_3_0) + const char *pszVersion = msOWSGetVersionString(nVersion, szVersionBuf); + if (nVersion >= OWS_1_3_0) msIO_printf("web.metadata), "MO", "inspire_capabilities") ) { - msIO_printf(" xmlns:" MS_INSPIRE_COMMON_NAMESPACE_PREFIX "=\"" MS_INSPIRE_COMMON_NAMESPACE_URI "\"" - " xmlns:" MS_INSPIRE_VS_NAMESPACE_PREFIX "=\"" MS_INSPIRE_VS_NAMESPACE_URI "\"" ); + if (msOWSLookupMetadata(&(map->web.metadata), "MO", + "inspire_capabilities")) { + msIO_printf(" xmlns:" MS_INSPIRE_COMMON_NAMESPACE_PREFIX + "=\"" MS_INSPIRE_COMMON_NAMESPACE_URI "\"" + " xmlns:" MS_INSPIRE_VS_NAMESPACE_PREFIX + "=\"" MS_INSPIRE_VS_NAMESPACE_URI "\""); } - msIO_printf(" xsi:schemaLocation=\"http://www.opengis.net/wms %s/wms/%s/capabilities_1_3_0.xsd " - " http://www.opengis.net/sld %s/sld/1.1.0/sld_capabilities.xsd ", - msOWSGetSchemasLocation(map), pszVersion, msOWSGetSchemasLocation(map)); + msIO_printf( + " xsi:schemaLocation=\"http://www.opengis.net/wms " + "%s/wms/%s/capabilities_1_3_0.xsd " + " http://www.opengis.net/sld %s/sld/1.1.0/sld_capabilities.xsd ", + msOWSGetSchemasLocation(map), pszVersion, msOWSGetSchemasLocation(map)); - if ( msOWSLookupMetadata(&(map->web.metadata), "MO", "inspire_capabilities") ) { - char* inspireschemalocation = msEncodeHTMLEntities( msOWSGetInspireSchemasLocation(map) ); + if (msOWSLookupMetadata(&(map->web.metadata), "MO", + "inspire_capabilities")) { + char *inspireschemalocation = + msEncodeHTMLEntities(msOWSGetInspireSchemasLocation(map)); msIO_printf(" " MS_INSPIRE_VS_NAMESPACE_URI " " - " %s%s", inspireschemalocation, MS_INSPIRE_VS_SCHEMA_LOCATION); + " %s%s", + inspireschemalocation, MS_INSPIRE_VS_SCHEMA_LOCATION); free(inspireschemalocation); } - msIO_printf(" http://mapserver.gis.umn.edu/mapserver %sservice=WMS&version=1.3.0&request=GetSchemaExtension\"", - script_url_encoded); + msIO_printf( + " http://mapserver.gis.umn.edu/mapserver " + "%sservice=WMS&version=1.3.0&request=GetSchemaExtension\"", + script_url_encoded); } msIO_printf(">\n"); @@ -2905,34 +3328,37 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque /* Service name is defined by the spec and changed at v1.0.0 */ if (nVersion <= OWS_1_0_7) - msIO_printf(" GetMap\n"); /* v 1.0.0 to 1.0.7 */ + msIO_printf(" GetMap\n"); /* v 1.0.0 to 1.0.7 */ else if (nVersion > OWS_1_0_7 && nVersion < OWS_1_3_0) msIO_printf(" OGC:WMS\n"); /* v 1.1.0 to 1.1.1*/ else msIO_printf(" WMS\n"); /* v 1.3.0+ */ - - /* the majority of this section is dependent on appropriately named metadata in the WEB object */ + /* the majority of this section is dependent on appropriately named metadata + * in the WEB object */ msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "title", - OWS_WARN, " %s\n", map->name, validated_language.c_str()); + OWS_WARN, " %s\n", map->name, + validated_language.c_str()); msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "abstract", - OWS_NOERR, " %s\n", NULL, validated_language.c_str()); + OWS_NOERR, " %s\n", NULL, + validated_language.c_str()); - msWMSPrintKeywordlist(stdout, " ", "keywordlist", &(map->web.metadata), "MO", nVersion); + msWMSPrintKeywordlist(stdout, " ", "keywordlist", &(map->web.metadata), "MO", + nVersion); /* Service/onlineresource */ - /* Defaults to same as request onlineresource if wms_service_onlineresource */ + /* Defaults to same as request onlineresource if wms_service_onlineresource */ /* is not set. */ - if (nVersion== OWS_1_0_0) - msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), - "MO", "service_onlineresource", OWS_NOERR, - " %s\n", - script_url_encoded); + if (nVersion == OWS_1_0_0) + msOWSPrintEncodeMetadata( + stdout, &(map->web.metadata), "MO", "service_onlineresource", OWS_NOERR, + " %s\n", script_url_encoded); else - msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), - "MO", "service_onlineresource", OWS_NOERR, - " \n", - script_url_encoded); + msOWSPrintEncodeMetadata( + stdout, &(map->web.metadata), "MO", "service_onlineresource", OWS_NOERR, + " \n", + script_url_encoded); /* contact information is a required element in 1.0.7 but the */ /* sub-elements such as ContactPersonPrimary, etc. are not! */ @@ -2942,12 +3368,13 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", "fees", OWS_NOERR, " %s\n", NULL); - msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", - "accessconstraints", OWS_NOERR, - " %s\n", NULL); + msOWSPrintEncodeMetadata( + stdout, &(map->web.metadata), "MO", "accessconstraints", OWS_NOERR, + " %s\n", NULL); if (nVersion >= OWS_1_3_0) { - const char* layerlimit = msOWSLookupMetadata(&(map->web.metadata), "MO", "layerlimit"); + const char *layerlimit = + msOWSLookupMetadata(&(map->web.metadata), "MO", "layerlimit"); if (layerlimit) { msIO_printf(" %s\n", layerlimit); } @@ -2962,9 +3389,11 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msIO_printf(" \n"); if (nVersion <= OWS_1_0_7) { - /* WMS 1.0.0 to 1.0.7 - We don't try to use outputformats list here for now */ + /* WMS 1.0.0 to 1.0.7 - We don't try to use outputformats list here for now + */ if (msOWSRequestIsEnabled(map, NULL, "M", "GetMap", MS_FALSE)) - msWMSPrintRequestCap(nVersion, "Map", script_url_encoded, "" + msWMSPrintRequestCap(nVersion, "Map", script_url_encoded, + "" #if defined USE_PNG "" @@ -2972,12 +3401,14 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque #if defined USE_JPEG "" #endif - "" - , NULL); + "", + NULL); if (msOWSRequestIsEnabled(map, NULL, "M", "GetCapabilities", MS_TRUE)) - msWMSPrintRequestCap(nVersion, "Capabilities", script_url_encoded, "", NULL); + msWMSPrintRequestCap(nVersion, "Capabilities", script_url_encoded, + "", NULL); if (msOWSRequestIsEnabled(map, NULL, "M", "GetFeatureInfo", MS_FALSE)) - msWMSPrintRequestCap(nVersion, "FeatureInfo", script_url_encoded, "", NULL); + msWMSPrintRequestCap(nVersion, "FeatureInfo", script_url_encoded, + "", NULL); } else { const char *mime_list[20]; int mime_count = 0; @@ -2988,26 +3419,25 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque if (msOWSRequestIsEnabled(map, NULL, "M", "GetCapabilities", MS_TRUE)) { if (nVersion >= OWS_1_3_0) msWMSPrintRequestCap(nVersion, "GetCapabilities", script_url_encoded, - "text/xml", - NULL); + "text/xml", NULL); else msWMSPrintRequestCap(nVersion, "GetCapabilities", script_url_encoded, - "application/vnd.ogc.wms_xml", - NULL); + "application/vnd.ogc.wms_xml", NULL); } - msGetOutputFormatMimeListWMS(map,mime_list,sizeof(mime_list)/sizeof(char*)); + msGetOutputFormatMimeListWMS(map, mime_list, + sizeof(mime_list) / sizeof(char *)); if (msOWSRequestIsEnabled(map, NULL, "M", "GetMap", MS_FALSE)) - msWMSPrintRequestCap(nVersion, "GetMap", script_url_encoded, - mime_list[0], mime_list[1], mime_list[2], mime_list[3], - mime_list[4], mime_list[5], mime_list[6], mime_list[7], - mime_list[8], mime_list[9], mime_list[10], mime_list[11], - mime_list[12], mime_list[13], mime_list[14], mime_list[15], - mime_list[16], mime_list[17], mime_list[18], mime_list[19], - NULL ); - - const char* format_list = msOWSLookupMetadata(&(map->web.metadata), "M", - "getfeatureinfo_formatlist"); + msWMSPrintRequestCap( + nVersion, "GetMap", script_url_encoded, mime_list[0], mime_list[1], + mime_list[2], mime_list[3], mime_list[4], mime_list[5], mime_list[6], + mime_list[7], mime_list[8], mime_list[9], mime_list[10], + mime_list[11], mime_list[12], mime_list[13], mime_list[14], + mime_list[15], mime_list[16], mime_list[17], mime_list[18], + mime_list[19], NULL); + + const char *format_list = msOWSLookupMetadata(&(map->web.metadata), "M", + "getfeatureinfo_formatlist"); /*feature_info_mime_type depricated for MapServer 6.0*/ if (!format_list) format_list = msOWSLookupMetadata(&(map->web.metadata), "MO", @@ -3015,92 +3445,93 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque if (format_list && strlen(format_list) > 0) { auto tokens = msStringSplit(format_list, ','); - for(auto& token: tokens) { - msStringTrim(token); - /*text plain and gml do not need to be a format and accepted by default*/ - /*can not really validate since the old way of using template - with wei->header, layer->template ... should be kept*/ - if (!token.empty() && mime_countheader, layer->template ... should be kept*/ + if (!token.empty() && mime_count < max_mime) + mime_list[mime_count++] = token.c_str(); } /*add text/plain and gml */ if (strcasestr(format_list, "GML") == 0 && strcasestr(format_list, "application/vnd.ogc.gml") == 0) { - if (mime_count0) { - if (mime_count 0) { + if (mime_count < max_mime) mime_list[mime_count] = NULL; - msWMSPrintRequestCap(nVersion, "GetFeatureInfo", script_url_encoded, - mime_list[0], mime_list[1], mime_list[2], mime_list[3], - mime_list[4], mime_list[5], mime_list[6], mime_list[7], - mime_list[8], mime_list[9], mime_list[10], mime_list[11], - mime_list[12], mime_list[13], mime_list[14], mime_list[15], - mime_list[16], mime_list[17], mime_list[18], mime_list[19], - NULL); + msWMSPrintRequestCap( + nVersion, "GetFeatureInfo", script_url_encoded, mime_list[0], + mime_list[1], mime_list[2], mime_list[3], mime_list[4], + mime_list[5], mime_list[6], mime_list[7], mime_list[8], + mime_list[9], mime_list[10], mime_list[11], mime_list[12], + mime_list[13], mime_list[14], mime_list[15], mime_list[16], + mime_list[17], mime_list[18], mime_list[19], NULL); } /*if all formats given are invalid go to default*/ else msWMSPrintRequestCap(nVersion, "GetFeatureInfo", script_url_encoded, - "text/plain", - "application/vnd.ogc.gml", - NULL); + "text/plain", "application/vnd.ogc.gml", NULL); } } else { if (msOWSRequestIsEnabled(map, NULL, "M", "GetFeatureInfo", MS_FALSE)) msWMSPrintRequestCap(nVersion, "GetFeatureInfo", script_url_encoded, - "text/plain", - "application/vnd.ogc.gml", - NULL); + "text/plain", "application/vnd.ogc.gml", NULL); } - if (strcasecmp(sldenabled, "true") == 0) { if (msOWSRequestIsEnabled(map, NULL, "M", "DescribeLayer", MS_FALSE)) { if (nVersion == OWS_1_3_0) - msWMSPrintRequestCap(nVersion, "sld:DescribeLayer", script_url_encoded, "text/xml", NULL); + msWMSPrintRequestCap(nVersion, "sld:DescribeLayer", + script_url_encoded, "text/xml", NULL); else - msWMSPrintRequestCap(nVersion, "DescribeLayer", script_url_encoded, "text/xml", NULL); + msWMSPrintRequestCap(nVersion, "DescribeLayer", script_url_encoded, + "text/xml", NULL); } - msGetOutputFormatMimeListImg(map,mime_list,sizeof(mime_list)/sizeof(char*)); + msGetOutputFormatMimeListImg(map, mime_list, + sizeof(mime_list) / sizeof(char *)); if (nVersion >= OWS_1_1_1) { const auto isGetLegendGraphicEnabled = msOWSRequestIsEnabled(map, NULL, "M", "GetLegendGraphic", MS_FALSE); if (nVersion == OWS_1_3_0) { if (isGetLegendGraphicEnabled) - msWMSPrintRequestCap(nVersion, "sld:GetLegendGraphic", script_url_encoded, - mime_list[0], mime_list[1], mime_list[2], mime_list[3], - mime_list[4], mime_list[5], mime_list[6], mime_list[7], - mime_list[8], mime_list[9], mime_list[10], mime_list[11], - mime_list[12], mime_list[13], mime_list[14], mime_list[15], - mime_list[16], mime_list[17], mime_list[18], mime_list[19], - NULL ); + msWMSPrintRequestCap( + nVersion, "sld:GetLegendGraphic", script_url_encoded, + mime_list[0], mime_list[1], mime_list[2], mime_list[3], + mime_list[4], mime_list[5], mime_list[6], mime_list[7], + mime_list[8], mime_list[9], mime_list[10], mime_list[11], + mime_list[12], mime_list[13], mime_list[14], mime_list[15], + mime_list[16], mime_list[17], mime_list[18], mime_list[19], + NULL); if (msOWSRequestIsEnabled(map, NULL, "M", "GetStyles", MS_FALSE)) - msWMSPrintRequestCap(nVersion, "ms:GetStyles", script_url_encoded, "text/xml", NULL); + msWMSPrintRequestCap(nVersion, "ms:GetStyles", script_url_encoded, + "text/xml", NULL); } else { if (isGetLegendGraphicEnabled) - msWMSPrintRequestCap(nVersion, "GetLegendGraphic", script_url_encoded, - mime_list[0], mime_list[1], mime_list[2], mime_list[3], - mime_list[4], mime_list[5], mime_list[6], mime_list[7], - mime_list[8], mime_list[9], mime_list[10], mime_list[11], - mime_list[12], mime_list[13], mime_list[14], mime_list[15], - mime_list[16], mime_list[17], mime_list[18], mime_list[19], - NULL ); + msWMSPrintRequestCap( + nVersion, "GetLegendGraphic", script_url_encoded, mime_list[0], + mime_list[1], mime_list[2], mime_list[3], mime_list[4], + mime_list[5], mime_list[6], mime_list[7], mime_list[8], + mime_list[9], mime_list[10], mime_list[11], mime_list[12], + mime_list[13], mime_list[14], mime_list[15], mime_list[16], + mime_list[17], mime_list[18], mime_list[19], NULL); if (msOWSRequestIsEnabled(map, NULL, "M", "GetStyles", MS_FALSE)) - msWMSPrintRequestCap(nVersion, "GetStyles", script_url_encoded, "text/xml", NULL); + msWMSPrintRequestCap(nVersion, "GetStyles", script_url_encoded, + "text/xml", NULL); } } } @@ -3119,15 +3550,17 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msIO_printf(" XML\n"); msIO_printf(" INIMAGE\n"); msIO_printf(" BLANK\n"); - } msIO_printf(" \n"); if (nVersion != OWS_1_3_0) { /* INSPIRE extended capabilities for WMS 1.1.1 */ - if (nVersion == OWS_1_1_1 && msOWSLookupMetadata(&(map->web.metadata), "MO", "inspire_capabilities") ) { + if (nVersion == OWS_1_1_1 && msOWSLookupMetadata(&(map->web.metadata), "MO", + "inspire_capabilities")) { msIO_printf(" \n"); - msOWSPrintInspireCommonExtendedCapabilities(stdout, map, "MO", OWS_WARN, "inspire_vs:ExtendedCapabilities", NULL, validated_language.c_str(), OWS_WMS); + msOWSPrintInspireCommonExtendedCapabilities( + stdout, map, "MO", OWS_WARN, "inspire_vs:ExtendedCapabilities", NULL, + validated_language.c_str(), OWS_WMS); msIO_printf(" \n"); } else { msIO_printf(" \n"); /* nothing yet */ @@ -3138,106 +3571,135 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque if (strcasecmp(sldenabled, "true") == 0) { if (nVersion >= OWS_1_0_7) { if (nVersion >= OWS_1_3_0) - msIO_printf(" \n"); + msIO_printf(" \n"); else - msIO_printf(" \n"); + msIO_printf(" \n"); } } /* INSPIRE extended capabilities for WMS 1.3.0 */ - if (nVersion >= OWS_1_3_0 && msOWSLookupMetadata(&(map->web.metadata), "MO", "inspire_capabilities") ) { - msOWSPrintInspireCommonExtendedCapabilities(stdout, map, "MO", OWS_WARN, "inspire_vs:ExtendedCapabilities", NULL, validated_language.c_str(), OWS_WMS); + if (nVersion >= OWS_1_3_0 && + msOWSLookupMetadata(&(map->web.metadata), "MO", "inspire_capabilities")) { + msOWSPrintInspireCommonExtendedCapabilities( + stdout, map, "MO", OWS_WARN, "inspire_vs:ExtendedCapabilities", NULL, + validated_language.c_str(), OWS_WMS); } /* Top-level layer with map extents and SRS, encloses all map layers */ /* Output only if at least one layers is enabled. */ if (ows_request->numlayers == 0) { - msIO_fprintf(stdout, " \n"); + msIO_fprintf(stdout, " \n"); } else { int root_is_queryable = MS_FALSE; - const char* rootlayer_name = msOWSLookupMetadata(&(map->web.metadata), "MO", "rootlayer_name"); + const char *rootlayer_name = + msOWSLookupMetadata(&(map->web.metadata), "MO", "rootlayer_name"); /* Root layer is queryable if it has a valid name and at list one layer */ /* is queryable */ - if( !rootlayer_name || strlen(rootlayer_name) > 0 ) { + if (!rootlayer_name || strlen(rootlayer_name) > 0) { int j; - for(j=0; jnumlayers; j++) { - layerObj* layer = GET_LAYER(map, j); - if( msIsLayerQueryable(layer) && - msIntegerInArray(layer->index, ows_request->enabled_layers, ows_request->numlayers) ) { + for (j = 0; j < map->numlayers; j++) { + layerObj *layer = GET_LAYER(map, j); + if (msIsLayerQueryable(layer) && + msIntegerInArray(layer->index, ows_request->enabled_layers, + ows_request->numlayers)) { root_is_queryable = MS_TRUE; break; } } } - msIO_printf(" \n",root_is_queryable ? " queryable=\"1\"" : ""); + msIO_printf(" \n", root_is_queryable ? " queryable=\"1\"" : ""); /* Layer Name is optional but title is mandatory. */ if (map->name && strlen(map->name) > 0 && (msIsXMLTagValid(map->name) == MS_FALSE || isdigit(map->name[0]))) - msIO_fprintf(stdout, "\n", + msIO_fprintf(stdout, + "\n", map->name); if (rootlayer_name) { - if (strlen(rootlayer_name) > 0) { - msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", "rootlayer_name", - OWS_NOERR, " %s\n", - NULL); - } - } - else { - msOWSPrintEncodeParam(stdout, "MAP.NAME", map->name, OWS_NOERR, - " %s\n", NULL); + if (strlen(rootlayer_name) > 0) { + msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", + "rootlayer_name", OWS_NOERR, + " %s\n", NULL); + } + } else { + msOWSPrintEncodeParam(stdout, "MAP.NAME", map->name, OWS_NOERR, + " %s\n", NULL); } - if (msOWSLookupMetadataWithLanguage(&(map->web.metadata), "MO", "rootlayer_title", validated_language.c_str())) - msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "rootlayer_title", OWS_WARN, " %s\n", map->name, validated_language.c_str()); + if (msOWSLookupMetadataWithLanguage(&(map->web.metadata), "MO", + "rootlayer_title", + validated_language.c_str())) + msOWSPrintEncodeMetadata2( + stdout, &(map->web.metadata), "MO", "rootlayer_title", OWS_WARN, + " %s\n", map->name, validated_language.c_str()); else - msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "title", OWS_WARN, " %s\n", map->name, validated_language.c_str()); + msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "title", + OWS_WARN, " %s\n", map->name, + validated_language.c_str()); - if (msOWSLookupMetadataWithLanguage(&(map->web.metadata), "MO", "rootlayer_abstract", validated_language.c_str())) - msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "rootlayer_abstract", OWS_NOERR, " %s\n", map->name, validated_language.c_str()); + if (msOWSLookupMetadataWithLanguage(&(map->web.metadata), "MO", + "rootlayer_abstract", + validated_language.c_str())) + msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", + "rootlayer_abstract", OWS_NOERR, + " %s\n", map->name, + validated_language.c_str()); else - msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "abstract", OWS_NOERR, " %s\n", map->name, validated_language.c_str()); - - const char* pszTmp; - if (msOWSLookupMetadata(&(map->web.metadata), "MO", "rootlayer_keywordlist") || - msOWSLookupMetadata(&(map->web.metadata), "MO", "rootlayer_keywordlist_vocabulary")) + msOWSPrintEncodeMetadata2(stdout, &(map->web.metadata), "MO", "abstract", + OWS_NOERR, " %s\n", + map->name, validated_language.c_str()); + + const char *pszTmp; + if (msOWSLookupMetadata(&(map->web.metadata), "MO", + "rootlayer_keywordlist") || + msOWSLookupMetadata(&(map->web.metadata), "MO", + "rootlayer_keywordlist_vocabulary")) pszTmp = "rootlayer_keywordlist"; else pszTmp = "keywordlist"; - msWMSPrintKeywordlist(stdout, " ", pszTmp, &(map->web.metadata), "MO", nVersion); + msWMSPrintKeywordlist(stdout, " ", pszTmp, &(map->web.metadata), "MO", + nVersion); - /* According to normative comments in the 1.0.7 DTD, the root layer's SRS tag */ - /* is REQUIRED. It also suggests that we use an empty SRS element if there */ + /* According to normative comments in the 1.0.7 DTD, the root layer's SRS + * tag */ + /* is REQUIRED. It also suggests that we use an empty SRS element if there + */ /* is no common SRS. */ char *pszMapEPSG; - msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "MO", MS_FALSE, &pszMapEPSG); + msOWSGetEPSGProj(&(map->projection), &(map->web.metadata), "MO", MS_FALSE, + &pszMapEPSG); if (nVersion > OWS_1_1_0) { /* starting 1.1.1 SRS are given in individual tags */ if (nVersion >= OWS_1_3_0) { - msOWSPrintEncodeParamList(stdout, "(at least one of) " + msOWSPrintEncodeParamList(stdout, + "(at least one of) " "MAP.PROJECTION, LAYER.PROJECTION " "or wms_srs metadata", - pszMapEPSG, - OWS_WARN, ' ', NULL, NULL, + pszMapEPSG, OWS_WARN, ' ', NULL, NULL, " %s\n", ""); } else { - msOWSPrintEncodeParamList(stdout, "(at least one of) " + msOWSPrintEncodeParamList(stdout, + "(at least one of) " "MAP.PROJECTION, LAYER.PROJECTION " "or wms_srs metadata", - pszMapEPSG, - OWS_WARN, ' ', NULL, NULL, + pszMapEPSG, OWS_WARN, ' ', NULL, NULL, " %s\n", ""); } } else { - /* If map has no proj then every layer MUST have one or produce a warning */ + /* If map has no proj then every layer MUST have one or produce a warning + */ msOWSPrintEncodeParam(stdout, "MAP.PROJECTION (or wms_srs metadata)", - pszMapEPSG, - OWS_WARN, " %s\n", ""); + pszMapEPSG, OWS_WARN, " %s\n", ""); } msFree(pszMapEPSG); @@ -3248,35 +3710,36 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msOWSPrintLatLonBoundingBox(stdout, " ", &(map->extent), &(map->projection), NULL, OWS_WMS); - msOWSPrintBoundingBox( stdout, " ", &(map->extent), &(map->projection), - NULL, &(map->web.metadata), "MO", nVersion); + msOWSPrintBoundingBox(stdout, " ", &(map->extent), &(map->projection), + NULL, &(map->web.metadata), "MO", nVersion); if (nVersion >= OWS_1_0_7) { msWMSPrintAttribution(stdout, " ", &(map->web.metadata), "MO"); } - /* AuthorityURL support and Identifier support, only available >= WMS 1.1.0 */ - if(nVersion >= OWS_1_1_0) { + /* AuthorityURL support and Identifier support, only available >= WMS 1.1.0 + */ + if (nVersion >= OWS_1_1_0) { msWMSPrintAuthorityURL(stdout, " ", &(map->web.metadata), "MO"); msWMSPrintIdentifier(stdout, " ", &(map->web.metadata), "MO"); } /* MetadataURL */ - if(nVersion >= OWS_1_1_0) + if (nVersion >= OWS_1_1_0) msOWSPrintURLType(stdout, &(map->web.metadata), "MO", "metadataurl", - OWS_NOERR, NULL, "MetadataURL", " type=\"%s\"", - NULL, NULL, ">\n %s\n %s\n ", - MS_TRUE, MS_FALSE, MS_FALSE, MS_TRUE, MS_TRUE, - NULL, NULL, NULL, NULL, NULL, " "); + MS_TRUE, MS_FALSE, MS_FALSE, MS_TRUE, MS_TRUE, NULL, + NULL, NULL, NULL, NULL, " "); /* DataURL */ - if(nVersion < OWS_1_1_0) - msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", "dataurl_href", - OWS_NOERR, " %s\n", - NULL); + if (nVersion < OWS_1_1_0) + msOWSPrintEncodeMetadata(stdout, &(map->web.metadata), "MO", + "dataurl_href", OWS_NOERR, + " %s\n", NULL); else msOWSPrintURLType(stdout, &(map->web.metadata), "MO", "dataurl", OWS_NOERR, NULL, "DataURL", NULL, NULL, NULL, @@ -3284,10 +3747,12 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque "\n \n ", - MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, MS_TRUE, - NULL, NULL, NULL, NULL, NULL, " "); + MS_FALSE, MS_FALSE, MS_FALSE, MS_TRUE, MS_TRUE, NULL, + NULL, NULL, NULL, NULL, " "); - if (map->name && strlen(map->name) > 0 && msOWSLookupMetadata(&(map->web.metadata), "MO", "inspire_capabilities") ) { + if (map->name && strlen(map->name) > 0 && + msOWSLookupMetadata(&(map->web.metadata), "MO", + "inspire_capabilities")) { char *pszEncodedName = NULL; const char *styleName = NULL; char *pszEncodedStyleName = NULL; @@ -3303,41 +3768,42 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque msIO_fprintf(stdout, " \n"); msFree(pszEncodedName); msFree(pszEncodedStyleName); - } - if (nVersion < OWS_1_3_0) - msWMSPrintScaleHint(" ", map->web.minscaledenom, map->web.maxscaledenom, - map->resolution); + if (nVersion < OWS_1_3_0) + msWMSPrintScaleHint(" ", map->web.minscaledenom, + map->web.maxscaledenom, map->resolution); else - msWMSPrintScaleDenominator(" ", map->web.minscaledenom, map->web.maxscaledenom); + msWMSPrintScaleDenominator(" ", map->web.minscaledenom, + map->web.maxscaledenom); /* */ - /* Dump list of layers organized by groups. Layers with no group are listed */ + /* Dump list of layers organized by groups. Layers with no group are listed + */ /* individually, at the same level as the groups in the layer hierarchy */ /* */ if (map->numlayers) { @@ -3402,49 +3867,58 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque int *numNestedGroups = NULL; int *isUsedInNestedGroup = NULL; - /* We'll use this array of booleans to track which layer/group have been */ + /* We'll use this array of booleans to track which layer/group have been + */ /* processed already */ std::vector pabLayerProcessed(map->numlayers); - /* Mark disabled layers as processed to prevent from being displayed in nested groups (#4533)*/ - for(int i=0; inumlayers; i++) { - if (!msIntegerInArray(GET_LAYER(map, i)->index, ows_request->enabled_layers, ows_request->numlayers)) + /* Mark disabled layers as processed to prevent from being displayed in + * nested groups (#4533)*/ + for (int i = 0; i < map->numlayers; i++) { + if (!msIntegerInArray(GET_LAYER(map, i)->index, + ows_request->enabled_layers, + ows_request->numlayers)) pabLayerProcessed[i] = 1; } - nestedGroups = (char***)msSmallCalloc(map->numlayers, sizeof(char**)); - numNestedGroups = (int*)msSmallCalloc(map->numlayers, sizeof(int)); - isUsedInNestedGroup = (int*)msSmallCalloc(map->numlayers, sizeof(int)); - msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, isUsedInNestedGroup); + nestedGroups = (char ***)msSmallCalloc(map->numlayers, sizeof(char **)); + numNestedGroups = (int *)msSmallCalloc(map->numlayers, sizeof(int)); + isUsedInNestedGroup = (int *)msSmallCalloc(map->numlayers, sizeof(int)); + msWMSPrepareNestedGroups(map, nVersion, nestedGroups, numNestedGroups, + isUsedInNestedGroup); - for(int i=0; inumlayers; i++) { + for (int i = 0; i < map->numlayers; i++) { layerObj *lp = (GET_LAYER(map, i)); if (pabLayerProcessed[i] || (lp->status == MS_DELETE)) - continue; /* Layer is hidden or has already been handled */ + continue; /* Layer is hidden or has already been handled */ if (numNestedGroups[i] > 0) { /* Has nested groups. */ msWMSPrintNestedGroups(map, nVersion, pabLayerProcessed.data(), i, 0, - nestedGroups, numNestedGroups, isUsedInNestedGroup, - script_url_encoded, validated_language.c_str()); + nestedGroups, numNestedGroups, + isUsedInNestedGroup, script_url_encoded, + validated_language.c_str()); } else if (lp->group == NULL || strlen(lp->group) == 0) { /* Don't dump layer if it is used in wms_group_layer. */ if (!isUsedInNestedGroup[i]) { /* This layer is not part of a group... dump it directly */ - msDumpLayer(map, lp, nVersion, script_url_encoded, "", validated_language.c_str(), MS_FALSE, MS_FALSE); + msDumpLayer(map, lp, nVersion, script_url_encoded, "", + validated_language.c_str(), MS_FALSE, MS_FALSE); pabLayerProcessed[i] = 1; } } else { bool group_is_queryable = false; /* Group is queryable as soon as its member layers is. */ - for(int j=i; jnumlayers; j++) { + for (int j = i; j < map->numlayers; j++) { if (GET_LAYER(map, j)->group && strcmp(lp->group, GET_LAYER(map, j)->group) == 0 && - msIntegerInArray(GET_LAYER(map, j)->index, ows_request->enabled_layers, ows_request->numlayers) && - msIsLayerQueryable(GET_LAYER(map, j)) ) { - group_is_queryable = true; - break; + msIntegerInArray(GET_LAYER(map, j)->index, + ows_request->enabled_layers, + ows_request->numlayers) && + msIsLayerQueryable(GET_LAYER(map, j))) { + group_is_queryable = true; + break; } } /* Beginning of a new group... enclose the group in a layer block */ @@ -3452,22 +3926,26 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque group_is_queryable ? " queryable=\"1\"" : ""); /* Layer Name is optional but title is mandatory. */ - if (lp->group && strlen(lp->group) > 0 && + if (lp->group && strlen(lp->group) > 0 && (msIsXMLTagValid(lp->group) == MS_FALSE || isdigit(lp->group[0]))) - msIO_fprintf(stdout, "\n", - lp->group); - msOWSPrintEncodeParam(stdout, "GROUP.NAME", lp->group, - OWS_NOERR, " %s\n", NULL); - msOWSPrintGroupMetadata2(stdout, map, lp->group, - "MO", "GROUP_TITLE", OWS_WARN, - " %s\n", lp->group, validated_language.c_str()); - msOWSPrintGroupMetadata2(stdout, map, lp->group, - "MO", "GROUP_ABSTRACT", OWS_NOERR, - " %s\n", lp->group, validated_language.c_str()); + msIO_fprintf( + stdout, + "\n", + lp->group); + msOWSPrintEncodeParam(stdout, "GROUP.NAME", lp->group, OWS_NOERR, + " %s\n", NULL); + msOWSPrintGroupMetadata2(stdout, map, lp->group, "MO", "GROUP_TITLE", + OWS_WARN, " %s\n", + lp->group, validated_language.c_str()); + msOWSPrintGroupMetadata2(stdout, map, lp->group, "MO", + "GROUP_ABSTRACT", OWS_NOERR, + " %s\n", lp->group, + validated_language.c_str()); /*build a getlegendgraphicurl*/ - if( script_url_encoded) { + if (script_url_encoded) { if (lp->group && strlen(lp->group) > 0) { char *pszEncodedName = NULL; const char *styleName = NULL; @@ -3476,56 +3954,61 @@ int msWMSGetCapabilities(mapObj *map, int nVersion, cgiRequestObj *req, owsReque pszEncodedName = msEncodeHTMLEntities(lp->group); - styleName = msOWSLookupMetadata(&(lp->metadata), "MO", "group_style_name"); + styleName = msOWSLookupMetadata(&(lp->metadata), "MO", + "group_style_name"); if (styleName == NULL) styleName = "default"; pszEncodedStyleName = msEncodeHTMLEntities(styleName); msIO_fprintf(stdout, "