summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-03 11:35:43 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-03 11:35:43 +0100
commit097bd1acc473501062e488c323478bd9143b5716 (patch)
tree2c40b738b3d192a45b10c44ef1f4a4fd47afd7b6 /src
parent6407924747622d6785ecfed24c35db355ca38032 (diff)
Add Experimental struct.
Diffstat (limited to 'src')
-rw-r--r--src/picture_frame.cc10
-rw-r--r--src/picture_frame.h5
-rw-r--r--src/util.cc99
-rw-r--r--src/util.h17
4 files changed, 95 insertions, 36 deletions
diff --git a/src/picture_frame.cc b/src/picture_frame.cc
index 98802101..702b36c7 100644
--- a/src/picture_frame.cc
+++ b/src/picture_frame.cc
@@ -80,11 +80,13 @@ MonoPictureFrame::j2k_size () const
*
*/
shared_ptr<ARGBFrame>
-MonoPictureFrame::argb_frame (int reduce, float srgb_gamma) const
+MonoPictureFrame::argb_frame (Experimental& exp, int reduce, float srgb_gamma) const
{
opj_image_t* xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->RoData()), _buffer->Size(), reduce);
assert (xyz_frame->numcomps == 3);
- shared_ptr<ARGBFrame> f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma));
+ shared_ptr<ARGBFrame> f = xyz_to_rgb (
+ xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma), exp
+ );
opj_image_destroy (xyz_frame);
return f;
}
@@ -126,7 +128,7 @@ StereoPictureFrame::~StereoPictureFrame ()
*
*/
shared_ptr<ARGBFrame>
-StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
+StereoPictureFrame::argb_frame (Eye eye, Experimental& exp, int reduce, float srgb_gamma) const
{
opj_image_t* xyz_frame = 0;
switch (eye) {
@@ -139,7 +141,7 @@ StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
}
assert (xyz_frame->numcomps == 3);
- shared_ptr<ARGBFrame> f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma));
+ shared_ptr<ARGBFrame> f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma), exp);
opj_image_destroy (xyz_frame);
return f;
}
diff --git a/src/picture_frame.h b/src/picture_frame.h
index 42c5d629..78f7f657 100644
--- a/src/picture_frame.h
+++ b/src/picture_frame.h
@@ -21,6 +21,7 @@
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include "types.h"
+#include "util.h"
namespace ASDCP {
namespace JP2K {
@@ -40,7 +41,7 @@ public:
MonoPictureFrame (std::string mxf_path, int n);
~MonoPictureFrame ();
- boost::shared_ptr<ARGBFrame> argb_frame (int reduce = 0, float srgb_gamma = 2.4) const;
+ boost::shared_ptr<ARGBFrame> argb_frame (Experimental &, int reduce = 0, float srgb_gamma = 2.4) const;
uint8_t const * j2k_data () const;
int j2k_size () const;
@@ -55,7 +56,7 @@ public:
StereoPictureFrame (std::string mxf_path, int n);
~StereoPictureFrame ();
- boost::shared_ptr<ARGBFrame> argb_frame (Eye eye, int reduce = 0, float srgb_gamma = 2.4) const;
+ boost::shared_ptr<ARGBFrame> argb_frame (Eye eye, Experimental &, int reduce = 0, float srgb_gamma = 2.4) const;
uint8_t const * left_j2k_data () const;
int left_j2k_size () const;
uint8_t const * right_j2k_data () const;
diff --git a/src/util.cc b/src/util.cc
index 2fae8561..56bd1a7b 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -25,6 +25,7 @@
#include <sstream>
#include <iostream>
#include <iomanip>
+#include <cfloat>
#include <boost/filesystem.hpp>
#include <openssl/sha.h>
#include "KM_util.h"
@@ -203,27 +204,39 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
* @return RGB image.
*/
shared_ptr<ARGBFrame>
-libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr<const GammaLUT> lut_in, shared_ptr<const XYZsRGBLUT> lut_out)
+libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr<const GammaLUT> lut_in, shared_ptr<const XYZsRGBLUT> lut_out, Experimental& exp)
{
float const dci_coefficient = 48.0 / 52.37;
/* sRGB color matrix for XYZ -> RGB */
- float const colour_matrix[3][3] = {
- { 3.24096989631653, -1.5373831987381, -0.498610764741898 },
- { -0.96924364566803, 1.87596750259399, 0.0415550582110882 },
- { 0.0556300804018974, -0.203976958990097, 1.05697154998779 }
- };
+ float colour_matrix[3][3];
+
+ switch (exp.lut_type) {
+ case Experimental::FRAUNHOFER:
+ colour_matrix[0][0] = 3.24096989631653;
+ colour_matrix[0][1] = -1.5373831987381;
+ colour_matrix[0][2] = -0.498610764741898;
+ colour_matrix[1][0] = -0.96924364566803;
+ colour_matrix[1][1] = 1.87596750259399;
+ colour_matrix[1][2] = 0.0415550582110882;
+ colour_matrix[2][0] = 0.0556300804018974;
+ colour_matrix[2][1] = -0.203976958990097;
+ colour_matrix[2][2] = 1.05697154998779;
+ break;
+ default:
+ assert (false);
+ }
int const max_colour = pow (2, lut_out->bit_depth()) - 1;
struct {
double x, y, z;
} s;
-
- struct {
- double r, g, b;
- } d;
+
+ double* linear_r = new double[xyz_frame->x1 * xyz_frame->y1];
+ double* linear_g = new double[xyz_frame->x1 * xyz_frame->y1];
+ double* linear_b = new double[xyz_frame->x1 * xyz_frame->y1];
int* xyz_x = xyz_frame->comps[0].data;
int* xyz_y = xyz_frame->comps[1].data;
@@ -232,9 +245,15 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr<const GammaLUT> lut_in, s
shared_ptr<ARGBFrame> argb_frame (new ARGBFrame (Size (xyz_frame->x1, xyz_frame->y1)));
uint8_t* argb = argb_frame->data ();
-
+
+ double* lr = linear_r;
+ double* lg = linear_g;
+ double* lb = linear_b;
+
+ exp.linear_rgb_min = DBL_MAX;
+ exp.linear_rgb_max = -DBL_MAX;
+
for (int y = 0; y < xyz_frame->y1; ++y) {
- uint8_t* argb_line = argb;
for (int x = 0; x < xyz_frame->x1; ++x) {
assert (*xyz_x >= 0 && *xyz_y >= 0 && *xyz_z >= 0 && *xyz_x < 4096 && *xyz_x < 4096 && *xyz_z < 4096);
@@ -248,31 +267,53 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr<const GammaLUT> lut_in, s
s.x /= dci_coefficient;
s.y /= dci_coefficient;
s.z /= dci_coefficient;
-
+
/* XYZ to RGB */
- d.r = ((s.x * colour_matrix[0][0]) + (s.y * colour_matrix[0][1]) + (s.z * colour_matrix[0][2]));
- d.g = ((s.x * colour_matrix[1][0]) + (s.y * colour_matrix[1][1]) + (s.z * colour_matrix[1][2]));
- d.b = ((s.x * colour_matrix[2][0]) + (s.y * colour_matrix[2][1]) + (s.z * colour_matrix[2][2]));
-
- d.r = min (d.r, 1.0);
- d.r = max (d.r, 0.0);
-
- d.g = min (d.g, 1.0);
- d.g = max (d.g, 0.0);
-
- d.b = min (d.b, 1.0);
- d.b = max (d.b, 0.0);
-
+ *lr = ((s.x * colour_matrix[0][0]) + (s.y * colour_matrix[0][1]) + (s.z * colour_matrix[0][2]));
+ *lg = ((s.x * colour_matrix[1][0]) + (s.y * colour_matrix[1][1]) + (s.z * colour_matrix[1][2]));
+ *lb = ((s.x * colour_matrix[2][0]) + (s.y * colour_matrix[2][1]) + (s.z * colour_matrix[2][2]));
+
+ /* Update linear_rgb_min */
+ exp.linear_rgb_min = min (exp.linear_rgb_min, *lr);
+ exp.linear_rgb_min = min (exp.linear_rgb_min, *lg);
+ exp.linear_rgb_min = min (exp.linear_rgb_min, *lb);
+
+ /* And linear_rgb_max */
+ exp.linear_rgb_max = max (exp.linear_rgb_max, *lr);
+ exp.linear_rgb_max = max (exp.linear_rgb_max, *lg);
+ exp.linear_rgb_max = max (exp.linear_rgb_max, *lb);
+
+ ++lr;
+ ++lg;
+ ++lb;
+ }
+ }
+
+ lr = linear_r;
+ lg = linear_g;
+ lb = linear_b;
+
+ for (int y = 0; y < xyz_frame->y1; ++y) {
+ uint8_t* argb_line = argb;
+ for (int x = 0; x < xyz_frame->x1; ++x) {
/* Out gamma LUT */
- *argb_line++ = lut_out->lut()[(int) (d.b * max_colour)];
- *argb_line++ = lut_out->lut()[(int) (d.g * max_colour)];
- *argb_line++ = lut_out->lut()[(int) (d.r * max_colour)];
+ *argb_line++ = lut_out->lut()[max (0, min (max_colour - 1, int ((*lb + exp.linear_rgb_shift) * max_colour)))];
+ *argb_line++ = lut_out->lut()[max (0, min (max_colour - 1, int ((*lg + exp.linear_rgb_shift) * max_colour)))];
+ *argb_line++ = lut_out->lut()[max (0, min (max_colour - 1, int ((*lr + exp.linear_rgb_shift) * max_colour)))];
*argb_line++ = 0xff;
+
+ ++lr;
+ ++lg;
+ ++lb;
}
argb += argb_frame->stride ();
}
+ delete[] linear_r;
+ delete[] linear_g;
+ delete[] linear_b;
+
return argb_frame;
}
diff --git a/src/util.h b/src/util.h
index 2036a7ce..ffb77f0c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -60,7 +60,22 @@ extern std::string content_kind_to_string (ContentKind kind);
extern ContentKind content_kind_from_string (std::string kind);
extern bool empty_or_white_space (std::string s);
extern opj_image_t* decompress_j2k (uint8_t* data, int64_t size, int reduce);
-extern boost::shared_ptr<ARGBFrame> xyz_to_rgb (opj_image_t* xyz_frame, boost::shared_ptr<const GammaLUT>, boost::shared_ptr<const XYZsRGBLUT>);
+
+struct Experimental
+{
+ enum {
+ FRAUNHOFER,
+ } lut_type;
+
+ double linear_rgb_shift;
+ double linear_rgb_min;
+ double linear_rgb_max;
+};
+
+extern boost::shared_ptr<ARGBFrame> xyz_to_rgb (
+ opj_image_t* xyz_frame, boost::shared_ptr<const GammaLUT>, boost::shared_ptr<const XYZsRGBLUT>,
+ Experimental &
+ );
}