]> git.sesse.net Git - movit/blobdiff - ycbcr.cpp
Release Movit 1.3.2. (From a branch, since I do not want to break ABI compatibility...
[movit] / ycbcr.cpp
index f0124eaab178048a2ae3a00c758355fa275668a2..50059125dc4a3c866dff4ef08e82916d94ff7a43 100644 (file)
--- a/ycbcr.cpp
+++ b/ycbcr.cpp
@@ -1,3 +1,6 @@
+// Note: These functions are tested in ycbcr_input_test.cpp; both through some
+// direct matrix tests, but most of all through YCbCrInput's unit tests.
+
 #include <Eigen/Core>
 #include <Eigen/LU>
 
 #include <Eigen/Core>
 #include <Eigen/LU>
 
@@ -45,7 +48,12 @@ namespace movit {
 float compute_chroma_offset(float pos, unsigned subsampling_factor, unsigned resolution)
 {
        float local_chroma_pos = (0.5 + pos * (subsampling_factor - 1)) / subsampling_factor;
 float compute_chroma_offset(float pos, unsigned subsampling_factor, unsigned resolution)
 {
        float local_chroma_pos = (0.5 + pos * (subsampling_factor - 1)) / subsampling_factor;
-       return (0.5 - local_chroma_pos) / resolution;
+       if (fabs(local_chroma_pos - 0.5) < 1e-10) {
+               // x + (-0) can be optimized away freely, as opposed to x + 0.
+               return -0.0;
+       } else {
+               return (0.5 - local_chroma_pos) / resolution;
+       }
 }
 
 // Given <ycbcr_format>, compute the values needed to turn Y'CbCr into R'G'B';
 }
 
 // Given <ycbcr_format>, compute the values needed to turn Y'CbCr into R'G'B';
@@ -82,6 +90,7 @@ void compute_ycbcr_matrix(YCbCrFormat ycbcr_format, float* offset, Matrix3d* ycb
        }
 
        if (ycbcr_format.full_range) {
        }
 
        if (ycbcr_format.full_range) {
+               // TODO: Use num_levels.
                offset[0] = 0.0 / 255.0;
                offset[1] = 128.0 / 255.0;
                offset[2] = 128.0 / 255.0;
                offset[0] = 0.0 / 255.0;
                offset[1] = 128.0 / 255.0;
                offset[2] = 128.0 / 255.0;
@@ -91,6 +100,7 @@ void compute_ycbcr_matrix(YCbCrFormat ycbcr_format, float* offset, Matrix3d* ycb
                scale[2] = 1.0;
        } else {
                // Rec. 601, page 4; Rec. 709, page 19; Rec. 2020, page 4.
                scale[2] = 1.0;
        } else {
                // Rec. 601, page 4; Rec. 709, page 19; Rec. 2020, page 4.
+               // TODO: Use num_levels.
                offset[0] = 16.0 / 255.0;
                offset[1] = 128.0 / 255.0;
                offset[2] = 128.0 / 255.0;
                offset[0] = 16.0 / 255.0;
                offset[1] = 128.0 / 255.0;
                offset[2] = 128.0 / 255.0;
@@ -106,12 +116,12 @@ void compute_ycbcr_matrix(YCbCrFormat ycbcr_format, float* offset, Matrix3d* ycb
        rgb_to_ycbcr(0,1) = coeff[1];
        rgb_to_ycbcr(0,2) = coeff[2];
 
        rgb_to_ycbcr(0,1) = coeff[1];
        rgb_to_ycbcr(0,2) = coeff[2];
 
-       float cb_fac = (224.0 / 219.0) / (coeff[0] + coeff[1] + 1.0f - coeff[2]);
+       float cb_fac = 1.0 / (coeff[0] + coeff[1] + 1.0f - coeff[2]);
        rgb_to_ycbcr(1,0) = -coeff[0] * cb_fac;
        rgb_to_ycbcr(1,1) = -coeff[1] * cb_fac;
        rgb_to_ycbcr(1,2) = (1.0f - coeff[2]) * cb_fac;
 
        rgb_to_ycbcr(1,0) = -coeff[0] * cb_fac;
        rgb_to_ycbcr(1,1) = -coeff[1] * cb_fac;
        rgb_to_ycbcr(1,2) = (1.0f - coeff[2]) * cb_fac;
 
-       float cr_fac = (224.0 / 219.0) / (1.0f - coeff[0] + coeff[1] + coeff[2]);
+       float cr_fac = 1.0 / (1.0f - coeff[0] + coeff[1] + coeff[2]);
        rgb_to_ycbcr(2,0) = (1.0f - coeff[0]) * cr_fac;
        rgb_to_ycbcr(2,1) = -coeff[1] * cr_fac;
        rgb_to_ycbcr(2,2) = -coeff[2] * cr_fac;
        rgb_to_ycbcr(2,0) = (1.0f - coeff[0]) * cr_fac;
        rgb_to_ycbcr(2,1) = -coeff[1] * cr_fac;
        rgb_to_ycbcr(2,2) = -coeff[2] * cr_fac;