summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-01-24 13:28:22 +0100
committerCarl Hetherington <cth@carlh.net>2025-01-24 13:28:22 +0100
commit7187b59857f84a5a94441f0873130cf0801e8ea6 (patch)
tree8ba431dbf60d2b6458de051d19be084242f1e675 /src
parent744eae9a14f834088289d10d7158ad89857565ad (diff)
Diffstat (limited to 'src')
-rw-r--r--src/cancel.h26
-rw-r--r--src/j2k_transcode.cc59
-rw-r--r--src/j2k_transcode.h39
-rw-r--r--src/wscript1
4 files changed, 111 insertions, 14 deletions
diff --git a/src/cancel.h b/src/cancel.h
new file mode 100644
index 00000000..a292e135
--- /dev/null
+++ b/src/cancel.h
@@ -0,0 +1,26 @@
+#ifndef LIBDCP_CANCEL_H
+#define LIBDCP_CANCEL_H
+
+
+#include <stdexcept>
+
+
+namespace dcp {
+
+
+class Cancel
+{
+public:
+ virtual ~Cancel() {}
+
+ virtual void cancel() = 0;
+ virtual void reset() = 0;
+};
+
+
+class Cancelled : public std::exception {};
+
+
+}
+
+#endif
diff --git a/src/j2k_transcode.cc b/src/j2k_transcode.cc
index 664d18a3..4fc48042 100644
--- a/src/j2k_transcode.cc
+++ b/src/j2k_transcode.cc
@@ -57,16 +57,16 @@ using namespace dcp;
shared_ptr<dcp::OpenJPEGImage>
-dcp::decompress_j2k (Data const& data, int reduce)
+dcp::decompress_j2k(Data const& data, int reduce, shared_ptr<OpenJPEGCancel> cancel)
{
- return dcp::decompress_j2k (data.data(), data.size(), reduce);
+ return dcp::decompress_j2k(data.data(), data.size(), reduce, cancel);
}
shared_ptr<dcp::OpenJPEGImage>
-dcp::decompress_j2k (shared_ptr<const Data> data, int reduce)
+dcp::decompress_j2k(shared_ptr<const Data> data, int reduce, shared_ptr<OpenJPEGCancel> cancel)
{
- return dcp::decompress_j2k (data->data(), data->size(), reduce);
+ return dcp::decompress_j2k (data->data(), data->size(), reduce, cancel);
}
@@ -123,7 +123,7 @@ compress_error_callback (char const * msg, void *)
shared_ptr<dcp::OpenJPEGImage>
-dcp::decompress_j2k (uint8_t const * data, int64_t size, int reduce)
+dcp::decompress_j2k(uint8_t const * data, int64_t size, int reduce, shared_ptr<OpenJPEGCancel> cancel)
{
DCP_ASSERT (reduce >= 0);
@@ -152,6 +152,10 @@ dcp::decompress_j2k (uint8_t const * data, int64_t size, int reduce)
parameters.cp_reduce = reduce;
opj_setup_decoder (decoder, &parameters);
+ if (cancel) {
+ opj_set_cancel(decoder, cancel->opj_cancel());
+ }
+
auto stream = opj_stream_default_create (OPJ_TRUE);
if (!stream) {
throw MiscError ("could not create JPEG2000 stream");
@@ -166,19 +170,24 @@ dcp::decompress_j2k (uint8_t const * data, int64_t size, int reduce)
opj_image_t* image = 0;
opj_read_header (stream, decoder, &image);
- if (opj_decode (decoder, stream, image) == OPJ_FALSE) {
- opj_destroy_codec (decoder);
- opj_stream_destroy (stream);
+ auto const result = opj_decode(decoder, stream, image);
+ opj_destroy_codec (decoder);
+ opj_stream_destroy (stream);
+
+ switch (result) {
+ case OPJ_FAILURE:
if (format == OPJ_CODEC_J2K) {
boost::throw_exception (ReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
} else {
boost::throw_exception (ReadError (String::compose ("could not decode JP2 file of %1 bytes.", size)));
}
+ break;
+ case OPJ_CANCEL:
+ boost::throw_exception(Cancelled{});
+ default:
+ break;
}
- opj_destroy_codec (decoder);
- opj_stream_destroy (stream);
-
image->x1 = rint (float(image->x1) / pow (2.0f, reduce));
image->y1 = rint (float(image->y1) / pow (2.0f, reduce));
return std::make_shared<OpenJPEGImage>(image);
@@ -332,3 +341,31 @@ dcp::compress_j2k (shared_ptr<const OpenJPEGImage> xyz, int bandwidth, int frame
return enc;
}
+
+OpenJPEGCancel::OpenJPEGCancel()
+{
+ _cancel = opj_create_cancel();
+}
+
+
+OpenJPEGCancel::~OpenJPEGCancel()
+{
+ opj_destroy_cancel(_cancel);
+}
+
+
+void
+OpenJPEGCancel::cancel()
+{
+ ::opj_cancel(_cancel);
+}
+
+
+void
+OpenJPEGCancel::reset()
+{
+ ::opj_reset(_cancel);
+}
+
+
+
diff --git a/src/j2k_transcode.h b/src/j2k_transcode.h
index 1e149293..17613baf 100644
--- a/src/j2k_transcode.h
+++ b/src/j2k_transcode.h
@@ -32,22 +32,51 @@
*/
+#ifndef LIBDCP_J2K_TRANSCODE_H
+#define LIBDCP_J2K_TRANSCODE_H
+
+
/** @file src/j2k_transcode.h
* @brief Methods to encode and decode JPEG2000
*/
#include "array_data.h"
+#include "cancel.h"
#include <memory>
#include <stdint.h>
+typedef struct opj_cancel opj_cancel_t;
+
+
namespace dcp {
class OpenJPEGImage;
+class OpenJPEGCancel : public Cancel
+{
+public:
+ OpenJPEGCancel();
+ ~OpenJPEGCancel();
+
+ OpenJPEGCancel(OpenJPEGCancel const&) = delete;
+ OpenJPEGCancel& operator=(OpenJPEGCancel const&) = delete;
+
+ void cancel() override;
+ void reset() override;
+
+ opj_cancel_t* opj_cancel() {
+ return _cancel;
+ }
+
+private:
+ opj_cancel_t* _cancel;
+};
+
+
/** Decompress a JPEG2000 image to a bitmap
* @param data JPEG2000 data
* @param size Size of data in bytes
@@ -57,10 +86,10 @@ class OpenJPEGImage;
* This is useful for scaling 4K DCP images down to 2K.
* @return OpenJPEGImage
*/
-extern std::shared_ptr<OpenJPEGImage> decompress_j2k (uint8_t const * data, int64_t size, int reduce);
+extern std::shared_ptr<OpenJPEGImage> decompress_j2k(uint8_t const * data, int64_t size, int reduce, std::shared_ptr<OpenJPEGCancel> cancel = {});
-extern std::shared_ptr<OpenJPEGImage> decompress_j2k (Data const& data, int reduce);
-extern std::shared_ptr<OpenJPEGImage> decompress_j2k (std::shared_ptr<const Data> data, int reduce);
+extern std::shared_ptr<OpenJPEGImage> decompress_j2k (Data const& data, int reduce, std::shared_ptr<OpenJPEGCancel> cancel = {});
+extern std::shared_ptr<OpenJPEGImage> decompress_j2k (std::shared_ptr<const Data> data, int reduce, std::shared_ptr<OpenJPEGCancel> cancel = {});
/** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used
* after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data.
@@ -69,3 +98,7 @@ extern ArrayData compress_j2k (std::shared_ptr<const OpenJPEGImage>, int bandwid
}
+
+
+#endif
+
diff --git a/src/wscript b/src/wscript
index 8c6ae134..ab417d6e 100644
--- a/src/wscript
+++ b/src/wscript
@@ -147,6 +147,7 @@ def build(bld):
atmos_asset_writer.h
atmos_frame.h
behaviour.h
+ cancel.h
certificate.h
certificate_chain.h
chromaticity.h