// framebuffer, ie., the range [0.0,1.0] maps to [0,255] for 8-bit
// and to [0,1023] (or [0_d,255.75_d] in BT.601 parlance) for 10-bit.
//
-// BT.701 (page 5) seems to agree with BT.601; it specifies range 16–235 for
+// BT.709 (page 5) seems to agree with BT.601; it specifies range 16–235 for
// 8-bit luma, and 64–940 for 10-bit luma. This would indicate, for a GPU,
// that that for 8-bit mode, the range would be 16/255 to 235/255
// (0.06275 to 0.92157), while for 10-bit, it should be 64/1023 to 940/1023
// (or destination); the num_levels field is the right place. Most people
// will want to simply set this to 256, as 8-bit Y'CbCr is the most common,
// but the right value will naturally depend on your input.
+//
+// We could use unsigned formats (e.g. GL_R8UI), which in a sense would
+// solve all of this, but then we'd lose filtering.
#include "image_format.h"
+#include <epoxy/gl.h>
#include <Eigen/Core>
namespace movit {
// Given <ycbcr_format>, compute the values needed to turn Y'CbCr into R'G'B';
// first subtract the returned offset, then left-multiply the returned matrix
// (the scaling is already folded into it).
-void compute_ycbcr_matrix(YCbCrFormat ycbcr_format, float *offset, Eigen::Matrix3d *ycbcr_to_rgb);
+//
+// <type> is the data type you're rendering from; normally, it would should match
+// <ycbcr_format.num_levels>, but for the special case of 10- and 12-bit Y'CbCr,
+// we support storing it in 16-bit formats, which incurs extra scaling factors.
+// You can get that scaling factor in <scale> if you want.
+void compute_ycbcr_matrix(YCbCrFormat ycbcr_format, float *offset, Eigen::Matrix3d *ycbcr_to_rgb,
+ GLenum type = GL_UNSIGNED_BYTE, double *scale_factor = nullptr);
} // namespace movit