Index: libraries/thuban/gdalwarp.cpp
===================================================================
RCS file: /home/thuban/jail/thubanrepository/thuban/libraries/thuban/gdalwarp.cpp,v
retrieving revision 1.1
diff -u -r1.1 gdalwarp.cpp
--- libraries/thuban/gdalwarp.cpp	19 Aug 2003 21:32:24 -0000	1.1
+++ libraries/thuban/gdalwarp.cpp	20 Jan 2005 16:17:37 -0000
@@ -91,32 +91,23 @@
  *
  */
 
+#include <Python.h>
+
+#include "gdal.h"
 #include "gdal_alg.h"
+#include "gdal_priv.h"
 #include "cpl_string.h"
 #include "ogr_srs_api.h"
-#include "cpl_mfile.h"
-
-CPL_C_START
-void CPL_DLL GDALRegister_THUBANBMP(void);
-CPL_C_END
-
-                                                                                
-/* MFILENAME takes the name of a variable to declare as being the
- * "filename", and the address of a MFILEReceiver.
- */
-#define MFILENAME(name, ptr) \
-char name[ 8 + 2 * sizeof( void* ) + 1]; \
-{snprintf( name, sizeof(name), "\3\1\4MFILE%0*x", 2*sizeof(void*), (int)(ptr)); \
- memset( ptr, 0, sizeof( ptr ) );}
-
 
-#include <Python.h>
 #define PYTHON_ERR(x) \
     {const char *str = CPLGetLastErrorMsg(); \
         str != NULL ? PyErr_SetString(x, str) : PyErr_SetString(x, "");}
 
 #define LEAVE_NOW(e) { err = e; goto getOut; }
 
+#define NO_DATA_VAL 255
+#define NO_DATA_VAL_STR "255"
+
 CPL_CVSID("$Id: gdalwarp.cpp,v 1.1 2003/08/19 21:32:24 jan Exp $");
 
 static GDALDatasetH 
@@ -188,11 +179,193 @@
     return pszResult;
 }
 
