}
-J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::MonoPictureFrame> frame, dcp::Size size, AVPixelFormat pixel_format)
+J2KImageProxy::J2KImageProxy (
+ shared_ptr<const dcp::MonoPictureFrame> frame,
+ dcp::Size size,
+ AVPixelFormat pixel_format,
+ optional<int> forced_reduction
+ )
: _data (frame->j2k_size ())
, _size (size)
, _pixel_format (pixel_format)
+ , _forced_reduction (forced_reduction)
{
memcpy (_data.data().get(), frame->j2k_data(), _data.size ());
}
-J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::StereoPictureFrame> frame, dcp::Size size, dcp::Eye eye, AVPixelFormat pixel_format)
+J2KImageProxy::J2KImageProxy (
+ shared_ptr<const dcp::StereoPictureFrame> frame,
+ dcp::Size size,
+ dcp::Eye eye,
+ AVPixelFormat pixel_format,
+ optional<int> forced_reduction
+ )
: _size (size)
, _eye (eye)
, _pixel_format (pixel_format)
+ , _forced_reduction (forced_reduction)
{
switch (eye) {
case dcp::EYE_LEFT:
socket->read (_data.data().get (), _data.size ());
}
-shared_ptr<Image>
-J2KImageProxy::image (optional<dcp::NoteHandler>, optional<dcp::Size> target_size) const
+void
+J2KImageProxy::prepare (optional<dcp::Size> target_size) const
{
- if (!_decompressed || target_size != _target_size) {
- int reduce = 0;
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (_decompressed && target_size == _target_size) {
+ return;
+ }
+
+ int reduce = 0;
+ if (_forced_reduction) {
+ reduce = *_forced_reduction;
+ } else {
while (target_size && (_size.width / pow(2, reduce)) > target_size->width && (_size.height / pow(2, reduce)) > target_size->height) {
++reduce;
}
--reduce;
reduce = max (0, reduce);
- _decompressed = dcp::decompress_j2k (const_cast<uint8_t*> (_data.data().get()), _data.size (), reduce);
+ }
- if (_decompressed->precision(0) < 12) {
- int const shift = 12 - _decompressed->precision (0);
- for (int c = 0; c < 3; ++c) {
- int* p = _decompressed->data (c);
- for (int y = 0; y < _decompressed->size().height; ++y) {
- for (int x = 0; x < _decompressed->size().width; ++x) {
- *p++ <<= shift;
- }
+ _decompressed = dcp::decompress_j2k (const_cast<uint8_t*> (_data.data().get()), _data.size (), reduce);
+
+ if (_decompressed->precision(0) < 12) {
+ int const shift = 12 - _decompressed->precision (0);
+ for (int c = 0; c < 3; ++c) {
+ int* p = _decompressed->data (c);
+ for (int y = 0; y < _decompressed->size().height; ++y) {
+ for (int x = 0; x < _decompressed->size().width; ++x) {
+ *p++ <<= shift;
}
}
}
-
- _target_size = target_size;
}
+ _target_size = target_size;
+}
+
+shared_ptr<Image>
+J2KImageProxy::image (optional<dcp::NoteHandler>, optional<dcp::Size> target_size) const
+{
+ prepare (target_size);
+
shared_ptr<Image> image (new Image (_pixel_format, _decompressed->size(), true));
/* Copy data in whatever format (sRGB or XYZ) into our Image; I'm assuming