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)