Index: trunk/psLib/src/image/psImageManip.c
===================================================================
--- trunk/psLib/src/image/psImageManip.c	(revision 1406)
+++ trunk/psLib/src/image/psImageManip.c	(revision 1407)
@@ -1,2 +1,3 @@
+
 /** @file  psImageManip.c
  *
@@ -10,13 +11,17 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-08-06 22:34:05 $
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-07 00:06:06 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  */
-#include <math.h>                      // for isfinite(), etc.
+#include <math.h>                          // for
+// isfinite(),
+// etc.
 #include <stdlib.h>
 #include <stdbool.h>
-#include <string.h>                    // for memcpy, etc.
+#include <string.h>                        // for
+// memcpy,
+// etc.
 
 #include "psError.h"
@@ -26,5 +31,5 @@
 #include "psImageExtraction.h"
 
-int psImageClip(psImage* input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
+int psImageClip(psImage * input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
 {
     int numClipped = 0;
@@ -37,5 +42,5 @@
 
     if (max < min) {
-        psError(__func__,"psImageClip can not be invoked with max < min.");
+        psError(__func__, "psImageClip can not be invoked with max < min.");
         return 0;
     }
@@ -100,20 +105,19 @@
         break;
 
-        psImageClipCase(S8,"psS8")
-        psImageClipCase(S16,"psS16")
-        psImageClipCase(S32,"psS32")
-        psImageClipCase(S64,"psS64")
-        psImageClipCase(U8,"psU8")
-        psImageClipCase(U16,"psU16")
-        psImageClipCase(U32,"psU32")
-        psImageClipCase(U64,"psU64")
-        psImageClipCase(F32,"psF32")
-        psImageClipCase(F64,"psF64")
-        psImageClipCaseComplex(C32,"psC32",cabsf)
-        psImageClipCaseComplex(C64,"psC64",cabs)
+        psImageClipCase(S8, "psS8")
+        psImageClipCase(S16, "psS16")
+        psImageClipCase(S32, "psS32")
+        psImageClipCase(S64, "psS64")
+        psImageClipCase(U8, "psU8")
+        psImageClipCase(U16, "psU16")
+        psImageClipCase(U32, "psU32")
+        psImageClipCase(U64, "psU64")
+        psImageClipCase(F32, "psF32")
+        psImageClipCase(F64, "psF64")
+        psImageClipCaseComplex(C32, "psC32", cabsf)
+        psImageClipCaseComplex(C64, "psC64", cabs)
 
     default:
-        psError(__func__,"psImageClip does not support the given datatype (%d)",
-                input->type.type);
+        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
     }
 
@@ -121,5 +125,5 @@
 }
 
-int psImageClipNaN(psImage* input,psF64 value)
+int psImageClipNaN(psImage * input, psF64 value)
 {
     int numClipped = 0;
@@ -154,6 +158,5 @@
 
     default:
-        psError(__func__,"psImageClip does not support the given datatype (%d)",
-                input->type.type);
+        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
     }
 
@@ -161,6 +164,5 @@
 }
 
