summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-12 20:27:48 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-12 20:27:48 +0100
commitac8c7f049ebaba3fc9561ccb920496ea04f974ef (patch)
tree3e1c68516de19bc2e4e89ce95c527ba3feaf9a19 /src/lib
parentad6c0bbec4f354f29fb968099ff1a0ce2e57c43a (diff)
Use run-time-generated LUTs for XYZ/RGB conversion.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/colour_matrices.cc37
-rw-r--r--src/lib/colour_matrices.h (renamed from src/lib/lut.h)25
-rw-r--r--src/lib/dcp_video_frame.cc36
-rw-r--r--src/lib/wscript2
4 files changed, 64 insertions, 36 deletions
diff --git a/src/lib/colour_matrices.cc b/src/lib/colour_matrices.cc
new file mode 100644
index 000000000..4ec43f40d
--- /dev/null
+++ b/src/lib/colour_matrices.cc
@@ -0,0 +1,37 @@
+/*
+ Taken from OpenDCP: Builds Digital Cinema Packages
+ Copyright (c) 2010-2011 Terrence Meiczinger, All Rights Reserved
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "colour_matrices.h"
+
+/* Color Matrices */
+float color_matrix[3][3][3] = {
+ /* SRGB */
+ {{0.4124564, 0.3575761, 0.1804375},
+ {0.2126729, 0.7151522, 0.0721750},
+ {0.0193339, 0.1191920, 0.9503041}},
+
+ /* REC.709 */
+ {{0.4124564, 0.3575761, 0.1804375},
+ {0.2126729, 0.7151522, 0.0721750},
+ {0.0193339, 0.1191920, 0.9503041}},
+
+ /* DC28.30 (2006-02-24) */
+ {{0.4451698156, 0.2771344092, 0.1722826698},
+ {0.2094916779, 0.7215952542, 0.0689130679},
+ {0.0000000000, 0.0470605601, 0.9073553944}}
+};
diff --git a/src/lib/lut.h b/src/lib/colour_matrices.h
index 26888a24a..8e009299a 100644
--- a/src/lib/lut.h
+++ b/src/lib/colour_matrices.h
@@ -16,18 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** @file src/lut.h
- * @brief Look-up tables for colour conversions (from OpenDCP)
- */
-
-#define BIT_DEPTH 12
-#define BIT_PRECISION 16
-#define COLOR_DEPTH (4095)
-#define DCI_LUT_SIZE ((COLOR_DEPTH + 1) * BIT_PRECISION)
-#define DCI_GAMMA (2.6)
-#define DCI_DEGAMMA (1/DCI_GAMMA)
-#define DCI_COEFFICENT (48.0/52.37)
-
enum COLOR_PROFILE_ENUM {
CP_SRGB = 0,
CP_REC709,
@@ -35,17 +23,4 @@ enum COLOR_PROFILE_ENUM {
CP_MAX
};
-enum LUT_IN_ENUM {
- LI_SRGB = 0,
- LI_REC709,
- LI_MAX
-};
-
-enum LUT_OUT_ENUM {
- LO_DCI = 0,
- LO_MAX
-};
-
extern float color_matrix[3][3][3];
-extern float lut_in[LI_MAX][4095+1];
-extern int lut_out[1][DCI_LUT_SIZE];
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 2f597522c..c4234b1da 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -43,9 +43,11 @@
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
+#include <libdcp/rec709_linearised_gamma_lut.h>
+#include <libdcp/srgb_linearised_gamma_lut.h>
+#include <libdcp/gamma_lut.h>
#include "film.h"
#include "dcp_video_frame.h"
-#include "lut.h"
#include "config.h"
#include "exceptions.h"
#include "server.h"
@@ -53,6 +55,7 @@
#include "scaler.h"
#include "image.h"
#include "log.h"
+#include "colour_matrices.h"
#include "i18n.h"
@@ -63,6 +66,8 @@ using std::cout;
using boost::shared_ptr;
using libdcp::Size;
+#define DCI_COEFFICENT (48.0 / 52.37)
+
/** Construct a DCP video frame.
* @param input Input image.
* @param f Index of the frame within the DCP.
@@ -151,6 +156,17 @@ DCPVideoFrame::encode_locally ()
double x, y, z;
} d;
+ /* In sRGB / Rec709 gamma LUT */
+ shared_ptr<libdcp::LUT<float> > lut_in;
+ if (_colour_lut == 0) {
+ lut_in = libdcp::SRGBLinearisedGammaLUT::cache.get (12, 2.4);
+ } else {
+ lut_in = libdcp::Rec709LinearisedGammaLUT::cache.get (12, 1 / 0.45);
+ }
+
+ /* Out DCI gamma LUT */
+ shared_ptr<libdcp::LUT<float> > lut_out = libdcp::GammaLUT::cache.get (16, 1 / 2.6);
+
/* Copy our RGB into the openjpeg container, converting to XYZ in the process */
int jn = 0;
@@ -159,9 +175,9 @@ DCPVideoFrame::encode_locally ()
for (int x = 0; x < _image->size().width; ++x) {
/* In gamma LUT (converting 8-bit input to 12-bit) */
- s.r = lut_in[_colour_lut][*p++ << 4];
- s.g = lut_in[_colour_lut][*p++ << 4];
- s.b = lut_in[_colour_lut][*p++ << 4];
+ s.r = lut_in->lut()[*p++ << 4];
+ s.g = lut_in->lut()[*p++ << 4];
+ s.b = lut_in->lut()[*p++ << 4];
/* RGB to XYZ Matrix */
d.x = ((s.r * color_matrix[_colour_lut][0][0]) +
@@ -177,14 +193,14 @@ DCPVideoFrame::encode_locally ()
(s.b * color_matrix[_colour_lut][2][2]));
/* DCI companding */
- d.x = d.x * DCI_COEFFICENT * (DCI_LUT_SIZE - 1);
- d.y = d.y * DCI_COEFFICENT * (DCI_LUT_SIZE - 1);
- d.z = d.z * DCI_COEFFICENT * (DCI_LUT_SIZE - 1);
+ d.x = d.x * DCI_COEFFICENT * 65535;
+ d.y = d.y * DCI_COEFFICENT * 65535;
+ d.z = d.z * DCI_COEFFICENT * 65535;
/* Out gamma LUT */
- _opj_image->comps[0].data[jn] = lut_out[LO_DCI][(int) d.x];
- _opj_image->comps[1].data[jn] = lut_out[LO_DCI][(int) d.y];
- _opj_image->comps[2].data[jn] = lut_out[LO_DCI][(int) d.z];
+ _opj_image->comps[0].data[jn] = lut_out->lut()[(int) d.x] * 4096;
+ _opj_image->comps[1].data[jn] = lut_out->lut()[(int) d.y] * 4096;
+ _opj_image->comps[2].data[jn] = lut_out->lut()[(int) d.z] * 4096;
++jn;
}
diff --git a/src/lib/wscript b/src/lib/wscript
index 2f1f7d325..60fa96df6 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -8,6 +8,7 @@ sources = """
audio_content.cc
audio_decoder.cc
audio_mapping.cc
+ colour_matrices.cc
config.cc
content.cc
cross.cc
@@ -33,7 +34,6 @@ sources = """
job.cc
job_manager.cc
log.cc
- lut.cc
player.cc
playlist.cc
ratio.cc