Index: trunk/psLib/src/image/psImage.c
===================================================================
--- trunk/psLib/src/image/psImage.c	(revision 712)
+++ trunk/psLib/src/image/psImage.c	(revision 714)
@@ -7,6 +7,6 @@
  *  @author Ross Harman, MHPCC
  *   
- *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-05-17 21:00:24 $
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-18 02:33:59 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -121,5 +121,5 @@
 
     for (int row = 0; row < numRows; row++) {
-        memcpy(out->data.v[row],image->data.u8[row0+row] + inputColOffset,outputRowSize);
+        memcpy(out->data.v[row],image->data.U8[row0+row] + inputColOffset,outputRowSize);
     }
 
@@ -165,2 +165,148 @@
     return numFreed;
 }
+
+psImage *psImageCopy(psImage* restrict output, const psImage *input, psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int numRows;
+    int numCols;
+
+    if (input == NULL || input->data.v == NULL) {
+        psError(__func__,"Can not copy image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (input == output) {
+        psError(__func__,"Can not copy image because given input and output parameter reference the same "
+                "psImage struct.");
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not copy image because input image is not actually an image.");
+        return NULL;
+    }
+
+    inDatatype = input->type.type;
+    numRows = input->numRows;
+    numCols = input->numCols;
+    elementSize = PSELEMTYPE_SIZEOF(inDatatype);
+
+    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
+        psError(__func__,"Can not copy image to/from a void* matrix");
+        return NULL;
+    }
+
+
+    if (output == NULL) {
+        output = psImageAlloc(numCols,numRows,type);
+    } else if (output->numCols != numCols || output->numRows != numRows ||
+               output->type.type != type) {        // sizes/type different, can't reuse the given image buffer
+        psImageFree(output);
+        output = psImageAlloc(numCols,numRows,type);
+    }
+
+    // cover the trival case of copy of the same type.
+    if (type == inDatatype) {
+        memcpy(output->data.v[0],input->data.v[0],elementSize*numRows*numCols);
+        return output;
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,INTYPE,OUTTYPE) \
+    { \
+        ps##INTYPE *in; \
+        ps##OUTTYPE *out; \
+        for (int row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (int col=0;col<numCols;col++) { \
+                in[col] = (ps##INTYPE) out[col]; \
+            } \
+        } \
+    }
+
+    #define PSIMAGE_ELEMENT_ASSIGN(OUT,IN,OUTTYPE) \
+    switch (IN->type.type) { \
+    case PS_TYPE_S8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S8,OUTTYPE); \
+        break; \
+    case PS_TYPE_S16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S16,OUTTYPE); \
+        break; \
+    case PS_TYPE_S32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S32,OUTTYPE); \
+        break; \
+    case PS_TYPE_S64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S64,OUTTYPE); \
+        break; \
+    case PS_TYPE_U8: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U8,OUTTYPE); \
+        break; \
+    case PS_TYPE_U16: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U16,OUTTYPE); \
+        break; \
+    case PS_TYPE_U32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U32,OUTTYPE); \
+        break; \
+    case PS_TYPE_U64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U64,OUTTYPE); \
+        break; \
+    case PS_TYPE_F32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F32,OUTTYPE); \
+        break; \
+    case PS_TYPE_F64: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F64,OUTTYPE); \
+        break; \
+    case PS_TYPE_C32: \
+        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,C32,OUTTYPE); \
+        break; \
+    default: \
+        break; \
+    }
+
+    switch (type) {
+    case PS_TYPE_S8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U8);
+        break;
+    case PS_TYPE_U16:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_ELEMENT_ASSIGN(output,input,C64);
+        break;
+    case PS_TYPE_PTR:
+        psError(__func__,"Can't copy image into a matrix of pointers.");
+        psImageFree(output);
+        return NULL;
+    }
+
+    return output;
+}
