diff --git a/Utilities/GDAL/frmts/pgchip/INSTALL b/Utilities/GDAL/frmts/pgchip/INSTALL new file mode 100755 index 0000000000000000000000000000000000000000..36da77dedb55f674388d44333a4dc8048ebea0e6 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/INSTALL @@ -0,0 +1,37 @@ +REQUIREMENTS : + +* Make sure you have a full PostgreSQL/Postgis clean source installation +* You need to have Proj4 installed and configured in Pstgis to get the driver work + + +INSTALL NOTES : + +1* Go to frmts directory under GDAL source tree + +2* Unpack pgchip archive in the frmts directory + +3* Edit GNUMakefile to set your Postgis include path + +4* Add registration entry point declaration : + - Open gdal/gcore/gdal_frmts.h + - Add "void CPL_DLL GDALRegister_PGCHIP(void);" between the CPL_C_START and CPL_C_END tags + +5* Add a call to the registration function in frmts/gdalallregister.c + In the GDALAllRegister() function add the followinf lines : + #ifdef FRMT_pgchip + GDALRegister_PGCHIP(); + #endif + +6* Add the format short name to the GDAL_FORMATS macro in GDALmake.opt.in (and to GDALmake.opt) : + - Locate the variable GDAL_FORMATS and add "pgchip" (lowercase) to the list of formats + +7* Add a format specific item to the EXTRAFLAGS macro in frmts/makefile.vc + +8* Recompile your GDAL library : + - make clean + -./configure + - make + - make install + +9* Test your pgchip installation : + execute gdalinfo --formats and search for pgchip \ No newline at end of file diff --git a/Utilities/GDAL/frmts/pgchip/README b/Utilities/GDAL/frmts/pgchip/README new file mode 100755 index 0000000000000000000000000000000000000000..5fab1f71a0d0fa25524f5f200891c1d1271d1079 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/README @@ -0,0 +1,29 @@ +Important Drivers Restrictions : + + * PGCHIP driver is currently under development which means it has NOT been fully tested and no stable release is downloadable. + + * The driver only supports GDT_Byte and GDT_UInt16 datatypes and deals with 1 or 4 bands (GREY_SCALE, PALETTE and RGBA) + + * The column name for the chip is not yet changeable and is "raster" by default + + * In order to specify the database you want to connect to, you have to give a connection string. The differents connection parameters (host,port,dbname) must be delimited with a "#" character. The name of the Postgis layer should be given at the end of the string after a "%layer=" argument. Example : + + $ gdalinfo PG:host=192.168.1.1#dbname=mydb%layer=myRasterTable + + +How can I test the driver : + + * You can choose to build your own application using the GDAL API or use the utility programs. + * Some examples with gdal_translate : + + Import BMP raster : + gdal_translate -of pgchip /DATA/myRaster.bmp PG:host=192.168.1.1#dbname=mydb#port=5432%layer=myRaster + + Then export to PNG : + gdal_translate -of png -ot UInt16 PG:host=192.168.1.1#dbname=mydb#port=5432%layer=myRaster /DATA/myRaster.png + + +Author information and bug report : + + website : http://simon.benjamin.free.fr/pgchip/ + email : noumayoss@gmail.com diff --git a/Utilities/GDAL/frmts/pgchip/makefile.vc b/Utilities/GDAL/frmts/pgchip/makefile.vc new file mode 100755 index 0000000000000000000000000000000000000000..87a08aea0d8ed488820c2b30ac83aa48182dc9df --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/makefile.vc @@ -0,0 +1,15 @@ + +OBJ = pgChipdataset.obj + +EXTRAFLAGS = -I..\iso8211 + +GDAL_ROOT = ..\.. + +!INCLUDE $(GDAL_ROOT)\nmake.opt + +default: $(OBJ) + copy *.obj ..\o + +clean: + -del *.obj + diff --git a/Utilities/GDAL/frmts/pgchip/pgchip.h b/Utilities/GDAL/frmts/pgchip/pgchip.h new file mode 100755 index 0000000000000000000000000000000000000000..4e428fbd5c80bcee72878e18b80d5c5fb0779f88 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/pgchip.h @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * File : pgchip.h + * Project: PGCHIP Driver + * Purpose: Main header file for POSTGIS CHIP/GDAL Driver + * Author: Benjamin Simon, noumayoss@gmail.com + * + ****************************************************************************** + * Copyright (c) 2005, Benjamin Simon, noumayoss@gmail.com + * + * 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 or substantial portions of the 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. + ****************************************************************************** + * + * Revision 1.1 2005/08/29 bsimon + * New + * + */ + +#include "gdal_priv.h" +#include "libpq-fe.h" +#include "liblwgeom.h" + +// External functions (what's again the reason for using explicit hex form ?) +extern void deparse_hex_string(unsigned char *strOut,char *strIn,int length); +extern void parse_hex_string(unsigned char *strOut,char *strIn,int length); + +/* color types */ +#define PGCHIP_COLOR_TYPE_GRAY 0 +#define PGCHIP_COLOR_TYPE_PALETTE 1 +#define PGCHIP_COLOR_TYPE_RGB_ALPHA 4 + +//pg_chip color struct +typedef struct pgchip_color_nohex_struct +{ + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; +} pgchip_color; + + +/************************************************************************/ +/* ==================================================================== */ +/* PGCHIPDataset */ +/* ==================================================================== */ +/************************************************************************/ + +class PGCHIPRasterBand; + +class PGCHIPDataset : public GDALDataset{ + + friend class PGCHIPRasterBand; + + PGconn *hPGConn; + char *pszConnectionString; + char *pszDBName; + char *pszName; + char *pszProjection; + int bHavePostGIS; + + CHIP *PGCHIP; + int SRID; + int nBitDepth; + + int nColorType; /* PGHIP_COLOR_TYPE_* */ + GDALColorTable *poColorTable; + int bHaveNoData; + double dfNoDataValue; + + double adfGeoTransform[6]; + int bGeoTransformValid; + + public: + + PGCHIPDataset(); + ~PGCHIPDataset(); + + static GDALDataset *Open( GDALOpenInfo * ); + + void printChipInfo(); + + CPLErr GetGeoTransform( double * padfTransform ); + virtual CPLErr SetGeoTransform( double * ); + + CPLErr SetProjection( const char *); + const char *GetProjectionRef(); +}; + +/************************************************************************/ +/* ==================================================================== */ +/* PGCHIPRasterBand */ +/* ==================================================================== */ +/************************************************************************/ + +class PGCHIPRasterBand : public GDALRasterBand{ + + friend class PGCHIPDataset; + + public: + + PGCHIPRasterBand( PGCHIPDataset *, int ); + + virtual CPLErr IReadBlock( int, int, void * ); + virtual GDALColorInterp GetColorInterpretation(); + virtual GDALColorTable *GetColorTable(); + +}; diff --git a/Utilities/GDAL/frmts/pgchip/pgchipdataset.cpp b/Utilities/GDAL/frmts/pgchip/pgchipdataset.cpp new file mode 100755 index 0000000000000000000000000000000000000000..5def63f11b440e2add6575aae0c286b06b930cc7 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/pgchipdataset.cpp @@ -0,0 +1,1074 @@ +/****************************************************************************** + * + * File : pgchipdataset.cpp + * Project: PGCHIP Driver + * Purpose: GDALDataset code for POSTGIS CHIP/GDAL Driver + * Author: Benjamin Simon, noumayoss@gmail.com + * + ****************************************************************************** + * Copyright (c) 2005, Benjamin Simon, noumayoss@gmail.com + * + * 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 or substantial portions of the 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. + ****************************************************************************** + * + * Revision 1.1 2005/08/29 bsimon + * New + * + */ + +#include "pgchip.h" + + +CPL_C_START +void GDALRegister_PGCHIP(void); +CPL_C_END + + +/************************************************************************/ +/* ==================================================================== */ +/* PGCHIPDataset */ +/* ==================================================================== */ +/************************************************************************/ + + +/************************************************************************/ +/* PGCHIPDataset() */ +/************************************************************************/ + +PGCHIPDataset::PGCHIPDataset(){ + + hPGConn = NULL; + pszConnectionString = NULL; + pszDBName = NULL; + pszName = NULL; + bHavePostGIS = FALSE; + PGCHIP = NULL; + + bGeoTransformValid = FALSE; + adfGeoTransform[0] = 0.0; + adfGeoTransform[1] = 1.0; + adfGeoTransform[2] = 0.0; + adfGeoTransform[3] = 0.0; + adfGeoTransform[4] = 0.0; + adfGeoTransform[5] = 1.0; + + SRID = -1; + pszProjection = CPLStrdup(""); + + bHaveNoData = FALSE; + dfNoDataValue = -1; +} + +/************************************************************************/ +/* ~PGCHIPDataset() */ +/************************************************************************/ + +PGCHIPDataset::~PGCHIPDataset(){ + + CPLFree(pszProjection); + CPLFree(pszConnectionString); + CPLFree(pszDBName); + CPLFree(pszName); + + + if(PGCHIP->data) + CPLFree(PGCHIP->data); + + if(PGCHIP) + CPLFree(PGCHIP); + +} + +/************************************************************************/ +/* GetGeoTransform() */ +/************************************************************************/ + +CPLErr PGCHIPDataset::GetGeoTransform( double * padfTransform ){ + + memcpy( padfTransform, adfGeoTransform, sizeof(adfGeoTransform[0]) * 6 ); + + if( bGeoTransformValid ) + return CE_None; + else + return CE_Failure; +} + + + +/************************************************************************/ +/* SetGeoTransform() */ +/************************************************************************/ + +CPLErr PGCHIPDataset::SetGeoTransform( double * padfTransform ){ + + CPLErr eErr = CE_None; + + memcpy( adfGeoTransform, padfTransform, sizeof(double) * 6 ); + + if ( pszConnectionString && bGeoTransformValid ) + { + + /* NOT YET AVAILABLE */ + + } + + return eErr; +} + + +/************************************************************************/ +/* GetProjectionRef() */ +/************************************************************************/ + +const char *PGCHIPDataset::GetProjectionRef(){ + + char szCommand[1024]; + PGconn *hPGConn; + PGresult *hResult; + int SRID = -1; + + hPGConn = this->hPGConn; + + SRID = this->PGCHIP->SRID; + +/* -------------------------------------------------------------------- */ +/* Reading proj */ +/* -------------------------------------------------------------------- */ + + sprintf( szCommand,"SELECT srtext FROM spatial_ref_sys where SRID=%d",SRID); + + hResult = PQexec(hPGConn,szCommand); + + if(SRID == -1) { + return ""; + } + else if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ){ + + pszProjection = CPLStrdup(PQgetvalue(hResult,0,0)); + + return( pszProjection ); + } + + if( hResult ) + PQclear( hResult ); + + return NULL; +} + + +/************************************************************************/ +/* SetProjection() */ +/************************************************************************/ + +CPLErr PGCHIPDataset::SetProjection( const char * pszNewProjection ){ + + char szCommand[1024]; + PGconn *hPGConn; + PGresult *hResult; + + hPGConn = this->hPGConn; + + + if( !EQUALN(pszNewProjection,"GEOGCS",6) + && !EQUALN(pszNewProjection,"PROJCS",6) + && !EQUALN(pszProjection,"+",1) + && !EQUAL(pszNewProjection,"") ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "Only OGC WKT Projections supported for writing to Postgis.\n" + "%s not supported.", + pszNewProjection ); + + return CE_Failure; + } + + CPLFree( pszProjection ); + +/* -------------------------------------------------------------------- */ +/* Reading SRID */ +/* -------------------------------------------------------------------- */ + + this->SRID = -1; + + if( pszNewProjection[0]=='+') + sprintf( szCommand,"SELECT SRID FROM spatial_ref_sys where proj4text=%s",pszNewProjection); + else + sprintf( szCommand,"SELECT SRID FROM spatial_ref_sys where srtext=%s",pszNewProjection); + + + hResult = PQexec(hPGConn,szCommand); + + + if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ){ + + this->SRID = atoi(PQgetvalue(hResult,0,0)); + + pszProjection = CPLStrdup( pszNewProjection ); + + PQclear( hResult ); + + return CE_None; + } + + // Try to find SRID via EPSG number + if (this->SRID == -1 && strcmp(pszNewProjection,"")!=0){ + + char *buf; + char epsg[16]; + memset(epsg,0,16); + char *workingproj = (char *)pszNewProjection; + + while( (buf = strstr(workingproj,"EPSG")) != 0){ + workingproj = buf+4; + } + + int iChar = 0; + workingproj = workingproj + 3; + + while(workingproj[iChar] != '"'){ + epsg[iChar] = workingproj[iChar]; + iChar++; + } + + if(epsg[0] != 0){ + this->SRID = atoi(epsg); + pszProjection = CPLStrdup(pszNewProjection); + } + + return CE_None; + } + else{ + + CPLError( CE_Failure, CPLE_AppDefined, + "Projection %s not found in spatial_ref_sys table.\n", + pszNewProjection ); + + this->SRID = -1; + pszProjection = CPLStrdup(""); + + if( hResult ) + PQclear( hResult ); + + return CE_Failure; + } +} + + + +/************************************************************************/ +/* Open() */ +/************************************************************************/ + +GDALDataset *PGCHIPDataset::Open( GDALOpenInfo * poOpenInfo ){ + + char szCommand[1024]; + PGresult *hResult = NULL; + PGCHIPDataset *poDS = NULL; + char *chipStringHex; + + unsigned char *chipdata; + char *layerName; + int t; + + + /* Chek Postgis connection string */ + if( poOpenInfo->pszFilename == NULL) + return NULL; + +/* -------------------------------------------------------------------- */ +/* Create a corresponding GDALDataset. */ +/* -------------------------------------------------------------------- */ + + poDS = new PGCHIPDataset(); + poDS->pszConnectionString = CPLStrdup(poOpenInfo->pszFilename); + layerName = CPLStrdup(poOpenInfo->pszFilename); + +/* -------------------------------------------------------------------- */ +/* Verify postgresql prefix. */ +/* -------------------------------------------------------------------- */ + if( !EQUALN(poDS->pszConnectionString,"PG:",3) ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "%s does not conform to PostgreSQL naming convention," + " PG:*\n" ); + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Try to establish connection. */ +/* -------------------------------------------------------------------- */ + int i=0; + while(poDS->pszConnectionString[i] != '\0'){ + + if(poDS->pszConnectionString[i] == '#') + poDS->pszConnectionString[i] = ' '; + if(poDS->pszConnectionString[i] == '%') + poDS->pszConnectionString[i] = '\0'; + i++; + } + + + poDS->hPGConn = PQconnectdb( poDS->pszConnectionString + 3 ); + + if( poDS->hPGConn == NULL || PQstatus(poDS->hPGConn) == CONNECTION_BAD ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "PGconnectcb failed.\n%s", + PQerrorMessage(poDS->hPGConn) ); + PQfinish(poDS->hPGConn); + poDS->hPGConn = NULL; + return NULL; + } + + +/* -------------------------------------------------------------------- */ +/* Try to establish the database name from the connection */ +/* string passed. */ +/* -------------------------------------------------------------------- */ + if( strstr(poDS->pszConnectionString, "dbname=") != NULL ) + { + int i; + + poDS->pszDBName = CPLStrdup( strstr(poDS->pszConnectionString, "dbname=") + 7 ); + + for( i = 0; poDS->pszDBName[i] != '\0'; i++ ) + { + if( poDS->pszDBName[i] == ' ' ) + { + poDS->pszDBName[i] = '\0'; + break; + } + } + } + else if( getenv( "USER" ) != NULL ) + poDS->pszDBName = CPLStrdup( getenv("USER") ); + else + poDS->pszDBName = CPLStrdup( "unknown_dbname" ); + + +/* -------------------------------------------------------------------- */ +/* Test to see if this database instance has support for the */ +/* PostGIS Geometry type. If so, disable sequential scanning */ +/* so we will get the value of the gist indexes. */ +/* -------------------------------------------------------------------- */ + + + hResult = PQexec(poDS->hPGConn, + "SELECT oid FROM pg_type WHERE typname = 'geometry'" ); + + + if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ) + { + poDS->bHavePostGIS = TRUE; + } + + if( hResult ) + PQclear( hResult ); + + if(!poDS->bHavePostGIS){ + CPLError( CE_Failure, CPLE_AppDefined, + "Can't find geometry type, is Postgis correctly installed ?\n"); + return NULL; + } + + +/* -------------------------------------------------------------------- */ +/* try opening the layer */ +/* -------------------------------------------------------------------- */ + + if( strstr(layerName, "layer=") != NULL ) + { + poDS->pszName = CPLStrdup( strstr(layerName, "layer=") + 6 ); + } + else + poDS->pszName = CPLStrdup("unknown_layer"); + + +/* -------------------------------------------------------------------- */ +/* Read the chip header */ +/* -------------------------------------------------------------------- */ + + + hResult = PQexec(poDS->hPGConn, "BEGIN"); + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) + { + PQclear( hResult ); + sprintf( szCommand, + "SELECT raster FROM %s", + poDS->pszName); + + hResult = PQexec(poDS->hPGConn,szCommand); + } + + + if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "%s", PQerrorMessage(poDS->hPGConn) ); + return NULL; + } + + chipStringHex = PQgetvalue(hResult, 0, 0); + int stringlen = strlen((char *)chipStringHex); + + // Allocating memory for chip + chipdata = (unsigned char *) CPLMalloc(stringlen/2); + + for (t=0;t<stringlen/2;t++){ + chipdata[t] = parse_hex( &chipStringHex[t*2]) ; + } + + // Chip assigment + poDS->PGCHIP = (CHIP *)chipdata; + + if( hResult ) + PQclear( hResult ); + + hResult = PQexec(poDS->hPGConn, "COMMIT"); + PQclear( hResult ); + + +/* -------------------------------------------------------------------- */ +/* Set some information from the file that is of interest. */ +/* -------------------------------------------------------------------- */ + + poDS->nRasterXSize = poDS->PGCHIP->width; + poDS->nRasterYSize = poDS->PGCHIP->height; + poDS->nBands = (int)poDS->PGCHIP->future[0]; + poDS->nBitDepth = (int)poDS->PGCHIP->future[1]; + poDS->nColorType = (int)poDS->PGCHIP->future[2]; + + +/* -------------------------------------------------------------------- */ +/* Create band information objects. */ +/* -------------------------------------------------------------------- */ + for( int iBand = 0; iBand < poDS->nBands; iBand++ ) + poDS->SetBand( iBand+1, new PGCHIPRasterBand( poDS, iBand+1 ) ); + + +/* -------------------------------------------------------------------- */ +/* Is there a palette? Note: we should also read back and */ +/* apply transparency values if available. */ +/* -------------------------------------------------------------------- */ + if( poDS->nColorType == PGCHIP_COLOR_TYPE_PALETTE ) + { + unsigned char *pPalette; + int nColorCount = 0; + int sizePalette = 0; + int offsetColor = -1; + GDALColorEntry oEntry; + + nColorCount = (int)poDS->PGCHIP->compression; + pPalette = (unsigned char *)chipdata + sizeof(CHIP); + sizePalette = nColorCount * sizeof(pgchip_color); + + poDS->poColorTable = new GDALColorTable(); + + for( int iColor = 0; iColor < nColorCount; iColor++ ) + { + oEntry.c1 = pPalette[offsetColor++]; + oEntry.c2 = pPalette[offsetColor++]; + oEntry.c3 = pPalette[offsetColor++]; + oEntry.c4 = pPalette[offsetColor++]; + + poDS->poColorTable->SetColorEntry( iColor, &oEntry ); + } + } + + return( poDS ); +} + + +/************************************************************************/ +/* PGCHIPCreateCopy() */ +/************************************************************************/ +static GDALDataset * PGCHIPCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, + int bStrict, char ** papszOptions, + GDALProgressFunc pfnProgress, void * pProgressData ){ + + + PGconn *hPGConn; + char *pszConnectionString; + char *pszDBName; + char *pszName; + int bHavePostGIS; + char *szCommand; + PGresult *hResult; + char *layerName; + char *pszProjection; + int SRID; + GDALColorTable *poCT= NULL; + + int nXSize = poSrcDS->GetRasterXSize(); + int nYSize = poSrcDS->GetRasterYSize(); + int nBands = poSrcDS->GetRasterCount(); + + +/* -------------------------------------------------------------------- */ +/* Some some rudimentary checks */ +/* -------------------------------------------------------------------- */ + + /* check number of bands */ + if( nBands != 1 && nBands != 4) + { + CPLError( CE_Failure, CPLE_NotSupported, + "Under development : PGCHIP driver doesn't support %d bands. Must be 1 or 4\n", nBands ); + + return NULL; + } + + + if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte + && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16) + { + CPLError( CE_Failure, CPLE_NotSupported, + "Under development : PGCHIP driver doesn't support data type %s. " + "Only eight bit (Byte) and sixteen bit (UInt16) bands supported.\n", + GDALGetDataTypeName( + poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); + + return NULL; + } + + /* Check Postgis connection string */ + if( pszFilename == NULL){ + CPLError( CE_Failure, CPLE_NotSupported, + "Connection string is NULL.\n"); + return NULL; + } + + +/* -------------------------------------------------------------------- */ +/* Setup some parameters. */ +/* -------------------------------------------------------------------- */ + + int nBitDepth; + GDALDataType eType; + int storageChunk; + int nColorType=0; + + + if( nBands == 1 && poSrcDS->GetRasterBand(1)->GetColorTable() == NULL ){ + nColorType = PGCHIP_COLOR_TYPE_GRAY; + } + else if( nBands == 1 ){ + nColorType = PGCHIP_COLOR_TYPE_PALETTE; + } + else if( nBands == 4 ){ + nColorType = PGCHIP_COLOR_TYPE_RGB_ALPHA; + } + + if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16 ) + { + eType = GDT_Byte; + nBitDepth = 8; + } + else + { + eType = GDT_UInt16; + nBitDepth = 16; + } + + storageChunk = nBitDepth/8; + + printf("nBands = %d, nBitDepth = %d\n",nBands,nBitDepth); + +/* -------------------------------------------------------------------- */ +/* Verify postgresql prefix. */ +/* -------------------------------------------------------------------- */ + + if( !EQUALN(pszFilename,"PG:",3) ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "%s does not conform to PostgreSQL naming convention," + " PG:*\n" ); + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Try to establish connection. */ +/* -------------------------------------------------------------------- */ + + pszConnectionString = CPLStrdup(pszFilename); + layerName = CPLStrdup(pszFilename); + + int i=0; + while(pszConnectionString[i] != '\0'){ + + if(pszConnectionString[i] == '#') + pszConnectionString[i] = ' '; + + i++; + } + + hPGConn = PQconnectdb( pszConnectionString + 3 ); + + if( hPGConn == NULL || PQstatus(hPGConn) == CONNECTION_BAD ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "PGconnectcb failed.\n%s", + PQerrorMessage(hPGConn) ); + PQfinish(hPGConn); + hPGConn = NULL; + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Try to establish the database name from the connection */ +/* string passed. */ +/* -------------------------------------------------------------------- */ + + if( strstr(pszFilename, "dbname=") != NULL ) + { + int i; + + pszDBName = CPLStrdup( strstr(pszFilename, "dbname=") + 7 ); + + for( i = 0; pszDBName[i] != '\0'; i++ ) + { + if( pszDBName[i] == ' ' ) + { + pszDBName[i] = '\0'; + break; + } + } + } + else if( getenv( "USER" ) != NULL ) + pszDBName = CPLStrdup( getenv("USER") ); + else + pszDBName = CPLStrdup( "unknown_dbname" ); + + +/* -------------------------------------------------------------------- */ +/* Test to see if this database instance has support for the */ +/* PostGIS Geometry type. If so, disable sequential scanning */ +/* so we will get the value of the gist indexes. */ +/* -------------------------------------------------------------------- */ + + hResult = PQexec(hPGConn, "BEGIN"); + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) + { + PQclear( hResult ); + + hResult = PQexec(hPGConn, + "SELECT oid FROM pg_type WHERE typname = 'geometry'" ); + } + + if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ) + { + bHavePostGIS = TRUE; + } + else { + CPLError( CE_Failure, CPLE_AppDefined, + "You don't seem to have Postgis installed. Check your settings.\n"); + return NULL; + } + + if( hResult ) + PQclear( hResult ); + + + hResult = PQexec(hPGConn, "COMMIT"); + PQclear( hResult ); + + +/* -------------------------------------------------------------------- */ +/* try opening Postgis Raster Layer */ +/* -------------------------------------------------------------------- */ + + if( strstr(layerName, "layer=") != NULL ) + { + pszName = CPLStrdup( strstr(layerName, "layer=") + 6 ); + } + else + pszName = CPLStrdup("unknown_layer"); + + CPLFree(layerName); + + + // First allocation is small + szCommand = (char *)CPLMalloc(1024); + + hResult = PQexec(hPGConn, "BEGIN"); + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) + { + int bTableExists = FALSE; + + PQclear( hResult ); + sprintf( szCommand, + "select b.attname from pg_class a,pg_attribute b where a.oid=b.attrelid and a.relname='%s' and b.attname='raster';", + pszName); + + hResult = PQexec(hPGConn,szCommand); + + if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ){ + bTableExists = TRUE; + } + + if(!bTableExists){ + PQclear( hResult ); + sprintf( szCommand, + "CREATE TABLE %s(raster chip)", + pszName); + + hResult = PQexec(hPGConn,szCommand); + } + } + + if( hResult && (PQresultStatus(hResult) == PGRES_COMMAND_OK || PQresultStatus(hResult) == PGRES_TUPLES_OK)){ + PQclear( hResult ); + } + else { + CPLError( CE_Failure, CPLE_AppDefined, + "%s", PQerrorMessage(hPGConn) ); + CPLFree(szCommand); + return NULL; + } + + hResult = PQexec(hPGConn, "COMMIT"); + PQclear( hResult ); + + +/* -------------------------------------------------------------------- */ +/* Projection, finding SRID */ +/* -------------------------------------------------------------------- */ + + pszProjection = (char *)poSrcDS->GetProjectionRef(); + SRID = -1; + + if( !EQUALN(pszProjection,"GEOGCS",6) + && !EQUALN(pszProjection,"PROJCS",6) + && !EQUALN(pszProjection,"+",6) + && !EQUAL(pszProjection,"") ) + { + CPLError( CE_Failure, CPLE_AppDefined, + "Only OGC WKT Projections supported for writing to Postgis.\n" + "%s not supported.", + pszProjection ); + } + + + if( pszProjection[0]=='+') + sprintf( szCommand,"SELECT SRID FROM spatial_ref_sys where proj4text=%s",pszProjection); + else + sprintf( szCommand,"SELECT SRID FROM spatial_ref_sys where srtext=%s",pszProjection); + + hResult = PQexec(hPGConn,szCommand); + + if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK + && PQntuples(hResult) > 0 ){ + + SRID = atoi(PQgetvalue(hResult,0,0)); + + } + + // Try to find SRID via EPSG number + if (SRID == -1 && strcmp(pszProjection,"") != 0){ + + char *buf; + char epsg[16]; + memset(epsg,0,16); + char *workingproj = CPLStrdup( pszProjection ); + + while( (buf = strstr(workingproj,"EPSG")) != 0){ + workingproj = buf+4; + } + + int iChar = 0; + workingproj = workingproj + 3; + + + while(workingproj[iChar] != '"'){ + epsg[iChar] = workingproj[iChar]; + iChar++; + } + + if(epsg[0] != 0){ + SRID = atoi(epsg); + } + } + else{ + CPLError( CE_Failure, CPLE_AppDefined, + "Projection %s not found in spatial_ref_sys table. SRID will be set to -1.\n", + pszProjection ); + + SRID = -1; + } + + if( hResult ) + PQclear( hResult ); + + +/* -------------------------------------------------------------------- */ +/* Write palette if there is one. Technically, I think it is */ +/* possible to write 16bit palettes for PNG, but we will omit */ +/* this for now. */ +/* -------------------------------------------------------------------- */ + + unsigned char *pPalette = NULL; + int bHaveNoData = FALSE; + double dfNoDataValue = -1; + int nbColors = 0,bFoundTrans = FALSE; + int sizePalette = 0; + + if( nColorType == PGCHIP_COLOR_TYPE_PALETTE ) + { + + GDALColorEntry sEntry; + int iColor; + int offsetColor = -1; + + poCT = poSrcDS->GetRasterBand(1)->GetColorTable(); + nbColors = poCT->GetColorEntryCount(); + + sizePalette += sizeof(pgchip_color) * poCT->GetColorEntryCount(); + + pPalette = (unsigned char *) CPLMalloc(sizePalette); + + + for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ ) + { + poCT->GetColorEntryAsRGB( iColor, &sEntry ); + if( sEntry.c4 != 255 ) + bFoundTrans = TRUE; + + pPalette[offsetColor++] = (unsigned char) sEntry.c1; + pPalette[offsetColor++] = (unsigned char) sEntry.c2; + pPalette[offsetColor++] = (unsigned char) sEntry.c3; + + + if( bHaveNoData && iColor == (int) dfNoDataValue ){ + pPalette[offsetColor++] = 0; + } + else{ + pPalette[offsetColor++] = (unsigned char) sEntry.c4; + } + } + } + + +/* -------------------------------------------------------------------- */ +/* Initialize CHIP Structure */ +/* -------------------------------------------------------------------- */ + + CHIP PGCHIP; + + memset(&PGCHIP,0,sizeof(PGCHIP)); + + PGCHIP.factor = 1.0; + PGCHIP.endian_hint = 1; + PGCHIP.compression = nbColors; // To cope with palette extra information : <header><palette><data> + PGCHIP.height = nYSize; + PGCHIP.width = nXSize; + PGCHIP.SRID = SRID; + PGCHIP.future[0] = nBands; //nBands is stored in future variable + PGCHIP.future[1] = nBitDepth; //nBitDepth is stored in future variable + PGCHIP.future[2] = nColorType; //nBitDepth is stored in future variable + PGCHIP.future[3] = nbColors; // Useless as we store nbColors in the "compression" integer + PGCHIP.data = NULL; // Serialized Form + + // PGCHIP.size changes if there is a palette. + // Is calculated by Postgis when inserting anyway + PGCHIP.size = sizeof(CHIP) + (nYSize * nXSize * storageChunk * nBands) + sizePalette; + + switch(storageChunk*nBands){ + case 1 : + PGCHIP.datatype = 8; + break; + case 2 : + PGCHIP.datatype = 6; + break; + case 4 : + // Postgis sets data_size to 4 by default anyway + PGCHIP.datatype = 0; + break; + default : + CPLError( CE_Failure, CPLE_AppDefined,"Under development : ERROR STORAGE CHUNK SIZE NOT SUPPORTED\n"); + break; + } + + +/* -------------------------------------------------------------------- */ +/* Loop over image */ +/* -------------------------------------------------------------------- */ + + CPLErr eErr; + int lineSize = nXSize * storageChunk * nBands; + + // allocating data buffer + GByte *data = (GByte *) CPLMalloc( nYSize * lineSize); + + for( int iLine = 0; iLine < nYSize; iLine++ ){ + for( int iBand = 0; iBand < nBands; iBand++ ){ + + GDALRasterBand * poBand = poSrcDS->GetRasterBand( iBand+1 ); + + eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, + data + (iBand*storageChunk) + iLine * lineSize, + nXSize, 1, eType, + nBands * storageChunk, + lineSize ); + } + } + + +/* -------------------------------------------------------------------- */ +/* Write Header, Palette and Data */ +/* -------------------------------------------------------------------- */ + + char *result; + int j=0; + + // Calculating result length (*2 -> Hex form, +1 -> end string) + int size_result = (PGCHIP.size * 2) + 1; + + // memory allocation + result = (char *) CPLMalloc( size_result * sizeof(char)); + + // Assign chip + GByte *header = (GByte *)&PGCHIP; + + // Copy header into result string + for(j=0;j<(int)sizeof(PGCHIP);j++){ + deparse_hex( ((unsigned char *) header)[j], (unsigned char *)&result[j*2]); + } + + // Copy Palette into result string if required + int offsetPalette = (int)sizeof(PGCHIP) * 2; + if(nColorType == PGCHIP_COLOR_TYPE_PALETTE && sizePalette>0){ + for(j=0;j<sizePalette;j++){ + deparse_hex( ((unsigned char *) pPalette)[j], (unsigned char *)&result[offsetPalette + (j*2)]); + } + } + + // Copy data into result string + int offsetData = offsetPalette + sizePalette * 2; + for(j=0;j<(nYSize * lineSize);j++){ + deparse_hex( ((unsigned char *) data)[j], (unsigned char *)&result[offsetData + (j*2)]); + } + + + // end string + result[offsetData + j*2] = '\0'; + + +/* -------------------------------------------------------------------- */ +/* Inserting Chip */ +/* -------------------------------------------------------------------- */ + + // Second allocation to cope with data size + CPLFree(szCommand); + szCommand = (char *)CPLMalloc(PGCHIP.size*2 + 256); + + hResult = PQexec(hPGConn, "BEGIN"); + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) + { + + PQclear( hResult ); + sprintf( szCommand, + "INSERT INTO %s(raster) values('%s')", + pszName,result); + + + hResult = PQexec(hPGConn,szCommand); + + } + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ){ + PQclear( hResult ); + } + else { + CPLError( CE_Failure, CPLE_AppDefined, + "%s", PQerrorMessage(hPGConn) ); + CPLFree(szCommand); + return NULL; + } + + hResult = PQexec(hPGConn, "COMMIT"); + PQclear( hResult ); + + CPLFree( szCommand ); + CPLFree( pPalette ); + CPLFree( data ); + CPLFree( result ); + + return (GDALDataset *)GDALOpen(pszFilename,GA_Update); +} + + +/************************************************************************/ +/* Display CHIP information */ +/************************************************************************/ +void PGCHIPDataset::printChipInfo(){ + + if(this->PGCHIP != NULL){ + printf("\n---< CHIP INFO >----\n"); + printf("CHIP.datatype = %d\n",this->PGCHIP->datatype); + printf("CHIP.compression = %d\n",this->PGCHIP->compression); + printf("CHIP.size = %d\n",this->PGCHIP->size); + printf("CHIP.factor = %f\n",this->PGCHIP->factor); + printf("CHIP.width = %d\n",this->PGCHIP->width); + printf("CHIP.height = %d\n",this->PGCHIP->height); + printf("CHIP.nBands = %d\n",(int)this->PGCHIP->future[0]); + printf("CHIP.nBitDepth = %d\n",(int)this->PGCHIP->future[1]); + printf("--------------------\n"); + } +} + + +/************************************************************************/ +/* GDALRegister_PGCHIP() */ +/************************************************************************/ +void GDALRegister_PGCHIP(){ + + GDALDriver *poDriver; + + if( GDALGetDriverByName( "PGCHIP" ) == NULL ) + { + poDriver = new GDALDriver(); + + poDriver->SetDescription( "PGCHIP" ); + poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, + "Postgis CHIP raster" ); + + poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, + "Byte UInt16" ); + + poDriver->pfnOpen = PGCHIPDataset::Open; + poDriver->pfnCreateCopy = PGCHIPCreateCopy; + + GetGDALDriverManager()->RegisterDriver( poDriver ); + } +} + + + + + + + diff --git a/Utilities/GDAL/frmts/pgchip/pgchiprasterband.cpp b/Utilities/GDAL/frmts/pgchip/pgchiprasterband.cpp new file mode 100755 index 0000000000000000000000000000000000000000..b33626214de091d3fb92c161debe7b40bb828fd4 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/pgchiprasterband.cpp @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * File : pgchiprasterband.cpp + * Project: PGCHIP Driver + * Purpose: GDALRasterBand code for POSTGIS CHIP/GDAL Driver + * Author: Benjamin Simon, noumayoss@gmail.com + * + ****************************************************************************** + * Copyright (c) 2005, Benjamin Simon, noumayoss@gmail.com + * + * 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 or substantial portions of the 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. + ****************************************************************************** + * + * Revision 1.1 2005/08/29 bsimon + * New + * + */ + +/************************************************************************/ +/* ==================================================================== */ +/* PGCHIPRasterBand */ +/* ==================================================================== */ +/************************************************************************/ + +#include "pgchip.h" + + +/************************************************************************/ +/* PGCHIPRasterBand() */ +/************************************************************************/ + +PGCHIPRasterBand::PGCHIPRasterBand( PGCHIPDataset *poDS, int nBand ){ + + this->poDS = poDS; + this->nBand = nBand; + + if( poDS->nBitDepth == 16 ) + eDataType = GDT_UInt16; + else + eDataType = GDT_Byte; + + nBlockXSize = poDS->GetRasterXSize(); + nBlockYSize = 1; + +} + +/************************************************************************/ +/* IReadBlock() */ +/************************************************************************/ + +CPLErr PGCHIPRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, + void * pImage ){ + + char szCommand[1024]; + PGCHIPDataset *poGDS = (PGCHIPDataset *) poDS; + PGconn *hPGConn; + PGresult *hResult; + + int chipDataSize; + int bandSize; + int nPixelSize; + int nPixelOffset; + int nXSize; + int i; + + hPGConn = poGDS->hPGConn; + + // Must start on the very left + CPLAssert( nBlockXOff == 0 ); + + + if( poGDS->nBitDepth == 16 ) + nPixelSize = 2; + else + nPixelSize = 1; + + nPixelOffset = poGDS->nBands * nPixelSize; + nXSize = GetXSize(); + bandSize = nPixelSize * nXSize; + int sizePalette = 0; + + if(poGDS->PGCHIP->future[2] == PGCHIP_COLOR_TYPE_PALETTE){ + sizePalette = (int)poGDS->PGCHIP->compression * sizeof(pgchip_color); + } + + // Determine size of whole Image Data + chipDataSize = poGDS->PGCHIP->size - sizeof(CHIP) - sizePalette; + + +/* -------------------------------------------------------------------- */ +/* Reading Chip (first pas only) */ +/* -------------------------------------------------------------------- */ + + if(poGDS->PGCHIP->data == NULL){ + + hResult = PQexec(hPGConn, "BEGIN"); + + if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) + { + + PQclear( hResult ); + sprintf( szCommand,"SELECT raster FROM %s",poGDS->pszName); + + hResult = PQexec(hPGConn,szCommand); + + char *chipData = PQgetvalue(hResult,0,0); + poGDS->PGCHIP->data = (char *) CPLMalloc(chipDataSize); + + char *data = chipData + (sizePalette + sizeof(CHIP))*2; + + // Reading whole data + for(i=0 ; i<chipDataSize ; i++){ + ((unsigned char *)poGDS->PGCHIP->data)[i] = parse_hex( &data[i*2]) ; + } + + PQclear( hResult ); + + } + else { + CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) ); + PQclear( hResult ); + } + + hResult = PQexec(hPGConn, "COMMIT"); + PQclear( hResult ); + + } + +/* -------------------------------------------------------------------- */ +/* Extracting band from pointer */ +/* -------------------------------------------------------------------- */ + + if(poGDS->PGCHIP->data){ + + + if( nPixelSize == 1 ){ + + char *bufferData = ((char *)poGDS->PGCHIP->data) + (nBlockYOff * poGDS->nBands * bandSize) + ((nBand-1) * nPixelSize); + + for(i = 0; i < nXSize; i++ ){ + ((char *) pImage)[i] = bufferData[i*nPixelOffset]; + } + } + else { + + GUInt16 *bufferData = (GUInt16 *)(((char *)poGDS->PGCHIP->data) + (nBlockYOff * poGDS->nBands * bandSize) + ((nBand-1) * nPixelSize)); + + for(i = 0; i < nXSize; i++ ){ + + ((GUInt16 *) pImage)[i] = bufferData[i*poGDS->nBands]; + + } + } + + } + + return CE_None; +} + + + +/************************************************************************/ +/* GetColorInterpretation() */ +/************************************************************************/ +GDALColorInterp PGCHIPRasterBand::GetColorInterpretation(){ + + PGCHIPDataset *poGDS = (PGCHIPDataset *) poDS; + + if( poGDS->nColorType == PGCHIP_COLOR_TYPE_GRAY ){ + return GCI_GrayIndex; + } + else if( poGDS->nColorType == PGCHIP_COLOR_TYPE_PALETTE ){ + return GCI_PaletteIndex; + } + else if(poGDS->nColorType == PGCHIP_COLOR_TYPE_RGB_ALPHA){ + if( nBand == 1 ) + return GCI_RedBand; + else if( nBand == 2 ) + return GCI_GreenBand; + else if( nBand == 3 ) + return GCI_BlueBand; + else + return GCI_AlphaBand; + } + + return GCI_GrayIndex; +} + + +/************************************************************************/ +/* GetColorTable() */ +/************************************************************************/ + +GDALColorTable *PGCHIPRasterBand::GetColorTable(){ + + PGCHIPDataset *poGDS = (PGCHIPDataset *) poDS; + + if( nBand == 1 ) + return poGDS->poColorTable; + else + return NULL; +} diff --git a/Utilities/GDAL/frmts/pgchip/pgchiputilities.cpp b/Utilities/GDAL/frmts/pgchip/pgchiputilities.cpp new file mode 100755 index 0000000000000000000000000000000000000000..9921497c0806d8a4ae5cb95d6ea5dd9d9bcd4b6b --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/pgchiputilities.cpp @@ -0,0 +1,290 @@ +/****************************************************************************** + * + * File : pgchiputilities.cpp + * Project: PGCHIP Driver + * Purpose: Utility functions for POSTGIS CHIP/GDAL Driver + * Author: Benjamin Simon, noumayoss@gmail.com + * + ****************************************************************************** + * Copyright (c) 2005, Benjamin Simon, noumayoss@gmail.com + * + * 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 or substantial portions of the 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. + ****************************************************************************** + * + * Revision 1.1 2005/08/29 bsimon + * New + * + */ + +#include "pgchip.h" + +/************************************************************************/ +/* ==================================================================== */ +/* Utility Hex Functions */ +/* ==================================================================== */ +/************************************************************************/ + +void deparse_hex(unsigned char str, unsigned char *result){ + + int input_high; + int input_low; + + input_high = (str>>4); + input_low = (str & 0x0F); + + switch (input_high) + { + case 0: + result[0] = '0'; + break; + case 1: + result[0] = '1'; + break; + case 2: + result[0] = '2'; + break; + case 3: + result[0] = '3'; + break; + case 4: + result[0] = '4'; + break; + case 5: + result[0] = '5'; + break; + case 6: + result[0] = '6'; + break; + case 7: + result[0] = '7'; + break; + case 8: + result[0] = '8'; + break; + case 9: + result[0] = '9'; + break; + case 10: + result[0] = 'A'; + break; + case 11: + result[0] = 'B'; + break; + case 12: + result[0] = 'C'; + break; + case 13: + result[0] = 'D'; + break; + case 14: + result[0] = 'E'; + break; + case 15: + result[0] = 'F'; + break; + } + + switch (input_low) + { + case 0: + result[1] = '0'; + break; + case 1: + result[1] = '1'; + break; + case 2: + result[1] = '2'; + break; + case 3: + result[1] = '3'; + break; + case 4: + result[1] = '4'; + break; + case 5: + result[1] = '5'; + break; + case 6: + result[1] = '6'; + break; + case 7: + result[1] = '7'; + break; + case 8: + result[1] = '8'; + break; + case 9: + result[1] = '9'; + break; + case 10: + result[1] = 'A'; + break; + case 11: + result[1] = 'B'; + break; + case 12: + result[1] = 'C'; + break; + case 13: + result[1] = 'D'; + break; + case 14: + result[1] = 'E'; + break; + case 15: + result[1] = 'F'; + break; + } +} + +//given a string with at least 2 chars in it, convert them to +// a byte value. No error checking done! +unsigned char parse_hex(char *str){ + + //do this a little brute force to make it faster + + unsigned char result_high = 0; + unsigned char result_low = 0; + + switch (str[0]) + { + case '0' : + result_high = 0; + break; + case '1' : + result_high = 1; + break; + case '2' : + result_high = 2; + break; + case '3' : + result_high = 3; + break; + case '4' : + result_high = 4; + break; + case '5' : + result_high = 5; + break; + case '6' : + result_high = 6; + break; + case '7' : + result_high = 7; + break; + case '8' : + result_high = 8; + break; + case '9' : + result_high = 9; + break; + case 'A' : + result_high = 10; + break; + case 'B' : + result_high = 11; + break; + case 'C' : + result_high = 12; + break; + case 'D' : + result_high = 13; + break; + case 'E' : + result_high = 14; + break; + case 'F' : + result_high = 15; + break; + } + switch (str[1]) + { + case '0' : + result_low = 0; + break; + case '1' : + result_low = 1; + break; + case '2' : + result_low = 2; + break; + case '3' : + result_low = 3; + break; + case '4' : + result_low = 4; + break; + case '5' : + result_low = 5; + break; + case '6' : + result_low = 6; + break; + case '7' : + result_low = 7; + break; + case '8' : + result_low = 8; + break; + case '9' : + result_low = 9; + break; + case 'A' : + result_low = 10; + break; + case 'B' : + result_low = 11; + break; + case 'C' : + result_low = 12; + break; + case 'D' : + result_low = 13; + break; + case 'E' : + result_low = 14; + break; + case 'F' : + result_low = 15; + break; + } + return (unsigned char) ((result_high<<4) + result_low); +} + +/* Parse an hex string */ +void parse_hex_string(unsigned char *strOut,char *strIn,int length){ + + int i; + for(i=0;i<length;i++){ + //printf("Before = %c\n",strIn[i]); + strOut[i] = parse_hex(&strIn[i]); + //printf("After = %c\n",strOut[i]); + } + +} + +/* Deparse an hex string */ +void deparse_hex_string(unsigned char *strOut,char *strIn,int length){ + + int i; + + for(i=0;i<length;i++) + deparse_hex(strIn[i],&strOut[i]); + +} diff --git a/Utilities/GDAL/frmts/pgchip/todo b/Utilities/GDAL/frmts/pgchip/todo new file mode 100755 index 0000000000000000000000000000000000000000..e9a65ef2234584edf5d954d97eb3a91b62e095e6 --- /dev/null +++ b/Utilities/GDAL/frmts/pgchip/todo @@ -0,0 +1,9 @@ +TODO List : + +* Test Driver compatibility with various raster formats +* Modify the connection string to cope with the name of the raster column +* Improve the number of color interpretation options +* Manage geoTrasnform +* Deal with more datatypes +* Improve SRID conversion +* Test makefile.vc (Visual C)