summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-09-26 16:06:11 +0100
committerRobin Watts <robin.watts@artifex.com>2016-09-26 19:14:43 +0100
commit3dd90d46498cb50122de97960378a2f4e081fbb0 (patch)
tree0e29c231ad4d1c056a7dcf848c5984f2e005c430
parenteedec4421fdc61fda830bcec4f4a2d4e3eed2268 (diff)
downloadmupdf-3dd90d46498cb50122de97960378a2f4e081fbb0.tar.xz
Update OpenJPEG to the latest (git) version.
Part of the change in this code is to require opj_malloc and co. Sadly, opj_malloc and co do not take a context field, so a we need to wrap calls to openjpeg with a lock. I am reusing the freetype lock here for simplicity.
-rw-r--r--Makethird1
-rw-r--r--platform/win32/libthirdparty.vcproj12
-rw-r--r--source/fitz/load-jpx.c144
m---------thirdparty/openjpeg0
4 files changed, 155 insertions, 2 deletions
diff --git a/Makethird b/Makethird
index 628c1054..2dd108e9 100644
--- a/Makethird
+++ b/Makethird
@@ -397,6 +397,7 @@ OPENJPEG_SRC := \
tgt.c \
thix_manager.c \
tpix_manager.c \
+ thread.c
OPENJPEG_OBJ := $(addprefix $(OPENJPEG_OUT)/, $(OPENJPEG_SRC:%.c=%.o))
diff --git a/platform/win32/libthirdparty.vcproj b/platform/win32/libthirdparty.vcproj
index ad07b188..9b618605 100644
--- a/platform/win32/libthirdparty.vcproj
+++ b/platform/win32/libthirdparty.vcproj
@@ -1088,6 +1088,18 @@
>
</File>
<File
+ RelativePath="..\..\thirdparty\openjpeg\src\lib\openjp2\thread.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\thirdparty\openjpeg\src\lib\openjp2\thread.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\thirdparty\openjpeg\src\lib\openjp2\tls_keys.h"
+ >
+ </File>
+ <File
RelativePath="..\..\thirdparty\openjpeg\src\lib\openjp2\tpix_manager.c"
>
</File>
diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c
index a1430973..a7775fc7 100644
--- a/source/fitz/load-jpx.c
+++ b/source/fitz/load-jpx.c
@@ -489,6 +489,125 @@ fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *wp, int
#include <openjpeg.h>
+/* OpenJPEG does not provide a safe mechanism to intercept
+ * allocations. In the latest version all allocations go
+ * though opj_malloc etc, but no context is passed around.
+ *
+ * In order to ensure that allocations throughout mupdf
+ * are done consistently, we implement opj_malloc etc as
+ * functions that call down to fz_malloc etc. These
+ * require context variables, so we lock and unlock around
+ * calls to openjpeg. Any attempt to call through
+ * without setting these is detected.
+ *
+ * It is therefore vital that any fz_lock/fz_unlock
+ * handlers are shared between all the fz_contexts in
+ * use at a time.
+ */
+
+/* Potentially we can write different versions
+ * of get_context and set_context for different
+ * threading systems.
+ */
+
+static fz_context *opj_secret = NULL;
+
+static void set_opj_context(fz_context *ctx)
+{
+ opj_secret = ctx;
+}
+
+static fz_context *get_opj_context()
+{
+ return opj_secret;
+}
+
+void opj_lock(fz_context *ctx)
+{
+ fz_lock(ctx, FZ_LOCK_FREETYPE);
+
+ set_opj_context(ctx);
+}
+
+void opj_unlock(fz_context *ctx)
+{
+ set_opj_context(NULL);
+
+ fz_unlock(ctx, FZ_LOCK_FREETYPE);
+}
+
+void *opj_malloc(size_t size)
+{
+ fz_context *ctx = get_opj_context();
+
+ assert(ctx != NULL);
+
+ return fz_malloc_no_throw(ctx, size);
+}
+
+void *opj_calloc(size_t n, size_t size)
+{
+ fz_context *ctx = get_opj_context();
+
+ assert(ctx != NULL);
+
+ return fz_calloc_no_throw(ctx, n, size);
+}
+
+void *opj_realloc(void *ptr, size_t size)
+{
+ fz_context *ctx = get_opj_context();
+
+ assert(ctx != NULL);
+
+ return fz_resize_array_no_throw(ctx, ptr, 1, size);
+}
+
+void opj_free(void *ptr)
+{
+ fz_context *ctx = get_opj_context();
+
+ assert(ctx != NULL);
+
+ fz_free(ctx, ptr);
+}
+
+void * opj_aligned_malloc(size_t size)
+{
+ uint8_t *ptr;
+ int off;
+
+ if (size == 0)
+ return NULL;
+
+ size += 16 + sizeof(uint8_t);
+ ptr = opj_malloc(size);
+ if (ptr == NULL)
+ return NULL;
+ off = 16-(((int)(intptr_t)ptr) & 15);
+ ptr[off-1] = off;
+ return ptr + off;
+}
+
+void opj_aligned_free(void* ptr_)
+{
+ uint8_t *ptr = (uint8_t *)ptr_;
+ uint8_t off;
+ if (ptr == NULL)
+ return;
+
+ off = ptr[-1];
+ opj_free((void *)(((unsigned char *)ptr) - off));
+}
+
+#if 0
+/* UNUSED currently, and moderately tricky, so deferred until required */
+void * opj_aligned_realloc(void *ptr, size_t size)
+{
+ return opj_realloc(ptr, size);
+}
+#endif
+
static void fz_opj_error_callback(const char *msg, void *client_data)
{
fz_context *ctx = (fz_context *)client_data;
@@ -734,13 +853,34 @@ jpx_read_image(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace
fz_pixmap *
fz_load_jpx(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed)
{
- return jpx_read_image(ctx, data, size, defcs, indexed, 0);
+ fz_pixmap *pix;
+ fz_try(ctx)
+ {
+ opj_lock(ctx);
+ pix = jpx_read_image(ctx, data, size, defcs, indexed, 0);
+ }
+ fz_always(ctx)
+ opj_unlock(ctx);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+
+ return pix;
}
void
fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
{
- fz_pixmap *img = jpx_read_image(ctx, data, size, NULL, 0, 1);
+ fz_pixmap *img;
+
+ fz_try(ctx)
+ {
+ opj_lock(ctx);
+ img = jpx_read_image(ctx, data, size, NULL, 0, 1);
+ }
+ fz_always(ctx)
+ opj_unlock(ctx);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
*cspacep = fz_keep_colorspace(ctx, img->colorspace);
*wp = img->w;
diff --git a/thirdparty/openjpeg b/thirdparty/openjpeg
-Subproject 731b9d0b35ce1d913620387eab8d6e294afac69
+Subproject 1ae3470ea8c4618fa411e213f1dfcaf3b87378d