-int psImageOverlaySection(psImage* image, const psImage* overlay, int col0,
-                          int row0, const char* op)
+int psImageOverlaySection(psImage * image, const psImage * overlay, int col0, int row0, const char *op)
 {
     unsigned int imageNumRows;
@@ -170,13 +172,13 @@
     unsigned int imageRowLimit;
     unsigned int imageColLimit;
-    psElemType  type;
+    psElemType type;
 
     if (image == NULL || overlay == NULL) {
-        psError(__func__,"one of the input images was NULL.");
+        psError(__func__, "one of the input images was NULL.");
         return 1;
     }
 
     if (op == NULL) {
-        psError(__func__,"Operation can not be NULL.");
+        psError(__func__, "Operation can not be NULL.");
         return 1;
     }
@@ -185,6 +187,5 @@
 
     if (type != overlay->type.type) {
-        psError(__func__,"Image and overlay datatypes must match. (%d vs %d)",
-                type,overlay->type.type);
+        psError(__func__, "Image and overlay datatypes must match. (%d vs %d)", type, overlay->type.type);
         return 2;
     }
@@ -197,5 +198,6 @@
     /* check row0/col0 to see if it is within the image size */
     if (row0 < 0 || col0 < 0 || row0 >= imageNumRows || col0 >= imageNumCols) {
-        psError(__func__, "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
+        psError(__func__,
+                "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
                 col0, row0, imageNumCols, imageNumRows);
         return 3;
@@ -203,11 +205,11 @@
 
     /* check if overlay is totally withing input image */
-    imageRowLimit = row0+overlayNumRows;
-    imageColLimit = col0+overlayNumCols;
+    imageRowLimit = row0 + overlayNumRows;
+    imageColLimit = col0 + overlayNumCols;
     if (imageRowLimit > imageNumRows || imageColLimit > imageNumCols) {
-        psError(__func__, "Overlay image (%d,%d -> %d,%d) is partially outside"
+        psError(__func__,
+                "Overlay image (%d,%d -> %d,%d) is partially outside"
                 " of the input image (%d x %d).",
-                col0, row0, col0+overlayNumCols-1, row0+overlayNumRows-1,
-                imageNumCols,imageNumRows);
+                col0, row0, col0 + overlayNumCols - 1, row0 + overlayNumRows - 1, imageNumCols, imageNumRows);
         return 4;
     }
@@ -259,5 +261,5 @@
 
     default:
-        psError(__func__,"Can not operate on type %d.",type);
+        psError(__func__, "Can not operate on type %d.", type);
     }
 
@@ -265,5 +267,5 @@
 }
 
-int psImageClipComplexRegion(psImage* input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
+int psImageClipComplexRegion(psImage * input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
 {
     int numClipped = 0;
@@ -276,15 +278,16 @@
 
     if (input == NULL) {
-        psError(__func__,"Can not perform clip on NULL image");
+        psError(__func__, "Can not perform clip on NULL image");
         return 0;
     }
 
-    if ( realMax < realMin ) {
-        psError(__func__,"psImageClipComplexRegion can not be invoked with "
-                "max < min in the real image space.");
+    if (realMax < realMin) {
+        psError(__func__,
+                "psImageClipComplexRegion can not be invoked with " "max < min in the real image space.");
         return 0;
     }
-    if ( imagMax < imagMin ) {
-        psError(__func__,"psImageClipComplexRegion can not be invoked with "
+    if (imagMax < imagMin) {
+        psError(__func__,
+                "psImageClipComplexRegion can not be invoked with "
                 "max < min in the imaginary image space.");
         return 0;
@@ -294,43 +297,42 @@
     numCols = input->numCols;
 
+    #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
+case PS_TYPE_##type: { \
+        if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
+                realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
+            psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
+                    typename " pixel range", \
+                    creal(vmin),cimag(vmin)); \
+            break; \
+        } \
+        if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
+                realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
+            psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
+                    typename " pixel range", \
+                    creal(vmax),cimag(vmax)); \
+            break; \
+        } \
+        for (unsigned int row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (unsigned int col = 0; col < numCols; col++) { \
+                if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
+                    inputRow[col] = (ps##type)vmax; \
+                    numClipped++; \
+                } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \
+                    inputRow[col] = (ps##type)vmin; \
+                    numClipped++; \
+                } \
+            } \
+        } \
+    } \
+    break;
+
     switch (input->type.type) {
 
-        #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
-    case PS_TYPE_##type: { \
-            if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
-                    realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
-                psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
-                        typename " pixel range", \
-                        creal(vmin),cimag(vmin)); \
-                break; \
-            } \
-            if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
-                    realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
-                psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
-                        typename " pixel range", \
-                        creal(vmax),cimag(vmax)); \
-                break; \
-            } \
-            for (unsigned int row = 0;row<numRows;row++) { \
-                ps##type* inputRow = input->data.type[row]; \
-                for (unsigned int col = 0; col < numCols; col++) { \
-                    if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
-                        inputRow[col] = (ps##type)vmax; \
-                        numClipped++; \
-                    } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \
-                        inputRow[col] = (ps##type)vmin; \
-                        numClipped++; \
-                    } \
-                } \
-            } \
-        } \
-        break;
-
-        psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf)
-        psImageClipComplexRegionCase(C64,"psC64",creal,cimag)
+        psImageClipComplexRegionCase(C32, "psC32", crealf, cimagf)
+        psImageClipComplexRegionCase(C64, "psC64", creal, cimag)
 
     default:
