| 344 | /// Checks if a bilinear interpolation artifact will occur inbetween two diagonally adjacent texels a, d (with b, c forming the other diagonal). |
| 345 | template <class ArtifactClassifier> |
| 346 | static bool hasDiagonalArtifact(const ArtifactClassifier &artifactClassifier, float am, const float *a, const float *b, const float *c, const float *d) { |
| 347 | float dm = median(d[0], d[1], d[2]); |
| 348 | // Out of the pair, only report artifacts for the texel further from the edge to minimize side effects. |
| 349 | if (fabsf(am-.5f) >= fabsf(dm-.5f)) { |
| 350 | float abc[3] = { |
| 351 | a[0]-b[0]-c[0], |
| 352 | a[1]-b[1]-c[1], |
| 353 | a[2]-b[2]-c[2] |
| 354 | }; |
| 355 | // Compute the linear terms for bilinear interpolation. |
| 356 | float l[3] = { |
| 357 | -a[0]-abc[0], |
| 358 | -a[1]-abc[1], |
| 359 | -a[2]-abc[2] |
| 360 | }; |
| 361 | // Compute the quadratic terms for bilinear interpolation. |
| 362 | float q[3] = { |
| 363 | d[0]+abc[0], |
| 364 | d[1]+abc[1], |
| 365 | d[2]+abc[2] |
| 366 | }; |
| 367 | // Compute interpolation ratios tEx (0 < tEx[i] < 1) for the local extremes of each color channel (the derivative 2*q[i]*tEx[i]+l[i] == 0). |
| 368 | double tEx[3] = { |
| 369 | -.5*l[0]/q[0], |
| 370 | -.5*l[1]/q[1], |
| 371 | -.5*l[2]/q[2] |
| 372 | }; |
| 373 | // Check points where each pair of color channels meets. |
| 374 | return ( |
| 375 | hasDiagonalArtifactInner(artifactClassifier, am, dm, a, l, q, a[1]-a[0], b[1]-b[0]+c[1]-c[0], d[1]-d[0], tEx[0], tEx[1]) || |
| 376 | hasDiagonalArtifactInner(artifactClassifier, am, dm, a, l, q, a[2]-a[1], b[2]-b[1]+c[2]-c[1], d[2]-d[1], tEx[1], tEx[2]) || |
| 377 | hasDiagonalArtifactInner(artifactClassifier, am, dm, a, l, q, a[0]-a[2], b[0]-b[2]+c[0]-c[2], d[0]-d[2], tEx[2], tEx[0]) |
| 378 | ); |
| 379 | } |
| 380 | return false; |
| 381 | } |
| 382 | |
| 383 | template <int N> |
| 384 | void MSDFErrorCorrection::findErrors(const BitmapConstSection<float, N> &sdf) { |
no test coverage detected