IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 6, 2004, 2:06:06 PM (22 years ago)
Author:
desonia
Message:

another attempt to get astyle to get it right.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/image/psImageManip.c

    r1406 r1407  
     1
    12/** @file  psImageManip.c
    23 *
     
    1011 *  @author Ross Harman, MHPCC
    1112 *
    12  *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-08-06 22:34:05 $
     13 *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     14 *  @date $Date: 2004-08-07 00:06:06 $
    1415 *
    1516 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1617 */
    17 #include <math.h>                      // for isfinite(), etc.
     18#include <math.h>                          // for
     19// isfinite(),
     20// etc.
    1821#include <stdlib.h>
    1922#include <stdbool.h>
    20 #include <string.h>                    // for memcpy, etc.
     23#include <string.h>                        // for
     24// memcpy,
     25// etc.
    2126
    2227#include "psError.h"
     
    2631#include "psImageExtraction.h"
    2732
    28 int psImageClip(psImage* input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
     33int psImageClip(psImage * input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
    2934{
    3035    int numClipped = 0;
     
    3742
    3843    if (max < min) {
    39         psError(__func__,"psImageClip can not be invoked with max < min.");
     44        psError(__func__, "psImageClip can not be invoked with max < min.");
    4045        return 0;
    4146    }
     
    100105        break;
    101106
    102         psImageClipCase(S8,"psS8")
    103         psImageClipCase(S16,"psS16")
    104         psImageClipCase(S32,"psS32")
    105         psImageClipCase(S64,"psS64")
    106         psImageClipCase(U8,"psU8")
    107         psImageClipCase(U16,"psU16")
    108         psImageClipCase(U32,"psU32")
    109         psImageClipCase(U64,"psU64")
    110         psImageClipCase(F32,"psF32")
    111         psImageClipCase(F64,"psF64")
    112         psImageClipCaseComplex(C32,"psC32",cabsf)
    113         psImageClipCaseComplex(C64,"psC64",cabs)
     107        psImageClipCase(S8, "psS8")
     108        psImageClipCase(S16, "psS16")
     109        psImageClipCase(S32, "psS32")
     110        psImageClipCase(S64, "psS64")
     111        psImageClipCase(U8, "psU8")
     112        psImageClipCase(U16, "psU16")
     113        psImageClipCase(U32, "psU32")
     114        psImageClipCase(U64, "psU64")
     115        psImageClipCase(F32, "psF32")
     116        psImageClipCase(F64, "psF64")
     117        psImageClipCaseComplex(C32, "psC32", cabsf)
     118        psImageClipCaseComplex(C64, "psC64", cabs)
    114119
    115120    default:
    116         psError(__func__,"psImageClip does not support the given datatype (%d)",
    117                 input->type.type);
     121        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
    118122    }
    119123
     
    121125}
    122126
    123 int psImageClipNaN(psImage* input,psF64 value)
     127int psImageClipNaN(psImage * input, psF64 value)
    124128{
    125129    int numClipped = 0;
     
    154158
    155159    default:
    156         psError(__func__,"psImageClip does not support the given datatype (%d)",
    157                 input->type.type);
     160        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
    158161    }
    159162
     
    161164}
    162165
    163 int psImageOverlaySection(psImage* image, const psImage* overlay, int col0,
    164                           int row0, const char* op)
     166int psImageOverlaySection(psImage * image, const psImage * overlay, int col0, int row0, const char *op)
    165167{
    166168    unsigned int imageNumRows;
     
    170172    unsigned int imageRowLimit;
    171173    unsigned int imageColLimit;
    172     psElemType  type;
     174    psElemType type;
    173175
    174176    if (image == NULL || overlay == NULL) {
    175         psError(__func__,"one of the input images was NULL.");
     177        psError(__func__, "one of the input images was NULL.");
    176178        return 1;
    177179    }
    178180
    179181    if (op == NULL) {
    180         psError(__func__,"Operation can not be NULL.");
     182        psError(__func__, "Operation can not be NULL.");
    181183        return 1;
    182184    }
     
    185187
    186188    if (type != overlay->type.type) {
    187         psError(__func__,"Image and overlay datatypes must match. (%d vs %d)",
    188                 type,overlay->type.type);
     189        psError(__func__, "Image and overlay datatypes must match. (%d vs %d)", type, overlay->type.type);
    189190        return 2;
    190191    }
     
    197198    /* check row0/col0 to see if it is within the image size */
    198199    if (row0 < 0 || col0 < 0 || row0 >= imageNumRows || col0 >= imageNumCols) {
    199         psError(__func__, "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
     200        psError(__func__,
     201                "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).",
    200202                col0, row0, imageNumCols, imageNumRows);
    201203        return 3;
     
    203205
    204206    /* check if overlay is totally withing input image */
    205     imageRowLimit = row0+overlayNumRows;
    206     imageColLimit = col0+overlayNumCols;
     207    imageRowLimit = row0 + overlayNumRows;
     208    imageColLimit = col0 + overlayNumCols;
    207209    if (imageRowLimit > imageNumRows || imageColLimit > imageNumCols) {
    208         psError(__func__, "Overlay image (%d,%d -> %d,%d) is partially outside"
     210        psError(__func__,
     211                "Overlay image (%d,%d -> %d,%d) is partially outside"
    209212                " of the input image (%d x %d).",
    210                 col0, row0, col0+overlayNumCols-1, row0+overlayNumRows-1,
    211                 imageNumCols,imageNumRows);
     213                col0, row0, col0 + overlayNumCols - 1, row0 + overlayNumRows - 1, imageNumCols, imageNumRows);
    212214        return 4;
    213215    }
     
    259261
    260262    default:
    261         psError(__func__,"Can not operate on type %d.",type);
     263        psError(__func__, "Can not operate on type %d.", type);
    262264    }
    263265
     
    265267}
    266268
    267 int psImageClipComplexRegion(psImage* input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
     269int psImageClipComplexRegion(psImage * input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
    268270{
    269271    int numClipped = 0;
     
    276278
    277279    if (input == NULL) {
    278         psError(__func__,"Can not perform clip on NULL image");
     280        psError(__func__, "Can not perform clip on NULL image");
    279281        return 0;
    280282    }
    281283
    282     if ( realMax < realMin ) {
    283         psError(__func__,"psImageClipComplexRegion can not be invoked with "
    284                 "max < min in the real image space.");
     284    if (realMax < realMin) {
     285        psError(__func__,
     286                "psImageClipComplexRegion can not be invoked with " "max < min in the real image space.");
    285287        return 0;
    286288    }
    287     if ( imagMax < imagMin ) {
    288         psError(__func__,"psImageClipComplexRegion can not be invoked with "
     289    if (imagMax < imagMin) {
     290        psError(__func__,
     291                "psImageClipComplexRegion can not be invoked with "
    289292                "max < min in the imaginary image space.");
    290293        return 0;
     
    294297    numCols = input->numCols;
    295298
     299    #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
     300case PS_TYPE_##type: { \
     301        if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
     302                realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
     303            psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
     304                    typename " pixel range", \
     305                    creal(vmin),cimag(vmin)); \
     306            break; \
     307        } \
     308        if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
     309                realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
     310            psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
     311                    typename " pixel range", \
     312                    creal(vmax),cimag(vmax)); \
     313            break; \
     314        } \
     315        for (unsigned int row = 0;row<numRows;row++) { \
     316            ps##type* inputRow = input->data.type[row]; \
     317            for (unsigned int col = 0; col < numCols; col++) { \
     318                if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
     319                    inputRow[col] = (ps##type)vmax; \
     320                    numClipped++; \
     321                } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \
     322                    inputRow[col] = (ps##type)vmin; \
     323                    numClipped++; \
     324                } \
     325            } \
     326        } \
     327    } \
     328    break;
     329
    296330    switch (input->type.type) {
    297331
    298         #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
    299     case PS_TYPE_##type: { \
    300             if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
    301                     realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
    302                 psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
    303                         typename " pixel range", \
    304                         creal(vmin),cimag(vmin)); \
    305                 break; \
    306             } \
    307             if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
    308                     realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
    309                 psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
    310                         typename " pixel range", \
    311                         creal(vmax),cimag(vmax)); \
    312                 break; \
    313             } \
    314             for (unsigned int row = 0;row<numRows;row++) { \
    315                 ps##type* inputRow = input->data.type[row]; \
    316                 for (unsigned int col = 0; col < numCols; col++) { \
    317                     if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
    318                         inputRow[col] = (ps##type)vmax; \
    319                         numClipped++; \
    320                     } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \
    321                         inputRow[col] = (ps##type)vmin; \
    322                         numClipped++; \
    323                     } \
    324                 } \
    325             } \
    326         } \
    327         break;
    328 
    329         psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf)
    330         psImageClipComplexRegionCase(C64,"psC64",creal,cimag)
     332        psImageClipComplexRegionCase(C32, "psC32", crealf, cimagf)
     333        psImageClipComplexRegionCase(C64, "psC64", creal, cimag)
    331334
    332335    default:
    333         psError(__func__,"psImageClip does not support the given datatype (%d)",
    334                 input->type.type);
     336        psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type);
    335337    }
    336338
     
    338340}
    339341
    340 
    341 psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats)
     342psImage *psImageRebin(psImage * out, const psImage * in, unsigned int scale, const psStats * stats)
    342343{
    343344    int inRows;
     
    345346    int outRows;
    346347    int outCols;
    347     psVector* vec;            // vector to hold the values of a single bin.
    348     psStats* myStats;
     348    psVector *vec;              // vector to hold
     349
     350    // the values of
     351    // a single bin.
     352    psStats *myStats;
    349353    double statVal;
    350354
    351355    if (in == NULL) {
    352         psError(__func__,"Input image is NULL.");
     356        psError(__func__, "Input image is NULL.");
    353357        psFree(out);
    354358        return NULL;
     
    356360
    357361    if (scale < 1) {
    358         psError(__func__,"The scale must be positive.");
     362        psError(__func__, "The scale must be positive.");
    359363        psFree(out);
    360364        return NULL;
     
    362366
    363367    if (stats == NULL) {
    364         psError(__func__,"The stats input can not be NULL.");
     368        psError(__func__, "The stats input can not be NULL.");
    365369        psFree(out);
    366370        return NULL;
    367371    }
    368372
    369     if (p_psGetStatValue(stats,&statVal) == false) {
    370         psError(__func__,"The stat options didn't specify a single supported statistic type.");
     373    if (p_psGetStatValue(stats, &statVal) == false) {
     374        psError(__func__, "The stat options didn't specify a single supported statistic type.");
    371375        psFree(out);
    372376        return NULL;
     
    376380    *myStats = *stats;
    377381
    378     vec = psVectorAlloc(scale*scale,in->type.type);
     382    vec = psVectorAlloc(scale * scale, in->type.type);
    379383
    380384    // create output image.
    381385    inRows = in->numRows;
    382386    inCols = in->numCols;
    383     outRows = (inRows+scale-1) / scale;   // round-up for remainders
    384     outCols = (inCols+scale-1) / scale;   // round-up for remainders
    385     out = psImageRecycle(out,outCols,outRows,in->type.type);
     387    outRows = (inRows + scale - 1) / scale;     // round-up
     388    // for
     389    // remainders
     390    outCols = (inCols + scale - 1) / scale;     // round-up
     391    // for
     392    // remainders
     393    out = psImageRecycle(out, outCols, outRows, in->type.type);
    386394
    387395    #define PS_IMAGE_REBIN_CASE(type) \
     
    425433        PS_IMAGE_REBIN_CASE(C64);
    426434    default:
    427         psError(__func__,"Input image type not supported.");
     435        psError(__func__, "Input image type not supported.");
    428436        psFree(out);
    429437        out = NULL;
     
    435443    return out;
    436444}
    437 psImage* psImageResample(psImage* out, const psImage* in, int scale, psImageInterpolateMode mode)
     445
     446psImage *psImageResample(psImage * out, const psImage * in, int scale, psImageInterpolateMode mode)
    438447{
    439448    int outRows;
     
    442451
    443452    if (in == NULL) {
    444         psError(__func__,"Input image can not be NULL.");
     453        psError(__func__, "Input image can not be NULL.");
    445454        psFree(out);
    446455        return NULL;
    447456    }
    448 
    449     // create an output image of the same size and type
    450     outRows = in->numRows*scale;
    451     outCols = in->numCols*scale;
     457    // create an output image of the same size
     458    // and type
     459    outRows = in->numRows * scale;
     460    outCols = in->numCols * scale;
    452461    invScale = 1.0f / (float)scale;
    453 
    454462
    455463    #define PSIMAGE_RESAMPLE_CASE(TYPE) \
     
    466474    }
    467475
    468     switch(in->type.type) {
     476    switch (in->type.type) {
    469477        PSIMAGE_RESAMPLE_CASE(U8)
    470478        PSIMAGE_RESAMPLE_CASE(U16)
     
    480488        PSIMAGE_RESAMPLE_CASE(C64)
    481489    default:
    482         psError(__func__,"Unsupported type (%d)",in->type.type);
     490        psError(__func__, "Unsupported type (%d)", in->type.type);
    483491        psFree(out);
    484492        return NULL;
     
    488496}
    489497
    490 psImage* psImageRoll(psImage* out, const psImage* in, int dx, int dy)
     498psImage *psImageRoll(psImage * out, const psImage * in, int dx, int dy)
    491499{
    492500    int outRows;
     
    495503
    496504    if (in == NULL) {
    497         psError(__func__,"Input image can not be NULL.");
     505        psError(__func__, "Input image can not be NULL.");
    498506        psFree(out);
    499507        return NULL;
    500508    }
    501 
    502     // create an output image of the same size and type
     509    // create an output image of the same size
     510    // and type
    503511    outRows = in->numRows;
    504512    outCols = in->numCols;
    505513    elementSize = PSELEMTYPE_SIZEOF(in->type.type);
    506     out = psImageRecycle(out,outCols, outRows, in->type.type);
    507 
    508     // make dx and dy between 0 and outCols or outRows, respectively
     514    out = psImageRecycle(out, outCols, outRows, in->type.type);
     515
     516    // make dx and dy between 0 and outCols or
     517    // outRows, respectively
    509518    dx = dx % outCols;
    510519    dy = dy % outRows;
     
    516525    }
    517526
    518     int segment1Size = elementSize*(outCols-dx);
    519     int segment2Size = elementSize*dx;
    520 
    521     for (int row=0;row<outRows;row++) {
    522         int inRowNumber = row+dy;
     527    int segment1Size = elementSize * (outCols - dx);
     528    int segment2Size = elementSize * dx;
     529
     530    for (int row = 0; row < outRows; row++) {
     531        int inRowNumber = row + dy;
     532
    523533        if (inRowNumber >= outRows) {
    524534            inRowNumber -= outRows;
    525535        }
    526         psU8* inRow = in->data.U8[inRowNumber]; // to allow byte arithmetic, but for all types
    527         psU8* outRow = out->data.U8[row];
    528         memcpy(outRow,inRow+segment2Size,segment1Size);
    529         memcpy(outRow+segment1Size,inRow,segment2Size);
     536        psU8 *inRow = in->data.U8[inRowNumber]; // to
     537
     538        // allow
     539
     540        // byte
     541        // arithmetic,
     542
     543        // but for all types
     544        psU8 *outRow = out->data.U8[row];
     545
     546        memcpy(outRow, inRow + segment2Size, segment1Size);
     547        memcpy(outRow + segment1Size, inRow, segment2Size);
    530548    }
    531549
     
    533551}
    534552
    535 psImage* psImageRotate(psImage* out, const psImage* in, float angle, float unexposedValue, psImageInterpolateMode mode)
     553psImage *psImageRotate(psImage * out,
     554                       const psImage * in, float angle, float unexposedValue, psImageInterpolateMode mode)
    536555{
    537556    if (in == NULL) {
    538         psError(__func__,"The input image was NULL.");
     557        psError(__func__, "The input image was NULL.");
    539558        psFree(out);
    540559        return NULL;
    541560    }
    542 
    543561    // put the angle in the range of 0...360.
    544     angle = angle - 360.0f*floor(angle/360.0f);
    545 
    546     if (fabsf(angle-90.0f) < FLT_EPSILON) {
     562    angle = angle - 360.0f * floor(angle / 360.0f);
     563
     564    if (fabsf(angle - 90.0f) < FLT_EPSILON) {
    547565        // perform 1/4 rotate counter-clockwise
    548566        int numRows = in->numCols;
     
    550568        int lastCol = numCols - 1;
    551569        psElemType type = in->type.type;
    552         out = psImageRecycle(out,numCols,numRows,type);
     570
     571        out = psImageRecycle(out, numCols, numRows, type);
    553572
    554573        #define PSIMAGE_ROTATE_LEFT_90(TYPE) \
     
    578597            PSIMAGE_ROTATE_LEFT_90(C64);
    579598        default:
    580             psError(__func__,"Unsupported type (%d)",type);
     599            psError(__func__, "Unsupported type (%d)", type);
    581600            psFree(out);
    582601            return NULL;
    583602        }
    584     } else
    585         if (fabsf(angle-180.0f) < FLT_EPSILON) {
    586             // perform 1/2 rotate
    587             int numRows = in->numRows;
    588             int lastRow = numRows - 1;
    589             int numCols = in->numCols;
    590             int lastCol = numCols - 1;
    591             psElemType type = in->type.type;
    592             out = psImageRecycle(out,numCols,numRows,type);
    593 
    594             #define PSIMAGE_ROTATE_180_CASE(TYPE) \
    595         case PS_TYPE_##TYPE: { \
    596                 for (int row=0;row<numRows;row++) { \
    597                     ps##TYPE* outRow = out->data.TYPE[row]; \
    598                     ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
    599                     for (int col=0;col<numCols;col++) { \
    600                         outRow[col] = inRow[lastCol - col]; \
    601                     } \
    602                 } \
    603             } \
    604             break;
    605 
    606             switch (type) {
    607                 PSIMAGE_ROTATE_180_CASE(U8);
    608                 PSIMAGE_ROTATE_180_CASE(U16);
    609                 PSIMAGE_ROTATE_180_CASE(U32);
    610                 PSIMAGE_ROTATE_180_CASE(U64);
    611                 PSIMAGE_ROTATE_180_CASE(S8);
    612                 PSIMAGE_ROTATE_180_CASE(S16);
    613                 PSIMAGE_ROTATE_180_CASE(S32);
    614                 PSIMAGE_ROTATE_180_CASE(S64);
    615                 PSIMAGE_ROTATE_180_CASE(F32);
    616                 PSIMAGE_ROTATE_180_CASE(F64);
    617                 PSIMAGE_ROTATE_180_CASE(C32);
    618                 PSIMAGE_ROTATE_180_CASE(C64);
    619             default:
    620                 psError(__func__,"Unsupported type (%d)",type);
    621                 psFree(out);
    622                 return NULL;
    623             }
    624         } else
    625             if (fabsf(angle-270.0f) < FLT_EPSILON) {
    626                 // perform 1/4 rotate clockwise
    627                 int numRows = in->numCols;
    628                 int lastRow = numRows - 1;
    629                 int numCols = in->numRows;
    630                 psElemType type = in->type.type;
    631                 out = psImageRecycle(out,numCols,numRows,type);
    632 
    633                 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \
    634             case PS_TYPE_##TYPE: { \
    635                     ps##TYPE** inData = in->data.TYPE; \
    636                     for (int row=0;row<numRows;row++) { \
    637                         ps##TYPE* outRow = out->data.TYPE[row]; \
    638                         for (int col=0;col<numCols;col++) { \
    639                             outRow[col] = inData[col][lastRow-row]; \
    640                         } \
    641                     } \
    642                 } \
    643                 break;
    644 
    645                 switch (type) {
    646                     PSIMAGE_ROTATE_RIGHT_90(U8);
    647                     PSIMAGE_ROTATE_RIGHT_90(U16);
    648                     PSIMAGE_ROTATE_RIGHT_90(U32);
    649                     PSIMAGE_ROTATE_RIGHT_90(U64);
    650                     PSIMAGE_ROTATE_RIGHT_90(S8);
    651                     PSIMAGE_ROTATE_RIGHT_90(S16);
    652                     PSIMAGE_ROTATE_RIGHT_90(S32);
    653                     PSIMAGE_ROTATE_RIGHT_90(S64);
    654                     PSIMAGE_ROTATE_RIGHT_90(F32);
    655                     PSIMAGE_ROTATE_RIGHT_90(F64);
    656                     PSIMAGE_ROTATE_RIGHT_90(C32);
    657                     PSIMAGE_ROTATE_RIGHT_90(C64);
    658                 default:
    659                     psError(__func__,"Unsupported type (%d)",type);
    660                     psFree(out);
    661                     return NULL;
    662                 }
    663             } else
    664                 if (fabsf(angle) < FLT_EPSILON) {
    665                     out = psImageCopy(out,in,in->type.type);
    666                 } else {
    667                     psElemType type = in->type.type;
    668                     int numRows = in->numRows;
    669                     int numCols = in->numCols;
    670                     double centerX = (float)(numCols) / 2.0f;
    671                     float centerY = (float)(numRows) / 2.0f;
    672                     float t = angle*(3.14159265358f/180.0f);
    673                     float cosT = cosf(t);
    674                     float sinT = sinf(t);
    675 
    676                     // calculate the corners of the rotated image so we know the proper output image size.
    677                     //    x' = x cos(t) + y sin(t);  i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT;
    678                     //    y' = y cos(t) - x sin(t);  i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT;
    679 
    680 
    681                     int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1;
    682                     int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1;
    683                     float minX = (float)outCols/-2.0f;
    684                     int intMinY = outRows/-2;
    685 
    686                     out = psImageRecycle(out,outCols,outRows,type);
    687 
    688                     /* optimized public domain rotation routine by Karl Lager
    689                     float cosT,sinT;
    690                     cosT = cos(t);
    691                     sinT = sin(t);
    692                     for (y = min_y; y <= max_y; y++)
    693                      { x' = min_x * cosT + y * sinT + x1';
    694                        y' = y * cosT - min_x * sinT + y1';
    695                        for (x = min_x; x <= max_x; x++)
    696                         { if (x', y') is in the bounds of the bitmap,
    697                              get pixel(x', y') and plot the pixel to
    698                              (x, y) on screen.
    699                           x' += cosT;
    700                           y' -= sinT;
    701                         }
    702                      }
    703                     */
    704 
    705                     // precalculate some figures that are used within loop
    706                     float minXTimesCosTPlusCenterX = minX*cosT+centerX;
    707                     float CenterYMinusminXTimesSinT = centerY-minX*sinT;
    708 
    709                     #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
    710                         if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \
    711                             psError(__func__,"The given unexposedValue (%g) is outside of the " \
    712                                     "image type's range (%g->%g).", \
    713                                     unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
    714                             psFree(out); \
    715                             out = NULL; \
    716                             break; \
    717                         } \
    718                         float inX; \
    719                         float inY; \
    720                         ps##TYPE* outRow; \
    721                         for (int y = 0; y < outRows; y++) { \
    722                             inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
    723                             inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
    724                             outRow = out->data.TYPE[y]; \
    725                             for (int x = 0; x < outCols; x++) { \
    726                                 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \
    727                                 inX += cosT; \
    728                                 inY -= sinT; \
    729                             } \
    730                         } \
    731                     }
    732 
    733                     #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
    734                 case PS_INTERPOLATE_##MODE: \
    735                     switch (type) { \
    736                     case PS_TYPE_U8: \
    737                         PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
    738                         break; \
    739                     case PS_TYPE_U16: \
    740                         PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
    741                         break; \
    742                     case PS_TYPE_U32: \
    743                         PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
    744                         break; \
    745                     case PS_TYPE_U64: \
    746                         PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
    747                         break; \
    748                     case PS_TYPE_S8: \
    749                         PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
    750                         break; \
    751                     case PS_TYPE_S16: \
    752                         PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
    753                         break; \
    754                     case PS_TYPE_S32: \
    755                         PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
    756                         break; \
    757                     case PS_TYPE_S64: \
    758                         PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
    759                         break; \
    760                     case PS_TYPE_F32: \
    761                         PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
    762                         break; \
    763                     case PS_TYPE_F64: \
    764                         PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
    765                         break; \
    766                     case PS_TYPE_C32: \
    767                         PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \
    768                         break; \
    769                     case PS_TYPE_C64: \
    770                         PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \
    771                         break; \
    772                     default: \
    773                         psError(__func__,"Image type (%d) not supported",type); \
    774                         psFree(out); \
    775                         out = NULL; \
    776                     } \
    777                     break;
    778 
    779                     switch (mode) {
    780                         PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
    781                         PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
    782                     default:
    783                         psError(__func__,"Unsupported interpolation mode (%d)",mode);
    784                         psFree(out);
    785                         out = NULL;
    786                     }
    787                 }
     603    } else if (fabsf(angle - 180.0f) < FLT_EPSILON) {
     604        // perform 1/2 rotate
     605        int numRows = in->numRows;
     606        int lastRow = numRows - 1;
     607        int numCols = in->numCols;
     608        int lastCol = numCols - 1;
     609        psElemType type = in->type.type;
     610
     611        out = psImageRecycle(out, numCols, numRows, type);
     612
     613        #define PSIMAGE_ROTATE_180_CASE(TYPE) \
     614    case PS_TYPE_##TYPE: { \
     615            for (int row=0;row<numRows;row++) { \
     616                ps##TYPE* outRow = out->data.TYPE[row]; \
     617                ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
     618                for (int col=0;col<numCols;col++) { \
     619                    outRow[col] = inRow[lastCol - col]; \
     620                } \
     621            } \
     622        } \
     623        break;
     624
     625        switch (type) {
     626            PSIMAGE_ROTATE_180_CASE(U8);
     627            PSIMAGE_ROTATE_180_CASE(U16);
     628            PSIMAGE_ROTATE_180_CASE(U32);
     629            PSIMAGE_ROTATE_180_CASE(U64);
     630            PSIMAGE_ROTATE_180_CASE(S8);
     631            PSIMAGE_ROTATE_180_CASE(S16);
     632            PSIMAGE_ROTATE_180_CASE(S32);
     633            PSIMAGE_ROTATE_180_CASE(S64);
     634            PSIMAGE_ROTATE_180_CASE(F32);
     635            PSIMAGE_ROTATE_180_CASE(F64);
     636            PSIMAGE_ROTATE_180_CASE(C32);
     637            PSIMAGE_ROTATE_180_CASE(C64);
     638        default:
     639            psError(__func__, "Unsupported type (%d)", type);
     640            psFree(out);
     641            return NULL;
     642        }
     643    } else if (fabsf(angle - 270.0f) < FLT_EPSILON) {
     644        // perform 1/4 rotate clockwise
     645        int numRows = in->numCols;
     646        int lastRow = numRows - 1;
     647        int numCols = in->numRows;
     648        psElemType type = in->type.type;
     649
     650        out = psImageRecycle(out, numCols, numRows, type);
     651
     652        #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \
     653    case PS_TYPE_##TYPE: { \
     654            ps##TYPE** inData = in->data.TYPE; \
     655            for (int row=0;row<numRows;row++) { \
     656                ps##TYPE* outRow = out->data.TYPE[row]; \
     657                for (int col=0;col<numCols;col++) { \
     658                    outRow[col] = inData[col][lastRow-row]; \
     659                } \
     660            } \
     661        } \
     662        break;
     663
     664        switch (type) {
     665            PSIMAGE_ROTATE_RIGHT_90(U8);
     666            PSIMAGE_ROTATE_RIGHT_90(U16);
     667            PSIMAGE_ROTATE_RIGHT_90(U32);
     668            PSIMAGE_ROTATE_RIGHT_90(U64);
     669            PSIMAGE_ROTATE_RIGHT_90(S8);
     670            PSIMAGE_ROTATE_RIGHT_90(S16);
     671            PSIMAGE_ROTATE_RIGHT_90(S32);
     672            PSIMAGE_ROTATE_RIGHT_90(S64);
     673            PSIMAGE_ROTATE_RIGHT_90(F32);
     674            PSIMAGE_ROTATE_RIGHT_90(F64);
     675            PSIMAGE_ROTATE_RIGHT_90(C32);
     676            PSIMAGE_ROTATE_RIGHT_90(C64);
     677        default:
     678            psError(__func__, "Unsupported type (%d)", type);
     679            psFree(out);
     680            return NULL;
     681        }
     682    } else if (fabsf(angle) < FLT_EPSILON) {
     683        out = psImageCopy(out, in, in->type.type);
     684    } else {
     685        psElemType type = in->type.type;
     686        int numRows = in->numRows;
     687        int numCols = in->numCols;
     688        double centerX = (float)(numCols) / 2.0f;
     689        float centerY = (float)(numRows) / 2.0f;
     690        float t = angle * (3.14159265358f / 180.0f);
     691        float cosT = cosf(t);
     692        float sinT = sinf(t);
     693
     694        // calculate the corners of the rotated
     695        // image so we know the proper
     696        // output image size.
     697        // x' = x cos(t) + y sin(t); i.e, x' =
     698        // (x-centerX)*cosT +
     699        // (y-centerY)*sinT;
     700        // y' = y cos(t) - x sin(t); i.e. y' =
     701        // (y-centerY)*cosT -
     702        // (x-centerX)*sinT;
     703
     704        int outCols = ceil(abs(numCols * cosT) + abs(numRows * sinT)) + 1;
     705        int outRows = ceil(abs(numCols * sinT) + abs(numRows * cosT)) + 1;
     706        float minX = (float)outCols / -2.0f;
     707        int intMinY = outRows / -2;
     708
     709        out = psImageRecycle(out, outCols, outRows, type);
     710
     711        /* optimized public domain rotation routine by Karl Lager float cosT,sinT; cosT = cos(t); sinT =
     712         * sin(t); for (y = min_y; y <= max_y; y++) { x' = min_x * cosT + y * sinT + x1'; y' = y * cosT -
     713         * min_x * sinT + y1'; for (x = min_x; x <= max_x; x++) { if (x', y') * * * * * * * * is in the
     714         * bounds of the bitmap, get pixel(x', y') and plot the pixel to (x, y) on screen. x' += cosT; y' -=
     715         * sinT; } } */
     716
     717        // precalculate some figures that are
     718        // used within loop
     719        float minXTimesCosTPlusCenterX = minX * cosT + centerX;
     720        float CenterYMinusminXTimesSinT = centerY - minX * sinT;
     721
     722        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
     723            if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \
     724                psError(__func__,"The given unexposedValue (%g) is outside of the " \
     725                        "image type's range (%g->%g).", \
     726                        unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
     727                psFree(out); \
     728                out = NULL; \
     729                break; \
     730            } \
     731            float inX; \
     732            float inY; \
     733            ps##TYPE* outRow; \
     734            for (int y = 0; y < outRows; y++) { \
     735                inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
     736                inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
     737                outRow = out->data.TYPE[y]; \
     738                for (int x = 0; x < outCols; x++) { \
     739                    outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \
     740                    inX += cosT; \
     741                    inY -= sinT; \
     742                } \
     743            } \
     744        }
     745
     746        #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
     747    case PS_INTERPOLATE_##MODE: \
     748        switch (type) { \
     749        case PS_TYPE_U8: \
     750            PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
     751            break; \
     752        case PS_TYPE_U16: \
     753            PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
     754            break; \
     755        case PS_TYPE_U32: \
     756            PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \
     757            break; \
     758        case PS_TYPE_U64: \
     759            PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \
     760            break; \
     761        case PS_TYPE_S8: \
     762            PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
     763            break; \
     764        case PS_TYPE_S16: \
     765            PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
     766            break; \
     767        case PS_TYPE_S32: \
     768            PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \
     769            break; \
     770        case PS_TYPE_S64: \
     771            PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \
     772            break; \
     773        case PS_TYPE_F32: \
     774            PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
     775            break; \
     776        case PS_TYPE_F64: \
     777            PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
     778            break; \
     779        case PS_TYPE_C32: \
     780            PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \
     781            break; \
     782        case PS_TYPE_C64: \
     783            PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \
     784            break; \
     785        default: \
     786            psError(__func__,"Image type (%d) not supported",type); \
     787            psFree(out); \
     788            out = NULL; \
     789        } \
     790        break;
     791
     792        switch (mode) {
     793            PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
     794            PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
     795        default:
     796            psError(__func__, "Unsupported interpolation mode (%d)", mode);
     797            psFree(out);
     798            out = NULL;
     799        }
     800    }
    788801
    789802    return out;
    790803}
    791804
    792 psImage* psImageShift(psImage* out, const psImage* in, float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode)
     805psImage *psImageShift(psImage * out,
     806                      const psImage * in,
     807                      float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode)
    793808{
    794809    int outRows;
     
    798813
    799814    if (in == NULL) {
    800         psError(__func__,"Input image can not be NULL.");
     815        psError(__func__, "Input image can not be NULL.");
    801816        return NULL;
    802817    }
    803 
    804     // create an output image of the same size and type
     818    // create an output image of the same size
     819    // and type
    805820    outRows = in->numRows;
    806821    outCols = in->numCols;
    807822    type = in->type.type;
    808823    elementSize = PSELEMTYPE_SIZEOF(type);
    809     out = psImageRecycle(out,outCols, outRows, type);
     824    out = psImageRecycle(out, outCols, outRows, type);
    810825
    811826    #define PSIMAGE_SHIFT_CASE(TYPE) \
     
    842857        PSIMAGE_SHIFT_CASE(C64);
    843858    default:
    844         psError(__func__,"Image type (%d) not supported.",type);
     859        psError(__func__, "Image type (%d) not supported.", type);
    845860        psFree(out);
    846861        out = NULL;
Note: See TracChangeset for help on using the changeset viewer.