+/************************************************************************/
+/*                             GetImageData                             */
+/*                                                                      */ 
+/* Extract the image data from the GDALDataset and pack it into a single*/
+/* array of RGB triples. Use the ColorTable to determine the RGB        */
+/* values. We extract the data from the GDALDataset rather than create  */
+/* our own driver because the data needs to be translated from          */
+/* 4 byte pixel information into 3 byte RGB information. This could be  */
+/* done as the data is written to the data set or afterwards, as it is  */
+/* done here. Any minor savings from our own driver are outweighed by   */
+/* the high development/maintenance costs.                              */
+/*                                                                      */ 
+/* TODO:                                                                */
+/*                                                                      */ 
+/*  o Handle out of memory issues more cleanly than asserting           */ 
+/*  o Handle the case where there is no color table (is there a case?)  */ 
+/*                                                                      */ 
+/************************************************************************/
+
+static CPLErr GetImageData(GDALDataset *ds, 
+                           unsigned char **imgbuf, unsigned int *imglen)
+{
+    CPLErr ret = CE_None;
+
+    GDALColorEntry color;
+    GDALColorTable *pal = NULL;
+
+    int nWordSize = 0;
+
+    ds->FlushCache();
+
+    int rasterCount  = ds->GetRasterCount();
+    int nRasterXSize = ds->GetRasterXSize();
+    int nRasterYSize = ds->GetRasterYSize();
+    if ( ! (nRasterXSize > 0 && nRasterYSize > 0 ))
+        return CE_Failure;
+
+    //
+    // create the new image array for RGBRGB... values
+    //
+    *imglen = 3 * nRasterXSize * nRasterYSize;
+    *imgbuf = new unsigned char[*imglen];
+    if ( *imgbuf == NULL )
+        return CE_Failure;
+
+    memset(*imgbuf, 170, *imglen);
+
+    //
+    // if there are three bands assume for now that they are RGB bands
+    //
+    if (rasterCount == 3)
+    {
+        for (int i=1; i <= rasterCount; i++)
+        {
+            int offs = 0;
+            GDALRasterBand *band = ds->GetRasterBand(i);
+
+            switch (band->GetColorInterpretation())
+            {
+                case GCI_RedBand:   offs = 1; break;
+                case GCI_GreenBand: offs = 2; break;
+                case GCI_BlueBand:  offs = 3; break;
+                default:            offs = i-1; break;
+            }
+
+            //
+            // copy the image into the buffer using the proper offset
+            // so we first copy over all Red values, then all Green
+            // values, and then all Blue values
+            //
+            ret = band->RasterIO(GF_Read, 0, 0, 
+                                 nRasterXSize, nRasterYSize,
+                                 *imgbuf+offs, nRasterXSize, nRasterYSize, 
+                                 GDT_Byte, 3, 0);
+                    
+            if (ret == CE_Failure) break;
+        }
+    }
+    else if (rasterCount == 1)
+    {
+        //
+        // one band is either a palette based image, or greyscale
+        //
+
+        GDALRasterBand *band = ds->GetRasterBand(1);
+
+        switch (band->GetColorInterpretation())
+        {
+            case GCI_PaletteIndex:
+
+                pal = band->GetColorTable();
+                // FIXME: what happens if pal is NULL? ignore?
+                
+                // test this once to see if conversion is supported. 
+                if (pal && pal->GetColorEntryAsRGB(0, &color))
+                {
+                    //
+                    // copy over all the palette indices and then
+                    // loop through the buffer replacing the values
+                    // with the correct RGB triples. 
+                    //
+                    ret = band->RasterIO(GF_Read, 0, 0, 
+                                         nRasterXSize, nRasterYSize,
+                                         *imgbuf, nRasterXSize, nRasterYSize, 
+                                         GDT_Byte, 3, 0);
+                            
+                    if (ret == CE_Failure) break;
+
+                    for (unsigned char *data = *imgbuf;
+                         data != (*imgbuf+*imglen);
+                         data += 3)
+                    {
+                        if (*data == NO_DATA_VAL)
+                        {
+                            *(data + 0) = 3;
+                            *(data + 1) = 1;
+                            *(data + 2) = 4;
+                        }
+                        else
+                        {
+                            pal->GetColorEntryAsRGB(*data, &color);
+
+                            *(data + 0) = color.c1;
+                            *(data + 1) = color.c2;
+                            *(data + 2) = color.c3;
+                        }
+                    }
+                }
+                break;
+
+            case GCI_Undefined: // can we try to make a greyscale image?
+            case GCI_GrayIndex:
+
+                //
+                // copy over all the palette indices and then
+                // loop through the buffer replacing the values
+                // with the correct RGB triples. 
+                //
+                ret = band->RasterIO(GF_Read, 0, 0, 
+                                     nRasterXSize, nRasterYSize,
+                                     *imgbuf, nRasterXSize, nRasterYSize, 
+                                     GDT_Byte, 3, 0);
+                        
+                if (ret == CE_Failure) break;
+
+                for (unsigned char *data = *imgbuf;
+                     data != (*imgbuf+*imglen);
+                     data += 3)
+                {
+                    if (*data == NO_DATA_VAL)
+                    {
+                        *(data + 0) = 3;
+                        *(data + 1) = 1;
+                        *(data + 2) = 4;
+                    }
+                    else
+                    {
+                        //pal->GetColorEntry(*data, &color);
+
+                        //*(data + 0) = *data; // already correct
+                        *(data + 1) = *data;
+                        *(data + 2) = *data;
+                    }
+                }
+                break;
+
+            default:
+                fprintf(stderr,
+                        "GetImageData: Unsupported color interpretation '%s'\n",
+                        GDALGetColorInterpretationName(
+                           band->GetColorInterpretation()));
+                break;
+        }
+    }
+
+    if (ret != CE_None) 
+        if (imgbuf != NULL) delete imgbuf;
+
+    return ret;
+}
+
 static PyObject*
 ProjectRasterFile(PyObject *, PyObject * args)
 {
-    GDALDatasetH	hSrcDS, hDstDS;
-    const char         *pszFormat = "GTiff";
+    GDALDatasetH        hSrcDS = NULL, hDstDS = NULL;
+    const char         *pszFormat = "MEM";
+    const char         *pszDstFilename = "MEM:::"; 
     char               *pszTargetSRS = NULL;
     char               *pszSourceSRS = NULL;
     const char         *pszSrcFilename = NULL;
@@ -203,9 +376,10 @@
     GDALTransformerFunc pfnTransformer = NULL;
     char                **papszCreateOptions = NULL;
     int                 err = 0;
+    unsigned char      *imgbuf = NULL;
+    unsigned int        imglen = 0;
 
-    PyObject * returnFileData = NULL;
-
+    PyObject * pyImageData = NULL;
     PyObject * filename;
     PyObject * srcImageArgs;
     PyObject * dstImageArgs;
@@ -213,11 +387,6 @@
     PyObject * resolution;
     PyObject * imageRes;
 
-    MFILEReceiver receiver;
-    MFILENAME(pszDstFilename, &receiver);
-
-    //dummycall();
-
     if (!PyArg_ParseTuple(args, "OOOOOO", &filename, &srcImageArgs, 
                 &dstImageArgs, 
                 &extents, 
@@ -242,12 +411,10 @@
     nForcePixels = ( int )PyInt_AsLong( PyTuple_GetItem( imageRes, 0 ) );
     nForceLines  = ( int )PyInt_AsLong( PyTuple_GetItem( imageRes, 1 ) );
 
-    pszFormat = "THUBANBMP";
-
     bCreateOutput = TRUE;
 
     GDALAllRegister();
-    GDALRegister_THUBANBMP();
+    GDALRegister_MEM();
 
 /* -------------------------------------------------------------------- */
 /*      Open source dataset.                                            */
@@ -283,7 +450,8 @@
     hDstDS = GDALWarpCreateOutput( hSrcDS, pszDstFilename, pszFormat, 
                                    pszSourceSRS, pszTargetSRS, nOrder,
                                    papszCreateOptions );
-    papszWarpOptions = CSLSetNameValue( papszWarpOptions, "INIT", "0" );
+    papszWarpOptions = CSLSetNameValue( papszWarpOptions, 
+                                        "INIT", NO_DATA_VAL_STR );
     CSLDestroy( papszCreateOptions );
     papszCreateOptions = NULL;
 
@@ -322,6 +490,7 @@
         pfnTransformer = GDALApproxTransform;
     }
 
+
 /* -------------------------------------------------------------------- */
 /*      Now actually invoke the warper to do the work.                  */
 /* -------------------------------------------------------------------- */
@@ -344,24 +513,28 @@
     CPLErrorReset();
     err = 0;
 
-getOut:
+    imglen = 0;
+    imgbuf = NULL;
 
-    GDALClose( hDstDS );
-    GDALClose( hSrcDS );
+    if ( GetImageData((GDALDataset *)hDstDS, &imgbuf, &imglen) == CE_None)
+    {
+        //printf("imglen: %i\n", imglen);
 
-    if ( receiver.data != NULL )
+        pyImageData = PyString_FromStringAndSize( ( char * )imgbuf, imglen);
+
+        delete imgbuf;
+        imgbuf = NULL;
+    }
+    else
     {
-        returnFileData = PyString_FromStringAndSize( ( char * )receiver.data, 
-                                                 receiver.len );
-#if 0
-        FILE *fp;
-        fp = fopen("dummy.bmp", "w+b");
-        fwrite(receiver->data, receiver->len, 1, fp);
-        fclose(fp);
-        free( receiver->data );
-#endif
+        PYTHON_ERR( PyExc_StandardError );
     }
 
+getOut:
+
+    GDALClose( hDstDS );
+    GDALClose( hSrcDS );
+
     if ( papszWarpOptions ) CSLDestroy( papszWarpOptions );
     if ( pszTargetSRS != NULL ) CPLFree(pszTargetSRS);
     if ( pszSourceSRS != NULL ) CPLFree(pszSourceSRS);
@@ -378,15 +551,13 @@
 
     if ( err ) 
     {
-        CPLError( CE_Failure, err, "" );
+        //CPLError( CE_Failure, err, "%s\n", CPLGetLastErrorMsg() );
         return NULL;
     }
     else
     {
-        Py_XINCREF( returnFileData );
-        return returnFileData;
+        return pyImageData;
     }
-    
 }
 
 /************************************************************************/