-        psError(__func__,"psImageClip does not support the given datatype (%d)",
-                input->type.type);
+        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
     }
 
@@ -338,6 +340,5 @@
 }
 
-
-psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats)
+psImage *psImageRebin(psImage * out, const psImage * in, unsigned int scale, const psStats * stats)
 {
     int inRows;
@@ -345,10 +346,13 @@
     int outRows;
     int outCols;
-    psVector* vec;            // vector to hold the values of a single bin.
-    psStats* myStats;
+    psVector *vec;              // vector to hold
+
+    // the values of
+    // a single bin.
+    psStats *myStats;
     double statVal;
 
     if (in == NULL) {
-        psError(__func__,"Input image is NULL.");
+        psError(__func__, "Input image is NULL.");
         psFree(out);
         return NULL;
@@ -356,5 +360,5 @@
 
     if (scale < 1) {
-        psError(__func__,"The scale must be positive.");
+        psError(__func__, "The scale must be positive.");
         psFree(out);
         return NULL;
@@ -362,11 +366,11 @@
 
     if (stats == NULL) {
-        psError(__func__,"The stats input can not be NULL.");
+        psError(__func__, "The stats input can not be NULL.");
         psFree(out);
         return NULL;
     }
 
-    if (p_psGetStatValue(stats,&statVal) == false) {
-        psError(__func__,"The stat options didn't specify a single supported statistic type.");
+    if (p_psGetStatValue(stats, &statVal) == false) {
+        psError(__func__, "The stat options didn't specify a single supported statistic type.");
         psFree(out);
         return NULL;
@@ -376,12 +380,16 @@
     *myStats = *stats;
 
-    vec = psVectorAlloc(scale*scale,in->type.type);
+    vec = psVectorAlloc(scale * scale, in->type.type);
 
     // create output image.
     inRows = in->numRows;
     inCols = in->numCols;
-    outRows = (inRows+scale-1) / scale;   // round-up for remainders
-    outCols = (inCols+scale-1) / scale;   // round-up for remainders
-    out = psImageRecycle(out,outCols,outRows,in->type.type);
+    outRows = (inRows + scale - 1) / scale;     // round-up
+    // for
+    // remainders
+    outCols = (inCols + scale - 1) / scale;     // round-up
+    // for
+    // remainders
+    out = psImageRecycle(out, outCols, outRows, in->type.type);
 
     #define PS_IMAGE_REBIN_CASE(type) \
@@ -425,5 +433,5 @@
         PS_IMAGE_REBIN_CASE(C64);
     default:
-        psError(__func__,"Input image type not supported.");
+        psError(__func__, "Input image type not supported.");
         psFree(out);
         out = NULL;
@@ -435,5 +443,6 @@
     return out;
 }
-psImage* psImageResample(psImage* out, const psImage* in, int scale, psImageInterpolateMode mode)
+
+psImage *psImageResample(psImage * out, const psImage * in, int scale, psImageInterpolateMode mode)
 {
     int outRows;
@@ -442,14 +451,13 @@
 
     if (in == NULL) {
-        psError(__func__,"Input image can not be NULL.");
+        psError(__func__, "Input image can not be NULL.");
         psFree(out);
         return NULL;
     }
-
-    // create an output image of the same size and type
-    outRows = in->numRows*scale;
-    outCols = in->numCols*scale;
+    // create an output image of the same size
+    // and type
+    outRows = in->numRows * scale;
+    outCols = in->numCols * scale;
     invScale = 1.0f / (float)scale;
-
 
     #define PSIMAGE_RESAMPLE_CASE(TYPE) \
@@ -466,5 +474,5 @@
     }
 
-    switch(in->type.type) {
+    switch (in->type.type) {
         PSIMAGE_RESAMPLE_CASE(U8)
         PSIMAGE_RESAMPLE_CASE(U16)
@@ -480,5 +488,5 @@
         PSIMAGE_RESAMPLE_CASE(C64)
     default:
-        psError(__func__,"Unsupported type (%d)",in->type.type);
+        psError(__func__, "Unsupported type (%d)", in->type.type);
         psFree(out);
         return NULL;
@@ -488,5 +496,5 @@
 }
 
-psImage* psImageRoll(psImage* out, const psImage* in, int dx, int dy)
+psImage *psImageRoll(psImage * out, const psImage * in, int dx, int dy)
 {
     int outRows;
@@ -495,16 +503,17 @@
 
     if (in == NULL) {
-        psError(__func__,"Input image can not be NULL.");
+        psError(__func__, "Input image can not be NULL.");
         psFree(out);
         return NULL;
     }
-
-    // create an output image of the same size and type
+    // create an output image of the same size
+    // and type
     outRows = in->numRows;
     outCols = in->numCols;
     elementSize = PSELEMTYPE_SIZEOF(in->type.type);
-    out = psImageRecycle(out,outCols, outRows, in->type.type);
-
-    // make dx and dy between 0 and outCols or outRows, respectively
+    out = psImageRecycle(out, outCols, outRows, in->type.type);
+
+    // make dx and dy between 0 and outCols or
+    // outRows, respectively
     dx = dx % outCols;
     dy = dy % outRows;
@@ -516,16 +525,25 @@
     }
 
-    int segment1Size = elementSize*(outCols-dx);
-    int segment2Size = elementSize*dx;
-
-    for (int row=0;row<outRows;row++) {
-        int inRowNumber = row+dy;
+    int segment1Size = elementSize * (outCols - dx);
+    int segment2Size = elementSize * dx;
+
+    for (int row = 0; row < outRows; row++) {
+        int inRowNumber = row + dy;
+
         if (inRowNumber >= outRows) {
             inRowNumber -= outRows;
         }
-        psU8* inRow = in->data.U8[inRowNumber]; // to allow byte arithmetic, but for all types
-        psU8* outRow = out->data.U8[row];
-        memcpy(outRow,inRow+segment2Size,segment1Size);
-        memcpy(outRow+segment1Size,inRow,segment2Size);
+        psU8 *inRow = in->data.U8[inRowNumber]; // to
+
+        // allow
+
+        // byte
+        // arithmetic,
+
+        // but for all types
+        psU8 *outRow = out->data.U8[row];
+
+        memcpy(outRow, inRow + segment2Size, segment1Size);
+        memcpy(outRow + segment1Size, inRow, segment2Size);
     }
 
@@ -533,16 +551,16 @@
 }
 
-psImage* psImageRotate(psImage* out, const psImage* in, float angle, float unexposedValue, psImageInterpolateMode mode)
+psImage *psImageRotate(psImage * out,
+                       const psImage * in, float angle, float unexposedValue, psImageInterpolateMode mode)
 {
     if (in == NULL) {
-        psError(__func__,"The input image was NULL.");
+        psError(__func__, "The input image was NULL.");
         psFree(out);
         return NULL;
     }
-
     // put the angle in the range of 0...360.
-    angle = angle - 360.0f*floor(angle/360.0f);
-
-    if (fabsf(angle-90.0f) < FLT_EPSILON) {
+    angle = angle - 360.0f * floor(angle / 360.0f);
+
+    if (fabsf(angle - 90.0f) < FLT_EPSILON) {
         // perform 1/4 rotate counter-clockwise
         int numRows = in->numCols;
@@ -550,5 +568,6 @@
         int lastCol = numCols - 1;
         psElemType type = in->type.type;
-        out = psImageRecycle(out,numCols,numRows,type);
+
+        out = psImageRecycle(out, numCols, numRows, type);
 
         #define PSIMAGE_ROTATE_LEFT_90(TYPE) \
@@ -578,217 +597,213 @@
             PSIMAGE_ROTATE_LEFT_90(C64);
         default:
-            psError(__func__,"Unsupported type (%d)",type);
+            psError(__func__, "Unsupported type (%d)", type);
             psFree(out);
             return NULL;
         }
-    } else
-        if (fabsf(angle-180.0f) < FLT_EPSILON) {
-            // perform 1/2 rotate
-            int numRows = in->numRows;
-            int lastRow = numRows - 1;
-            int numCols = in->numCols;
-            int lastCol = numCols - 1;
-            psElemType type = in->type.type;
-            out = psImageRecycle(out,numCols,numRows,type);
-
-            #define PSIMAGE_ROTATE_180_CASE(TYPE) \
-        case PS_TYPE_##TYPE: { \
-                for (int row=0;row<numRows;row++) { \
-                    ps##TYPE* outRow = out->data.TYPE[row]; \
-                    ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
-                    for (int col=0;col<numCols;col++) { \
-                        outRow[col] = inRow[lastCol - col]; \
-                    } \
-                } \
-            } \
-            break;
-
-            switch (type) {
-                PSIMAGE_ROTATE_180_CASE(U8);
-                PSIMAGE_ROTATE_180_CASE(U16);
-                PSIMAGE_ROTATE_180_CASE(U32);
-                PSIMAGE_ROTATE_180_CASE(U64);
-                PSIMAGE_ROTATE_180_CASE(S8);
-                PSIMAGE_ROTATE_180_CASE(S16);
-                PSIMAGE_ROTATE_180_CASE(S32);
-                PSIMAGE_ROTATE_180_CASE(S64);
-                PSIMAGE_ROTATE_180_CASE(F32);
-                PSIMAGE_ROTATE_180_CASE(F64);
-                PSIMAGE_ROTATE_180_CASE(C32);
-                PSIMAGE_ROTATE_180_CASE(C64);
-            default:
-                psError(__func__,"Unsupported type (%d)",type);
-                psFree(out);
-                return NULL;
-            }
-        } else
-            if (fabsf(angle-270.0f) < FLT_EPSILON) {
-                // perform 1/4 rotate clockwise
-                int numRows = in->numCols;
-                int lastRow = numRows - 1;
-                int numCols = in->numRows;
-                psElemType type = in->type.type;
-                out = psImageRecycle(out,numCols,numRows,type);
-
-                #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \
-            case PS_TYPE_##TYPE: { \
-                    ps##TYPE** inData = in->data.TYPE; \
-                    for (int row=0;row<numRows;row++) { \
-                        ps##TYPE* outRow = out->data.TYPE[row]; \
-                        for (int col=0;col<numCols;col++) { \
-                            outRow[col] = inData[col][lastRow-row]; \
-                        } \
-                    } \
-                } \
-                break;
-
-                switch (type) {
-                    PSIMAGE_ROTATE_RIGHT_90(U8);
-                    PSIMAGE_ROTATE_RIGHT_90(U16);
-                    PSIMAGE_ROTATE_RIGHT_90(U32);
-                    PSIMAGE_ROTATE_RIGHT_90(U64);
-                    PSIMAGE_ROTATE_RIGHT_90(S8);
-                    PSIMAGE_ROTATE_RIGHT_90(S16);
-                    PSIMAGE_ROTATE_RIGHT_90(S32);
-                    PSIMAGE_ROTATE_RIGHT_90(S64);
-                    PSIMAGE_ROTATE_RIGHT_90(F32);
-                    PSIMAGE_ROTATE_RIGHT_90(F64);
-                    PSIMAGE_ROTATE_RIGHT_90(C32);
-                    PSIMAGE_ROTATE_RIGHT_90(C64);
-                default:
-                    psError(__func__,"Unsupported type (%d)",type);
-                    psFree(out);
-                    return NULL;
-                }
-            } else
-                if (fabsf(angle) < FLT_EPSILON) {
-                    out = psImageCopy(out,in,in->type.type);
-                } else {
-                    psElemType type = in->type.type;
-                    int numRows = in->numRows;
-                    int numCols = in->numCols;
-                    double centerX = (float)(numCols) / 2.0f;
-                    float centerY = (float)(numRows) / 2.0f;
-                    float t = angle*(3.14159265358f/180.0f);
-                    float cosT = cosf(t);
-                    float sinT = sinf(t);
-
-                    // calculate the corners of the rotated image so we know the proper output image size.
-                    //    x' = x cos(t) + y sin(t);  i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT;
-                    //    y' = y cos(t) - x sin(t);  i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT;
-
-
-                    int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1;
-                    int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1;
-                    float minX = (float)outCols/-2.0f;
-                    int intMinY = outRows/-2;
-
-                    out = psImageRecycle(out,outCols,outRows,type);
-
-                    /* optimized public domain rotation routine by Karl Lager
-                    float cosT,sinT;
-                    cosT = cos(t);
-                    sinT = sin(t);
-                    for (y = min_y; y <= max_y; y++)
-                     { x' = min_x * cosT + y * sinT + x1';
-                       y' = y * cosT - min_x * sinT + y1';
-                       for (x = min_x; x <= max_x; x++)
-                        { if (x', y') is in the bounds of the bitmap, 
-                             get pixel(x', y') and plot the pixel to 
-                             (x, y) on screen.
-                          x' += cosT;
-                          y' -= sinT;
-                        }
-                     }
-                    */
-
-                    // precalculate some figures that are used within loop
-                    float minXTimesCosTPlusCenterX = minX*cosT+centerX;
-                    float CenterYMinusminXTimesSinT = centerY-minX*sinT;
-
-                    #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
-                        if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \
-                            psError(__func__,"The given unexposedValue (%g) is outside of the " \
-                                    "image type's range (%g->%g).", \
-                                    unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
-                            psFree(out); \
-                            out = NULL; \
-                            break; \
-                        } \
-                        float inX; \
-                        float inY; \
-                        ps##TYPE* outRow; \
-                        for (int y = 0; y < outRows; y++) { \
-                            inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
-                            inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
-                            outRow = out->data.TYPE[y]; \
-                            for (int x = 0; x < outCols; x++) { \
-                                outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \
-                                inX += cosT; \
-                                inY -= sinT; \
-                            } \
-                        } \
-                    }
-
-                    #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
-                case PS_INTERPOLATE_##MODE: \
-                    switch (type) { \
-                    case PS_TYPE_U8: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
-                        break; \
-                    case PS_TYPE_U16: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
-                        break; \
-                    case PS_TYPE_U32: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
-                        break; \
-                    case PS_TYPE_U64: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
-                        break; \
-                    case PS_TYPE_S8: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
-                        break; \
-                    case PS_TYPE_S16: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
-                        break; \
-                    case PS_TYPE_S32: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
-                        break; \
-                    case PS_TYPE_S64: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
-                        break; \
-                    case PS_TYPE_F32: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
-                        break; \
-                    case PS_TYPE_F64: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
-                        break; \
-                    case PS_TYPE_C32: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \
-                        break; \
-                    case PS_TYPE_C64: \
-                        PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \
-                        break; \
-                    default: \
-                        psError(__func__,"Image type (%d) not supported",type); \
-                        psFree(out); \
-                        out = NULL; \
-                    } \
-                    break;
-
-                    switch (mode) {
-                        PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
-                        PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
-                    default:
-                        psError(__func__,"Unsupported interpolation mode (%d)",mode);
-                        psFree(out);
-                        out = NULL;
-                    }
-                }
+    } else if (fabsf(angle - 180.0f) < FLT_EPSILON) {
+        // perform 1/2 rotate
+        int numRows = in->numRows;
+        int lastRow = numRows - 1;
+        int numCols = in->numCols;
+        int lastCol = numCols - 1;
+        psElemType type = in->type.type;
+
+        out = psImageRecycle(out, numCols, numRows, type);
+
+        #define PSIMAGE_ROTATE_180_CASE(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
+                for (int col=0;col<numCols;col++) { \
+                    outRow[col] = inRow[lastCol - col]; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (type) {
+            PSIMAGE_ROTATE_180_CASE(U8);
+            PSIMAGE_ROTATE_180_CASE(U16);
+            PSIMAGE_ROTATE_180_CASE(U32);
+            PSIMAGE_ROTATE_180_CASE(U64);
+            PSIMAGE_ROTATE_180_CASE(S8);
+            PSIMAGE_ROTATE_180_CASE(S16);
+            PSIMAGE_ROTATE_180_CASE(S32);
+            PSIMAGE_ROTATE_180_CASE(S64);
+            PSIMAGE_ROTATE_180_CASE(F32);
+            PSIMAGE_ROTATE_180_CASE(F64);
+            PSIMAGE_ROTATE_180_CASE(C32);
+            PSIMAGE_ROTATE_180_CASE(C64);
+        default:
+            psError(__func__, "Unsupported type (%d)", type);
+            psFree(out);
+            return NULL;
+        }
+    } else if (fabsf(angle - 270.0f) < FLT_EPSILON) {
+        // perform 1/4 rotate clockwise
+        int numRows = in->numCols;
+        int lastRow = numRows - 1;
+        int numCols = in->numRows;
+        psElemType type = in->type.type;
+
+        out = psImageRecycle(out, numCols, numRows, type);
+
+        #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            ps##TYPE** inData = in->data.TYPE; \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (int col=0;col<numCols;col++) { \
+                    outRow[col] = inData[col][lastRow-row]; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (type) {
+            PSIMAGE_ROTATE_RIGHT_90(U8);
+            PSIMAGE_ROTATE_RIGHT_90(U16);
+            PSIMAGE_ROTATE_RIGHT_90(U32);
+            PSIMAGE_ROTATE_RIGHT_90(U64);
+            PSIMAGE_ROTATE_RIGHT_90(S8);
+            PSIMAGE_ROTATE_RIGHT_90(S16);
+            PSIMAGE_ROTATE_RIGHT_90(S32);
+            PSIMAGE_ROTATE_RIGHT_90(S64);
+            PSIMAGE_ROTATE_RIGHT_90(F32);
+            PSIMAGE_ROTATE_RIGHT_90(F64);
+            PSIMAGE_ROTATE_RIGHT_90(C32);
+            PSIMAGE_ROTATE_RIGHT_90(C64);
+        default:
+            psError(__func__, "Unsupported type (%d)", type);
+            psFree(out);
+            return NULL;
+        }
+    } else if (fabsf(angle) < FLT_EPSILON) {
+        out = psImageCopy(out, in, in->type.type);
+    } else {
+        psElemType type = in->type.type;
+        int numRows = in->numRows;
+        int numCols = in->numCols;
+        double centerX = (float)(numCols) / 2.0f;
+        float centerY = (float)(numRows) / 2.0f;
+        float t = angle * (3.14159265358f / 180.0f);
+        float cosT = cosf(t);
+        float sinT = sinf(t);
+
+        // calculate the corners of the rotated
+        // image so we know the proper
+        // output image size.
+        // x' = x cos(t) + y sin(t); i.e, x' =
+        // (x-centerX)*cosT +
+        // (y-centerY)*sinT;
+        // y' = y cos(t) - x sin(t); i.e. y' =
+        // (y-centerY)*cosT -
+        // (x-centerX)*sinT;
+
+        int outCols = ceil(abs(numCols * cosT) + abs(numRows * sinT)) + 1;
+        int outRows = ceil(abs(numCols * sinT) + abs(numRows * cosT)) + 1;
+        float minX = (float)outCols / -2.0f;
+        int intMinY = outRows / -2;
+
+        out = psImageRecycle(out, outCols, outRows, type);
+
+        /* optimized public domain rotation routine by Karl Lager float cosT,sinT; cosT = cos(t); sinT =
+         * sin(t); for (y = min_y; y <= max_y; y++) { x' = min_x * cosT + y * sinT + x1'; y' = y * cosT -
+         * min_x * sinT + y1'; for (x = min_x; x <= max_x; x++) { if (x', y') * * * * * * * * is in the
+         * bounds of the bitmap, get pixel(x', y') and plot the pixel to (x, y) on screen. x' += cosT; y' -=
+         * sinT; } } */
+
+        // precalculate some figures that are
+        // used within loop
+        float minXTimesCosTPlusCenterX = minX * cosT + centerX;
+        float CenterYMinusminXTimesSinT = centerY - minX * sinT;
+
+        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
+            if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \
+                psError(__func__,"The given unexposedValue (%g) is outside of the " \
+                        "image type's range (%g->%g).", \
+                        unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
+                psFree(out); \
+                out = NULL; \
+                break; \
+            } \
+            float inX; \
+            float inY; \
+            ps##TYPE* outRow; \
+            for (int y = 0; y < outRows; y++) { \
+                inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
+                inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
+                outRow = out->data.TYPE[y]; \
+                for (int x = 0; x < outCols; x++) { \
+                    outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \
+                    inX += cosT; \
+                    inY -= sinT; \
+                } \
+            } \
+        }
+
+        #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
+    case PS_INTERPOLATE_##MODE: \
+        switch (type) { \
+        case PS_TYPE_U8: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
+            break; \
+        case PS_TYPE_U16: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
+            break; \
+        case PS_TYPE_U32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
+            break; \
+        case PS_TYPE_U64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
+            break; \
+        case PS_TYPE_S8: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
+            break; \
+        case PS_TYPE_S16: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
+            break; \
+        case PS_TYPE_S32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
+            break; \
+        case PS_TYPE_S64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
+            break; \
+        case PS_TYPE_F32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
+            break; \
+        case PS_TYPE_F64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
+            break; \
+        case PS_TYPE_C32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \
+            break; \
+        case PS_TYPE_C64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \
+            break; \
+        default: \
+            psError(__func__,"Image type (%d) not supported",type); \
+            psFree(out); \
+            out = NULL; \
+        } \
+        break;
+
+        switch (mode) {
+            PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
+            PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
+        default:
+            psError(__func__, "Unsupported interpolation mode (%d)", mode);
+            psFree(out);
+            out = NULL;
+        }
+    }
 
     return out;
 }
 
-psImage* psImageShift(psImage* out, const psImage* in, float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode)
+psImage *psImageShift(psImage * out,
+                      const psImage * in,
+                      float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode)
 {
     int outRows;
@@ -798,14 +813,14 @@
 
     if (in == NULL) {
-        psError(__func__,"Input image can not be NULL.");
+        psError(__func__, "Input image can not be NULL.");
         return NULL;
     }
-
-    // create an output image of the same size and type
+    // create an output image of the same size
+    // and type
     outRows = in->numRows;
     outCols = in->numCols;
     type = in->type.type;
     elementSize = PSELEMTYPE_SIZEOF(type);
-    out = psImageRecycle(out,outCols, outRows, type);
+    out = psImageRecycle(out, outCols, outRows, type);
 
     #define PSIMAGE_SHIFT_CASE(TYPE) \
@@ -842,5 +857,5 @@
         PSIMAGE_SHIFT_CASE(C64);
     default:
-        psError(__func__,"Image type (%d) not supported.",type);
+        psError(__func__, "Image type (%d) not supported.", type);
         psFree(out);
         out = NULL;
