jonathan: thuban/libraries/thuban gdalwarp.cpp,1.3,1.4

cvs@intevation.de cvs at intevation.de
Fri Jan 28 16:54:02 CET 2005


Author: jonathan

Update of /thubanrepository/thuban/libraries/thuban
In directory doto:/tmp/cvs-serv8849/libraries/thuban

Modified Files:
	gdalwarp.cpp 
Log Message:
Make layer's use_mask flag default to true. Support a bit array describing
the mask to use. Improve error handling in ProjectRasterFile (also addresses
RT #2947).


Index: gdalwarp.cpp
===================================================================
RCS file: /thubanrepository/thuban/libraries/thuban/gdalwarp.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- gdalwarp.cpp	27 Jan 2005 14:17:01 -0000	1.3
+++ gdalwarp.cpp	28 Jan 2005 15:54:00 -0000	1.4
@@ -29,6 +29,11 @@
  ******************************************************************************
  *
  * $Log$
+ * Revision 1.4  2005/01/28 15:54:00  jonathan
+ * Make layer's use_mask flag default to true. Support a bit array describing
+ * the mask to use. Improve error handling in ProjectRasterFile (also addresses
+ * RT #2947).
+ *
  * Revision 1.3  2005/01/27 14:17:01  jonathan
  * Replace the old gdalwarp.cpp code with the non-simple version supplied with
  * gdal. This allows added features such as creating an alpha band.
@@ -125,10 +130,16 @@
         str != NULL ? PyErr_SetString(x, str) : PyErr_SetString(x, "");}
 
 #define PYTHON_ERR(n, str) \
-    {str != NULL ? PyErr_SetString(n, str) : PyErr_SetString(n, "");}
+    {if (str != NULL) PyErr_SetString(n, "");}
+
+#define PYTHON_ERRF(n, str, ...) \
+    {if (str != NULL) PyErr_Format(n, str, ## __VA_ARGS__);}
 
 #define LEAVE_NOW(e) { err = e; goto getOut; }
 
+#define OPTS_MASK  1
+#define OPTS_ALPHA 2
+
 CPL_CVSID("$Id$");
 
 static GDALDatasetH 
@@ -143,6 +154,8 @@
 static double	       dfXRes=0.0, dfYRes=0.0;
 static int             nForcePixels=0, nForceLines=0;
 static int             bEnableDstAlpha = FALSE, bEnableSrcAlpha = FALSE;
+static int             bMakeMask, bMakeAlpha;
+const char             *pszSrcFilename = NULL, *pszDstFilename = "MEM:::";
 
 static PyMethodDef gdalwarp_methods[] = {
     { "ProjectRasterFile", ProjectRasterFile, METH_VARARGS },
@@ -224,41 +237,43 @@
 /* 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,
                            unsigned char **maskbuf, 
-                           unsigned int *imglen)
+                           unsigned int   *masklen) 
 {
     CPLErr ret = CE_None;
 
     GDALColorTable *pal = NULL;
 
+
     ds->FlushCache();
 
     int rasterCount  = ds->GetRasterCount();
     int nRasterXSize = ds->GetRasterXSize();
     int nRasterYSize = ds->GetRasterYSize();
     if ( ! (nRasterXSize > 0 && nRasterYSize > 0 ))
+    {
+        PYTHON_ERRF(PyExc_ValueError, 
+                "The dimensions (%ix%i) are invalid in %s", 
+                nRasterXSize, nRasterYSize, pszSrcFilename);
         return CE_Failure;
+    }
 
     //
     // create the new image array for RGBRGB... values
     //
     *imglen = 3 * nRasterXSize * nRasterYSize;
-    *imgbuf = new unsigned char[*imglen];
-    if ( *imgbuf == NULL ) { ret=CE_Failure; goto no_mem; }
-
-    if (bEnableDstAlpha)
+    *imgbuf = (unsigned char*)CPLMalloc(*imglen);
+    if ( *imgbuf == NULL ) 
     {
-        *maskbuf = new unsigned char[*imglen];
-        if ( *maskbuf == NULL ) { ret=CE_Failure; goto no_mem; }
+        PYTHON_ERRF(PyExc_MemoryError, 
+                "The system does not have enough memory to project %s", 
+                pszSrcFilename);
+        return CE_Failure;
     }
 
     //
@@ -293,7 +308,13 @@
                                      nRasterXSize, nRasterYSize,
                                      *imgbuf+offs, nRasterXSize, nRasterYSize, 
                                      GDT_Byte, 3, 0);
-                if (ret == CE_Failure) break;
+                if (ret == CE_Failure)
+                {
+                    PYTHON_ERRF(PyExc_IOError, 
+                        "An unknown error occured while reading band %i in %s",
+                        i, pszSrcFilename);
+                    break;
+                }
             }
         }
     }
@@ -310,10 +331,15 @@
             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 != NULL)
+                if (pal == NULL)
+                {
+                    PYTHON_ERRF(PyExc_IOError, 
+                        "Couldn't find a palette for palette-based image %s", 
+                        pszSrcFilename);
+                    ret = CE_Failure;
+                }
+                else
                 {
                     GDALPaletteInterp pal_interp 
                         = pal->GetPaletteInterpretation();
@@ -328,7 +354,12 @@
                                          *imgbuf, nRasterXSize, nRasterYSize, 
                                          GDT_UInt16, 3, 0);
                             
-                    if (ret == CE_Failure) break;
+                    if (ret == CE_Failure) 
+                    {
+                        PYTHON_ERRF(PyExc_IOError, 
+                            "An unknown error occured while reading band 1 in %s", pszSrcFilename);
+                        break;
+                    }
 
                     for (unsigned char *data = *imgbuf;
                          data != (*imgbuf+*imglen);
@@ -368,7 +399,13 @@
                                      *imgbuf, nRasterXSize, nRasterYSize, 
                                      GDT_Byte, 3, 0);
                         
-                if (ret == CE_Failure) break;
+                if (ret == CE_Failure) 
+                {
+                    PYTHON_ERRF(PyExc_IOError, 
+                        "An unknown error occured while reading band 1 in %s", 
+                        pszSrcFilename);
+                    break;
+                }
 
                 for (unsigned char *data = *imgbuf;
                      data != (*imgbuf+*imglen);
@@ -383,42 +420,129 @@
                 break;
 
             default:
-                fprintf(stderr,
-                        "GetImageData: Unsupported color interpretation '%s'\n",
-                        GDALGetColorInterpretationName(
-                           band->GetColorInterpretation()));
+                PYTHON_ERRF(PyExc_ValueError, 
+                    "Unsupported color interpretation '%s' in image %s", 
+                    GDALGetColorInterpretationName(
+                        band->GetColorInterpretation()),
+                    pszSrcFilename);
+
+                ret = CE_Failure;
                 break;
         }
     }
     else
     {
-        memset(*imgbuf, 170, *imglen);
-        if (bEnableDstAlpha) memset(*maskbuf, 255, *imglen);
+        PYTHON_ERRF(PyExc_ValueError, 
+                  "Unsupported number of raster bands (%i) in image %s\n",
+                  rasterCount, pszSrcFilename);
+
+        ret = CE_Failure;
     }
 
-    if (bEnableDstAlpha && rasterCount > 1)
+    if (ret == CE_None && bEnableDstAlpha && rasterCount > 1)
     {
-        GDALRasterBand *band = ds->GetRasterBand(rasterCount);
+        if (bMakeMask)
+        {
+            //
+            // The mask is really an XBM image. In other words, each
+            // pixel is represented by one bit in a byte array.
+            //
+            // First read the alpha band, and then convert it to
+            // a bit array by thresholding each pixel value at 128.
+            //
+            
+            *masklen = ((nRasterXSize + 7) / 8) * nRasterYSize;
+            *maskbuf = (unsigned char *)CPLMalloc(*masklen);
 
-        // 
-        // Unfortunately, wxImage requires the data be in RGB format,
-        // so here the data is tripled
-        //
-        for (int i=0; i < 3; i++)
+            if ( *maskbuf != NULL )
+            {
+                unsigned char *tmp 
+                    = (unsigned char *)CPLMalloc(nRasterXSize * nRasterYSize);
+
+                if ( tmp == NULL )
+                {
+                    CPLFree(*maskbuf);
+                    *maskbuf = NULL;
+                }
+                else
+                {
+                    GDALRasterBand *band = ds->GetRasterBand(rasterCount);
+
+                    ret = band->RasterIO(GF_Read, 0, 0, 
+                                         nRasterXSize, nRasterYSize,
+                                         tmp, nRasterXSize, nRasterYSize, 
+                                         GDT_Byte, 0, 0);
+
+                    if (ret != CE_Failure)
+                    {
+                        int col = 0;
+                        int index=0, offs = 0;
+
+                        memset(*maskbuf, 0, *masklen);
+
+                        for (int i=0; i < nRasterXSize*nRasterYSize; i++)
+                        {
+                            (*maskbuf)[index] |= (tmp[i] < 128) << offs;
+
+                            col++;
+                            if (col == nRasterXSize)
+                            {
+                                col = 0;
+                                offs = 0;
+                                index++;
+                            }
+                            else
+                            {
+                                offs++;
+                                if (offs == 8)
+                                {
+                                    offs = 0;
+                                    index++;
+                                }
+                            }
+                        }
+                    }
+
+                    CPLFree(tmp);
+                    tmp = NULL;
+                }
+
+            }
+        }
+        else if (bMakeAlpha)
         {
-            ret = band->RasterIO(GF_Read, 0, 0, 
-                                 nRasterXSize, nRasterYSize,
-                                 *maskbuf+i, nRasterXSize, nRasterYSize, 
-                                 GDT_Byte, 3, 0);
+            //
+            // This is the simple case. The array we get back from RasterIO
+            // is already in the correct format.
+            //
+            
+            *masklen = nRasterXSize * nRasterYSize;
+            *maskbuf = (unsigned char *)CPLMalloc(*masklen);
+
+            if ( *maskbuf != NULL )
+            {
+                GDALRasterBand *band = ds->GetRasterBand(rasterCount);
+
+                ret = band->RasterIO(GF_Read, 0, 0, 
+                                     nRasterXSize, nRasterYSize,
+                                     *maskbuf, nRasterXSize, nRasterYSize, 
+                                     GDT_Byte, 0, 0);
+
+#if 0
+                if (ret == CE_Failure)
+                {
+                    CPLFree(*maskbuf);
+                    *maskbuf = NULL;
+                }
+#endif
+            }
         }
     }
 
-no_mem:
-
     if (ret != CE_None) 
     {
-        if (imgbuf  != NULL) { delete imgbuf; imgbuf = NULL; }
-        if (maskbuf != NULL) { delete maskbuf; maskbuf = NULL; }
+        if (*imgbuf  != NULL) { CPLFree(*imgbuf);  *imgbuf  = NULL; }
+        if (*maskbuf != NULL) { CPLFree(*maskbuf); *maskbuf = NULL; }
     }
 
     return ret;
@@ -435,7 +559,6 @@
     const char         *pszFormat = "MEM";
     char               *pszTargetSRS = NULL;
     char               *pszSourceSRS = NULL;
-    const char         *pszSrcFilename = NULL, *pszDstFilename = "MEM:::";
     int                 bCreateOutput = FALSE, i, nOrder = 0;
     void               *hTransformArg, *hGenImgProjArg=NULL, *hApproxArg=NULL;
     char               **papszWarpOptions = NULL;
@@ -450,6 +573,8 @@
     unsigned char      *imgbuf = NULL;
     unsigned int        imglen = 0;
     unsigned char      *maskbuf = NULL;
+    unsigned int        masklen = 0;
+    int                 options = 0;
 
     GDALWarpOperation oWO;
     GDALWarpOptions *psWO = NULL;
@@ -462,7 +587,7 @@
     PyObject * extents;
     PyObject * resolution;
     PyObject * imageRes;
-    PyObject * mask;
+    PyObject * opts;
     PyObject * pyReturnData = NULL;
 
 
@@ -470,7 +595,7 @@
                 &dstImageArgs, 
                 &extents, 
                 &resolution, &imageRes,
-                &mask))
+                &opts))
     {
         return NULL;
     }
@@ -490,7 +615,13 @@
     nForcePixels = ( int )PyInt_AsLong( PyTuple_GetItem( imageRes, 0 ) );
     nForceLines  = ( int )PyInt_AsLong( PyTuple_GetItem( imageRes, 1 ) );
 
-    bEnableDstAlpha = mask == Py_True;
+    options  = ( int )PyInt_AsLong( opts );
+    bMakeMask  = (options & OPTS_MASK) == OPTS_MASK;
+    bMakeAlpha = (options & OPTS_ALPHA) == OPTS_ALPHA;
+
+    // FIXME: error if bMakeMask == bMaskAlpha
+
+    bEnableDstAlpha = bMakeMask || bMakeAlpha;
 
     GDALAllRegister();
 
@@ -521,8 +652,9 @@
 
     if( pszTargetSRS != NULL && strlen(pszSourceSRS) == 0 )
     {
-        PYTHON_ERR(PyExc_ValueError, 
-            "A target projection was specified, but there is no source projection." );
+        PYTHON_ERRF(PyExc_ValueError, 
+            "A target projection was specified, "
+            "but there is no source projection in %s", pszSrcFilename );
         LEAVE_NOW( 1 );
     }
 
@@ -560,7 +692,9 @@
 
     if( hDstDS == NULL )
     {
-        PYTHON_CPL_ERR( PyExc_IOError );
+        PYTHON_ERRF(PyExc_IOError, 
+            "Error creating destination image for projecting %s",
+            pszSrcFilename);
         LEAVE_NOW( CPLE_FileIO );
     }
 
@@ -573,9 +707,10 @@
                                          hDstDS, pszTargetSRS, 
                                          TRUE, 1000.0, nOrder );
 
+
     if( hTransformArg == NULL )
     {
-        PYTHON_CPL_ERR( PyExc_ValueError );
+        PYTHON_CPL_ERR(PyExc_ValueError );
         LEAVE_NOW( CPLE_IllegalArg );
     }
 
@@ -762,17 +897,16 @@
 
     imglen = 0;
     imgbuf = NULL;
+    masklen = 0;
     maskbuf = NULL;
 
-#if 1
-
-    if ( GetImageData((GDALDataset *)hDstDS, &imgbuf, &maskbuf, &imglen) 
-            == CE_None)
+    if ( GetImageData((GDALDataset *)hDstDS, 
+                      &imgbuf, &imglen, &maskbuf, &masklen) == CE_None)
     {
         pyImageData = PyString_FromStringAndSize( ( char * )imgbuf,  imglen);
 
-        if (bEnableDstAlpha)
-            pyMaskData = PyString_FromStringAndSize( ( char * )maskbuf, imglen);
+        if (bEnableDstAlpha && maskbuf != NULL)
+            pyMaskData = PyString_FromStringAndSize( ( char * )maskbuf,masklen);
         else
             pyMaskData = Py_None;
 
@@ -780,14 +914,10 @@
         PyTuple_SetItem(pyReturnData, 0, pyImageData);
         PyTuple_SetItem(pyReturnData, 1, pyMaskData);
 
-        if (imgbuf  != NULL) { delete imgbuf;  imgbuf  = NULL; }
-        if (maskbuf != NULL) { delete maskbuf; maskbuf = NULL; }
-    }
-    else
-    {
-        PYTHON_CPL_ERR( PyExc_StandardError );
+        if (imgbuf  != NULL) { CPLFree(imgbuf);  imgbuf  = NULL; }
+        if (maskbuf != NULL) { CPLFree(maskbuf); maskbuf = NULL; }
+
     }
-#endif
 
 getOut:
 
@@ -837,6 +967,8 @@
     double adfDstGeoTransform[6];
     int nPixels=0, nLines=0;
 
+    CPLErrorReset();
+
     if( eDT == GDT_Unknown )
         eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDS,1));
 
@@ -883,6 +1015,16 @@
 
     if( hTransformArg == NULL )
         return NULL;
+
+    //
+    // This could happen if the proj library didn't load correctly
+    // Fixes RF#2947
+    //
+    if (CPLGetLastErrorNo() != CE_None)
+    {
+        GDALDestroyGenImgProjTransformer(hTransformArg);
+        return NULL;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Get approximate output definition.                              */





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)