Revision: 8966
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8966&view=rev
Author:   efiring
Date:     2011-02-09 07:45:18 +0000 (Wed, 09 Feb 2011)

Log Message:
-----------
_image.cpp: speed up image_frombyte; patch by C. Gohlke

Non-contiguous arrays, such as those resulting from pan and zoom,
are handled efficiently without additional copying.  This
noticeably speeds up zoom and pan on large images.

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

Modified: trunk/matplotlib/src/_image.cpp
===================================================================
--- trunk/matplotlib/src/_image.cpp     2011-02-09 04:16:08 UTC (rev 8965)
+++ trunk/matplotlib/src/_image.cpp     2011-02-09 07:45:18 UTC (rev 8966)
@@ -1085,7 +1085,7 @@
     Py::Object x = args[0];
     int isoutput = Py::Int(args[1]);
 
-    PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), 
PyArray_UBYTE, 3, 3);
+    PyArrayObject *A = (PyArrayObject *) PyArray_FromObject(x.ptr(), 
PyArray_UBYTE, 3, 3);
     if (A == NULL)
     {
         throw Py::ValueError("Array must have 3 dimensions");
@@ -1104,35 +1104,86 @@
 
     agg::int8u *arrbuf;
     agg::int8u *buffer;
+    agg::int8u *dstbuf;
 
     arrbuf = reinterpret_cast<agg::int8u *>(A->data);
 
     size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP);
-    buffer = new agg::int8u[NUMBYTES];
+    buffer = dstbuf = new agg::int8u[NUMBYTES];
 
     if (buffer == NULL) //todo: also handle allocation throw
     {
         throw Py::MemoryError("_image_module::frombyte could not allocate 
memory");
     }
 
-    const size_t N = imo->rowsIn * imo->colsIn * imo->BPP;
-    size_t i = 0;
-    if (A->dimensions[2] == 4)
+    if PyArray_ISCONTIGUOUS(A)
     {
-        memmove(buffer, arrbuf, N);
+        if (A->dimensions[2] == 4)
+        {
+            memmove(dstbuf, arrbuf, imo->rowsIn * imo->colsIn * 4);
+        }
+        else
+        {
+            size_t i = imo->rowsIn * imo->colsIn;
+            while (i--)
+            {
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = 255;
+            }
+        }
     }
+    else if ((A->strides[1] == 4) && (A->strides[2] == 1))
+    {
+        const size_t N = imo->colsIn * 4;
+        const size_t stride = A->strides[0];
+        for (size_t rownum = 0; rownum < imo->rowsIn; rownum++)
+        {
+            memmove(dstbuf, arrbuf, N);
+            arrbuf += stride;
+            dstbuf += N;
+        }
+    }
+    else if ((A->strides[1] == 3) && (A->strides[2] == 1))
+    {
+        const size_t stride = A->strides[0] - imo->colsIn * 3;
+        for (size_t rownum = 0; rownum < imo->rowsIn; rownum++)
+        {
+            for (size_t colnum = 0; colnum < imo->colsIn; colnum++)
+            {
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = *arrbuf++;
+                *dstbuf++ = 255;
+            }
+            arrbuf += stride;
+        }
+    }
     else
     {
-        while (i < N)
+        PyArrayIterObject *iter;
+        iter = (PyArrayIterObject *)PyArray_IterNew((PyObject *)A);
+        if (A->dimensions[2] == 4)
         {
-            memmove(buffer, arrbuf, 3);
-            buffer += 3;
-            arrbuf += 3;
-            *buffer++ = 255;
-            i += 4;
+            while (iter->index < iter->size) {
+                *dstbuf++ = *((unsigned char *)iter->dataptr);
+                PyArray_ITER_NEXT(iter);
+            }
         }
-        buffer -= N;
-        arrbuf -= imo->rowsIn * imo->colsIn;
+        else
+        {
+            while (iter->index < iter->size) {
+                *dstbuf++ = *((unsigned char *)iter->dataptr);
+                PyArray_ITER_NEXT(iter);
+                *dstbuf++ = *((unsigned char *)iter->dataptr);
+                PyArray_ITER_NEXT(iter);
+                *dstbuf++ = *((unsigned char *)iter->dataptr);
+                PyArray_ITER_NEXT(iter);
+                *dstbuf++ = 255;
+            }
+        }
+        Py_DECREF(iter);
     }
 
     if (isoutput)


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

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to