[postgis-commits] svn - r2697 - in branches/gSoC2007_raster/pgraster: . win32/build

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Sun Aug 19 18:57:54 PDT 2007


Author: xingkth
Date: 2007-08-19 18:57:53 -0700 (Sun, 19 Aug 2007)
New Revision: 2697

Added:
   branches/gSoC2007_raster/pgraster/win32/build/pgraster2geotiff.exe
Modified:
   branches/gSoC2007_raster/pgraster/geotiff2pgraster.c
   branches/gSoC2007_raster/pgraster/pgraster2geotiff.c
   branches/gSoC2007_raster/pgraster/pgraster_utils.c
   branches/gSoC2007_raster/pgraster/pgraster_utils.h
Log:
Xing. GoogleSoC2007 Code Upload(20070819)

Modified: branches/gSoC2007_raster/pgraster/geotiff2pgraster.c
===================================================================
--- branches/gSoC2007_raster/pgraster/geotiff2pgraster.c	2007-08-17 22:46:15 UTC (rev 2696)
+++ branches/gSoC2007_raster/pgraster/geotiff2pgraster.c	2007-08-20 01:57:53 UTC (rev 2697)
@@ -156,6 +156,8 @@
 	FILE *debug;
 #endif
 
+int getopt();
+
 /* Prototypes */
 char * getTableOID(char *schema, char *table);
 void usage(char* me, int status, FILE* out);
@@ -249,7 +251,7 @@
 	Cleanup();
 
 	/* Step 6. Function Successfully Return and Send Message To Terminal or Log */
-	PrintResultMessage();
+	PrintResultMessage(1);
 
 	return 0;
 }
@@ -400,7 +402,7 @@
 	int c, curindex;
 	char buf[QUERY_BUF_LENGTH];
 
