Index: trunk/psLib/src/imageops/psImageBinning.c
===================================================================
--- trunk/psLib/src/imageops/psImageBinning.c	(revision 12699)
+++ trunk/psLib/src/imageops/psImageBinning.c	(revision 14923)
@@ -8,6 +8,6 @@
  *  @author Eugene Magnier, IfA
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-03-31 02:59:41 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-09-20 23:53:46 $
  *
  *  Copyright 2007 Institute for Astronomy, University of Hawaii
@@ -44,7 +44,9 @@
     assert (binning->nYbin > 0);
 
+    // force nXruff*nXbin > nXfine
     binning->nXruff = binning->nXfine / binning->nXbin;
     if (binning->nXfine % binning->nXbin) binning->nXruff ++;
 
+    // force nYruff*nYbin > nYfine
     binning->nYruff = binning->nYfine / binning->nYbin;
     if (binning->nYfine % binning->nYbin) binning->nYruff ++;
@@ -56,10 +58,10 @@
 	break;
       case PS_IMAGE_BINNING_CENTER:
-	binning->nXoff = ((binning->nXruff * binning->nXbin) % binning->nXfine) / 2;
-	binning->nYoff = ((binning->nYruff * binning->nYbin) % binning->nYfine) / 2;
+	binning->nXoff = (binning->nXruff * binning->nXbin - binning->nXfine) / 2;
+	binning->nYoff = (binning->nYruff * binning->nYbin - binning->nYfine) / 2;
 	break;
       case PS_IMAGE_BINNING_RIGHT:
-	binning->nXoff = ((binning->nXruff * binning->nXbin) % binning->nXfine);
-	binning->nYoff = ((binning->nYruff * binning->nYbin) % binning->nYfine);
+	binning->nXoff = (binning->nXruff * binning->nXbin - binning->nXfine);
+	binning->nYoff = (binning->nYruff * binning->nYbin - binning->nYfine);
 	break;
       default:
@@ -78,6 +80,11 @@
 void psImageBinningSetSkip(psImageBinning *binning, psImage *image) {
 
-    binning->nXskip = image->col0 - binning->nXoff;
-    binning->nYskip = image->row0 - binning->nYoff;
+    if (image != NULL) {
+	binning->nXskip = image->col0 - binning->nXoff;
+	binning->nYskip = image->row0 - binning->nYoff;
+    } else {
+	binning->nXskip = 0 - binning->nXoff;
+	binning->nYskip = 0 - binning->nYoff;
+    }
     return;
 }
@@ -90,7 +97,9 @@
     assert (binning->nYruff > 0);
 
+    // force nXruff*nXbin > nXfine
     binning->nXbin = binning->nXfine / binning->nXruff;
     if (binning->nXfine % binning->nXruff) binning->nXbin ++;
 
+    // force nYruff*nYbin > nYfine
     binning->nYbin = binning->nYfine / binning->nYruff;
     if (binning->nYfine % binning->nYruff) binning->nYbin ++;
@@ -102,10 +111,10 @@
 	break;
       case PS_IMAGE_BINNING_CENTER:
-	binning->nXoff = (binning->nXfine % binning->nXbin) / 2;
-	binning->nYoff = (binning->nYfine % binning->nYbin) / 2;
+	binning->nXoff = (binning->nXruff * binning->nXbin - binning->nXfine) / 2;
+	binning->nYoff = (binning->nYruff * binning->nYbin - binning->nYfine) / 2;
 	break;
       case PS_IMAGE_BINNING_RIGHT:
-	binning->nXoff = (binning->nXfine % binning->nXbin);
-	binning->nYoff = (binning->nYfine % binning->nYbin);
+	binning->nXoff = (binning->nXruff * binning->nXbin - binning->nXfine);
+	binning->nYoff = (binning->nYruff * binning->nYbin - binning->nYfine);
 	break;
       default:
@@ -137,24 +146,46 @@
 }
 
-/*** pmFPACopy.c:binRegion had the following logic ***/
-# if (0)
-    // Want to include the lower bound: 1 binned by 4 --> 0; 3 binned by 4 --> 0; 4 binned by 4 --> 1
-    region->x0 = (int)(region->x0 / xBin);
-    region->y0 = (int)(region->y0 / yBin);
-    // Want to exclude the upper bound: 4 binned by 4 --> 1; 5 binned by 4 --> 2; 7 binned by 4 --> 2
-    region->x1 = (int)((region->x1 + xBin - 1) / xBin);
-    region->y1 = (int)((region->y1 + yBin - 1) / yBin);
-# endif
 
-/* 
- * dvoMakeCorrUnbin ** OK
- * psphotImageMedian ** OK?
- * psphotMagnitudes ** OK
- * pmFPACopy ** OK
- * pmConceptsUpdate ** OK
- * pmFPAMosaic ** OK (needs more use of psImageBinning functions)
- * psImageUnbin 
- * psImageRebin
- * ppImageRebinReadout
- */
+// convert the fine coordinate to the ruff coordinate
+double psImageBinningGetRuffX (const psImageBinning *binning, const double xFine) {
 
+    PS_ASSERT_INT_POSITIVE(binning->nXbin, NAN);
+    PS_ASSERT_INT_POSITIVE(binning->nYbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nXskip, binning->nXbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nYskip, binning->nYbin, NAN);
+
+    double xRuff = (xFine - binning->nXskip)/binning->nXbin;
+    return xRuff;
+}
+double psImageBinningGetRuffY (const psImageBinning *binning, const double yFine) {
+
+    PS_ASSERT_INT_POSITIVE(binning->nXbin, NAN);
+    PS_ASSERT_INT_POSITIVE(binning->nYbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nXskip, binning->nXbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nYskip, binning->nYbin, NAN);
+
+    double yRuff = (yFine - binning->nYskip)/binning->nYbin;
+    return yRuff;
+}
+
+// convert the ruff coordinate to the fine coordinate
+double psImageBinningGetFineX (const psImageBinning *binning, const double xRuff) {
+
+    PS_ASSERT_INT_POSITIVE(binning->nXbin, NAN);
+    PS_ASSERT_INT_POSITIVE(binning->nYbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nXskip, binning->nXbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nYskip, binning->nYbin, NAN);
+
+    double xFine = xRuff * binning->nXbin + binning->nXskip;
+    return xFine;
+}
+double psImageBinningGetFineY (const psImageBinning *binning, const double yRuff) {
+
+    PS_ASSERT_INT_POSITIVE(binning->nXbin, NAN);
+    PS_ASSERT_INT_POSITIVE(binning->nYbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nXskip, binning->nXbin, NAN);
+    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(binning->nYskip, binning->nYbin, NAN);
+
+    double yFine = yRuff * binning->nYbin + binning->nYskip;
+    return yFine;
+}
