Index: trunk/psLib/src/image/psImage.c
===================================================================
--- trunk/psLib/src/image/psImage.c	(revision 1165)
+++ trunk/psLib/src/image/psImage.c	(revision 1193)
@@ -9,6 +9,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-07-01 00:26:37 $
+ *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-08 01:05:00 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -261,4 +261,6 @@
 }
 
+
+
 psImage *psImageCopy(psImage* restrict output, const psImage *input,
                      psElemType type)
@@ -266,4 +268,5 @@
     psElemType inDatatype;
     int elementSize;
+    int elements;
     int numRows;
     int numCols;
@@ -288,4 +291,5 @@
     numRows = input->numRows;
     numCols = input->numCols;
+    elements = numRows*numCols;
     elementSize = PSELEMTYPE_SIZEOF(inDatatype);
 
@@ -299,1825 +303,98 @@
     // cover the trival case of copy of the same datatype.
     if (type == inDatatype) {
-        memcpy(output->data.V[0],input->data.V[0],elementSize*numRows*numCols);
+        memcpy(output->data.V[0],input->data.V[0],elementSize*elements);
         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++) { \
-                out[col] = (ps##OUTTYPE) in[col]; \
-            } \
+    #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \
+        ps##INTYPE *in = IN->data.INTYPE[0]; \
+        ps##OUTTYPE *out = OUT->data.OUTTYPE[0]; \
+        for (int e=0;e<ELEMENTS;e++) { \
+            *(out++) = *(in++); \
         } \
     }
 
-    #define PSIMAGE_ELEMENT_ASSIGN(OUT,IN,OUTTYPE) \
-    switch (IN->type.type) { \
+    #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) \
+    switch (inDatatype) { \
     case PS_TYPE_S8: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S8,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_S16: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S16,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_S32: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S32,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_S64: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,S64,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_U8: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U8,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_U16: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U16,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_U32: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U32,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_U64: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,U64,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_F32: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F32,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_F64: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,F64,OUTTYPE); \
+        PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
         break; \
     case PS_TYPE_C32: \
-        PSIMAGE_ELEMENT_ASSIGN_LOOP(OUT,IN,C32,OUTTYPE); \
-        break; \
-    case PS_TYPE_PTR: \
-        psError(__func__,"Can't copy image from a matrix of pointers."); \
-        psFree(output); \
-        return NULL; \
+        PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_C64: \
+        PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
+        break; \
     default: \
         break; \
     }
 
-    // XXX - GCC had problems with the length? of the above macro.  The original
-    // macro code here is commented out and the preprocessor output is pasted below it
-    // (effectively to the end of the function)
-    // We need to find out what is doing on here and move back to the macro version.
-    #if 0
-    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);
-    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.");
-        psFree(output);
-        return NULL;
-    }
-    #endif
-
-    #if 1
     switch (type) {
     case PS_TYPE_S8:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psS8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.S8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,S8);
         break;
     case PS_TYPE_S16:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psS16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.S16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,S16);
         break;
     case PS_TYPE_S32:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psS32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.S32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,S32);
         break;
     case PS_TYPE_S64:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psS64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.S64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psS64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,S64);
         break;
     case PS_TYPE_U8:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psU8 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.U8[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU8) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,U8);
         break;
     case PS_TYPE_U16:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psU16 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.U16[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU16) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,U16);
         break;
     case PS_TYPE_U32:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psU32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.U32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,U32);
         break;
     case PS_TYPE_U64:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psU64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.U64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psU64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,U64);
         break;
     case PS_TYPE_F32:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psF32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.F32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,F32);
         break;
     case PS_TYPE_F64:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psF64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.F64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psF64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,F64);
         break;
     case PS_TYPE_C32:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psC32 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.C32[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC32) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
+        PSIMAGE_COPY_CASE(output,C32);
         break;
     case PS_TYPE_C64:
-        switch (input->type.type) {
-        case PS_TYPE_S8: {
-                psS8 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S8[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S16: {
-                psS16 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S16[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S32: {
-                psS32 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S32[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_S64: {
-                psS64 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.S64[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U8: {
-                psU8 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U8[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U16: {
-                psU16 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U16[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U32: {
-                psU32 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U32[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_U64: {
-                psU64 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.U64[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F32: {
-                psF32 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F32[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_F64: {
-                psF64 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.F64[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_C32: {
-                psC32 *in;
-                psC64 *out;
-                for (int row = 0; row < numRows; row++) {
-                    in = input->data.C32[row];
-                    out = output->data.C64[row];
-                    for (int col = 0; col < numCols; col++) {
-                        out[col] = (psC64) in[col];
-                    }
-                }
-            };
-            break;
-        case PS_TYPE_PTR:
-            psError (__func__, "Can't copy image from a matrix of pointers.");
-            psFree (output);
-            return ((void *) 0);
-        default:
-            break;
-        };
-        break;
-    case PS_TYPE_PTR:
-        psError (__func__, "Can't copy image into a matrix of pointers.");
-        psFree (output);
-        return ((void *) 0);
-    }
-
+        PSIMAGE_COPY_CASE(output,C64);
+        break;
+    default:
+        break;
+    }
     return output;
 }
@@ -2340,6 +617,4 @@
     }
 
-    #endif
-
     return 0;
 }
