1diff --git a/third_party/libopenjpeg20/opj_malloc.h b/third_party/libopenjpeg20/opj_malloc.h
2index cbc4106c7..79b3a6410 100644
3--- a/third_party/libopenjpeg20/opj_malloc.h
4+++ b/third_party/libopenjpeg20/opj_malloc.h
5@@ -31,8 +31,6 @@
6  */
7 #ifndef OPJ_MALLOC_H
8 #define OPJ_MALLOC_H
9-
10-#include <stddef.h>
11 /**
12 @file opj_malloc.h
13 @brief Internal functions
14@@ -52,7 +50,16 @@ Allocate an uninitialized memory block
15 @param size Bytes to allocate
16 @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
17 */
18-void * opj_malloc(size_t size);
19+#ifdef ALLOC_PERF_OPT
20+void * OPJ_CALLCONV opj_malloc(size_t size);
21+#else
22+/* prevent assertion on overflow for MSVC */
23+#ifdef _MSC_VER
24+#define opj_malloc(size) ((size_t)(size) >= (size_t)-0x100 ? NULL : malloc(size))
25+#else
26+#define opj_malloc(size) malloc(size)
27+#endif
28+#endif
29
30 /**
31 Allocate a memory block with elements initialized to 0
32@@ -60,24 +67,98 @@ Allocate a memory block with elements initialized to 0
33 @param sizeOfElements Bytes per block to allocate
34 @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
35 */
36-void * opj_calloc(size_t numOfElements, size_t sizeOfElements);
37+#ifdef ALLOC_PERF_OPT
38+void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements);
39+#else
40+/* prevent assertion on overflow for MSVC */
41+#ifdef _MSC_VER
42+#define opj_calloc(num, size) ((size_t)(num) != 0 && (size_t)(num) >= (size_t)-0x100 / (size_t)(size) ? NULL : calloc(num, size))
43+#else
44+#define opj_calloc(num, size) calloc(num, size)
45+#endif
46+#endif
47
48 /**
49 Allocate memory aligned to a 16 byte boundary
50 @param size Bytes to allocate
51 @return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
52 */
53-void * opj_aligned_malloc(size_t size);
54-void * opj_aligned_realloc(void *ptr, size_t size);
55-void opj_aligned_free(void* ptr);
56+/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
57+#ifdef _WIN32
58+  /* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
59+  #ifdef __GNUC__
60+    #include <mm_malloc.h>
61+    #define HAVE_MM_MALLOC
62+  #else /* MSVC, Intel C++ */
63+    #include <malloc.h>
64+    #ifdef _mm_malloc
65+      #define HAVE_MM_MALLOC
66+    #endif
67+  #endif
68+#else /* Not _WIN32 */
69+  #if defined(__sun)
70+    #define HAVE_MEMALIGN
71+  #elif defined(__FreeBSD__)
72+    #define HAVE_POSIX_MEMALIGN
73+  /* Linux x86_64 and OSX always align allocations to 16 bytes */
74+  #elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
75+    #define HAVE_MEMALIGN
76+    #include <malloc.h>
77+  #endif
78+#endif
79
80-/**
81-Allocate memory aligned to a 32 byte boundary
82-@param size Bytes to allocate
83-@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
84-*/
85-void * opj_aligned_32_malloc(size_t size);
86-void * opj_aligned_32_realloc(void *ptr, size_t size);
87+#define opj_aligned_malloc(size) malloc(size)
88+#define opj_aligned_32_malloc(size) malloc(size)
89+#define opj_aligned_free(m) free(m)
90+
91+#ifdef HAVE_MM_MALLOC
92+  #undef opj_aligned_malloc
93+  #define opj_aligned_malloc(size) _mm_malloc((size), 16)
94+  #undef opj_aligned_32_malloc
95+  #define opj_aligned_32_malloc(size) _mm_malloc((size), 32)
96+  #undef opj_aligned_free
97+  #define opj_aligned_free(m) _mm_free(m)
98+#endif
99+
100+#ifdef HAVE_MEMALIGN
101+  extern void* memalign(size_t, size_t);
102+  #undef opj_aligned_malloc
103+  #define opj_aligned_malloc(size) memalign(16, (size))
104+  #undef opj_aligned_32_malloc
105+  #define opj_aligned_32_malloc(size) memalign(32, (size))
106+  #undef opj_aligned_free
107+  #define opj_aligned_free(m) free(m)
108+#endif
109+
110+#ifdef HAVE_POSIX_MEMALIGN
111+  #undef opj_aligned_malloc
112+  extern int posix_memalign(void**, size_t, size_t);
113+
114+  static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){
115+    void* mem = NULL;
116+    posix_memalign(&mem, 16, size);
117+    return mem;
118+  }
119+
120+  #undef opj_aligned_32_malloc
121+  static INLINE void* __attribute__ ((malloc)) opj_aligned_32_malloc(size_t size){
122+    void* mem = NULL;
123+    posix_memalign(&mem, 32, size);
124+    return mem;
125+  }
126+
127+  #undef opj_aligned_free
128+  #define opj_aligned_free(m) free(m)
129+#endif
130+
131+#ifdef ALLOC_PERF_OPT
132+  #undef opj_aligned_malloc
133+  #define opj_aligned_malloc(size) opj_malloc(size)
134+  #undef opj_aligned_32_malloc
135+  #define opj_aligned_32_malloc(size) opj_malloc(size)
136+  #undef opj_aligned_free
137+  #define opj_aligned_free(m) opj_free(m)
138+#endif
139
140 /**
141 Reallocate memory blocks.
142@@ -85,13 +166,26 @@ Reallocate memory blocks.
143 @param s New size in bytes
144 @return Returns a void pointer to the reallocated (and possibly moved) memory block
145 */
146-void * opj_realloc(void * m, size_t s);
147+#ifdef ALLOC_PERF_OPT
148+void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
149+#else
150+/* prevent assertion on overflow for MSVC */
151+#ifdef _MSC_VER
152+#define opj_realloc(m, s) ((size_t)(s) >= (size_t)-0x100 ? NULL : realloc(m, s))
153+#else
154+#define opj_realloc(m, s) realloc(m, s)
155+#endif
156+#endif
157
158 /**
159 Deallocates or frees a memory block.
160 @param m Previously allocated memory block to be freed
161 */
162-void opj_free(void * m);
163+#ifdef ALLOC_PERF_OPT
164+void OPJ_CALLCONV opj_free(void * m);
165+#else
166+#define opj_free(m) free(m)
167+#endif
168
169 #if defined(__GNUC__) && !defined(OPJ_SKIP_POISON)
170 #pragma GCC poison malloc calloc realloc free
171