-	memset(buf,QUERY_BUF_LENGTH, '\0'); 
+	memset(buf,'\0', QUERY_BUF_LENGTH); 
 
 	/* Parse command line */
     while ((c = getopt(ARGC, ARGV, "h:d:U:p:P:rk:vq")) != EOF){
@@ -1069,7 +1071,7 @@
 					else if(bps == 32)
 						datatype = DT_32BIT_S;
 					else
-					{
+					{// Read spatial extent information from PGRASTER_METADATA
 						if(outmode != MODE_QUIET)
 							fprintf(stderr , "**Error**: Unsupported TIFF sample format.\n");
 						exit_nicely(conn,1);
@@ -1087,7 +1089,7 @@
 					else
 					{
 						if(outmode != MODE_QUIET)
-							fprintf(stderr , "**Error**: Unsupported TIFF sample format.\n");
+							fprintf(stderr, "**Error**: Unsupported TIFF sample format.\n");
 						exit_nicely(conn,1);
 					}
 					break;
@@ -1313,7 +1315,7 @@
  	* this programe will exit abnormally.
  	* Using SQL functions.
  	*/
-	memset(query, QUERY_BUF_LENGTH, '\0');
+	memset(query,'\0', QUERY_BUF_LENGTH); 
 	sprintf(query,"SELECT AddRasterTableFull('%s','%s',%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d);",
 					schema,
 					table,
@@ -1345,11 +1347,11 @@
 	fldLen = PQgetlength(res,0,0);
 	pszValue = PQgetvalue(res,0,0);
 	metadata.name = malloc(fldLen * sizeof(char)+1);
-	memset(metadata.name,sizeof(char)*fldLen+1,'\0');
+	memset(metadata.name,'\0',sizeof(char)*fldLen+1);
 	memcpy(metadata.name,(char*)pszValue,fldLen*sizeof(char));
 	PQclear(res);
 
-	memset(query, QUERY_BUF_LENGTH, '\0');
+	memset(query, '\0', QUERY_BUF_LENGTH);
 	sprintf(query,"SELECT rasterObjectID FROM pgraster_metadata WHERE name='%s'",
 					metadata.name);
 
@@ -1390,7 +1392,7 @@
 		paramValues[0] = (char*)(metadata.spatialExtent);
 		paramLengths[0] = G_GetSize(metadata.spatialExtent);
 		paramFormats[0] = 1; //Binary
-		memset(query, QUERY_BUF_LENGTH, '\0');
+		memset(query, '\0' , QUERY_BUF_LENGTH);
 		
 		sprintf(query,"UPDATE \"%s\".\"pgraster_metadata\" SET spatialextent=GeomFromWKB($1,%d) WHERE rasterObjectID=%Ld", 
 				schema,
@@ -1421,12 +1423,12 @@
 	{
 		// Create Prepared Insert Statement for Raster Data Insertion
 		insertStmt = (char*)malloc(strlen(schema) + strlen(table) + 1);
-		memset(insertStmt, strlen(schema) + strlen(table) + 1, '\0');
+		memset(insertStmt, '\0' , strlen(schema) + strlen(table) + 1);
 		memcpy(insertStmt, schema, strlen(schema));
 		memcpy(insertStmt+strlen(schema), table, strlen(table));
 
 		
-		memset(query, QUERY_BUF_LENGTH, '\0');
+		memset(query, '\0' , QUERY_BUF_LENGTH);
 		sprintf(query,"INSERT INTO \"%s\".\"%s\"(rasterobjectid,pyramidlevel,bandblocknumber,rowblocknumber,columnblocknumber,blockbandsize,blockrowsize,blockcolumnsize,blockmbr,datablock) Values($1,$2,$3,$4,$5,$6,$7,$8,GeomFromWKB($9),$10)", 
 				schema,
 				table);
@@ -1459,7 +1461,7 @@
 void _CleanUpDemo()
 {
 	char query[QUERY_BUF_LENGTH];
-	memset(query, QUERY_BUF_LENGTH, '\0');
+	memset(query, '\0' , QUERY_BUF_LENGTH);
 	
 	printf("Executing CleanUpDemo()!!!!\n");
 
@@ -2289,7 +2291,7 @@
 void CreateIndex()
 {
 	char query[QUERY_BUF_LENGTH];
-	memset(query, QUERY_BUF_LENGTH, '\0');
+	memset(query, '\0', QUERY_BUF_LENGTH);
 	if(outmode == MODE_VERBOSE)
 		fprintf(stdout, "Start building GiST on block mbr.\n");
 	sprintf(query,"CREATE INDEX \"index_%s_%s\" ON \"%s\".\"%s\" using GIST ( blockMBR GIST_GEOMETRY_OPS)",
@@ -2321,7 +2323,7 @@
 	double	adfCoeff[6], x, y;
 	char query[QUERY_BUF_LENGTH];
 
-	memset(query,QUERY_BUF_LENGTH,'\0');
+	memset(query,'\0',QUERY_BUF_LENGTH);
 
 	if(outmode == MODE_VERBOSE)
 		fprintf(stdout, "Start loading SRS information.\n");
@@ -2354,7 +2356,7 @@
 	// A(0), B(1), C(2), D(3), E(4), F(5)
 	// Xgeo = E + Xpixel * A + Ypixel * C
 	// Ygeo = F + Ypixel * D + Xpixel * B
-	sprintf(query, "UPDATE \"%s\".\"pgraster_srs\" SET rowdenominator='{%lf,%lf,%lf}', columndenominator='{%lf,%lf,%lf}' WHERE rasterObjectID=%Ld",schema, adfCoeff[5], adfCoeff[3],adfCoeff[1],adfCoeff[4], adfCoeff[2],adfCoeff[0],metadata.rasterObjectID);
+	sprintf(query, "UPDATE \"%s\".\"pgraster_srs\" SET rowdenominator='{%lf,%lf,%lf}', columndenominator='{%lf,%lf,%lf}' WHERE rasterObjectID=%Ld",schema, adfCoeff[5], adfCoeff[3],adfCoeff[1],adfCoeff[4], adfCoeff[0],adfCoeff[2],metadata.rasterObjectID);
 
 	res = PQexec(conn,query);
 
@@ -2377,7 +2379,7 @@
 {
 	// Some metadata need to be updated after the data loading.
 	char query[QUERY_BUF_LENGTH];
-	memset(query, QUERY_BUF_LENGTH, '\0');
+	memset(query, '\0' , QUERY_BUF_LENGTH);
 	if(outmode == MODE_VERBOSE)
 		fprintf(stdout, "Start updating metadata second time.\n");
 	sprintf(query,"UPDATE \"%s\".\"pgraster_metadata\" SET rasterpyramiddepth=%d WHERE rasterObjectID=%Ld", schema, (int)nPyramidDepth, metadata.rasterObjectID);
@@ -2427,12 +2429,12 @@
 	if(sucessful == 1)
 	{
 		//sucessful
-		fprintf(stdout, "GeoTIFF file '%s' importing failed.\n", geotiff_file);
+		fprintf(stdout, "GeoTIFF file '%s' succesfully imported.\n", geotiff_file);
 	}
 	else
 	{
 		//fail
-		fprintf(stdout, "GeoTIFF file '%s' succesfully imported.\n", geotiff_file);
+		fprintf(stdout, "GeoTIFF file '%s' importing failed.\n", geotiff_file);
 	}
 }
 

Modified: branches/gSoC2007_raster/pgraster/pgraster2geotiff.c
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster2geotiff.c	2007-08-17 22:46:15 UTC (rev 2696)
+++ branches/gSoC2007_raster/pgraster/pgraster2geotiff.c	2007-08-20 01:57:53 UTC (rev 2697)
@@ -32,6 +32,7 @@
 static char rcsid[] =
   "$Id: pgraster2geotiff.c 2007-07-22 Xing.Lin $";
 
+#include "../config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -41,57 +42,1513 @@
 /* Solaris9 does not provide stdint.h */
 /* #include <stdint.h> */
 #include <inttypes.h>
+
+//GeoTIFF & TIFF library headers
+#include "geotiff.h"
+#include "xtiffio.h"
+#include "geotiffio.h"
+#include "geo_tiffp.h"
+#include "geo_normalize.h"
+#include "geovalues.h"
+
+//Libpq & PGRaster headers
 #include "libpq-fe.h"
 #include "getopt.h"
 #include "pgraster_const.h"
 #include "pgraster_types.h"
 #include "pgraster_utils.h"
+#include "pgraster_version.h"
+#include "wkb.h"
 #include "compat.h"
 /* Used to help create tempate tables names */
 #include <sys/types.h> // for getpid()
 #include <unistd.h> // for getpid()
 
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
 #ifdef __CYGWIN__
 #include <sys/param.h>       
 #endif
 
+#define TIFFOpen XTIFFOpen
+#define TIFFClose XTIFFClose
+#define	streq(a,b)	(strcmp(a,b) == 0)
+#define	strneq(a,b,n)	(strncmp(a,b,n) == 0)
+
 /* Debug Control Flag */
 #define DEBUG 1
 
-/*
- * Verbosity:
- *   set to 1 to see record fetching progress
- *   set to 2 to see also shapefile creation progress
- *   set to 3 for debugging
- */
-#define VERBOSE 1
+/* Buffer length for SQL statement */
+#define QUERY_BUF_LENGTH 1024
 
 /* Global data */
+PGconn *conn;
+PGresult *res;
+TIFF 	*tif=(TIFF*)0;  /* TIFF-level descriptor */
+GTIF	*gtif=(GTIF*)0; /* GeoKey-level descriptor */
+int rowbuflen;
+char *table, *geotiff_file, *schema, *geotiff_filename;
+int keep_fieldname_case = 0;
+int big_endian = 0;
+int pgis_major_version;
+#define MODE_QUIET 0
+#define MODE_NORMAL 1
+#define MODE_VERBOSE 2
+int outmode = 1; // 0=quiet mode;  1=normal mode, 2=verbose mode.
+bool beginTransaction = FALSE;
+char *PG_VERSION = "8.2.4\0";
+PGRasterMetadata metadata;
 
+/* TIFF Writer/Reader Global Data */
+byte *pDataBuffer = NULL;
+short scanlineMode = 0;
+int nTIFFBytePerPixel = 0;
+int nTIFFBitsPerPixel = 0;
+int nRealBytePerPixel = 0;
+int nRealBitsPerPixel = 0;
+uint32 stripMax, stripCount;
+tsize_t stripSize;
+uint32 rowsperstrip = 20;
+uint32 bufferSize;
+unsigned long imageOffset;
+uint16 bps       = 1;
+uint16 spp       = 1;
+uint16 mode      = PHOTOMETRIC_MINISBLACK;
+uint16 format    = SAMPLEFORMAT_UINT;
+uint16 planar    = PLANARCONFIG_CONTIG;
+uint16 compression = COMPRESSION_NONE;
+uint16 predictor = (uint16)-1;
+int jpegcolormode = JPEGCOLORMODE_RGB;
+uint32 defg3opts = (uint32) -1;
+uint16 defcompression = (uint16) -1;
+uint16 defpredictor = (uint16) -1;
+uint16 preMultiplied = 0;
+uint16 fillorder = FILLORDER_MSB2LSB ;
+byte tiff_bigendian = 0; // whether TIFF file uses big endian byte order.
+byte badIndians = 0; // whether TIFFBigEndian != big_endian
+byte hasAlpha = 0; // hasAlpha channel???
+uint32 rows = 0; // number of TIFF image rows
+uint32 cols = 0; // number of TIFF image column
+uint32 bands = 0; // number of raster bands (image channel)
+uint32 nPyramidDepth = 0; // pyramide depth.
+byte nPyramidEnabled = 0;
 
 
+/* GeoTIFF Paramaters */
+short dimensions = 0;
+_int64 objectid = 0;
+char *captureDate = NULL;
+short Model = -1;
+short RasterModel = -1; // Area or Point
+int SRID = -1;
+double xGeoResolution = 0.0;
+double yGeoResolution = 0.0;
+double zGeoResolution = 0.0;
+PGRasterDataType datatype = DT_UNKNOWN;
+PGRasterBandType bandtype = BT_UNKNOWN;
+PGRasterValueType valuetype = VT_IMAGE;
+char* pgraster_name = NULL;
+WKBGeometry* spatialExtent = NULL;
+double columnDominator[3];
+double rowDominator[3];
+uint32 blocksizeBands=0, blocksizeRows=0, blocksizeColumns = 0;
+uint32 padding = 0;
+uint32 georeferenced = 0;
+uint32 blockBandInterleaving = 0;
+uint32 blockCompression = CT_NONE;
+uint32 blockQuality = 0;
+double dblNodataValue = -1.0f;
+
+#ifdef USE_ICONV
+char	*encoding=NULL;
+#endif
+
+
+#ifdef DEBUG
+	FILE *debug;
+#endif
+
+/* External function declaration*/
+int getopt();
+
 /* Prototypes */
+char * getTableOID(char *schema, char *table);
+void usage(char* me, int status, FILE* out);
+int parse_commandline(int ARGC, char **ARGV);
+static void parse_table(char *spec);
+static void parse_geotiffname(char *spec);
+static void exit_nicely(PGconn *conn, int code);
+int get_pgraster_version(void);
+int get_postgis_version(void);
+int processCompressOptions(char* opt);
+void processG3Options(char* cp);
+void CheckAndCorrectColormap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b);
 
-  
+/*******************************************************/
+/* Function for data exporting from PGRaster to GeoTIFF*/
+/*******************************************************/
+
+/* Step 0. Parse Paramaters and Create Connection*/
+void ParseAndCreateConnection(int ARGC, char **ARGV);
+
+/* Step 1. Initialization*/
+void Initialization();
+
+void _ReadPGRasterMetadata();
+
+void _CreateGeoTIFF();
+
+void _SetUpTIFFDirectory(TIFF *tif);
+
+void _SetUpGeoKeys(GTIF* gtif);
+
+void _WriteGeoTIFFHeader();
+
+void _CleanUpDemo();
+
+/* Step 2. Read GeoTIFF Data & Insert into PGRaster via PreparedStatement */
+void WriteTIFFData();
+
+/* Step 3. Cleanup & Close Connection*/
+void Cleanup();
+
+/* Step 4. Function Successfully Return and Send Message To Terminal or Log */
+void PrintResultMessage();
+
+#ifdef USE_ICONV
+char *utf8(const char *fromcode, char *inputbuf);
+#endif
+void *safe_malloc(size_t size)
+{
+	void *ret = malloc(size);
+	if ( ! ret ) {
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error**: Out of virtual memory\n");
+		exit_nicely(conn, 1);
+	}
+	return ret;
+}
+#define malloc(x) safe_malloc(x)
+
 /* Main Programe */
 int main(int ARGC, char **ARGV)
 {
 	/* Definition for local variables */
 
-	/* Read User Input */
+	/* Step 0. Parse Paramaters and Create Connection */
+	ParseAndCreateConnection(ARGC, ARGV);
+	
+	/* Step 1. Initialization & Read Metadata of PGRaster dataset for Data Export*/
+	Initialization();
 
-	/* Initialization & Create PreparedStatement for Data Insert */
+	/* Step 2. Write TIFF Data Into TIFF files */
+	WriteTIFFData();
 
-	/* Read Metadata from PGRaster & Write into GeoTIFF header via libgeotiff*/
+	/* Step 3. Cleanup & Close Connection*/
+	Cleanup();
 
-	/* Read Data from PGRaster & Write into GeoTIFF via libgeotiff functions*/
+	/* Step 4. Function Successfully Return and Send Message To Terminal or Log */
+	PrintResultMessage(1);
 
-	/* Close Files, PGConn and Clear PGresult*/
+	return 0;
+}
 
-	/* Function Successfully Return and Send Message To Terminal or Log */
+/******** Implementation of Functions ********/
+/* 
+ * Return allocate memory. Free after use.
+ */
+char * getTableOID(char *schema, char *table)
+{
+	PGresult *res3;
+	char *query;
+	char *ret;
+	size_t size;
 
-	return -1;
+	size = strlen(table)+256;
+	if ( schema ) size += strlen(schema)+1;
+
+	query = (char *)malloc(size);
+
+	if ( schema )
+	{
+		sprintf(query, "SELECT oid FROM pg_class c, pg_namespace n WHERE c.relnamespace n.oid AND n.nspname = '%s' AND c.relname = '%s'", schema, table);
+	} 
+	else 
+	{
+		sprintf(query, "SELECT oid FROM pg_class WHERE relname = '%s'", table);
+	}
+
+	res3 = PQexec(conn, query);
+	free(query);
+	if ( ! res3 || PQresultStatus(res3) != PGRES_TUPLES_OK ) {
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when getting TableOID: %s", PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+	if(PQntuples(res3) == 1 ){
+		ret = strdup(PQgetvalue(res3, 0, 0));
+	}else if(PQntuples(res3) == 0 ){
+		if(outmode != MODE_QUIET)
+			fprintf(stdout, "Cannot find relation OID (does table exist?).\n");
+		PQclear(res3);
+		return NULL;
+	}else{
+		ret = strdup(PQgetvalue(res3, 0, 0));
+		if(outmode != MODE_QUIET)
+			printf( "Warning: Multiple relations detected, the program will only dump the first relation.\n");
+	}	
+	PQclear(res3);
+	return ret;
 }
 
-/******** Implementation of Functions ********/
+/*
+ * Print the usage information to standard output destination (terminal, file or so on).
+ */
+void usage(char* me, int status, FILE* out)
+{
+    fprintf(out,"PostgreSQL Version: %s \\ PostGIS Version: %s\n", PG_VERSION, POSTGIS_VERSION);
+	fprintf(out,"RCSID: %s RELEASE: %s\n", rcsid, PGRASTER_VERSION);
 
+	fprintf(out,"USAGE: %s [<options>] [<schema>.]table [geotiff-file] \n", me);
+	
+	fprintf(out,"\n");
+
+	fprintf(out,"OPTIONS:\n");
+   
+	fprintf(out," -h <host>\n");
+	fprintf(out,"     The database host to connect to. If ignored, the default address\n");
+    fprintf(out,"     of host will be \"localhost/127.0.0.1\". If no database running on\n");
+	fprintf(out,"     this host, the program will exit immediately with a error msg.\n");
+
+	fprintf(out," -p <port>\n");
+	fprintf(out,"     The port  to connect to  on the  database  host. If ignored, the\n");
+    fprintf(out,"     standard port number of 5432 will be used.If no database running\n");
+	fprintf(out,"     on this port, the program will exit immediately with a error msg.\n");
+
+	fprintf(out," -d <database>\n");
+	fprintf(out,"     The database to use when connecting. If ignored, the current  OS\n");
+    fprintf(out,"     username will be used the name of database to login into. If this\n");
+	fprintf(out,"     database is refused to login, the program will exit immediately\n");
+	fprintf(out,"     with a error message.\n");
+	
+	fprintf(out," -P <password>\n");
+	fprintf(out,"     The password to use when connecting to the database. This option\n");
+    fprintf(out,"     can't be ignored. If this password is refused to login, the pro-\n");
+	fprintf(out,"     gram will exit immediately with a error message.\n");
+	
+	fprintf(out," -U <user>\n");
+	fprintf(out,"     The username to use when connecting to the database. If ignored,\n");
+    fprintf(out,"     the current OS username will be used to login into the database.\n");
+	fprintf(out,"     If this username  is  refused to login, the  program  will  exit\n");
+	fprintf(out,"     immediately with a error message.\n");
+
+	fprintf(out,"[<schema>.]table [geotiff_file]\n");
+	fprintf(out,"     Export the specified pgraster table (e.x. public.usatm1990) into\n"); 
+	fprintf(out,"     GeoTIFF file. The <schema> and <geotiff_file> paramater is optional.\n");
+	fprintf(out,"     If ignored, the \'public\' as schema and <table> as geotiff_file will.\n");
+	fprintf(out,"     be adopted.\n");
+
+	fprintf(out," -k  			Keep postgresql identifiers case.\n");
+    fprintf(out," -?/--help 	Display this help screen.\n");
+
+	fprintf(out," -q  Load data in quiet mode.\n");
+
+	fprintf(out," -v  Load data in verbose mode.\n");
+
+    fprintf(out,"\n");
+
+	fprintf(out,"(Note that -a, -c, -d and -p are mutually exclusive.)\n");	
+
+	fprintf(out,"#######################  (NOT SUPPORTED YET)  #########################\n");
+    
+	fprintf(out,"(Note that -a, -c, -d and -p are mutually exclusive.)\n");	
+
+	fprintf(out," -d  Drops the database table before creating a new  table  with  the\n");
+    fprintf(out,"     data in the geotiff file.\n");
+
+	fprintf(out," -a  Appends  data  from the geotiff file into the existing database\n");
+    fprintf(out,"     table. Although it is not recommended to store raw data of sever-\n");
+	fprintf(out,"     ral raster dataset into one raster data table (sharing). But if\n");
+	fprintf(out,"     you insist, you can do it by this option\n");
+
+	fprintf(out," -c  Creates a new table and populates it from the geotiff file. This\n");
+    fprintf(out,"     is the default mode.\n");
+
+
+	fprintf(out," -p  Only produces the table creation SQL code,  without  adding  any\n");
+    fprintf(out,"     actual data. This can be used if you need to completely seperate\n");
+	fprintf(out,"     the table creation and data loading steps.\n");
+	fprintf(out,"     (NOT SUPPORTED YET)\n");
+	
+	fprintf(out," -D  Use the PostgreSQL \"dump\" format for the output data.  This  can\n");
+    fprintf(out,"     be  combined  with -a, -c and -d. It is much faster to load than\n");
+	fprintf(out,"     the default \"insert\" SQL format. Use this for  very  large  data\n");
+	fprintf(out,"     sets. If this option is set, then the following options could be\n");
+	fprintf(out,"     ignored.\n");
+	fprintf(out,"     (NOT SUPPORTED YET)\n");
+
+	fprintf(out,"#######################  (NOT SUPPORTED YET)  #########################\n");
+    
+	fprintf(out,"\n");
+
+	exit (status);
+}
+
+/* Parse command line parameters */
+int parse_commandline(int ARGC, char **ARGV)
+{
+    if ( ARGC == 1 ) {
+		usage(ARGV[0], 0, stdout);
+    }
+
+	int c, curindex;
+	char buf[QUERY_BUF_LENGTH];
+
+	memset(buf,'\0', QUERY_BUF_LENGTH); 
+
+	/* Parse command line */
+    while ((c = getopt(ARGC, ARGV, "h:d:U:p:P:rk:vq")) != EOF){
+		switch (c) {
+			case 'h':
+				/*setenv("PGHOST", optarg, 1); */
+				snprintf(buf, 255, "PGHOST=%s", optarg);				
+				putenv(strdup(buf));
+				break;
+			case 'd':
+				/*setenv("PGHOST", optarg, 1); */
+				snprintf(buf, 255, "PGDATABASE=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'U':
+				/*setenv("PGUSER", optarg, 1); */
+				snprintf(buf, 255, "PGUSER=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'p':
+				/*setenv("PGPORT", optarg, 1); */
+				snprintf(buf, 255, "PGPORT=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'P':
+				/*setenv("PGPASSWORD", optarg, 1); */
+				snprintf(buf, 255, "PGPASSWORD=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'v': // verbose mode
+				outmode = MODE_VERBOSE;
+				break;
+			case 'q': // quiet mode
+				outmode = MODE_QUIET;
+				break;
+			case 'k':
+				keep_fieldname_case = 1;
+				break;
+			case '?':
+                usage(ARGV[0], 0, stdout);
+			default:
+				return 0;
+		}
+    }
+
+    curindex=0;
+    for (; optind<ARGC; optind++){
+		if (curindex == 0) {
+	    	schema = "public\0";
+			parse_table(ARGV[optind]);
+			geotiff_filename = table;
+			geotiff_file = malloc(strlen(table) + 4);
+			memcpy(geotiff_file, table, strlen(table)); 
+			memcpy(geotiff_file,".tif", 4);
+        }else if(curindex == 1){
+			geotiff_file = ARGV[optind];
+			parse_geotiffname(geotiff_file);
+		}
+		curindex++;		
+    }
+
+	/* 
+	 * Transform table name to lower case unless asked
+	 * to keep original case (we'll quote it later on)
+	 */
+	if (keep_fieldname_case == 1)
+	{
+		LowerCase(table);
+		if ( schema ) LowerCase(schema);
+	}
+
+	// could only have on operant of geotiff_file
+    if (curindex < 1) 
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Get a table (and optionally a schema) if there  is any.
+ * The table option could be ommited if user choose to use
+ * the same table name as the input geotiff filename.
+ */
+static void parse_table(char *spec)
+{
+	char *ptr;
+    
+	table = spec;
+	if ( (ptr=strchr(table, '.')) )	
+	{
+			*ptr = '\0';
+			schema = table;
+			table = ptr+1; 
+	}
+}
+
+/*
+ * Parse the filename from geotiff_file path. Typical geotiff_file looks like:
+ * 1) /home/pgraster/data/usa_tm1990.tif
+ * 2) usa_tm1990.tif
+ * XXX: "Windows \" vs "Linux/Unix /"
+ */
+static void parse_geotiffname(char *spec)
+{
+	char	*ptr;
+	char	*strTemp;
+    int		nlen;
+	int 	nlen2;
+
+
+	if(spec == NULL)
+		return;
+
+	nlen = strlen(spec);
+
+	strTemp = (char*)malloc(sizeof(char)*nlen+1);
+	strTemp = strcpy(strTemp, spec);
+	strTemp[nlen-1]='\0';
+
+	if ( (ptr=strrchr(strTemp, '.')) )	
+	{
+			*ptr = '\0';
+			if( (ptr=strrchr(strTemp,92)) || (ptr=strrchr(strTemp,'/')) ) 
+				//XXX: how to deal with '/' and '\' different OS.
+			{
+				ptr = ptr+1;
+				nlen2 = strlen(ptr);
+				geotiff_filename = (char*)malloc(sizeof(char)*nlen2+1);
+				geotiff_filename = strcpy(geotiff_filename, ptr);
+			}
+			else
+			{
+				ptr = strTemp;
+				nlen2 = strlen(ptr);
+				geotiff_filename=(char*)malloc(sizeof(char)*nlen2+1);
+				geotiff_filename = strcpy(geotiff_filename, ptr);
+			}
+	}
+	else
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error**: Fail to parse GeoTIFF dataset name from file %s\n", geotiff_file);
+	}
+}
+
+/*
+ * Exit Nicely for PostgreSQL Client that uses libpq-fe.
+ */
+static void exit_nicely(PGconn *conn, int code)
+{
+	if(beginTransaction == TRUE)
+	{
+		res = PQexec(conn, "ROLLBACK");
+		PQclear(res);
+	}
+
+	/* Close GeoTIFF File */
+	if (gtif) GTIFFree(gtif);
+    if (tif) XTIFFClose(tif); 
+
+	/* Close PGConnection*/
+	PQfinish(conn);
+	exit(code);
+}
+
+/*
+ * Get PostGIS Major Version.
+ */
+int get_postgis_major_version(void)
+{
+	PGresult *res;
+	char *version;
+	int ver;
+	char *query = "SELECT postgis_version()";
+	res = PQexec(conn, query);
+
+	if ( ! res || PQresultStatus(res) != PGRES_TUPLES_OK ) 
+	{
+		if(outmode != MODE_QUIET)
+		{
+			fprintf(stderr, "**Error**: Can't detect postgis version:\n");
+			fprintf(stderr, "**Error**: PostgisVersionQuery: %s", PQerrorMessage(conn));
+		}
+		exit(1);
+	}
+
+	version = PQgetvalue(res, 0, 0);
+	ver = atoi(version);
+	PQclear(res);
+	return ver;
+}
+
+int processCompressOptions(char* opt)
+{
+    if (streq(opt, "none"))
+        compression = COMPRESSION_NONE;
+    else if (streq(opt, "packbits"))
+        compression = COMPRESSION_PACKBITS;
+    else if (strneq(opt, "jpeg", 4)) {
+        char* cp = strchr(opt, ':');
+        if (cp && isdigit(cp[1]))
+            blockQuality = atoi(cp+1);
+        if (cp && strchr(cp, 'r'))
+            jpegcolormode = JPEGCOLORMODE_RAW;
+        compression = COMPRESSION_JPEG;
+    } else if (strneq(opt, "g3", 2)) {
+        processG3Options(opt);
+        compression = COMPRESSION_CCITTFAX3;
+    } else if (streq(opt, "g4"))
+        compression = COMPRESSION_CCITTFAX4;
+    else if (strneq(opt, "lzw", 3)) {
+        char* cp = strchr(opt, ':');
+        if (cp)
+            defpredictor = atoi(cp+1);
+        compression = COMPRESSION_LZW;
+    } else if (strneq(opt, "zip", 3)) {
+        char* cp = strchr(opt, ':');
+        if (cp)
+            defpredictor = atoi(cp+1);
+        compression = COMPRESSION_DEFLATE;
+    } else
+        return (0);
+    return (1);
+}
+
+void processG3Options(char* cp)
+{
+    if( (cp = strchr(cp, ':')) != NULL ) {
+        if (defg3opts == (uint32) -1)
+            defg3opts = 0;
+        do {
+            cp++;
+            if (strneq(cp, "1d", 2))
+                defg3opts &= ~GROUP3OPT_2DENCODING;
+            else if (strneq(cp, "2d", 2))
+                defg3opts |= GROUP3OPT_2DENCODING;
+            else if (strneq(cp, "fill", 4))
+                defg3opts |= GROUP3OPT_FILLBITS;
+            else
+                usage("pgraster2geotiff", 2, stderr);;
+        } while( (cp = strchr(cp, ':')) != NULL );
+    }
+}
+
+/*
+ * Get PGRaster Major Version
+ */
+int get_pgraster_version(void)
+{
+	PGresult *res;
+	char *version;
+	int ver;
+	char query[] = "SELECT pgraster_version()";
+	res = PQexec(conn, query);
+
+	if ( ! res || PQresultStatus(res) != PGRES_TUPLES_OK ) 
+	{
+		if(outmode != MODE_QUIET)
+		{
+			fprintf(stderr, "**Error**: Can't detect PGRaster version:\n");
+			fprintf(stderr, "**Error**: PGRaster Version Query: %s", PQerrorMessage(conn));
+		}
+		exit(1);
+	}
+
+	version = PQgetvalue(res, 0, 0);
+	ver = atoi(version);
+	PQclear(res);
+	return ver;
+}
+
+/* make_good_string from shp_loader*/
+char * make_good_string(char *str)
+{
+	/*
+	 * find all the tabs and make them \<tab>s
+	 *
+	 * 1. find # of tabs
+	 * 2. make new string 
+	 *
+	 * we dont escape already escaped tabs
+	 */
+
+	char *result;
+	char *ptr, *optr;
+	int toescape = 0;
+	size_t size;
+#ifdef USE_ICONV
+	char *utf8str=NULL;
+
+	if ( encoding )
+	{
+		utf8str=utf8(encoding, str);
+		if ( ! utf8str ) exit(1);
+		str = utf8str; 
+	}
+#endif
+
+	ptr = str;
+
+	while (*ptr) {
+		if ( *ptr == '\t' || *ptr == '\\' ) toescape++;
+		ptr++;
+	}
+
+	if (toescape == 0) return str;
+
+	size = ptr-str+toescape+1;
+
+	result = calloc(1, size);
+
+	optr=result;
+	ptr=str;
+	while (*ptr) {
+		if ( *ptr == '\t' || *ptr == '\\' ) *optr++='\\';
+		*optr++=*ptr++;
+	}
+	*optr='\0';
+
+#ifdef USE_ICONV
+	if ( encoding ) free(str);
+#endif
+
+	return result;
+	
+}
+
+void CheckAndCorrectColormap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		if (r[i] >= 256 || g[i] >= 256 || b[i] >= 256)
+			return;
+	TIFFWarning(TIFFFileName(tif), "Scaling 8-bit colormap");
+#define	CVT(x)		(((x) * ((1L<<16)-1)) / 255)
+	for (i = 0; i < n; i++) {
+		r[i] = CVT(r[i]);
+		g[i] = CVT(g[i]);
+		b[i] = CVT(b[i]);
+	}
+#undef CVT
+}
+
+/* protect_quotes_string from shp_loader*/
+char * protect_quotes_string(char *str)
+{
+	/*
+	 * find all quotes and make them \quotes
+	 * find all '\' and make them '\\'
+	 * 	 
+	 * 1. find # of characters
+	 * 2. make new string 
+	 */
+
+	char	*result;
+	char	*ptr, *optr;
+	int	toescape = 0;
+	size_t size;
+#ifdef USE_ICONV
+	char *utf8str=NULL;
+
+	if ( encoding )
+	{
+		utf8str=utf8(encoding, str);
+		if ( ! utf8str ) exit(1);
+		str = utf8str; 
+	}
+#endif
+
+	ptr = str;
+
+	while (*ptr) {
+		if ( *ptr == '\'' || *ptr == '\\' ) toescape++;
+		ptr++;
+	}
+
+	if (toescape == 0) return str;
+	
+	size = ptr-str+toescape+1;
+
+	result = calloc(1, size);
+
+	optr=result;
+	ptr=str;
+	while (*ptr) {
+		if ( *ptr == '\'' || *ptr == '\\' ) *optr++='\\';
+		*optr++=*ptr++;
+	}
+	*optr='\0';
+
+#ifdef USE_ICONV
+	if ( encoding ) free(str);
+#endif
+
+	return result;
+}
+
+
+/********************************************************************/
+/******************** Functions for Data Loading ********************/
+/********************************************************************/
+void ParseAndCreateConnection(int ARGC, char **ARGV)
+{
+	/* Definition and Initialization for local/global variables */
+	big_endian = is_bigendian();
+
+	geotiff_file = NULL;
+	table = NULL;
+	schema = NULL;
+	geotiff_filename = NULL;
+	rowbuflen=100;
+	keep_fieldname_case = 0;
+	conn = NULL;
+	res = NULL;
+
+	if ( getenv("ROWBUFLEN") ) rowbuflen=atoi(getenv("ROWBUFLEN"));
+	/*
+	 * Make sure dates are returned in ISO
+	 * style (YYYY-MM-DD).
+	 * This is to allow goodDBFValue() function 
+	 * to successfully extract YYYYMMDD format
+	 * expected in shapefile's dbf file.
+	 */
+	putenv("PGDATESTYLE=ISO");
+
+	if ( ! parse_commandline(ARGC, ARGV) ) 
+	{
+		if(outmode != MODE_QUIET)
+		{	fprintf(stderr, "**ERROR** invalid option or command parameters.\n");
+			usage(ARGV[0], 2, stderr);
+		}
+		
+		exit_nicely(conn,1);
+	}
+
+#ifdef DEBUG
+	if(	getenv("PGHOST") != NULL && getenv("PGUSER") != NULL && 
+		getenv("PGPORT") != NULL && getenv("PGDATABASE") != NULL && 
+		getenv("PGPASSWORD") != NULL
+		)
+		fprintf(stdout, "PGHOST=%s PGPORT=%s PGDATABASE=%s PGUSER=%s PGPASSWORD=%s\n",
+				getenv("PGHOST"), getenv("PGPORT"), getenv("PGDATABASE"),
+				getenv("PGUSER"), getenv("PGPASSWORD"));
+	fprintf(stdout, "SCHEMA=%s TABLE=%s geotiff_file=%s geotiff_filename=%s\n",schema,table,geotiff_file,geotiff_filename);
+#endif
+	
+	if(outmode != MODE_QUIET)
+	{
+		fprintf(stdout, "****************************************************************\n");
+		fprintf(stdout, "****************** PGRaster2GeoTIFF Converter ******************\n");
+		fprintf(stdout, "****************************************************************\n");
+		fprintf(stdout, "From PostgreSQL:\n\t host=%s PGPORT=%s database=%s user=%s password=%s schema=%s table=%s \n",
+				getenv("PGHOST"), getenv("PGPORT"), getenv("PGDATABASE"),
+				getenv("PGUSER"), getenv("PGPASSWORD"),schema,table);
+		
+		fprintf(stdout, "To GeoTIFF:\n\tgeotiff_file=%s geotiff_filename=%s\n",  geotiff_file,geotiff_filename);
+	}
+}
+
+/* Step 1. Initialization*/
+void Initialization()
+{
+	/* Declare local variable */
+	char query[QUERY_BUF_LENGTH]; 
+	bool bResult = FALSE;
+
+	if(outmode == MODE_VERBOSE)
+	{
+ 		fprintf(stdout, "Start initializing data export from PGRaster to GeoTIFF......\n");
+	}
+
+	/* Make a connection to the specified database, and exit on failure */
+	// All the necessary information is stored in OS Env-Variables
+	conn = PQconnectdb("");
+	if (PQstatus(conn) != CONNECTION_OK) 
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error**: when making connection to PostgreSQL: %s", PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+
+#ifdef DEBUG
+	fprintf(stdout,"Connection OK!!!");
+#endif  /* DEBUG */
+
+#ifdef DEBUG
+	debug = fopen("geotiff2pgraster.log", "wt");
+	PQtrace(conn, debug);
+#endif	/* DEBUG */
+
+#ifdef DEBUG
+	_CleanUpDemo();
+#endif
+
+	/*
+	 * Check Input Schema & Table Valid for Insert???
+	 */
+	sprintf(query, "SELECT CheckRasterValidity('%s','%s')", schema, table); 
+
+#ifdef DEBUG
+	printf("Query=%s\n", query);
+#endif
+
+
+ 	res = PQexecParams(conn,
+                       query,
+                       0,       
+                       NULL,    
+                       NULL,
+                       NULL,
+                       NULL,
+                       1);      /* ask for binary results */
+
+ 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+  	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when check raster name validity: %s", PQerrorMessage(conn));
+        PQclear(res);
+        exit_nicely(conn,1);
+  	}	
+	else
+	{
+		bResult = ((byte*)PQgetvalue(res,0,0))[0];
+		PQclear(res);
+	}
+
+	if(bResult == TRUE)
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stdout, "Current schema & table name does NOT exist. Please try again using a different pair.");
+		exit_nicely(conn, 1);
+	}
+	else
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stdout, "Current schema & table name exist.\n");
+	}
+
+	/*
+	 * Read metadata from PGRaster into local variable 
+	 */
+	_ReadPGRasterMetadata();
+
+
+	/*
+	 * Create GeoTIFF file and prepare for data and metadata writing.
+	 */
+	_CreateGeoTIFF();
+
+	/*
+	 * Write GeoTIFF metadata into header. 
+	 */
+	_WriteGeoTIFFHeader();
+
+	if(outmode == MODE_VERBOSE)
+	{
+ 		fprintf(stdout, "Finish data loader initializaiton.\n");
+	}
+}
+
+/* Clean files in last demo */
+void _CleanUpDemo()
+{
+	FILE *f_old = fopen(protect_quotes_string(geotiff_file),"r");
+	if(f_old != NULL)
+	{
+		fclose(f_old);
+		remove(protect_quotes_string(geotiff_file));
+	}
+}
+
+void _ReadPGRasterMetadata()
+{
+	/*
+     * Open the file, read the GeoTIFF information 
+     */
+	char query[QUERY_BUF_LENGTH];
+
+	if(outmode == MODE_VERBOSE)
+	{
+ 		fprintf(stdout, "Start reading PGRaster metadata......\n");
+	}
+
+	// Read information from PGRASTER_META
+	memset(query, '\0' , QUERY_BUF_LENGTH);
+
+	sprintf(query, "SELECT rasterObjectID, name, capturedate,rasterdimensions,rasterbandtype,rasterdatatype,rastervaluetype,rasterbandcount,rasterrowcount,rastercolumncount,rastercelldepth,rasterpyramidenabled, rasterpyramiddepth,blocksizebands,blocksizerows,blocksizecolumns,blockpadding,blockbandinterleaving,blockcompression,blockquality,nodatavalue,srid, georeferenced FROM \"%s\".\"pgraster_metadata\" WHERE rasterSchema='%s' AND rasterDataTable='%s'",
+						schema,schema,table);
+
+	res = PQexec(conn,query);
+#ifdef DEBUG
+	printf("Query 1: %s\n",query);
+#endif
+
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+  	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when fecthing metadata information from PostgreSQL: %s\n.", PQerrorMessage(conn));
+		
+		PQclear(res);
+
+        exit_nicely(conn,1);
+  	}	
+	else
+	{
+		//rasterObjectID
+		objectid = atoi(PQgetvalue(res,0,0));		
+			
+		//Name
+		pgraster_name = malloc(PQgetlength(res,0,1));
+		memcpy(pgraster_name, (char*)(PQgetvalue(res,0,1)),PQgetlength(res,0,1));
+
+		//Capture Date
+		captureDate = malloc(PQgetlength(res,0,2));
+		memcpy(captureDate, (char*)(PQgetvalue(res,0,2)),PQgetlength(res,0,2));
+
+		//Dimensions
+		dimensions = atoi(PQgetvalue(res,0,3));
+
+		//rasterbandtype
+		bandtype = atoi(PQgetvalue(res,0,4));
+		
+		//rasterdatatype
+		datatype = atoi(PQgetvalue(res,0,5));
+
+		//rastervaluetype,
+		valuetype = atoi(PQgetvalue(res,0,6));
+
+		//rasterbandcount 
+		bands = atoi(PQgetvalue(res,0,7));
+
+		//rasterrowcount
+		rows = atoi(PQgetvalue(res,0,8));
+
+		//rastercolumncount
+		cols = atoi(PQgetvalue(res,0,9));
+
+		//rastercelldepth
+		nRealBitsPerPixel = atoi(PQgetvalue(res,0,10));
+
+		//rasterpyramidenabled
+		nPyramidEnabled = atoi(PQgetvalue(res,0,11));
+
+		//rasterpyramiddepth
+		nPyramidDepth = atoi(PQgetvalue(res,0,12));
+
+		//blocksizebands
+		blocksizeBands = atoi(PQgetvalue(res,0,13));	
+
+		//blocksizerows
+		blocksizeRows = atoi(PQgetvalue(res,0,14));
+
+		//blockcolumns
+		blocksizeColumns = atoi(PQgetvalue(res,0,15));
+
+		//blockpadding
+		padding = atoi(PQgetvalue(res,0,16));	
+
+		//blockbandinterleaving
+		blockBandInterleaving = atoi(PQgetvalue(res,0,17));
+
+		//blockcompression
+		blockCompression = atoi(PQgetvalue(res,0,18));
+
+		//blockquality,
+		blockQuality = atoi(PQgetvalue(res,0,18));
+
+		//nodatavalue
+		dblNodataValue = atof(PQgetvalue(res,0,19));
+		
+		//srid
+		SRID = atoi(PQgetvalue(res,0,20));
+
+		//georeferenced
+		georeferenced = atoi(PQgetvalue(res,0,21));
+
+#ifdef DEBUG
+		printf("SRID: %d\n", SRID);
+#endif 
+
+		PQclear(res);
+	}
+
+	// Read spatial extent information from PGRASTER_METADATA
+	memset(query, '\0' , QUERY_BUF_LENGTH);
+	sprintf(query, "SELECT AsBinary(spatialextent) FROM \"%s\".\"pgraster_metadata\" WHERE rasterSchema='%s' AND rasterDataTable='%s'",	schema,schema,table);
+	res = PQexecParams(conn,
+                       query,
+                       0,       
+                       NULL,    
+                       NULL,
+                       NULL,    
+                       NULL,    
+                       1); // Binary Format  
+
+#ifdef DEBUG
+	printf("Query 1: %s\n",query);
+#endif
+
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+  	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when fecthing SRS information from PostgreSQL:%s\n.", PQerrorMessage(conn));
+		
+		PQclear(res);
+
+        exit_nicely(conn,1);
+  	}	
+	else
+	{
+		//AsBinary(spatialextent)
+		spatialExtent = (WKBGeometry*)malloc(sizeof(char)*PQgetlength(res,0,0));
+		memcpy((byte*)spatialExtent, (byte*)PQgetvalue(res,0,0), PQgetlength(res,0,0));
+	
+#ifdef DEBUG
+		printf("WKB Size: %d, WKT: \n", PQgetlength(res,0,0));
+#endif
+	}
+
+	// Read spatial metadata information from PGRASTER_SRS
+	memset(query, '\0' , QUERY_BUF_LENGTH);
+	sprintf(query, "SELECT srid::integer,spatialresolutionx::double precision,spatialresolutiony::double precision,spatialresolutionz::double precision,rowdenominator[1]::double precision,rowdenominator[2]::double precision,rowdenominator[3]::double precision, columndenominator[1]::double precision,columndenominator[2]::double precision,columndenominator[3]::double precision FROM \"%s\".\"pgraster_srs\" WHERE rasterObjectID=%Ld", schema, objectid);
+	res = PQexecParams(conn,
+                       query,
+                       0,       
+                       NULL,    
+                       NULL,
+                       NULL,    
+                       NULL,    
+                       1); // Binary Format  
+
+#ifdef DEBUG
+	printf("Query 1: %s\n",query);
+#endif
+
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+  	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when fecthing SRS information from PostgreSQL:%s\n.", PQerrorMessage(conn));
+		
+		PQclear(res);
+
+        exit_nicely(conn,1);
+  	}	
+	else
+	{	
+	
+		//SRID
+		SRID = _ntohl(((int*)PQgetvalue(res,0,0))[0]);
+
+		//spatialresolutionx 
+		xGeoResolution = _ntohd(((double*)PQgetvalue(res,0,1))[0]);
+
+		//spatialresolutiony
+		yGeoResolution = _ntohd(((double*)PQgetvalue(res,0,2))[0]);
+
+		//spatialresolutionz 
+		zGeoResolution = _ntohd(((double*)PQgetvalue(res,0,3))[0]);
+
+#ifdef DEBUG
+		printf("SRID: %d, xGeoResolution: %f, yGeoResolution: %f,zGeoResolution: %f\n", SRID, xGeoResolution,yGeoResolution,zGeoResolution);
+#endif
+
+		//rowdenominator
+		rowDominator[0] = _ntohd(((double*)PQgetvalue(res,0,4))[0]);
+		rowDominator[1] = _ntohd(((double*)PQgetvalue(res,0,5))[0]);
+		rowDominator[2] = _ntohd(((double*)PQgetvalue(res,0,6))[0]);
+
+		//columndenominator
+		columnDominator[0] = _ntohd(((double*)PQgetvalue(res,0,7))[0]);
+		columnDominator[1] = _ntohd(((double*)PQgetvalue(res,0,8))[0]);
+		columnDominator[2] = _ntohd(((double*)PQgetvalue(res,0,9))[0]);
+
+#ifdef DEBUG
+		printf("rowDominator: %f, %f, %f\n ", rowDominator[0],rowDominator[1],rowDominator[2]);
+#endif
+		
+		PQclear(res);
+	}
+
+	// XXX: Not finished.
+	// Read information from PGRASTER_PALETTE (Skip this part.)		
+
+	// Pop Information into mode,sampleperpixel, bitspersample, sampleformat
+	if(bandtype == BT_RGB && datatype == DT_24BIT_RGB)
+	{
+		spp = bands * 3;
+		mode = PHOTOMETRIC_RGB;
+		bps = nTIFFBitsPerPixel / spp;
+		format = SAMPLEFORMAT_UINT;
+	}
+	else if(bandtype == BT_RGBA && datatype == DT_32BIT_RGBA)
+	{
+		spp = bands * 4;
+		mode = PHOTOMETRIC_RGB;
+		bps = nTIFFBitsPerPixel / spp;
+		format = SAMPLEFORMAT_UINT;
+	}
+	else 
+	{
+		spp = bands;
+		mode = PHOTOMETRIC_MINISBLACK;
+		bps = nRealBitsPerPixel/spp;
+		
+		switch(datatype)
+		{
+			case DT_1BIT:
+			case DT_2BIT:
+			case DT_4BIT:
+			case DT_8BIT_U:
+			case DT_16BIT_U:
+			case DT_32BIT_U:
+			//case DT_64BIT_U:
+				format = SAMPLEFORMAT_UINT;
+				break;
+
+			case DT_8BIT_S:
+			case DT_16BIT_S:
+			case DT_32BIT_S:
+			//case DT_64BIT_S:
+				format = SAMPLEFORMAT_INT;
+				break;
+
+			case DT_32BIT_REAL:
+				format = SAMPLEFORMAT_IEEEFP;
+				break;
+			
+			default:
+				format = SAMPLEFORMAT_VOID;
+				break;
+		}
+	}
+
+	if(outmode == MODE_VERBOSE)
+	{
+ 		fprintf(stdout, "Finish reading PGRaster metadata.\n");
+	}
+}
+
+void _CreateGeoTIFF()
+{
+	//Set BigEndian as default output byte order
+	uint16 tif_magic;
+	FILE* ftifftemp = fopen(geotiff_file, "w");
+			
+	if(ftifftemp == NULL)
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when open another instance of TIFF file\n");
+		exit_nicely(conn, 1);
+	}
+	fseek(ftifftemp,0,SEEK_SET);
+	if(big_endian)
+		tif_magic = TIFF_BIGENDIAN;
+	else
+		tif_magic = TIFF_LITTLEENDIAN;
+	fwrite(&tif_magic,sizeof(tif_magic),1, ftifftemp);
+	fclose(ftifftemp);
+	ftifftemp = NULL;
+	
+	tif=XTIFFOpen(geotiff_file,"w");
+	if (!tif) 
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when creating TIFF file.\n");
+		exit_nicely(conn,1);
+	}
+	
+	gtif = GTIFNew(tif);
+	if (!gtif)
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when creating GeoTIFF file.\n");
+		exit_nicely(conn,1);
+	}
+	
+	_SetUpTIFFDirectory(tif);
+
+	_SetUpGeoKeys(gtif);
+}
+
+void _SetUpTIFFDirectory(TIFF *tif)
+{
+	double pixscale[3]={xGeoResolution,yGeoResolution,zGeoResolution};
+	
+	TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,    cols);
+	TIFFSetField(tif,TIFFTAG_IMAGELENGTH,   rows);
+	TIFFSetField(tif,TIFFTAG_COMPRESSION,   compression);
+	TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,  format);
+	TIFFSetField(tif,TIFFTAG_PLANARCONFIG,  planar);
+	TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, bps);
+	TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,  mode);
+	TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,  rowsperstrip);
+	TIFFSetField(tif,TIFFTAG_FILLORDER, 	fillorder);
+	TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3,pixscale);
+}
+
+//XXX: NOT FINISHED
+void _SetUpGeoKeys(GTIF *gtif)
+{
+	// Should we read information from spatial_ref_sys 
+	// and parase them from the text???
+	GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
+	GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
+	GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, "Unknown GTCitationGeoKey");
+	GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT,  1, KvUserDefined);
+	GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "Unknow GeogCitationGeoKey");
+	GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT,  1, Angular_Degree);
+	GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT,  1, Linear_Meter);
+	GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT,     1, KvUserDefined);
+	GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT,     1, Ellipse_Everest_1830_1967_Definition);
+	GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, (double)6377298.556);
+	GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, (double)300.8017);
+
+	//
+		
+}
+
+void _WriteGeoTIFFHeader()
+{
+	/* Write SRS Information*/
+
+	/* Write tiepoints through spatial extent or TFW information*/
+	{
+		double	pixsize[3], xoff, yoff, tiepoint[6], x_rot, y_rot;
+		
+		pixsize[0] = columnDominator[1];
+		y_rot = rowDominator[2];
+		x_rot = columnDominator[2];
+		pixsize[1] = rowDominator[1];
+		xoff = columnDominator[0];
+		yoff = rowDominator[0];
+
+#ifdef DEBUG	
+		printf("%f\n,%f\n,%f\n,%f\n,%f\n,%f\n", pixsize[0],y_rot,x_rot,pixsize[1],xoff,yoff);
+#endif
+		/*
+     	 * Write out pixel scale, and tiepoint information.
+     	 */
+    	if( x_rot == 0.0 && y_rot == 0.0 )
+    	{
+        	pixsize[1] = ABS(pixsize[1]);
+        	pixsize[2] = 0.0;
+        	TIFFSetField(tif, GTIFF_PIXELSCALE, 3, pixsize);
+
+        	tiepoint[0] = 0.5;
+        	tiepoint[1] = 0.5;
+        	tiepoint[2] = 0.0;
+        	tiepoint[3] = xoff;
+        	tiepoint[4] = yoff;
+        	tiepoint[5] = 0.0;
+        	TIFFSetField(tif, GTIFF_TIEPOINTS, 6, tiepoint);
+    	}
+    	else
+    	{
+        	double	adfMatrix[16];
+        
+        	memset(adfMatrix,0,sizeof(double) * 16);
+        
+        	adfMatrix[0] = pixsize[0];
+        	adfMatrix[1] = x_rot;
+        	adfMatrix[3] = xoff - (pixsize[0]+x_rot) * 0.5;
+        	adfMatrix[4] = y_rot;
+        	adfMatrix[5] = pixsize[1];
+        	adfMatrix[7] = yoff - (pixsize[1]+y_rot) * 0.5;
+        	adfMatrix[15] = 1.0;
+        
+        	TIFFSetField( tif, TIFFTAG_GEOTRANSMATRIX, 16, adfMatrix );
+    	}
+	}
+}
+
+void WriteTIFFData()
+{
+
+/*
+ *	int i;
+	char buffer[WIDTH];
+	
+	memset(buffer,0,(size_t)WIDTH);
+	for (i=0;i<HEIGHT;i++)
+		if (!TIFFWriteScanline(tif, buffer, i, 0))
+			TIFFError("WriteImage","failure in WriteScanline\n");
+ */
+	char *exptStmt = malloc(strlen(schema)+1+strlen(table));
+	char query[QUERY_BUF_LENGTH];
+	const char *paramValues[2];
+	int         paramLengths[2];
+	int         paramFormats[2];
+	char *buffer = NULL;
+	int i=0,j=0,k=0,n=0;
+	_uint32 curBlockRow,curBlockBand;
+	_uint32 rowsReturned = 0;
+	_uint32 rowsToRead = 0;
+	rowsperstrip = blocksizeRows;
+	nTIFFBytePerPixel = (bps/8) * spp;
+	_uint32 stripsize = cols * rowsperstrip * bps * spp;
+	
+	if(stripsize % 8 == 0 )
+		stripsize =stripsize / 8;
+	else
+		stripsize = stripsize / 8 + 1;
+
+	if(rows % rowsperstrip == 0)
+		stripMax = rows / rowsperstrip;
+	else
+		stripMax = rows / rowsperstrip + 1;
+
+#ifdef DEBUG
+	printf("nTIFFBytePerPixel:%d, rowsperstrip: %d, stripMax: %d, stripsize: %d\n", 
+			nTIFFBytePerPixel, rowsperstrip,stripMax,  stripsize);
+#endif
+	
+	memcpy(exptStmt, schema, strlen(schema));
+	exptStmt[strlen(schema)] = '_';
+	memcpy(exptStmt+strlen(schema)+1, table, strlen(table));
+	
+	
+	memset(query,'\0',QUERY_BUF_LENGTH);
+	sprintf(query, "SELECT * FROM \"%s\".\"%s\" WHERE rasterObjectID=%d AND pyramidlevel=1 AND rowblocknumber=$1 AND bandblocknumber=$2 ORDER BY columnblocknumber",schema,table,(int)objectid);
+	
+	res = PQprepare( 	conn,
+                    	exptStmt,
+                    	query,
+                    	2,
+                    	NULL);
+	if ( PQresultStatus(res) != PGRES_COMMAND_OK )
+	{
+		if(outmode != MODE_QUIET)
+			fprintf(stderr, "**Error** when trying to create prepared statement for data exporting at server side: %s\n.",PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+	PQclear(res);
+	
+
+	buffer = malloc(stripsize);
+	for(i = 0 ; i < stripMax; i++)
+	{
+		memset(buffer,0, stripsize);
+	
+		if(i != (stripMax-1))
+			rowsToRead = rowsperstrip;
+		else
+			rowsToRead = rows - (stripMax - 1) * rowsperstrip;
+
+		curBlockRow = _htonl((_uint32)i+1);
+		paramValues[0] = (char*)(&(curBlockRow));
+		paramLengths[0] = sizeof(curBlockRow);
+		paramFormats[0] = 1; 
+
+#ifdef DEBUG
+		printf("rowsToRead: %d\n", rowsToRead);
+#endif	
+
+		for(j = 0; j < bands; j++)
+		{
+			curBlockBand = _htonl((_uint32)j+1);
+			paramValues[1] = (char*)(&(curBlockBand));
+			paramLengths[1] = sizeof(curBlockBand);
+			paramFormats[1] = 1;
+
+			// Execute Prepared Statement
+			res = PQexecPrepared( 	conn,
+                       				exptStmt,
+                       				2,           
+                       				paramValues,
+                       				paramLengths, 
+                       				paramFormats, 
+                       				1
+								);
+
+			if ( res == NULL || PQresultStatus(res) != PGRES_TUPLES_OK )
+			{
+				if(outmode != MODE_QUIET)
+					fprintf(stderr, "**Error** when trying to read raster data at server side: %s\n.",PQerrorMessage(conn));
+				exit_nicely(conn, 1);
+			}
+
+			//read data buffer
+			rowsReturned = (_uint32)PQntuples(res);
+
+#ifdef DEBUG
+			printf("rowsReturned: %d\n", rowsReturned);
+#endif	
+			
+			for(k = 0; k < rowsReturned; k++)
+			{
+				_uint32 realBlockColumnNumber = _ntohl(*((_uint32*)PQgetvalue(res,k,4)));
+				_uint32 realBlockBandSize = _ntohl(*((_uint32*)PQgetvalue(res,k,5)));
+				_uint32 realBlockRowSize = _ntohl(*((_uint32*)PQgetvalue(res,k,6)));
+				_uint32 realBlockColumnSize = _ntohl(*((_uint32*)PQgetvalue(res,k,7)));
+				byte* pQData = PQgetvalue(res,k,9);
+#ifdef DEBUG
+				printf("realBlockColumnNumber: %d    ", realBlockColumnNumber);
+				printf("realBlockBandSize: %d    ", realBlockBandSize);
+				printf("realBlockRowSize: %d    \n", realBlockRowSize);
+#endif
+				for(n=0; n < realBlockRowSize; n++)
+				{
+					//fill data buffer
+					memcpy(buffer+(cols*n+(realBlockColumnNumber-1)*blocksizeColumns)*nTIFFBytePerPixel, pQData+(realBlockColumnSize*n)*nTIFFBytePerPixel,nTIFFBytePerPixel*realBlockColumnSize);	
+				}
+			}
+
+			PQclear(res);
+		}
+
+		// flush data buffer to TIFF scanline
+		if( TIFFWriteEncodedStrip( tif, i, buffer,
+                                   nTIFFBytePerPixel * rowsToRead * cols ) == -1 )
+		{
+			// Write Failed.
+			if(outmode != MODE_QUIET)
+				fprintf(stderr, "**Error** when trying to write raster data to GeoTIFF file.");
+			exit_nicely(conn, 1);
+		}
+	}
+
+}
+
+void Cleanup()
+{
+	
+	GTIFWriteKeys(gtif);
+	GTIFFree(gtif);
+	XTIFFClose(tif);
+	
+	/* Close Connection*/
+	PQfinish(conn);	
+}
+
+void PrintResultMessage(int sucessful)
+{
+	if(sucessful == 1)
+	{
+		//sucessful
+		fprintf(stdout, "GeoTIFF file '%s' succesfully exported.\n", geotiff_file);
+	}
+	else
+	{
+		//fail
+		fprintf(stdout, "GeoTIFF file '%s' exporting failed.\n", geotiff_file);
+	}
+}

Modified: branches/gSoC2007_raster/pgraster/pgraster_utils.c
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_utils.c	2007-08-17 22:46:15 UTC (rev 2696)
+++ branches/gSoC2007_raster/pgraster/pgraster_utils.c	2007-08-20 01:57:53 UTC (rev 2697)
@@ -36,6 +36,8 @@
 #include "pgraster_const.h"
 #include "math.h"
 
+#pragma pack(1)
+
 /* Some byte data reading/seeking tools */
 void skipbyte(byte **c) {
 	*c+=1;
@@ -411,49 +413,62 @@
 {
   	//return ((n & 0xFF) << 56) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24);
 	return ((_uint64)(_ntohl((_uint32)((n << 32) >> 32))) << 32) | (_uint32)_ntohl(((int)(n >> 32)));
- 
 }
 
 _uint64 _ntohll(_uint64 n)
 {
- 	return _htonll(n); 
+	return _htonll(n);
 }
 
 double _htond(double f)
 {
-    union
+	union
 	{
 		double		f;
 		_uint32		h[2];
 	}swap;
-
+	
 	swap.f = f;
-	swap.h[0] = _htonl(swap.h[0]);
-	swap.h[1] = _htonl(swap.h[1]);
+	swap.h[0] = _ntohl(swap.h[0]);
+	swap.h[1] = _ntohl(swap.h[1]);
 
-    return swap.f;
+	if (!is_bigendian()) // little endian
+	{
+		_uint32 temp = swap.h[0];
+		swap.h[0] = swap.h[1];
+		swap.h[1] = temp;
+	}
+
+	return swap.f;
 }
 
 double _ntohd(double f)
 {
-    union
+	union
 	{
 		double		f;
 		_uint32		h[2];
 	}swap;
-
+	
 	swap.f = f;
-	swap.h[0] = _htonl(swap.h[0]);
-	swap.h[1] = _htonl(swap.h[1]);
+	swap.h[0] = _ntohl(swap.h[0]);
+	swap.h[1] = _ntohl(swap.h[1]);
 
-    return swap.f;
+	if (!is_bigendian()) // little endian
+	{
+		_uint32 temp = swap.h[0];
+		swap.h[0] = swap.h[1];
+		swap.h[1] = temp;
+	}
+
+	return swap.f;
 }
 
 float _htonf(float f)
 {
     union
 	{
-		double		f;
+		float		f;
 		_uint32		i;
 	}swap;
 
@@ -467,7 +482,7 @@
 {
     union
 	{
-		double		f;
+		float		f;
 		_uint32		i;
 	}swap;
 
@@ -476,5 +491,4 @@
 
     return swap.f;
 }
-
-
+#pragma pack()

Modified: branches/gSoC2007_raster/pgraster/pgraster_utils.h
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_utils.h	2007-08-17 22:46:15 UTC (rev 2696)
+++ branches/gSoC2007_raster/pgraster/pgraster_utils.h	2007-08-20 01:57:53 UTC (rev 2697)
@@ -119,7 +119,6 @@
 
 _uint16 _htons(_uint16 n);
 
-
 _uint16 _ntohs(_uint16 n);
 
 _uint32 _htonl(_uint32 n);
@@ -130,35 +129,12 @@
 
 _uint64 _ntohll(_uint64 n);
 
-uint32_t _htonf_(float f);
+float _ntohf(float f);
 
-float _ntohf_(uint32_t p);
+float _htonf(float f);
 
-/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
-*     National Laboratory.
-* Copyright (c) 2002 The Regents of the University of California, as
-*     Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution. 
-\*************************************************************************/
+double _ntohd(double d);
 
-/*
- * mitfp.c - routines to convert between VAX float and big endian
- * 		IEEE float
- *
- * Author: Jeffrey O. Hill
- *
- *
- */
+double _htond(double d);
 
-float _ntohf(float ieee);
-
-float _htonf(float mit);
-
-double _ntohlf(double ieee);
-
-double _htonlf(double mit);
-
 #endif

Added: branches/gSoC2007_raster/pgraster/win32/build/pgraster2geotiff.exe
===================================================================
(Binary files differ)


Property changes on: branches/gSoC2007_raster/pgraster/win32/build/pgraster2geotiff.exe
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream



More information about the postgis-commits mailing list