Revision: 4264
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4264&view=rev
Author:   efiring
Date:     2007-11-13 23:45:12 -0800 (Tue, 13 Nov 2007)

Log Message:
-----------
A step towards a fast rectilinear pcolor version

Modified Paths:
--------------
    trunk/matplotlib/src/_image.cpp
    trunk/matplotlib/src/_image.h

Modified: trunk/matplotlib/src/_image.cpp
===================================================================
--- trunk/matplotlib/src/_image.cpp     2007-11-14 04:03:46 UTC (rev 4263)
+++ trunk/matplotlib/src/_image.cpp     2007-11-14 07:45:12 UTC (rev 4264)
@@ -1403,8 +1403,8 @@
   // Create output
   Image* imo = new Image;
   imo->rowsIn = rows;
+  imo->colsIn = cols;
   imo->rowsOut = rows;
-  imo->colsIn = cols;
   imo->colsOut = cols;
   size_t NUMBYTES(rows * cols * 4);
   agg::int8u *buffer = new agg::int8u[NUMBYTES];
@@ -1499,6 +1499,227 @@
   return Py::asObject(imo);
 }
 
+void _bin_indices(int *irows, int nrows, double *y, int ny,
+                                            double sc, double offs)
+{
+    int i;
+    if (sc*(y[ny-1] - y[0]) > 0)
+    {
+        int ii = 0;
+        int iilast = ny-1;
+        int iy0 = (int)floor(sc * (y[ii]  - offs));
+        int iy1 = (int)floor(sc * (y[ii+1]  - offs));
+        for (i=0; i<nrows && i<iy0; i++) {
+            irows[i] = -1;
+        }
+        for (; i<nrows; i++) {
+            while (i > iy1 && ii < iilast) {
+                ii++;
+                iy0 = iy1;
+                iy1 = (int)floor(sc * (y[ii+1] - offs));
+            }
+            if (i >= iy0 && i <= iy1) irows[i] = ii;
+            else break;
+        }
+        for (; i<nrows; i++) {
+            irows[i] = -1;
+        }
+    }
+    else
+    {
+        int iilast = ny-1;
+        int ii = iilast;
+        int iy0 = (int)floor(sc * (y[ii]  - offs));
+        int iy1 = (int)floor(sc * (y[ii-1]  - offs));
+        for (i=0; i<nrows && i<iy0; i++) {
+            irows[i] = -1;
+        }
+        for (; i<nrows; i++) {
+            while (i > iy1 && ii > 1) {
+                ii--;
+                iy0 = iy1;
+                iy1 = (int)floor(sc * (y[ii-1] - offs));
+            }
+            if (i >= iy0 && i <= iy1) irows[i] = ii-1;
+            else break;
+        }
+        for (; i<nrows; i++) {
+            irows[i] = -1;
+        }
+    }
+}
+
+char __image_module_pcolor2__doc__[] =
+"pcolor2(x, y, data, rows, cols, bounds, bg)\n"
+"\n"
+"Generate a pseudo-color image from data on a non-uniform grid\n"
+"specified by its cell boundaries.\n"
+"bounds = (x_left, x_right, y_bot, y_top)\n"
+"bg = ndarray of 4 uint8 representing background rgba\n"
+;
+Py::Object
+_image_module::pcolor2(const Py::Tuple& args) {
+    _VERBOSE("_image_module::pcolor2");
+
+    if (args.length() != 7)
+        throw Py::TypeError("Incorrect number of arguments (6 expected)");
+
+    Py::Object xp = args[0];
+    Py::Object yp = args[1];
+    Py::Object dp = args[2];
+    int rows = Py::Int(args[3]);
+    int cols = Py::Int(args[4]);
+    Py::Tuple bounds = args[5];
+    Py::Object bgp = args[6];
+
+    if (bounds.length() !=4)
+        throw Py::TypeError("Incorrect number of bounds (4 expected)");
+    double x_left = Py::Float(bounds[0]);
+    double x_right = Py::Float(bounds[1]);
+    double y_bot = Py::Float(bounds[2]);
+    double y_top = Py::Float(bounds[3]);
+
+    // Check we have something to output to
+    if (rows == 0 || cols ==0)
+        throw Py::ValueError("rows or cols is zero; there are no pixels");
+
+    // Get numpy arrays
+    PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(),
+                                                          PyArray_DOUBLE, 1, 
1);
+    if (x == NULL)
+        throw Py::ValueError("x is of incorrect type (wanted 1D double)");
+    PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(),
+                                                          PyArray_DOUBLE, 1, 
1);
+    if (y == NULL) {
+        Py_XDECREF(x);
+        throw Py::ValueError("y is of incorrect type (wanted 1D double)");
+    }
+    PyArrayObject *d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(),
+                                                          PyArray_UBYTE, 3, 3);
+    if (d == NULL) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        throw Py::ValueError("data is of incorrect type (wanted 3D uint8)");
+    }
+    if (d->dimensions[2] != 4) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        throw Py::ValueError("data must be in RGBA format");
+    }
+
+    // Check dimensions match
+    int nx = x->dimensions[0];
+    int ny = y->dimensions[0];
+    if (nx != d->dimensions[1]+1 || ny != d->dimensions[0]+1) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        throw Py::ValueError("data and axis bin boundary dimensions are 
incompatible");
+    }
+
+    PyArrayObject *bg = (PyArrayObject *) 
PyArray_ContiguousFromObject(bgp.ptr(),
+                                                          PyArray_UBYTE, 1, 1);
+    if (bg == NULL) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        throw Py::ValueError("bg is of incorrect type (wanted 1D uint8)");
+    }
+    if (bg->dimensions[0] != 4) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        Py_XDECREF(bg);
+        throw Py::ValueError("bg must be in RGBA format");
+    }
+
+
+    // Allocate memory for pointer arrays
+    int * irows = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int)*rows));
+    if (irows == NULL) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        Py_XDECREF(bg);
+        throw Py::MemoryError("Cannot allocate memory for lookup table");
+    }
+    int * jcols = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int*)*cols));
+    if (jcols == NULL) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        Py_XDECREF(bg);
+        PyMem_Free(irows);
+        throw Py::MemoryError("Cannot allocate memory for lookup table");
+    }
+
+    // Create output
+    Image* imo = new Image;
+    imo->rowsIn = rows;
+    imo->rowsOut = rows;
+    imo->colsIn = cols;
+    imo->colsOut = cols;
+    size_t NUMBYTES(rows * cols * 4);
+    agg::int8u *buffer = new agg::int8u[NUMBYTES];
+    if (buffer == NULL) {
+        Py_XDECREF(x);
+        Py_XDECREF(y);
+        Py_XDECREF(d);
+        Py_XDECREF(bg);
+        PyMem_Free(irows);
+        PyMem_Free(jcols);
+        throw Py::MemoryError("Could not allocate memory for image");
+    }
+
+    // Calculate the pointer arrays to map input x to output x
+    int i, j;
+    double *x0 = reinterpret_cast<double*>(x->data);
+    double *y0 = reinterpret_cast<double*>(y->data);
+    double sx = cols/(x_right - x_left);
+    double sy = rows/(y_top - y_bot);
+    _bin_indices(jcols, cols, x0, nx, sx, x_left);
+    _bin_indices(irows, rows, y0, ny, sy, y_bot);
+
+    // Copy data to output buffer
+    agg::int8u * position = buffer;
+    unsigned char *start = reinterpret_cast<unsigned char*>(d->data);
+    unsigned char *bgptr = reinterpret_cast<unsigned char*>(bg->data);
+    int s0 = d->strides[0];
+    int s1 = d->strides[1];
+
+    for (i=0; i<rows; i++)
+    {
+        for (j=0; j<cols; j++)
+        {
+            if (irows[i] == -1 || jcols[j] == -1) {
+                memcpy(position, bgptr, 4*sizeof(agg::int8u));
+            }
+            else {
+                memcpy(position, (start + s0*irows[i] + s1*jcols[j]),
+                                                  4*sizeof(agg::int8u));
+            }
+            position += 4;
+        }
+    }
+
+    // Attach output buffer to output buffer
+    imo->rbufOut = new agg::rendering_buffer;
+    imo->bufferOut = buffer;
+    imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, 
imo->colsOut * imo->BPP);
+
+    Py_XDECREF(x);
+    Py_XDECREF(y);
+    Py_XDECREF(d);
+    Py_XDECREF(bg);
+    PyMem_Free(irows);
+    PyMem_Free(jcols);
+
+    return Py::asObject(imo);
+}
+
+
+
 #if defined(_MSC_VER)
 DL_EXPORT(void)
 #elif defined(__cplusplus)
