diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-12 20:55:29 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-12 20:55:29 +0100 |
| commit | f28303e1f00075841ac00fe4bb18ca37cbf1a7af (patch) | |
| tree | 82329bd11c6b061beec3c2e0f6db701fd7983fa4 /src | |
| parent | 493875161c36a782a785c191ff997c8e26cccde3 (diff) | |
Add XYZFrame and use it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/picture_asset.cc | 23 | ||||
| -rw-r--r-- | src/picture_frame.cc | 16 | ||||
| -rw-r--r-- | src/rec709_linearised_gamma_lut.cc | 38 | ||||
| -rw-r--r-- | src/rec709_linearised_gamma_lut.h | 32 | ||||
| -rw-r--r-- | src/srgb_linearised_gamma_lut.cc | 38 | ||||
| -rw-r--r-- | src/srgb_linearised_gamma_lut.h | 32 | ||||
| -rw-r--r-- | src/util.cc | 21 | ||||
| -rw-r--r-- | src/util.h | 6 | ||||
| -rw-r--r-- | src/wscript | 2 | ||||
| -rw-r--r-- | src/xyz_frame.cc | 49 | ||||
| -rw-r--r-- | src/xyz_frame.h | 42 |
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); @@ -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; +}; + +} |
