Index: /trunk/psLib/src/image/psImageExtraction.c
===================================================================
--- /trunk/psLib/src/image/psImageExtraction.c	(revision 1267)
+++ /trunk/psLib/src/image/psImageExtraction.c	(revision 1267)
@@ -0,0 +1,226 @@
+/** @file  psImageManip.h
+ *
+ *  @brief Contains basic image extraction operations, as specified in the 
+ *         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
+ *         Manipulation".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-22 20:48:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+
+#include "psMemory.h"
+#include "psImageExtraction.h"
+#include "psError.h"
+
+psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
+                       unsigned int numRows, unsigned int col0,
+                       unsigned int row0)
+{
+    unsigned int elementSize;           // size of image element in bytes
+    unsigned int outputRowSize;         // output row size in bytes
+    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
+
+    if (image == NULL || image->data.V == NULL) {
+        psError(__func__,"Can not subset image because input image or its pixel buffer is NULL.");
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not subset image because input image is not an image.");
+        return NULL;
+    }
+
+    if (numCols < 1 || numRows < 1) {
+        psError(__func__,"Can not subset image because number of rows or columns are zero (%dx%d).",
+                numCols, numRows);
+        return NULL;
+    }
+
+    if (col0 >= image->numCols || row0 >= image->numRows) {
+        psError(__func__,"Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",
+                col0,row0);
+        return NULL;
+    }
+
+    /* validate subimage size */
+    if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
+        psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
+                "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,col0,
+                col0+numCols, row0, row0+numRows);
+        return NULL;
+    }
+
+
+    elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+
+    out = psImageRecycle(out,numCols,numRows,image->type.type);
+
+    // set the parent information into the child output image
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    *(psImage**)&out->parent = (psImage*)image;
+
+    // add output image as a child of the input image.
+    image->nChildren++;
+    image->children = (psImage **) psRealloc(image->children,
+                      image->nChildren * sizeof(psImage*) );
+    image->children[image->nChildren-1] = out;
+
+    inputColOffset = elementSize*col0;
+    outputRowSize = elementSize*numCols;
+
+    for (int row = 0; row < numRows; row++) {
+        memcpy(out->data.V[row],image->data.U8[row0+row] + inputColOffset,
+               outputRowSize);
+    }
+
+    return (out);
+}
+
+
+psImage *psImageCopy(psImage* restrict output, const psImage *input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int elements;
+    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;
+    elements = numRows*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;
+    }
+
+    output = psImageRecycle(output,numCols,numRows,type);
+
+    // cover the trival case of copy of the same datatype.
+    if (type == inDatatype) {
+        memcpy(output->data.V[0],input->data.V[0],elementSize*elements);
+        return output;
+    }
+
+    #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_COPY_CASE(OUT,OUTTYPE) \
+    switch (inDatatype) { \
+    case PS_TYPE_S8: \
+        PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_S16: \
+        PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_S32: \
+        PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_S64: \
+        PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_U8: \
+        PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_U16: \
+        PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_U32: \
+        PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_U64: \
+        PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_F32: \
+        PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_F64: \
+        PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_C32: \
+        PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
+        break; \
+    case PS_TYPE_C64: \
+        PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
+        break; \
+    default: \
+        break; \
+    }
+
+    switch (type) {
+    case PS_TYPE_S8:
+        PSIMAGE_COPY_CASE(output,S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_COPY_CASE(output,S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_COPY_CASE(output,S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_COPY_CASE(output,S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_COPY_CASE(output,U8);
+        break;
+    case PS_TYPE_U16:
+        PSIMAGE_COPY_CASE(output,U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_COPY_CASE(output,U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_COPY_CASE(output,U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_COPY_CASE(output,F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_COPY_CASE(output,F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_COPY_CASE(output,C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_COPY_CASE(output,C64);
+        break;
+    default:
+        break;
+    }
+    return output;
+}
+
Index: /trunk/psLib/src/image/psImageExtraction.h
===================================================================
--- /trunk/psLib/src/image/psImageExtraction.h	(revision 1267)
+++ /trunk/psLib/src/image/psImageExtraction.h	(revision 1267)
@@ -0,0 +1,57 @@
+/** @file  psImageManip.h
+ *
+ *  @brief Contains basic image extraction operations, as specified in the 
+ *         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
+ *         Manipulation".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-22 20:48:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSIMAGEEXTRACTION_H
+#define PSIMAGEEXTRACTION_H
+
+#include "psImage.h"
+
+/** Create a subimage of the specified area.
+*
+* Uses psLib memory allocation functions to create an image based on a larger
+* one.
+*
+* @return psImage*: Pointer to psImage.
+*
+*/
+psImage *psImageSubset(
+    psImage *out,                       ///< Subimage to return, or NULL.
+    psImage *image,                     ///< Parent image.
+    unsigned int numCols,               ///< Subimage width (<= image.nCols - col0).
+    unsigned int numRows,               ///< Subimage height (<= image.nRows - row0).
+    unsigned int col0,                  ///< Subimage col-offset (0 <= col0 < nCol).
+    unsigned int row0                   ///< Subimage row-offset (0 <= row0 < nCol).
+);
+
+/** Makes a copy of a psImage
+ *
+ * @return psImage*  Copy of the input psImage.  This may not be equal to the
+ * output parameter
+ *
+ */
+psImage *psImageCopy(
+    psImage* restrict output,
+    /**< if not NULL, a psImage that could be recycled.  If it can not be used,
+     *   it will be freed via psImageFree
+     */
+    const psImage *input,
+    /**< the psImage to copy */
+    psElemType type
+    /**< the desired datatype of the returned copy */
+);
+
+
+#endif
