[Bf-blender-cvs] [440ef4235ff] master: OpenJPEG: support building against both 1.5 and 2.3.

Brecht Van Lommel noreply at git.blender.org
Wed Aug 8 20:31:00 CEST 2018


Commit: 440ef4235ff0b7a67de978d790bf923c04badabe
Author: Brecht Van Lommel
Date:   Wed Aug 8 19:48:12 2018 +0200
Branches: master
https://developer.blender.org/rB440ef4235ff0b7a67de978d790bf923c04badabe

OpenJPEG: support building against both 1.5 and 2.3.

Patch porting to OpenJPEG 2.3 is by Campbell.

Once all platforms are upgraded we can remove the code for 1.5, and upgrade
or remove the openjpeg version from extern/. This intermediate step makes it
possible for platform maintainers to upgrade to 2.3 without breaking other
platforms.

===================================================================

M	source/blender/imbuf/intern/IMB_filetype.h
M	source/blender/imbuf/intern/filetype.c
M	source/blender/imbuf/intern/jp2.c

===================================================================

diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index 31ebc3e54de..5351b00d301 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -82,8 +82,9 @@ int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags);
 
 /* jp2 */
 int imb_is_a_jp2(const unsigned char *buf);
-struct ImBuf *imb_jp2_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
-int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags);
+struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_load_jp2_filepath(const char *name, int flags, char colorspace[IM_MAX_SPACE]);
+int imb_save_jp2(struct ImBuf *ibuf, const char *name, int flags);
 
 /* jpeg */
 int imb_is_a_jpeg(const unsigned char *mem);
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index 5dcd9c1c68a..25bbd132a49 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -77,7 +77,7 @@ const ImFileType IMB_FILE_TYPES[] = {
 	{imb_initopenexr, NULL, imb_is_a_openexr, NULL, imb_ftype_default, imb_load_openexr, NULL, imb_save_openexr, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_OPENEXR, COLOR_ROLE_DEFAULT_FLOAT},
 #endif
 #ifdef WITH_OPENJPEG
-	{NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_jp2_decode, NULL, imb_savejp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE},
+	{NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_load_jp2, NULL, imb_save_jp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE},
 #endif
 #ifdef WITH_DDS
 	{NULL, NULL, imb_is_a_dds, NULL, imb_ftype_default, imb_load_dds, NULL, NULL, NULL, 0, IMB_FTYPE_DDS, COLOR_ROLE_DEFAULT_BYTE},
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 753b5276222..e4923e94635 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -38,7 +38,1251 @@
 
 #include "openjpeg.h"
 
-// #define JP2_FILEHEADER_SIZE 14  /* UNUSED */
+/* Temporary duplicated implementations for version 1.5 and 2.3, until we
+ * upgrade all platforms to 2.3. When removing the old code,
+ * imb_load_jp2_filepath can be added in filetype.c. */
+
+#if defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2
+
+#define JP2_FILEHEADER_SIZE 12
+
+static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
+static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00};
+
+/* We only need this because of how the presets are set */
+/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */
+typedef struct img_folder {
+	/** The directory path of the folder containing input images*/
+	char *imgdirpath;
+	/** Output format*/
+	char *out_format;
+	/** Enable option*/
+	char set_imgdir;
+	/** Enable Cod Format for output*/
+	char set_out_format;
+	/** User specified rate stored in case of cinema option*/
+	float *rates;
+} img_fol_t;
+
+enum {
+    DCP_CINEMA2K = 3,
+    DCP_CINEMA4K = 4,
+};
+
+static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */
+{
+	return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1;
+}
+
+static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */
+{
+	return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1;
+}
+
+static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE])
+{
+	if (check_jp2(mem)) {
+		return OPJ_CODEC_JP2;
+	}
+	else if (check_j2k(mem)) {
+		return OPJ_CODEC_J2K;
+	}
+	else {
+		return OPJ_CODEC_UNKNOWN;
+	}
+}
+
+int imb_is_a_jp2(const unsigned char *buf)
+{
+	return check_jp2(buf);
+}
+
+/**
+ * sample error callback expecting a FILE* client object
+ */
+static void error_callback(const char *msg, void *client_data)
+{
+	FILE *stream = (FILE *)client_data;
+	fprintf(stream, "[ERROR] %s", msg);
+}
+/**
+ * sample warning callback expecting a FILE* client object
+ */
+static void warning_callback(const char *msg, void *client_data)
+{
+	FILE *stream = (FILE *)client_data;
+	fprintf(stream, "[WARNING] %s", msg);
+}
+
+#ifdef DEBUG
+/**
+ * sample debug callback expecting no client object
+ */
+static void info_callback(const char *msg, void *client_data)
+{
+	FILE *stream = (FILE *)client_data;
+	fprintf(stream, "[INFO] %s", msg);
+}
+#endif
+
+#   define PIXEL_LOOPER_BEGIN(_rect)                                          \
+	for (y = h - 1; y != (unsigned int)(-1); y--) {                           \
+		for (i = y * w, i_next = (y + 1) * w;                                 \
+		     i < i_next;                                                      \
+		     i++, _rect += 4)                                                 \
+		{                                                                     \
+
+#   define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels)                      \
+	for (y = h - 1; y != (unsigned int)(-1); y--) {                           \
+		for (i = y * w, i_next = (y + 1) * w;                                 \
+		     i < i_next;                                                      \
+		     i++, _rect += _channels)                                         \
+		{                                                                     \
+
+#   define PIXEL_LOOPER_END \
+	} \
+} (void)0 \
+
+
+/** \name Buffer Stream
+ * \{ */
+
+struct BufInfo {
+	const unsigned char *buf;
+	const unsigned char *cur;
+	off_t len;
+};
+
+static void opj_read_from_buffer_free(void *UNUSED(p_user_data))
+{
+	/* nop */
+}
+
+static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
+{
+	struct BufInfo *p_file = p_user_data;
+	OPJ_UINT32 l_nb_read;
+
+	if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len ) {
+		l_nb_read = p_nb_bytes;
+	}
+	else {
+		l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur);
+	}
+	memcpy(p_buffer, p_file->cur, l_nb_read);
+	p_file->cur += l_nb_read;
+
+	return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1);
+}
+
+#if 0
+static OPJ_SIZE_T opj_write_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
+{
+	struct BufInfo *p_file = p_user_data;
+	memcpy(p_file->cur, p_buffer, p_nb_bytes);
+	p_file->cur += p_nb_bytes;
+	p_file->len += p_nb_bytes;
+	return p_nb_bytes;
+}
+#endif
+
+static OPJ_OFF_T opj_skip_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
+{
+	struct BufInfo *p_file = p_user_data;
+	if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
+		p_file->cur += p_nb_bytes;
+		return p_nb_bytes;
+	}
+	p_file->cur = p_file->buf + p_file->len;
+	return (OPJ_OFF_T)-1;
+}
+
+static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
+{
+	struct BufInfo *p_file = p_user_data;
+	if (p_nb_bytes < p_file->len) {
+		p_file->cur = p_file->buf + p_nb_bytes;
+		return OPJ_TRUE;
+	}
+	p_file->cur = p_file->buf + p_file->len;
+	return OPJ_FALSE;
+}
+
+/**
+ * Stream wrapper for memory buffer
+ * (would be nice if this was supported by the API).
+ */
+
+static opj_stream_t *opj_stream_create_from_buffer(
+        struct BufInfo *p_file, OPJ_UINT32 p_size,
+        OPJ_BOOL p_is_read_stream)
+{
+	opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
+	if (l_stream == NULL) {
+		return NULL;
+	}
+	opj_stream_set_user_data(l_stream, p_file , opj_read_from_buffer_free);
+	opj_stream_set_user_data_length(l_stream, p_file->len);
+	opj_stream_set_read_function(l_stream,  opj_read_from_buffer);
+#if 0  /* UNUSED */
+	opj_stream_set_write_function(l_stream, opj_write_from_buffer);
+#endif
+	opj_stream_set_skip_function(l_stream, opj_skip_from_buffer);
+	opj_stream_set_seek_function(l_stream, opj_seek_from_buffer);
+
+	return l_stream;
+}
+
+/** \} */
+
+
+/** \name File Stream
+ * \{ */
+
+static void opj_free_from_file(void *p_user_data)
+{
+	FILE *f = p_user_data;
+	fclose(f);
+}
+
+static OPJ_UINT64 opj_get_data_length_from_file (void *p_user_data)
+{
+	FILE *p_file = p_user_data;
+	OPJ_OFF_T file_length = 0;
+
+	fseek(p_file, 0, SEEK_END);
+	file_length = ftell(p_file);
+	fseek(p_file, 0, SEEK_SET);
+
+	return (OPJ_UINT64)file_length;
+}
+
+static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
+{
+	FILE *p_file = p_user_data;
+	OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
+	return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
+}
+
+static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
+{
+	FILE *p_file = p_user_data;
+	return fwrite(p_buffer, 1, p_nb_bytes, p_file);
+}
+
+static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
+{
+	FILE *p_file = p_user_data;
+	if (fseek(p_file, p_nb_bytes, SEEK_CUR)) {
+		return -1;
+	}
+	return p_nb_bytes;
+}
+
+static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
+{
+	FILE *p_file = p_user_data;
+	if (fseek(p_file, p_nb_bytes, SEEK_SET)) {
+		return OPJ_FALSE;
+	}
+	return OPJ_TRUE;
+}
+
+/**
+ * Stream wrapper for memory file
+ * (would be nice if this was supported by the API).
+ */
+
+static opj_stream_t *opj_stream_create_from_file(
+        const char *filepath, OPJ_UINT32 p_size, OPJ_BOOL p_is_read_stream,
+        FILE **r_file)
+{
+	FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb");
+	if (p_file == NULL) {
+		return NULL;
+	}
+
+	opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
+	if (l_stream == NULL) {
+		fclose(p_file);
+		return NULL;
+	}
+
+	opj_stream_set_user_data(l_stream, p_file, opj_free_from_file);
+	opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
+	opj_stream_set_write_function(l_stream, opj_write_from_file);
+	opj_stream_set_read_function(l_stream,  opj_read_from_file);
+	opj_stream_set_skip_function(l_stream, opj_skip_from_file);
+	opj_stream_set_seek_function(l_stream, opj_seek_from_file);
+
+	if (r_file) {
+		*r_file = p_file;
+	}
+	return l_stream;
+}
+
+/** \} */
+
+static ImBuf *imb_load_jp2_stream(
+        opj_stream_t *stream, OPJ_CODEC_FORMAT p_format,
+        int flags, char colorspace[IM_MAX_SPACE]);
+
+ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char co

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list