+ DCP_ASSERT (false);
+}
+
+/** Decompress a JPEG2000 image to a bitmap.
+ * @param data JPEG2000 data.
+ * @param size Size of data in bytes.
+ * @param reduce A power of 2 by which to reduce the size of the decoded image;
+ * 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 XYZ image.
+ */
+shared_ptr<dcp::XYZFrame>
+dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
+{
+ opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
+ opj_dparameters_t parameters;
+ opj_set_default_decoder_parameters (¶meters);
+ parameters.cp_reduce = reduce;
+ opj_setup_decoder (decoder, ¶meters);
+ opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size);
+ opj_image_t* image = opj_decode (decoder, cio);
+ if (!image) {
+ opj_destroy_decompress (decoder);
+ opj_cio_close (cio);
+ boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
+ }
+
+ opj_destroy_decompress (decoder);
+ opj_cio_close (cio);
+
+ image->x1 = rint (float(image->x1) / pow (2, reduce));
+ image->y1 = rint (float(image->y1) / pow (2, reduce));
+ return shared_ptr<XYZFrame> (new XYZFrame (image));
+}
+
+/** @param s A string.
+ * @return true if the string contains only space, newline or tab characters, or is empty.
+ */
+bool
+dcp::empty_or_white_space (string s)
+{
+ for (size_t i = 0; i < s.length(); ++i) {
+ if (s[i] != ' ' && s[i] != '\n' && s[i] != '\t') {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/** Set up various bits that the library needs. Should be called one
+ * by client applications.
+ */
+void
+dcp::init ()
+{
+ if (xmlSecInit() < 0) {
+ throw MiscError ("could not initialise xmlsec");
+ }
+
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+ if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+ throw MiscError ("unable to load default xmlsec-crypto library");
+ }
+#endif
+
+ if (xmlSecCryptoAppInit(0) < 0) {
+ throw MiscError ("could not initialise crypto");
+ }
+
+ if (xmlSecCryptoInit() < 0) {
+ throw MiscError ("could not initialise xmlsec-crypto");
+ }