diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-03 11:35:43 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-03 11:35:43 +0100 |
| commit | 097bd1acc473501062e488c323478bd9143b5716 (patch) | |
| tree | 2c40b738b3d192a45b10c44ef1f4a4fd47afd7b6 /src | |
| parent | 6407924747622d6785ecfed24c35db355ca38032 (diff) | |
Add Experimental struct.
Diffstat (limited to 'src')
| -rw-r--r-- | src/picture_frame.cc | 10 | ||||
| -rw-r--r-- | src/picture_frame.h | 5 | ||||
| -rw-r--r-- | src/util.cc | 99 | ||||
| -rw-r--r-- | src/util.h | 17 |
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; } @@ -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 & + ); } |
