summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-12 20:55:29 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-12 20:55:29 +0100
commitf28303e1f00075841ac00fe4bb18ca37cbf1a7af (patch)
tree82329bd11c6b061beec3c2e0f6db701fd7983fa4 /src
parent493875161c36a782a785c191ff997c8e26cccde3 (diff)
Add XYZFrame and use it.
Diffstat (limited to 'src')
-rw-r--r--src/picture_asset.cc23
-rw-r--r--src/picture_frame.cc16
-rw-r--r--src/rec709_linearised_gamma_lut.cc38
-rw-r--r--src/rec709_linearised_gamma_lut.h32
-rw-r--r--src/srgb_linearised_gamma_lut.cc38
-rw-r--r--src/srgb_linearised_gamma_lut.h32
-rw-r--r--src/util.cc21
-rw-r--r--src/util.h6
-rw-r--r--src/wscript2
-rw-r--r--src/xyz_frame.cc49
-rw-r--r--src/xyz_frame.h42
11 files changed, 261 insertions, 38 deletions
diff --git a/src/picture_asset.cc b/src/picture_asset.cc
index eb17813e..6be50b6d 100644
--- a/src/picture_asset.cc
+++ b/src/picture_asset.cc
@@ -36,6 +36,7 @@
#include "util.h"
#include "exceptions.h"
#include "picture_frame.h"
+#include "xyz_frame.h"
using std::string;
using std::ostream;
@@ -337,30 +338,25 @@ PictureAsset::frame_buffer_equals (
}
/* Decompress the images to bitmaps */
- opj_image_t* image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
- opj_image_t* image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
+ shared_ptr<XYZFrame> image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
+ shared_ptr<XYZFrame> image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
/* Compare them */
- if (image_A->numcomps != image_B->numcomps) {
- note (ERROR, "image component counts for frame " + lexical_cast<string>(frame) + " differ");
- return false;
- }
-
- vector<int> abs_diffs (image_A->comps[0].w * image_A->comps[0].h * image_A->numcomps);
+ vector<int> abs_diffs (image_A->size().width * image_A->size().height * 3);
int d = 0;
int max_diff = 0;
- for (int c = 0; c < image_A->numcomps; ++c) {
+ for (int c = 0; c < 3; ++c) {
- if (image_A->comps[c].w != image_B->comps[c].w || image_A->comps[c].h != image_B->comps[c].h) {
+ if (image_A->size() != image_B->size()) {
note (ERROR, "image sizes for frame " + lexical_cast<string>(frame) + " differ");
return false;
}
- int const pixels = image_A->comps[c].w * image_A->comps[c].h;
+ int const pixels = image_A->size().width * image_A->size().height;
for (int j = 0; j < pixels; ++j) {
- int const t = abs (image_A->comps[c].data[j] - image_B->comps[c].data[j]);
+ int const t = abs (image_A->data(c)[j] - image_B->data(c)[j]);
abs_diffs[d++] = t;
max_diff = max (max_diff, t);
}
@@ -392,9 +388,6 @@ PictureAsset::frame_buffer_equals (
return false;
}
- opj_image_destroy (image_A);
- opj_image_destroy (image_B);
-
return true;
}
diff --git a/src/picture_frame.cc b/src/picture_frame.cc
index b4d72f6f..d0784245 100644
--- a/src/picture_frame.cc
+++ b/src/picture_frame.cc
@@ -81,11 +81,10 @@ MonoPictureFrame::j2k_size () const
shared_ptr<ARGBFrame>
MonoPictureFrame::argb_frame (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), GammaLUT::cache.get (12, 1 / srgb_gamma));
- opj_image_destroy (xyz_frame);
- return f;
+ return xyz_to_rgb (
+ decompress_j2k (const_cast<uint8_t*> (_buffer->RoData()), _buffer->Size(), reduce),
+ GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma)
+ );
}
/** Make a picture frame from a 3D (stereoscopic) asset.
@@ -127,7 +126,7 @@ StereoPictureFrame::~StereoPictureFrame ()
shared_ptr<ARGBFrame>
StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
{
- opj_image_t* xyz_frame = 0;
+ shared_ptr<XYZFrame> xyz_frame;
switch (eye) {
case LEFT:
xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->Left.RoData()), _buffer->Left.Size(), reduce);
@@ -137,10 +136,7 @@ StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
break;
}
- assert (xyz_frame->numcomps == 3);
- shared_ptr<ARGBFrame> f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma));
- opj_image_destroy (xyz_frame);
- return f;
+ return xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma));
}
uint8_t const *
diff --git a/src/rec709_linearised_gamma_lut.cc b/src/rec709_linearised_gamma_lut.cc
new file mode 100644
index 00000000..f1ac0a6d
--- /dev/null
+++ b/src/rec709_linearised_gamma_lut.cc
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "rec709_linearised_gamma_lut.h"
+
+using namespace libdcp;
+
+LUTCache<Rec709LinearisedGammaLUT> Rec709LinearisedGammaLUT::cache;
+
+Rec709LinearisedGammaLUT::Rec709LinearisedGammaLUT (int bits, float gamma)
+ : LUT<float> (bits, gamma)
+{
+ int const bit_length = pow (2, bits);
+ for (int i = 0; i < bit_length; ++i) {
+ float const p = static_cast<float> (i) / (bit_length - 1);
+ if (p > 0.08125) {
+ _lut[i] = pow ((p + 0.099) / 1.099, gamma);
+ } else {
+ _lut[i] = p / 4.5;
+ }
+ }
+}
diff --git a/src/rec709_linearised_gamma_lut.h b/src/rec709_linearised_gamma_lut.h
new file mode 100644
index 00000000..75e71f74
--- /dev/null
+++ b/src/rec709_linearised_gamma_lut.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "lut.h"
+#include "lut_cache.h"
+
+namespace libdcp {
+
+class Rec709LinearisedGammaLUT : public LUT<float>
+{
+public:
+ Rec709LinearisedGammaLUT (int bit_length, float gamma);
+ static LUTCache<Rec709LinearisedGammaLUT> cache;
+};
+
+}
diff --git a/src/srgb_linearised_gamma_lut.cc b/src/srgb_linearised_gamma_lut.cc
new file mode 100644
index 00000000..1c10e118
--- /dev/null
+++ b/src/srgb_linearised_gamma_lut.cc
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "srgb_linearised_gamma_lut.h"
+
+using namespace libdcp;
+
+LUTCache<SRGBLinearisedGammaLUT> SRGBLinearisedGammaLUT::cache;
+
+SRGBLinearisedGammaLUT::SRGBLinearisedGammaLUT (int bits, float gamma)
+ : LUT<float> (bits, gamma)
+{
+ int const bit_length = pow (2, bits);
+ for (int i = 0; i < bit_length; ++i) {
+ float const p = static_cast<float> (i) / (bit_length - 1);
+ if (p > 0.04045) {
+ _lut[i] = pow ((p + 0.055) / 1.055, gamma);
+ } else {
+ _lut[i] = p / 12.92;
+ }
+ }
+}
diff --git a/src/srgb_linearised_gamma_lut.h b/src/srgb_linearised_gamma_lut.h
new file mode 100644
index 00000000..9e32463a
--- /dev/null
+++ b/src/srgb_linearised_gamma_lut.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "lut.h"
+#include "lut_cache.h"
+
+namespace libdcp {
+
+class SRGBLinearisedGammaLUT : public LUT<float>
+{
+public:
+ SRGBLinearisedGammaLUT (int bit_length, float gamma);
+ static LUTCache<SRGBLinearisedGammaLUT> cache;
+};
+
+}
diff --git a/src/util.cc b/src/util.cc
index 18fa1b17..24dc37fb 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -42,6 +42,7 @@
#include "argb_frame.h"
#include "certificates.h"
#include "gamma_lut.h"
+#include "xyz_frame.h"
using std::string;
using std::cout;
@@ -181,9 +182,9 @@ libdcp::content_kind_from_string (string type)
* e.g. 0 reduces by (2^0 == 1), ie keeping the same size.
* 1 reduces by (2^1 == 2), ie halving the size of the image.
* This is useful for scaling 4K DCP images down to 2K.
- * @return openjpeg image, which the caller must call opj_image_destroy() on.
+ * @return XYZ image.
*/
-opj_image_t *
+shared_ptr<libdcp::XYZFrame>
libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
{
opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
@@ -203,7 +204,7 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
image->x1 = rint (float(image->x1) / pow (2, reduce));
image->y1 = rint (float(image->y1) / pow (2, reduce));
- return image;
+ return shared_ptr<XYZFrame> (new XYZFrame (image));
}
/** Convert an openjpeg XYZ image to RGB.
@@ -211,7 +212,7 @@ 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 GammaLUT> lut_out)
+libdcp::xyz_to_rgb (shared_ptr<const XYZFrame> xyz_frame, shared_ptr<const GammaLUT> lut_in, shared_ptr<const GammaLUT> lut_out)
{
float const dci_coefficient = 48.0 / 52.37;
@@ -235,17 +236,17 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr<const GammaLUT> lut_in, s
double r, g, b;
} d;
- int* xyz_x = xyz_frame->comps[0].data;
- int* xyz_y = xyz_frame->comps[1].data;
- int* xyz_z = xyz_frame->comps[2].data;
+ int* xyz_x = xyz_frame->data (0);
+ int* xyz_y = xyz_frame->data (1);
+ int* xyz_z = xyz_frame->data (2);
- shared_ptr<ARGBFrame> argb_frame (new ARGBFrame (Size (xyz_frame->x1, xyz_frame->y1)));
+ shared_ptr<ARGBFrame> argb_frame (new ARGBFrame (xyz_frame->size ()));
uint8_t* argb = argb_frame->data ();
- for (int y = 0; y < xyz_frame->y1; ++y) {
+ for (int y = 0; y < xyz_frame->size().height; ++y) {
uint8_t* argb_line = argb;
- for (int x = 0; x < xyz_frame->x1; ++x) {
+ for (int x = 0; x < xyz_frame->size().width; ++x) {
assert (*xyz_x >= 0 && *xyz_y >= 0 && *xyz_z >= 0 && *xyz_x < 4096 && *xyz_x < 4096 && *xyz_z < 4096);
diff --git a/src/util.h b/src/util.h
index fab7bd37..e712d6fa 100644
--- a/src/util.h
+++ b/src/util.h
@@ -39,7 +39,7 @@ namespace libdcp {
class ARGBFrame;
class CertificateChain;
class GammaLUT;
-class XYZsRGBLUT;
+class XYZFrame;
struct Size {
Size ()
@@ -64,8 +64,8 @@ extern std::string make_digest (std::string filename);
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 GammaLUT>);
+extern boost::shared_ptr<XYZFrame> decompress_j2k (uint8_t* data, int64_t size, int reduce);
+extern boost::shared_ptr<ARGBFrame> xyz_to_rgb (boost::shared_ptr<const XYZFrame>, boost::shared_ptr<const GammaLUT>, boost::shared_ptr<const GammaLUT>);
extern void init ();
diff --git a/src/wscript b/src/wscript
index 5e0b8a0a..922ee1e9 100644
--- a/src/wscript
+++ b/src/wscript
@@ -32,6 +32,7 @@ def build(bld):
types.cc
util.cc
version.cc
+ xyz_frame.cc
parse/asset_map.cc
parse/cpl.cc
parse/pkl.cc
@@ -62,6 +63,7 @@ def build(bld):
types.h
util.h
version.h
+ xyz_frame.h
"""
bld.install_files('${PREFIX}/include/libdcp', headers)
diff --git a/src/xyz_frame.cc b/src/xyz_frame.cc
new file mode 100644
index 00000000..78df3f33
--- /dev/null
+++ b/src/xyz_frame.cc
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <cassert>
+#include "xyz_frame.h"
+
+using namespace libdcp;
+
+/** Construct an XYZFrame, taking ownership of the opj_image_t */
+XYZFrame::XYZFrame (opj_image_t* image)
+ : _opj_image (image)
+{
+ assert (_opj_image->numcomps == 3);
+}
+
+XYZFrame::~XYZFrame ()
+{
+ opj_image_destroy (_opj_image);
+}
+
+int *
+XYZFrame::data (int c) const
+{
+ assert (c >= 0 && c < 3);
+ return _opj_image->comps[c].data;
+}
+
+libdcp::Size
+XYZFrame::size () const
+{
+ /* XXX: this may not be right; x0 and y0 can presumably be non-zero */
+ return libdcp::Size (_opj_image->x1, _opj_image->y1);
+}
diff --git a/src/xyz_frame.h b/src/xyz_frame.h
new file mode 100644
index 00000000..9a10d1e3
--- /dev/null
+++ b/src/xyz_frame.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <openjpeg.h>
+#include "util.h"
+
+namespace libdcp {
+
+class XYZFrame
+{
+public:
+ XYZFrame (opj_image_t *);
+ ~XYZFrame ();
+
+ int* data (int) const;
+ libdcp::Size size () const;
+
+ opj_image_t* opj_image () const {
+ return _opj_image;
+ }
+
+private:
+ opj_image_t* _opj_image;
+};
+
+}