Index: /trunk/psLib/src/imageops/psImageUnbin.c
===================================================================
--- /trunk/psLib/src/imageops/psImageUnbin.c	(revision 7381)
+++ /trunk/psLib/src/imageops/psImageUnbin.c	(revision 7381)
@@ -0,0 +1,162 @@
+#include <stdio.h>
+
+#include "psError.h"
+#include "psImage.h"
+#include "psConstants.h"
+#include "psImageUnbin.h"
+
+// interpolate from model to background (~bresenham linear interpolation)
+// XXX this code skips the initial pixels?
+psImage *psImageUnbin(psImage *out, const psImage *in, int DX, int DY, int dx, int dy)
+{
+    PS_ASSERT_IMAGE_NON_NULL(in, NULL);
+    PS_ASSERT_IMAGE_NON_NULL(out, NULL);
+    PS_ASSERT_INT_POSITIVE(DX, NULL);
+    PS_ASSERT_INT_POSITIVE(DY, NULL);
+    PS_ASSERT_INT_NONNEGATIVE(dx, NULL);
+    PS_ASSERT_INT_NONNEGATIVE(dy, NULL);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(dx, DX, NULL);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(dy, DY, NULL);
+
+    long nx = in->numCols;
+    long ny = in->numRows;
+    long Nx = out->numCols;
+    long Ny = out->numRows;
+
+    psF32 **vIn = in->data.F32;
+    psF32 **vOut = out->data.F32;
+
+    for (int Iy = 0; Iy < ny-1; Iy ++) {
+        for (int Ix = 0; Ix < nx-1; Ix ++) {
+
+            float V00 = vIn[Iy+0][Ix+0];
+            float V01 = vIn[Iy+0][Ix+1];
+            float V10 = vIn[Iy+1][Ix+0];
+            float V11 = vIn[Iy+1][Ix+1];
+
+            // a single binned pixel quad
+            // (Xs,Ys) : (Xe,Ye) : binned pixel centers in unbinned coords
+            // corresponding to (Ix,Iy), (Ix+1,Iy+1)
+            int Xs = (Ix + 1)*DX - dx;
+            int Ys = (Iy + 1)*DY - dy;
+            int Xe = Xs + DX;
+            int Ye = Ys + DY;
+
+            for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
+                float Vxs = (V10 - V00)*(iy - Ys) / DY + V00;
+                float Vxe = (V11 - V01)*(iy - Ys) / DY + V01;
+                float dV = (Vxe - Vxs) / DX;
+                float V  = Vxs;
+                for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
+                    vOut[iy][ix] = V;
+                    V += dV;
+                }
+            }
+        }
+    }
+
+    // side pixels
+    int Xs = DX - dx;
+    int Xe = nx*DX - dx;
+    for (int Iy = 0; Iy < ny - 1; Iy++) {
+
+        int Ys = (Iy + 1)*DY - dy;
+        int Ye = Ys + DY;
+
+        // leading edge
+        float V0 = vIn[Iy+0][0];
+        float V1 = vIn[Iy+1][0];
+        float dV = (V1 - V0) / DY;
+        float V = V0;
+        for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
+            for (int ix = 0; ix < Xs; ix++) {
+                vOut[iy][ix] = V;
+            }
+            V += dV;
+        }
+
+        // trailing edge
+        V0 = vIn[Iy+0][nx-1];
+        V1 = vIn[Iy+1][nx-1];
+        dV = (V1 - V0) / DY;
+        V = V0;
+        for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
+            for (int ix = Xe; ix < Nx; ix++) {
+                vOut[iy][ix] = V;
+            }
+            V += dV;
+        }
+    }
+
+    // top and bottom pixels
+    int Ys = DY - dy;
+    int Ye = ny*DY - dy;
+    for (int Ix = 0; Ix < nx - 1; Ix++) {
+
+        int Xs = (Ix + 1)*DX - dx;
+        int Xe = Xs + DX;
+
+        // top edge
+        float V0 = vIn[0][Ix+0];
+        float V1 = vIn[0][Ix+1];
+        float dV = (V1 - V0) / DX;
+        for (int iy = 0; iy < Ys; iy++) {
+            float V = V0;
+            for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
+                vOut[iy][ix] = V;
+                V += dV;
+            }
+        }
+
+        // bottom edge
+        V0 = vIn[ny-1][Ix+0];
+        V1 = vIn[ny-1][Ix+1];
+        dV = (V1 - V0) / DX;
+        for (int iy = Ye; iy < Ny; iy++) {
+            float V = V0;
+            for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
+                vOut[iy][ix] = V;
+                V += dV;
+            }
+        }
+    }
+
+    // the four corners
+    {
+        float V;
+        // 0,0
+        V = vIn[0][0];
+        for (int iy = 0; iy < DY - dy; iy++)
+        {
+            for (int ix = 0; ix < DX - dx; ix++) {
+                vOut[iy][ix] = V;
+            }
+        }
+        // Nx,0
+        V = vIn[0][nx-1];
+        for (int iy = 0; iy < DY - dy; iy++)
+        {
+            for (int ix = nx*DX - dx; ix < Nx; ix++) {
+                vOut[iy][ix] = V;
+            }
+        }
+        // 0,Ny
+        V = vIn[ny-1][0];
+        for (int iy = ny*DY - dy; iy < Ny; iy++)
+        {
+            for (int ix = 0; ix < DX - dx; ix++) {
+                vOut[iy][ix] = V;
+            }
+        }
+        // Nx,Ny
+        V = vIn[ny-1][nx-1];
+        for (int iy = ny*DY - dy; iy < Ny; iy++)
+        {
+            for (int ix = nx*DX - dx; ix < Nx; ix++) {
+                vOut[iy][ix] = V;
+            }
+        }
+    }
+
+    return out;
+}
Index: /trunk/psLib/src/imageops/psImageUnbin.h
===================================================================
--- /trunk/psLib/src/imageops/psImageUnbin.h	(revision 7381)
+++ /trunk/psLib/src/imageops/psImageUnbin.h	(revision 7381)
@@ -0,0 +1,13 @@
+#ifndef PS_IMAGE_UNBIN_H
+#define PS_IMAGE_UNBIN_H
+
+#include "psImage.h"
+
+// This needs to be considered more carefully
+psImage *psImageUnbin (psImage *out,    // Output image
+                       const psImage *in, // Input image
+                       int DX, int DY,  // Scaling factors in x and y
+                       int dx, int dy   // Overhang
+                      );
+
+#endif
Index: /trunk/psLib/test/jpeg/.cvsignore
===================================================================
--- /trunk/psLib/test/jpeg/.cvsignore	(revision 7381)
+++ /trunk/psLib/test/jpeg/.cvsignore	(revision 7381)
@@ -0,0 +1,5 @@
+temp
+.deps
+.libs
+Makefile
+Makefile.in
