Originally committed as revision 6638 to svn://svn.mplayerhq.hu/mplayer/trunk/postproc
Michael Niedermayer authored on 2002/07/04 22:08:37... | ... |
@@ -958,6 +958,10 @@ void swsGetFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, Sws |
958 | 958 |
case 4: *flags|= SWS_POINT; break; |
959 | 959 |
case 5: *flags|= SWS_AREA; break; |
960 | 960 |
case 6: *flags|= SWS_BICUBLIN; break; |
961 |
+ case 7: *flags|= SWS_GAUSS; break; |
|
962 |
+ case 8: *flags|= SWS_SINC; break; |
|
963 |
+ case 9: *flags|= SWS_LANCZOS; break; |
|
964 |
+ case 10:*flags|= SWS_SPLINE; break; |
|
961 | 965 |
default:*flags|= SWS_BILINEAR; break; |
962 | 966 |
} |
963 | 967 |
|
... | ... |
@@ -975,6 +979,16 @@ SwsContext *getSwsContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW |
975 | 975 |
return getSwsContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, srcFilterParam, dstFilterParam); |
976 | 976 |
} |
977 | 977 |
|
978 |
+static double getSplineCoeff(double a, double b, double c, double d, double dist) |
|
979 |
+{ |
|
980 |
+// printf("%f %f %f %f %f\n", a,b,c,d,dist); |
|
981 |
+ if(dist<=1.0) return ((d*dist + c)*dist + b)*dist +a; |
|
982 |
+ else return getSplineCoeff( 0.0, |
|
983 |
+ b+ 2.0*c + 3.0*d, |
|
984 |
+ c + 3.0*d, |
|
985 |
+ -b- 3.0*c - 6.0*d, |
|
986 |
+ dist-1.0); |
|
987 |
+} |
|
978 | 988 |
|
979 | 989 |
static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, |
980 | 990 |
int srcW, int dstW, int filterAlign, int one, int flags, |
... | ... |
@@ -1025,7 +1039,7 @@ static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *out |
1025 | 1025 |
xDstInSrc+= xInc; |
1026 | 1026 |
} |
1027 | 1027 |
} |
1028 |
- else if(xInc <= (1<<16) || (flags&SWS_FAST_BILINEAR)) // upscale |
|
1028 |
+ else if((xInc <= (1<<16) && (flags&SWS_AREA)) || (flags&SWS_FAST_BILINEAR)) // bilinear upscale |
|
1029 | 1029 |
{ |
1030 | 1030 |
int i; |
1031 | 1031 |
int xDstInSrc; |
... | ... |
@@ -1041,32 +1055,6 @@ static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *out |
1041 | 1041 |
int j; |
1042 | 1042 |
|
1043 | 1043 |
(*filterPos)[i]= xx; |
1044 |
- if((flags & SWS_BICUBIC) || (flags & SWS_X)) |
|
1045 |
- { |
|
1046 |
- double d= ABS(((xx+1)<<16) - xDstInSrc)/(double)(1<<16); |
|
1047 |
- double y1,y2,y3,y4; |
|
1048 |
- double A= -0.6; |
|
1049 |
- if(flags & SWS_BICUBIC){ |
|
1050 |
- // Equation is from VirtualDub |
|
1051 |
- y1 = ( + A*d - 2.0*A*d*d + A*d*d*d); |
|
1052 |
- y2 = (+ 1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d); |
|
1053 |
- y3 = ( - A*d + (2.0*A+3.0)*d*d - (A+2.0)*d*d*d); |
|
1054 |
- y4 = ( + A*d*d - A*d*d*d); |
|
1055 |
- }else{ |
|
1056 |
- // cubic interpolation (derived it myself) |
|
1057 |
- y1 = ( -2.0*d + 3.0*d*d - 1.0*d*d*d)/6.0; |
|
1058 |
- y2 = (6.0 -3.0*d - 6.0*d*d + 3.0*d*d*d)/6.0; |
|
1059 |
- y3 = ( +6.0*d + 3.0*d*d - 3.0*d*d*d)/6.0; |
|
1060 |
- y4 = ( -1.0*d + 1.0*d*d*d)/6.0; |
|
1061 |
- } |
|
1062 |
- |
|
1063 |
- filter[i*filterSize + 0]= y1; |
|
1064 |
- filter[i*filterSize + 1]= y2; |
|
1065 |
- filter[i*filterSize + 2]= y3; |
|
1066 |
- filter[i*filterSize + 3]= y4; |
|
1067 |
- } |
|
1068 |
- else |
|
1069 |
- { |
|
1070 | 1044 |
//Bilinear upscale / linear interpolate / Area averaging |
1071 | 1045 |
for(j=0; j<filterSize; j++) |
1072 | 1046 |
{ |
... | ... |
@@ -1076,35 +1064,48 @@ static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *out |
1076 | 1076 |
filter[i*filterSize + j]= coeff; |
1077 | 1077 |
xx++; |
1078 | 1078 |
} |
1079 |
- } |
|
1080 | 1079 |
xDstInSrc+= xInc; |
1081 | 1080 |
} |
1082 | 1081 |
} |
1083 |
- else // downscale |
|
1082 |
+ else |
|
1084 | 1083 |
{ |
1085 |
- int xDstInSrc; |
|
1086 |
- ASSERT(dstW <= srcW) |
|
1084 |
+ double xDstInSrc; |
|
1085 |
+ double sizeFactor, filterSizeInSrc; |
|
1086 |
+ const double xInc1= (double)xInc / (double)(1<<16); |
|
1087 |
+ int param= (flags&SWS_PARAM_MASK)>>SWS_PARAM_SHIFT; |
|
1088 |
+ |
|
1089 |
+ if (flags&SWS_BICUBIC) sizeFactor= 4.0; |
|
1090 |
+ else if(flags&SWS_X) sizeFactor= 8.0; |
|
1091 |
+ else if(flags&SWS_AREA) sizeFactor= 1.0; //downscale only, for upscale it is bilinear |
|
1092 |
+ else if(flags&SWS_GAUSS) sizeFactor= 8.0; // infinite ;) |
|
1093 |
+ else if(flags&SWS_LANCZOS) sizeFactor= param ? 2.0*param : 6.0; |
|
1094 |
+ else if(flags&SWS_SINC) sizeFactor= 100.0; // infinite ;) |
|
1095 |
+ else if(flags&SWS_SPLINE) sizeFactor= 20.0; // infinite ;) |
|
1096 |
+ else if(flags&SWS_BILINEAR) sizeFactor= 2.0; |
|
1097 |
+ else ASSERT(0) |
|
1098 |
+ |
|
1099 |
+ if(xInc1 <= 1.0) filterSizeInSrc= sizeFactor; // upscale |
|
1100 |
+ else filterSizeInSrc= sizeFactor*srcW / (double)dstW; |
|
1087 | 1101 |
|
1088 |
- if(flags&SWS_BICUBIC) filterSize= (int)ceil(1 + 4.0*srcW / (double)dstW); |
|
1089 |
- else if(flags&SWS_X) filterSize= (int)ceil(1 + 4.0*srcW / (double)dstW); |
|
1090 |
- else if(flags&SWS_AREA) filterSize= (int)ceil(1 + 1.0*srcW / (double)dstW); |
|
1091 |
- else /* BILINEAR */ filterSize= (int)ceil(1 + 2.0*srcW / (double)dstW); |
|
1092 |
- filter= (double*)memalign(8, dstW*sizeof(double)*filterSize); |
|
1102 |
+ filterSize= (int)ceil(1 + filterSizeInSrc); // will be reduced later if possible |
|
1103 |
+ if(filterSize > srcW-2) filterSize=srcW-2; |
|
1093 | 1104 |
|
1094 |
- xDstInSrc= xInc/2 - 0x8000; |
|
1105 |
+ filter= (double*)memalign(16, dstW*sizeof(double)*filterSize); |
|
1106 |
+ |
|
1107 |
+ xDstInSrc= xInc1 / 2.0 - 0.5; |
|
1095 | 1108 |
for(i=0; i<dstW; i++) |
1096 | 1109 |
{ |
1097 |
- int xx= (int)((double)xDstInSrc/(double)(1<<16) - (filterSize-1)*0.5 + 0.5); |
|
1110 |
+ int xx= (int)(xDstInSrc - (filterSize-1)*0.5 + 0.5); |
|
1098 | 1111 |
int j; |
1099 | 1112 |
(*filterPos)[i]= xx; |
1100 | 1113 |
for(j=0; j<filterSize; j++) |
1101 | 1114 |
{ |
1102 |
- double d= ABS((xx<<16) - xDstInSrc)/(double)xInc; |
|
1115 |
+ double d= ABS(xx - xDstInSrc)/filterSizeInSrc*sizeFactor; |
|
1103 | 1116 |
double coeff; |
1104 |
- if((flags & SWS_BICUBIC) || (flags & SWS_X)) |
|
1117 |
+ if(flags & SWS_BICUBIC) |
|
1105 | 1118 |
{ |
1106 |
- double A= -0.75; |
|
1107 |
-// d*=2; |
|
1119 |
+ double A= param ? -param*0.01 : -0.60; |
|
1120 |
+ |
|
1108 | 1121 |
// Equation is from VirtualDub |
1109 | 1122 |
if(d<1.0) |
1110 | 1123 |
coeff = (1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d); |
... | ... |
@@ -1113,22 +1114,62 @@ static inline void initFilter(int16_t **outFilter, int16_t **filterPos, int *out |
1113 | 1113 |
else |
1114 | 1114 |
coeff=0.0; |
1115 | 1115 |
} |
1116 |
+/* else if(flags & SWS_X) |
|
1117 |
+ { |
|
1118 |
+ double p= param ? param*0.01 : 0.3; |
|
1119 |
+ coeff = d ? sin(d*PI)/(d*PI) : 1.0; |
|
1120 |
+ coeff*= pow(2.0, - p*d*d); |
|
1121 |
+ }*/ |
|
1122 |
+ else if(flags & SWS_X) |
|
1123 |
+ { |
|
1124 |
+ double A= param ? param*0.1 : 1.0; |
|
1125 |
+ |
|
1126 |
+ if(d<1.0) |
|
1127 |
+ coeff = cos(d*PI); |
|
1128 |
+ else |
|
1129 |
+ coeff=-1.0; |
|
1130 |
+ if(coeff<0.0) coeff= -pow(-coeff, A); |
|
1131 |
+ else coeff= pow( coeff, A); |
|
1132 |
+ coeff= coeff*0.5 + 0.5; |
|
1133 |
+ } |
|
1116 | 1134 |
else if(flags & SWS_AREA) |
1117 | 1135 |
{ |
1118 |
- double srcPixelSize= (1<<16)/(double)xInc; |
|
1136 |
+ double srcPixelSize= 1.0/xInc1; |
|
1119 | 1137 |
if(d + srcPixelSize/2 < 0.5) coeff= 1.0; |
1120 | 1138 |
else if(d - srcPixelSize/2 < 0.5) coeff= (0.5-d)/srcPixelSize + 0.5; |
1121 | 1139 |
else coeff=0.0; |
1122 | 1140 |
} |
1123 |
- else |
|
1141 |
+ else if(flags & SWS_GAUSS) |
|
1142 |
+ { |
|
1143 |
+ double p= param ? param*0.1 : 3.0; |
|
1144 |
+ coeff = pow(2.0, - p*d*d); |
|
1145 |
+ } |
|
1146 |
+ else if(flags & SWS_SINC) |
|
1147 |
+ { |
|
1148 |
+ coeff = d ? sin(d*PI)/(d*PI) : 1.0; |
|
1149 |
+ } |
|
1150 |
+ else if(flags & SWS_LANCZOS) |
|
1151 |
+ { |
|
1152 |
+ double p= param ? param : 3.0; |
|
1153 |
+ coeff = d ? sin(d*PI)*sin(d*PI/p)/(d*d*PI*PI/p) : 1.0; |
|
1154 |
+ if(d>p) coeff=0; |
|
1155 |
+ } |
|
1156 |
+ else if(flags & SWS_BILINEAR) |
|
1124 | 1157 |
{ |
1125 | 1158 |
coeff= 1.0 - d; |
1126 | 1159 |
if(coeff<0) coeff=0; |
1127 | 1160 |
} |
1161 |
+ else if(flags & SWS_SPLINE) |
|
1162 |
+ { |
|
1163 |
+ double p=-2.196152422706632; |
|
1164 |
+ coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, d); |
|
1165 |
+ } |
|
1166 |
+ else ASSERT(0) |
|
1167 |
+ |
|
1128 | 1168 |
filter[i*filterSize + j]= coeff; |
1129 | 1169 |
xx++; |
1130 | 1170 |
} |
1131 |
- xDstInSrc+= xInc; |
|
1171 |
+ xDstInSrc+= xInc1; |
|
1132 | 1172 |
} |
1133 | 1173 |
} |
1134 | 1174 |
|
... | ... |
@@ -2178,7 +2219,15 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, |
2178 | 2178 |
else if(flags&SWS_AREA) |
2179 | 2179 |
MSG_INFO("\nSwScaler: Area Averageing scaler, "); |
2180 | 2180 |
else if(flags&SWS_BICUBLIN) |
2181 |
- MSG_INFO("\nSwScaler: luma BICUBIC / chroma BILINEAR, "); |
|
2181 |
+ MSG_INFO("\nSwScaler: luma BICUBIC / chroma BILINEAR scaler, "); |
|
2182 |
+ else if(flags&SWS_GAUSS) |
|
2183 |
+ MSG_INFO("\nSwScaler: Gaussian scaler, "); |
|
2184 |
+ else if(flags&SWS_SINC) |
|
2185 |
+ MSG_INFO("\nSwScaler: Sinc scaler, "); |
|
2186 |
+ else if(flags&SWS_LANCZOS) |
|
2187 |
+ MSG_INFO("\nSwScaler: Lanczos scaler, "); |
|
2188 |
+ else if(flags&SWS_SPLINE) |
|
2189 |
+ MSG_INFO("\nSwScaler: Bicubic spline scaler, "); |
|
2182 | 2190 |
else |
2183 | 2191 |
MSG_INFO("\nSwScaler: ehh flags invalid?! "); |
2184 | 2192 |
|
... | ... |
@@ -24,18 +24,26 @@ |
24 | 24 |
#define SWS_POINT 0x10 |
25 | 25 |
#define SWS_AREA 0x20 |
26 | 26 |
#define SWS_BICUBLIN 0x40 |
27 |
+#define SWS_GAUSS 0x80 |
|
28 |
+#define SWS_SINC 0x100 |
|
29 |
+#define SWS_LANCZOS 0x200 |
|
30 |
+#define SWS_SPLINE 0x400 |
|
27 | 31 |
|
28 |
-#define SWS_SRC_V_CHR_DROP_MASK 0x300 |
|
29 |
-#define SWS_SRC_V_CHR_DROP_SHIFT 8 |
|
32 |
+#define SWS_SRC_V_CHR_DROP_MASK 0x30000 |
|
33 |
+#define SWS_SRC_V_CHR_DROP_SHIFT 16 |
|
30 | 34 |
|
31 |
-//the following 4 flags are not completly implemented |
|
35 |
+#define SWS_PARAM_MASK 0x3FC0000 |
|
36 |
+#define SWS_PARAM_SHIFT 18 |
|
37 |
+ |
|
38 |
+#define SWS_PRINT_INFO 0x1000 |
|
39 |
+ |
|
40 |
+//the following 3 flags are not completly implemented |
|
32 | 41 |
//internal chrominace subsamling info |
33 | 42 |
#define SWS_FULL_CHR_H_INT 0x2000 |
34 | 43 |
//input subsampling info |
35 | 44 |
#define SWS_FULL_CHR_H_INP 0x4000 |
36 | 45 |
#define SWS_DIRECT_BGR 0x8000 |
37 | 46 |
|
38 |
-#define SWS_PRINT_INFO 0x1000 |
|
39 | 47 |
|
40 | 48 |
#define SWS_MAX_REDUCE_CUTOFF 0.002 |
41 | 49 |
|