Vector FXAA::filterPixel(int row, int col, const ScalarImagePtr &img) const { const Vector rgbNW = pixel(row-1, col-1, img); const Vector rgbNE = pixel(row-1, col+1, img); const Vector rgbSW = pixel(row+1, col-1, img); const Vector rgbSE = pixel(row+1, col+1, img); const Vector rgbM = pixel(row, col, img); const Vector luma = Vector(Scalar(0.299), Scalar(0.587), Scalar(0.114)); Scalar lumaNW = rgbNW.dot(luma); Scalar lumaNE = rgbNE.dot(luma); Scalar lumaSW = rgbSW.dot(luma); Scalar lumaSE = rgbSE.dot(luma); Scalar lumaM = rgbM.dot(luma); Scalar lumaMin = SMIN(lumaNW, SMIN(lumaNE, SMIN(lumaSW, SMIN(lumaSE, lumaM)))); Scalar lumaMax = SMAX(lumaNW, SMAX(lumaNE, SMAX(lumaSW, SMAX(lumaSE, lumaM)))); // FXAA params - fixed here for now. const Scalar fxaa_reduce_mul = Scalar(1) / Scalar(32); const Scalar fxaa_reduce_min = Scalar(1) / Scalar(128); const Scalar fxaa_span_max = Scalar(8); // Find direction and blur orthogonal to edge. Vector2 dir; dir.x() = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); dir.y() = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); Scalar dirRed = SMAX((lumaNW + lumaNE + lumaSW + lumaSE) * (Scalar(0.25) * fxaa_reduce_mul), fxaa_reduce_min); Scalar invDirMin = Scalar(1) / (SMIN(abs(dir.x()), abs(dir.y())) + dirRed); dir *= invDirMin; dir.x() = clamp(dir.x(), -fxaa_span_max, fxaa_span_max); dir.y() = clamp(dir.y(), -fxaa_span_max, fxaa_span_max); const Scalar c = Scalar(1)/Scalar(3) - Scalar(0.5); const Scalar d = Scalar(2)/Scalar(3) - Scalar(0.5); const Scalar e = Scalar(0)/Scalar(3) - Scalar(0.5); const Scalar f = Scalar(3)/Scalar(3) - Scalar(0.5); Vector rgbA = Scalar(0.5) * (bilinearSample(row + c, col + c, img) + bilinearSample(row + d, col + d, img)); Vector rgbB = rgbA * Scalar(0.5) + Scalar(0.25) * (bilinearSample(row + e, col + e, img) + bilinearSample(row + f, col + f, img)); Scalar lumaB = rgbB.dot(luma); if ((lumaB < lumaMin) || (lumaB > lumaMax)) { return rgbA; } else { return rgbB; } }
void fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays) { double dec, prevdec, L; int h, d, prevangle, angle; int found = 0; double decleft, decright, decmiddle; int dial, s; int *cumdays; cumdays = cumdaytab[isleap(year)]; /* * Find the first equinox, somewhere in March: * It happens when the returned value "dec" goes from * [350 ... 360> -> [0 ... 10] */ for (d = 18; d < 31; d++) { /* printf("Comparing day %d to %d.\n", d, d+1); */ sunpos(year, 3, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft); sunpos(year, 3, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decright); /* printf("Found %g and %g.\n", decleft, decright); */ if (SIGN(decleft) == SIGN(decright)) continue; dial = SECSPERDAY; s = SECSPERDAY / 2; while (s > 0) { /* printf("Obtaining %d (%02d:%02d)\n", dial, SHOUR(dial), SMIN(dial)); */ sunpos(year, 3, d, UTCoffset, SHOUR(dial), SMIN(dial), SSEC(dial), 0.0, 0.0, &L, &decmiddle); /* printf("Found %g\n", decmiddle); */ if (SIGN(decleft) == SIGN(decmiddle)) { decleft = decmiddle; dial += s; } else { decright = decmiddle; dial -= s; } /* printf("New boundaries: %g - %g\n", decleft, decright); */ s /= 2; } equinoxdays[0] = 1 + cumdays[3] + d + (dial / FSECSPERDAY); break; } /* Find the second equinox, somewhere in September: * It happens when the returned value "dec" goes from * [10 ... 0] -> <360 ... 350] */ for (d = 18; d < 31; d++) { /* printf("Comparing day %d to %d.\n", d, d+1); */ sunpos(year, 9, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft); sunpos(year, 9, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decright); /* printf("Found %g and %g.\n", decleft, decright); */ if (SIGN(decleft) == SIGN(decright)) continue; dial = SECSPERDAY; s = SECSPERDAY / 2; while (s > 0) { /* printf("Obtaining %d (%02d:%02d)\n", dial, SHOUR(dial), SMIN(dial)); */ sunpos(year, 9, d, UTCoffset, SHOUR(dial), SMIN(dial), SSEC(dial), 0.0, 0.0, &L, &decmiddle); /* printf("Found %g\n", decmiddle); */ if (SIGN(decleft) == SIGN(decmiddle)) { decleft = decmiddle; dial += s; } else { decright = decmiddle; dial -= s; } /* printf("New boundaries: %g - %g\n", decleft, decright); */ s /= 2; } equinoxdays[1] = 1 + cumdays[9] + d + (dial / FSECSPERDAY); break; } /* * Find the first solstice, somewhere in June: * It happens when the returned value "dec" peaks * [40 ... 45] -> [45 ... 40] */ found = 0; prevdec = 0; prevangle = 1; for (d = 18; d < 31; d++) { for (h = 0; h < 4 * HOURSPERDAY; h++) { sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &L, &dec); angle = ANGLE(prevdec, dec); if (prevangle != angle) { #ifdef NOTDEF DEBUG2(year, 6, d, HOUR(h), MIN(h), prevdec, dec, prevangle, angle); #endif solsticedays[0] = 1 + cumdays[6] + d + ((h / 4.0) / 24.0); found = 1; break; } prevdec = dec; prevangle = angle; } if (found) break; } /* * Find the second solstice, somewhere in December: * It happens when the returned value "dec" peaks * [315 ... 310] -> [310 ... 315] */ found = 0; prevdec = 360; prevangle = -1; for (d = 18; d < 31; d++) { for (h = 0; h < 4 * HOURSPERDAY; h++) { sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &L, &dec); angle = ANGLE(prevdec, dec); if (prevangle != angle) { #ifdef NOTDEF DEBUG2(year, 12, d, HOUR(h), MIN(h), prevdec, dec, prevangle, angle); #endif solsticedays[1] = 1 + cumdays[12] + d + ((h / 4.0) / 24.0); found = 1; break; } prevdec = dec; prevangle = angle; } if (found) break; } return; }