Index: src/_image.cpp
===================================================================
RCS file: /cvsroot/matplotlib/matplotlib/src/_image.cpp,v
retrieving revision 1.35
diff -r1.35 _image.cpp
1279a1280,1437
> char __image_module_pcolor__doc__[] = 
> "pcolor(x, y, data, rows, cols, bounds)\n"
> "\n"
> "Generate a psudo-color image from data on a non-univorm grid using\n"
> "nearest neighbour interpolation.\n"
> "bounds = (x_min, x_max, y_min, y_max)\n"
> ;
> Py::Object
> _image_module::pcolor(const Py::Tuple& args) {
>   _VERBOSE("_image_module::pcolor");
> 
>   if (args.length() != 6)
>       throw Py::TypeError("Incorrect number of arguments (6 expected)");
> 
>   Py::Object xp = args[0];
>   Py::Object yp = args[1];
>   Py::Object dp = args[2];
>   unsigned int rows = Py::Int(args[3]);
>   unsigned int cols = Py::Int(args[4]);
>   Py::Tuple bounds = args[5];
>   
>   if (bounds.length() !=4)
>       throw Py::TypeError("Incorrect number of bounds (4 expected)");
>   float x_min = Py::Float(bounds[0]);
>   float x_max = Py::Float(bounds[1]);
>   float y_min = Py::Float(bounds[2]);
>   float y_max = Py::Float(bounds[3]);
>   float width = x_max - x_min;
>   float height = y_max - y_min;
>   float dx = width / ((float) cols);
>   float dy = height / ((float) rows);
> 
>   // Check we have something to output to
>   if (rows == 0 || cols ==0)
>       throw Py::ValueError("Cannot scale to zero size");
>   
>   // Get numeric arrays
>   PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(), PyArray_FLOAT, 1, 1);
>   if (x == NULL)
>       throw Py::ValueError("x is of incorrect type (wanted 1D float)");
>   PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(), PyArray_FLOAT, 1, 1);
>   if (y == NULL)
>       throw Py::ValueError("y is of incorrect type (wanted 1D float)");
>   PyArrayObject *d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(), PyArray_UBYTE, 3, 3);
>   if (d == NULL)
>       throw Py::ValueError("data is of incorrect type (wanted 3D UInt8)");
>   if (d->dimensions[2] != 4)
>       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] || ny != d->dimensions[0])
>       throw Py::ValueError("data and axis dimensions do not match");
>   
>   // 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];
>   
>   // Allocate memory for pointer arrays
>   agg::int32u * rowstarts = new agg::int32u[rows];
>   agg::int32u * colstarts = new agg::int32u[cols];
> 
>   // Calculate the pointer arrays to map input x to output x
>   unsigned int i, j, j_last;
>   agg::int32u * colstart = colstarts;
>   agg::int32u * rowstart = rowstarts;
>   float *xs1 = reinterpret_cast<float*>(x->data);
>   float *ys1 = reinterpret_cast<float*>(y->data);
>   float *xs2 = xs1+1;
>   float *ys2 = ys1+1;
>   float *xl = xs1 + nx - 1;
>   float *yl = ys1 + ny - 1;
>   float xo = x_min + dx/2.0;
>   float yo = y_min + dy/2.0;
>   float xm = 0.5*(*xs1 + *xs2);
>   float ym = 0.5*(*ys1 + *ys2);
>   // x/cols
>   j = 0;
>   j_last = j;
>   for (i=0;i<cols;i++,xo+=dx,colstart++) {
>       while(xs2 != xl && xo > xm) {
>           xs1 = xs2;
>           xs2 = xs1+1;
>           xm = 0.5*(*xs1 + *xs2);
>           j++;
>       }
>       *colstart = j - j_last;
>       j_last = j;
>   }
>   // y/rows
>   j = 0;
>   j_last = j;
>   for (i=0;i<rows;i++,yo+=dy,rowstart++) {
>       while(ys2 != yl && yo > ym) {
>           ys1 = ys2;
>           ys2 = ys1+1;
>           ym = 0.5*(*ys1 + *ys2);
>           j++;
>       }
>       *rowstart = j - j_last;
>       j_last = j;
> //      printf("%3.1f %3.1f %u\n", yo, ym, *rowstart);
>   }
> 
>   
>   // Copy data to output buffer
>   unsigned char *start;
>   unsigned char *inposition;
>   size_t inrowsize(nx*4);
>   size_t rowsize(cols*4);
>   rowstart = rowstarts;
>   agg::int8u * position = buffer;
>   agg::int8u * oldposition;
>   start = reinterpret_cast<unsigned char*>(d->data);
>   for(i=0;i<rows;i++,rowstart++)
>   { 
>       if (i > 0 && *rowstart == 0) {
>           memcpy(position, oldposition, rowsize*sizeof(agg::int8u));
>           oldposition = position;
>           position += rowsize;
>       } else {
>           oldposition = position;
>           start += *rowstart * inrowsize;
>           inposition = start;
>           for(j=0,colstart=colstarts;j<cols;j++,position+=4,colstart++) {
>               inposition += *colstart * 4;
>               memcpy(position, inposition, 4*sizeof(agg::int8u));
>           }
>       }
>   }
>       /*if (i > 0 && *rowstart == 0) {
>           newposition = position + rowsize;
>           memmove(newposition, position, rowsize*sizeof(agg::int8u));
>           position = newposition;
>       } else {
>           start += inrowsize * *rowstart;
>           inposition = start;
>           colstart = colstarts;
>           for (j=0;j<cols;j++,colstart++,position+=4) {
>               inposition += 4 * *colstart;
>               memmove(position, inposition, 4*sizeof(agg::int8u));
>           }
>       }*/
> 
>   // Attatch 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);
> 
>   return Py::asObject(imo);
> }
> 
Index: src/_image.h
===================================================================
RCS file: /cvsroot/matplotlib/matplotlib/src/_image.h,v
retrieving revision 1.15
diff -r1.15 _image.h
132a133,134
>     add_varargs_method("pcolor", &_image_module::pcolor,
>                "pcolor");
144a147
>   Py::Object pcolor (const Py::Tuple &args);
148a152
>   static char _image_module_pcolor__doc__[];
Index: lib/matplotlib/image.py
===================================================================
RCS file: /cvsroot/matplotlib/matplotlib/lib/matplotlib/image.py,v
retrieving revision 1.21
diff -r1.21 image.py
13c13
< from numerix import arange, asarray, UInt8
---
> from numerix import arange, asarray, UInt8, Float32, repeat, NewAxis
331a332,421
> class NonUniformImage(AxesImage):
>     def __init__(self, ax,
>                  cmap = None,
>                  norm = None,
>                 ):
>         AxesImage.__init__(self, ax,
>                            cmap = cmap,
>                            norm = norm,
>                            aspect = 'free',
>                            interpolation = 'nearest',
>                            origin = 'lower',
>                           )
>         
>     def make_image(self):
>         if self._A is None:
>             raise RuntimeError('You must first set the image array')
>         
>         x0, y0, v_width, v_height = self.axes.viewLim.get_bounds()
>         l, b, width, height = self.axes.bbox.get_bounds()
>         im = _image.pcolor(self._Ax, self._Ay, self._A,
>                            height, width,
>                            (x0, x0+v_width, y0, y0+v_height),
>                           )
>         
>         bg = colorConverter.to_rgba(self.axes.get_frame().get_facecolor(), 0)
>         im.set_bg(*bg)
>         im.set_aspect(self._aspectd[self._aspect])
>         return im
> 
>     def set_data(self, x, y, A):
>         x = asarray(x).astype(Float32)
>         y = asarray(y).astype(Float32)
>         A = asarray(A)
>         if len(x.shape) != 1 or len(y.shape) != 1\
>            or A.shape[0:2] != (y.shape[0], x.shape[0]):
>             raise TypeError("Axes don't match array shape")
>         if len(A.shape) not in [2, 3]:
>             raise TypeError("Can only plot 2D or 3D data")
>         if len(A.shape) == 3 and A.shape[2] not in [1, 3, 4]:
>             raise TypeError("3D arrays must have three (RGB) or four (RGBA) color components")
>         if len(A.shape) == 3 and A.shape[2] == 1:
>              A.shape = A.shape[0:2]
>         if len(A.shape) == 2:
>             if A.typecode() != UInt8:
>                 A = (self.cmap(self.norm(A))*255).astype(UInt8)
>             else:
>                 A = repeat(A[:,:,NewAxis], 4, 2)
>                 A[:,:,3] = 255
>         else:
>             if A.typecode() != UInt8:
>                 A = (255*A).astype(UInt8)
>             if A.shape[2] == 3:
>                 B = zeros(tuple(list(A.shape[0:2]) + [4]), UInt8)
>                 B[:,:,0:3] = A
>                 B[:,:,3] = 255
>                 A = B
>         self._A = A
>         self._Ax = x
>         self._Ay = y
>         self._imcache = None
> 
>     def set_array(self, *args):
>         raise NotImplementedError('Method not supported')
>     
>     def set_interpolation(self, s):
>         if s != 'nearest':
>             raise NotImplementedError('Only nearest neighbor supported')
> 
>     def get_extent(self):
>         if self._A is None:
>             raise RuntimeError('Must set data first')
>         return self._Ax[0], self._Ax[-1], self._Ay[0], self._Ay[-1]
> 
>     def set_filternorm(self, s):
>         pass
> 
>     def set_filterrad(self, s):
>         pass
> 
>     def set_norm(self, norm):
>         if self._A is not None:
>             raise RuntimeError('Cannot change colors after loading data')
>         cm.ScalarMappable.set_norm(self, norm)
> 
>     def set_cmap(self, cmap):
>         if self._A is not None:
>             raise RuntimeError('Cannot change colors after loading data')
>         cm.ScalarMappable.set_cmap(self, norm)
>     
> 