@@ -1532,7 +1753,7 @@
   d["SINC"]  = Py::Int(Image::SINC);
   d["LANCZOS"]  = Py::Int(Image::LANCZOS);
   d["BLACKMAN"] = Py::Int(Image::BLACKMAN);
-  
+
   d["ASPECT_FREE"] = Py::Int(Image::ASPECT_FREE);
   d["ASPECT_PRESERVE"] = Py::Int(Image::ASPECT_PRESERVE);
 

Modified: trunk/matplotlib/src/_image.h
===================================================================
--- trunk/matplotlib/src/_image.h       2007-11-14 04:03:46 UTC (rev 4263)
+++ trunk/matplotlib/src/_image.h       2007-11-14 07:45:12 UTC (rev 4264)
@@ -134,6 +134,8 @@
                       "from_images");
     add_varargs_method("pcolor", &_image_module::pcolor,
                "pcolor");
+    add_varargs_method("pcolor2", &_image_module::pcolor2,
+               "pcolor2");
     initialize( "The _image module" );
   }
 
@@ -145,11 +147,13 @@
   Py::Object fromarray (const Py::Tuple &args);
   Py::Object fromarray2 (const Py::Tuple &args);
   Py::Object pcolor (const Py::Tuple &args);
+  Py::Object pcolor2 (const Py::Tuple &args);
   Py::Object readpng (const Py::Tuple &args);
   Py::Object from_images (const Py::Tuple &args);
 
   static char _image_module_fromarray__doc__[];
   static char _image_module_pcolor__doc__[];
+  static char _image_module_pcolor2__doc__[];
   static char _image_module_fromarray2__doc__[];
   static char _image_module_frombyte__doc__[];
   static char _image_module_frombuffer__doc__[];


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to