Changeset 12741 for trunk/psLib/src/mathtypes
- Timestamp:
- Apr 4, 2007, 12:42:02 PM (19 years ago)
- Location:
- trunk/psLib/src/mathtypes
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/mathtypes/psImage.c
r12527 r12741 9 9 * @author Ross Harman, MHPCC 10 10 * 11 * @version $Revision: 1.12 7$ $Name: not supported by cvs2svn $12 * @date $Date: 2007-0 3-22 00:11:08$11 * @version $Revision: 1.128 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2007-04-04 22:42:02 $ 13 13 * 14 14 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 572 572 } 573 573 574 double psImagePixelInterpolate(const psImage* input,575 float x,576 float y,577 const psImage* mask,578 psMaskType maskVal,579 double unexposedValue,580 psImageInterpolateMode mode)581 {582 PS_ASSERT_IMAGE_NON_NULL(input, unexposedValue);583 584 #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE) \585 case PS_TYPE_##TYPE: \586 switch (mode) { \587 case PS_INTERPOLATE_FLAT: \588 return p_psImagePixelInterpolateFLAT_##TYPE( \589 input, \590 x, \591 y, \592 mask, \593 maskVal, \594 unexposedValue); \595 break; \596 case PS_INTERPOLATE_BILINEAR: \597 return p_psImagePixelInterpolateBILINEAR_##TYPE( \598 input, \599 x, \600 y, \601 mask, \602 maskVal, \603 unexposedValue); \604 break; \605 case PS_INTERPOLATE_BILINEAR_VARIANCE: \606 return p_psImagePixelInterpolateBILINEAR_VARIANCE_##TYPE( \607 input, \608 x, \609 y, \610 mask, \611 maskVal, \612 unexposedValue); \613 break; \614 case PS_INTERPOLATE_BICUBE: \615 return p_psImagePixelInterpolateBICUBE_##TYPE( \616 input, \617 x, \618 y, \619 mask, \620 maskVal, \621 unexposedValue); \622 break; \623 default: \624 psError(PS_ERR_BAD_PARAMETER_VALUE,true, \625 _("Specified interpolation method (%d) is not supported."), \626 mode); \627 } \628 break;629 630 switch (input->type.type) {631 PSIMAGE_PIXEL_INTERPOLATE_CASE(U8);632 PSIMAGE_PIXEL_INTERPOLATE_CASE(U16);633 PSIMAGE_PIXEL_INTERPOLATE_CASE(U32);634 PSIMAGE_PIXEL_INTERPOLATE_CASE(U64);635 PSIMAGE_PIXEL_INTERPOLATE_CASE(S8);636 PSIMAGE_PIXEL_INTERPOLATE_CASE(S16);637 PSIMAGE_PIXEL_INTERPOLATE_CASE(S32);638 PSIMAGE_PIXEL_INTERPOLATE_CASE(S64);639 PSIMAGE_PIXEL_INTERPOLATE_CASE(F32);640 PSIMAGE_PIXEL_INTERPOLATE_CASE(F64);641 default: {642 char* typeStr;643 PS_TYPE_NAME(typeStr,input->type.type);644 psError(PS_ERR_BAD_PARAMETER_TYPE,true,645 _("Specified psImage type, %s, is not supported."),646 typeStr);647 }648 }649 650 return unexposedValue;651 }652 574 653 575 psF64 p_psImageGetElementF64(psImage* image, … … 699 621 } 700 622 } 701 702 #define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE,RETURNTYPE) \703 inline RETURNTYPE p_psImagePixelInterpolateFLAT_##TYPE( \704 const psImage* input, \705 float x, \706 float y, \707 const psImage* mask, \708 psMaskType maskVal, \709 RETURNTYPE unexposedValue) \710 { \711 psS32 intX = (psS32) round((psF64)(x) - 0.5 + FLT_EPSILON); \712 psS32 intY = (psS32) round((psF64)(y) - 0.5 + FLT_EPSILON); \713 psS32 lastX = input->numCols - 1; \714 psS32 lastY = input->numRows - 1; \715 \716 if ((intX < 0) || \717 (intX > lastX) || \718 (intY < 0) || \719 (intY > lastY) || \720 ( (mask!=NULL) && \721 ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \722 return unexposedValue; \723 } \724 \725 return input->data.TYPE[intY][intX]; \726 }727 728 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8,psF64)729 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16,psF64)730 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32,psF64)731 PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64,psF64)732 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8,psF64)733 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16,psF64)734 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32,psF64)735 PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64,psF64)736 PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32,psF64)737 PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64,psF64)738 739 #define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE, RETURNTYPE, SUFFIX, FRACFUNC) \740 inline RETURNTYPE p_psImagePixelInterpolateBILINEAR_##SUFFIX( \741 const psImage* input, \742 float x, \743 float y, \744 const psImage* mask, \745 psMaskType maskVal, \746 RETURNTYPE unexposedValue) \747 { \748 int floorX = floor((x) - 0.5); \749 int floorY = floor((y) - 0.5); \750 float fracX = x - 0.5 - floorX; \751 float fracY = y - 0.5 - floorY; \752 int lastX = input->numCols - 1; \753 int lastY = input->numRows - 1; \754 ps##TYPE V00 = 0; \755 ps##TYPE V01 = 0; \756 ps##TYPE V10 = 0; \757 ps##TYPE V11 = 0; \758 bool valid00; \759 bool valid01; \760 bool valid10; \761 bool valid11; \762 \763 if (floorY >= 0 && floorY <= lastY) { \764 if (floorX >= 0 && floorX <= lastX) { \765 V00 = input->data.TYPE[floorY][floorX]; \766 valid00 = (mask == NULL) || \767 ((mask->data.PS_TYPE_MASK_DATA[floorY][floorX] & maskVal) == 0); \768 } else { \769 valid00 = false; \770 } \771 if (floorX >= -1 && floorX < lastX) { \772 V10 = input->data.TYPE[floorY][floorX+1]; \773 valid10 = (mask == NULL) || \774 ((mask->data.PS_TYPE_MASK_DATA[floorY][floorX+1] & maskVal) == 0); \775 } else { \776 valid10 = false; \777 } \778 } else { \779 valid00 = false; \780 valid10 = false; \781 } \782 if (floorY >= -1 && floorY < lastY) { \783 if (floorX >= 0 && floorX <= lastX) { \784 V01 = input->data.TYPE[floorY+1][floorX]; \785 valid01 = (mask == NULL) || \786 ((mask->data.PS_TYPE_MASK_DATA[floorY+1][floorX] & maskVal) == 0); \787 } else { \788 valid01 = false; \789 } \790 if (floorX >= -1 && floorX < lastX) { \791 V11 = input->data.TYPE[floorY+1][floorX+1]; \792 valid11 = (mask == NULL) || \793 ((mask->data.PS_TYPE_MASK_DATA[floorY+1][floorX+1] & maskVal) == 0); \794 } else { \795 valid11 = false; \796 } \797 } else { \798 valid01 = false; \799 valid11 = false; \800 } \801 \802 /* cover likely case of all pixels being valid more efficiently */ \803 if (valid00 && valid10 && valid01 && valid11) { \804 /* formula from the ADD */ \805 return V00*FRACFUNC((1.0-fracX)*(1.0-fracY)) + V10*FRACFUNC(fracX*(1.0-fracY)) + \806 V01*FRACFUNC(fracY*(1.0-fracX)) + V11*FRACFUNC(fracX*fracY); \807 } \808 \809 /* OK, at least one pixel is not valid - need to do it piecemeal */ \810 \811 RETURNTYPE V0 = 0.0; \812 bool valid0 = true; \813 if (valid00 && valid10) { \814 V0 = V00*FRACFUNC(1-fracX)+V10*FRACFUNC(fracX); \815 } else if (valid00) { \816 V0 = V00; \817 } else if (valid10) { \818 V0 = V10; \819 } else { \820 valid0 = false; \821 } \822 \823 RETURNTYPE V1 = 0.0; \824 bool valid1 = true; \825 if (valid01 && valid11) { \826 V1 = V01*FRACFUNC(1-fracX)+V11*FRACFUNC(fracX); \827 } else if (valid01) { \828 V1 = V01; \829 } else if (valid11) { \830 V1 = V11; \831 } else { \832 valid1 = false; \833 } \834 \835 if (valid0 && valid1) { \836 return V0*FRACFUNC(1-fracY) + V1*FRACFUNC(fracY); \837 } else if (valid0) { \838 return V0; \839 } else if (valid1) { \840 return V1; \841 } \842 \843 return unexposedValue; \844 }845 846 // XXX this would be much faster to use a 3x3 kernel to determine the shift847 // the same function can be used for all equivalent (kernel-based) shifts...848 #define PSIMAGE_PIXEL_INTERPOLATE_BICUBE(TYPE, RETURNTYPE, SUFFIX, FRACFUNC) \849 inline RETURNTYPE p_psImagePixelInterpolateBICUBE_##SUFFIX( \850 const psImage* input, \851 float x, \852 float y, \853 const psImage* mask, \854 psMaskType maskVal, \855 RETURNTYPE unexposedValue) \856 { \857 int floorX = floor(x); \858 int floorY = floor(y); \859 psF64 fracX = x - floorX - 0.5; \860 psF64 fracY = y - floorY - 0.5; \861 psS32 lastX = input->numCols - 1; \862 psS32 lastY = input->numRows - 1; \863 if (floorX < 1) return unexposedValue; \864 if (floorY < 1) return unexposedValue; \865 if (floorX >= lastX) return unexposedValue; \866 if (floorY >= lastY) return unexposedValue; \867 \868 /* XXX use care for masked and boundary pixels */ \869 psF64 Vmm = input->data.TYPE[floorY-1][floorX-1]; \870 psF64 Vom = input->data.TYPE[floorY-1][floorX+0]; \871 psF64 Vpm = input->data.TYPE[floorY-1][floorX+1]; \872 psF64 Vmo = input->data.TYPE[floorY+0][floorX-1]; \873 psF64 Voo = input->data.TYPE[floorY+0][floorX+0]; \874 psF64 Vpo = input->data.TYPE[floorY+0][floorX+1]; \875 psF64 Vmp = input->data.TYPE[floorY+1][floorX-1]; \876 psF64 Vop = input->data.TYPE[floorY+1][floorX+0]; \877 psF64 Vpp = input->data.TYPE[floorY+1][floorX+1]; \878 \879 psF64 Vxm = Vmm + Vmo + Vmp; \880 psF64 Vxp = Vpm + Vpo + Vpp; \881 psF64 Vym = Vmm + Vom + Vpm; \882 psF64 Vyp = Vmp + Vop + Vpp; \883 psF64 Vo = Vym + Vyp + Vmo + Voo + Vpo; \884 \885 psF64 Z_00 = Vo*(5.0/9.0) - (Vxp + Vxm)/3.0 - (Vyp + Vym)/3.0; \886 \887 psF64 Z_10 = (Vxp - Vxm)/6.0; \888 psF64 Z_01 = (Vyp - Vym)/6.0; \889 psF64 Z_20 = (Vxp + Vxm)/2.0 - Vo/3.0; \890 psF64 Z_02 = (Vyp + Vym)/2.0 - Vo/3.0; \891 psF64 Z_11 = (Vpp + Vmm - Vpm - Vmp)/4.0; \892 \893 psF64 value = Z_00 + Z_10*fracX + Z_01*fracY + Z_20*fracX*fracX + Z_11*fracX*fracY + Z_02*fracY*fracY; \894 return value; \895 }896 897 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,U8,)898 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,U16,)899 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,U32,)900 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,U64,)901 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,S8,)902 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,S16,)903 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,S32,)904 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,S64,)905 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,F32,)906 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,F64,)907 908 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U8,psF64,U8,)909 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U16,psF64,U16,)910 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U32,psF64,U32,)911 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(U64,psF64,U64,)912 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S8,psF64,S8,)913 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S16,psF64,S16,)914 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S32,psF64,S32,)915 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(S64,psF64,S64,)916 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(F32,psF64,F32,)917 PSIMAGE_PIXEL_INTERPOLATE_BICUBE(F64,psF64,F64,)918 919 // Variance Version920 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,VARIANCE_U8,PS_SQR)921 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,VARIANCE_U16,PS_SQR)922 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,VARIANCE_U32,PS_SQR)923 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,VARIANCE_U64,PS_SQR)924 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,VARIANCE_S8,PS_SQR)925 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,VARIANCE_S16,PS_SQR)926 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,VARIANCE_S32,PS_SQR)927 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,VARIANCE_S64,PS_SQR)928 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,VARIANCE_F32,PS_SQR)929 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,VARIANCE_F64,PS_SQR)930 931 psImageInterpolateMode psImageInterpolateModeFromString (char *name) {932 933 if (!strcasecmp(name, "FLAT")) return PS_INTERPOLATE_FLAT;934 if (!strcasecmp(name, "BILINEAR")) return PS_INTERPOLATE_BILINEAR;935 if (!strcasecmp(name, "BICUBE")) return PS_INTERPOLATE_BICUBE;936 if (!strcasecmp(name, "GAUSS")) return PS_INTERPOLATE_GAUSS;937 if (!strcasecmp(name, "LANCZOS2")) return PS_INTERPOLATE_LANCZOS2;938 if (!strcasecmp(name, "LANCZOS3")) return PS_INTERPOLATE_LANCZOS3;939 if (!strcasecmp(name, "LANCZOS4")) return PS_INTERPOLATE_LANCZOS4;940 if (!strcasecmp(name, "BILINEAR_VARIANCE")) return PS_INTERPOLATE_BILINEAR_VARIANCE;941 if (!strcasecmp(name, "LANCZOS2_VARIANCE")) return PS_INTERPOLATE_LANCZOS2_VARIANCE;942 if (!strcasecmp(name, "LANCZOS3_VARIANCE")) return PS_INTERPOLATE_LANCZOS3_VARIANCE;943 if (!strcasecmp(name, "LANCZOS4_VARIANCE")) return PS_INTERPOLATE_LANCZOS4_VARIANCE;944 945 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Unknown interpolate type %s"), name);946 return PS_INTERPOLATE_NONE;947 } -
trunk/psLib/src/mathtypes/psImage.h
r12527 r12741 9 9 * @author Joshua Hoblitt, University of Hawaii 10 10 * 11 * @version $Revision: 1.9 1$ $Name: not supported by cvs2svn $12 * @date $Date: 2007-0 3-22 00:11:08$11 * @version $Revision: 1.92 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2007-04-04 22:42:02 $ 13 13 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 14 14 */ … … 24 24 #include "psArray.h" 25 25 #include "psConstants.h" 26 27 /** enumeration of options in interpolation28 *29 */30 typedef enum {31 PS_INTERPOLATE_NONE, ///< no interpolate defined (error state)32 PS_INTERPOLATE_FLAT, ///< 'flat' interpolation (nearest pixel)33 PS_INTERPOLATE_BILINEAR, ///< bi-linear interpolation34 PS_INTERPOLATE_BICUBE, ///< bi-cubic interpolation with 3x3 region (EAM)35 PS_INTERPOLATE_GAUSS, ///< bi-cubic interpolation with 3x3 region (EAM)36 PS_INTERPOLATE_LANCZOS2, ///< Sinc interpolation with 4x4 pixel kernel37 PS_INTERPOLATE_LANCZOS3, ///< Sinc interpolation with 6x6 pixel kernel38 PS_INTERPOLATE_LANCZOS4, ///< Sinc interpolation with 8x8 pixel kernel39 PS_INTERPOLATE_BILINEAR_VARIANCE, ///< Variance version of PS_INTERPOLATE_BILINEAR40 PS_INTERPOLATE_LANCZOS2_VARIANCE, ///< Variance version of PS_INTERPOLATE_LANCZOS241 PS_INTERPOLATE_LANCZOS3_VARIANCE, ///< Variance version of PS_INTERPOLATE_LANCZOS342 PS_INTERPOLATE_LANCZOS4_VARIANCE ///< Variance version of PS_INTERPOLATE_LANCZOS443 // PS_INTERPOLATE_NUM_MODES ///< enum end-marker; does not coorespond to a interpolation mode44 } psImageInterpolateMode;45 26 46 27 … … 226 207 227 208 228 /** Interpolate image pixel value given floating point coordinates. 229 * 230 * @return double Pixel value interpolated from image or unexposedValue if 231 * given x,y doesn't coorespond to a valid image location 232 */ 233 double psImagePixelInterpolate( 234 const psImage* input, ///< input image for interpolation 235 float x, ///< column location to derive value of 236 float y, ///< row location ot derive value of 237 const psImage* mask, ///< if not NULL, the mask of the input image 238 psMaskType maskVal, ///< the mask value 239 double unexposedValue, ///< return value if x,y location is not in image. 240 psImageInterpolateMode mode ///< interpolation mode 241 ); 242 243 // return the mode equivalent to a char string name 244 psImageInterpolateMode psImageInterpolateModeFromString (char *name); 245 246 247 #define PIXEL_INTERPOLATE_FCN_PROTOTYPE(SUFFIX, RETURNTYPE) \ 248 inline RETURNTYPE p_psImagePixelInterpolate##SUFFIX( \ 249 const psImage* input, /**< input image for interpolation */ \ 250 float x, /**< column location to derive value of */ \ 251 float y, /**< row location ot derive value of */ \ 252 const psImage* mask, /**< if not NULL, the mask of the input image */ \ 253 psMaskType maskVal, /**< the mask value */ \ 254 RETURNTYPE unexposedValue /**< return value if x,y location is not in image. */ \ 255 ); 256 257 #define PIXEL_INTERPOLATE_FCNS(MODE) \ 258 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U8,psF64) \ 259 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U16,psF64) \ 260 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U32,psF64) \ 261 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_U64,psF64) \ 262 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S8,psF64) \ 263 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S16,psF64) \ 264 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S32,psF64) \ 265 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_S64,psF64) \ 266 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_F32,psF64) \ 267 PIXEL_INTERPOLATE_FCN_PROTOTYPE(MODE##_F64,psF64) 268 269 #ifndef SWIG 270 PIXEL_INTERPOLATE_FCNS(FLAT) 271 PIXEL_INTERPOLATE_FCNS(BILINEAR) 272 PIXEL_INTERPOLATE_FCNS(BILINEAR_VARIANCE) 273 PIXEL_INTERPOLATE_FCNS(BICUBE) 274 #endif // ! SWIG 275 276 #undef PIXEL_INTERPOLATE_FCN_PROTOTYPE 277 #undef PIXEL_INTERPOLATE_FCNS 209 278 210 279 211 /*****************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.
