diff --git a/autobuild.xml b/autobuild.xml
index 5a5ffa2898df4867c8ce2166708afafe4fc50551..801da4e7739a96973acb84e489e1296a0fb74a8d 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2195,9 +2195,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5abf2d9c0b250821c59cc60cd94fd8af</string>
+              <string>89e6436b256c98818fa736a460a04016</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54840/510064/openjpeg-1.5.1.538970-darwin64-538970.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105184/920580/openjpeg-2.5.0.575325-darwin64-575325.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2219,9 +2219,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>222a406ecb4071a9cc9635353afa337e</string>
+              <string>97b15b312c2dec38981ec63bd77d0491</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54977/511775/openjpeg-1.5.1.538970-windows-538970.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105185/920592/openjpeg-2.5.0.575325-windows-575325.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2231,16 +2231,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5b5c80807fa8161f3480be3d89fe9516</string>
+              <string>cdb55c8b074ce4f166ebc597f13f62a1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54974/511767/openjpeg-1.5.1.538970-windows64-538970.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105186/920591/openjpeg-2.5.0.575325-windows64-575325.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.5.1.538970</string>
+        <string>2.5.0.575325</string>
       </map>
       <key>openssl</key>
       <map>
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index ff705101ded51485ee120cc69017823871d68899..04b4202ca3de688a2af9aaea9f41c4da30d4d240 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -52,7 +52,7 @@ if(WINDOWS)
 
     set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
     set(release_files
-        openjpeg.dll
+        openjp2.dll
         libapr-1.dll
         libaprutil-1.dll
         libapriconv-1.dll
@@ -220,7 +220,7 @@ elseif(LINUX)
         libgobject-2.0.so
         libhunspell-1.3.so.0.0.0
         libopenal.so
-        libopenjpeg.so
+        libopenjp2.so
         libuuid.so.16
         libuuid.so.16.0.22
         libfontconfig.so.1.8.0
diff --git a/indra/cmake/FindOpenJPEG.cmake b/indra/cmake/FindOpenJPEG.cmake
index 949384eec4e1d0d9d245883d8d821710ed39c539..afe319fb06935ec8010ae8066cd9ab6620088f36 100644
--- a/indra/cmake/FindOpenJPEG.cmake
+++ b/indra/cmake/FindOpenJPEG.cmake
@@ -9,14 +9,15 @@
 # also defined, but not for general use are
 #  OPENJPEG_LIBRARY, where to find the OpenJPEG library.
 
-FIND_PATH(OPENJPEG_INCLUDE_DIR openjpeg.h
+FIND_PATH(OPENJPEG_INCLUDE_DIR openjp2.h
 /usr/local/include/openjpeg
 /usr/local/include
 /usr/include/openjpeg
 /usr/include
+include/openjpeg
 )
 
-SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjpeg)
+SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjp2)
 FIND_LIBRARY(OPENJPEG_LIBRARY
   NAMES ${OPENJPEG_NAMES}
   PATHS /usr/lib /usr/local/lib
diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake
index bf0bde2ba7b85084765c2e8bde21a24fb090be75..a078c97cb8fd209fc88bc9ff739d2eb4cabb841a 100644
--- a/indra/cmake/OpenJPEG.cmake
+++ b/indra/cmake/OpenJPEG.cmake
@@ -8,15 +8,7 @@ if (USESYSTEMLIBS)
   include(FindOpenJPEG)
 else (USESYSTEMLIBS)
   use_prebuilt_binary(openjpeg)
-  
-  if(WINDOWS)
-    # Windows has differently named release and debug openjpeg(d) libs.
-    set(OPENJPEG_LIBRARIES 
-        debug openjpegd
-        optimized openjpeg)
-  else(WINDOWS)
-    set(OPENJPEG_LIBRARIES openjpeg)
-  endif(WINDOWS)
-  
-    set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
+
+  set(OPENJPEG_LIBRARIES openjp2)
+  set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
 endif (USESYSTEMLIBS)
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index d7706e73b24ed6033609482a852323aaf077b04b..3957ede77f01d49af6eabc3cd7d389c223c4d8d8 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -99,14 +99,14 @@ if (WINDOWS)
     # Copy over OpenJPEG.dll
     # *NOTE: On Windows with VS2005, only the first comment prints
     set(OPENJPEG_RELEASE
-        "${ARCH_PREBUILT_DIRS_RELEASE}/openjpeg.dll")
+        "${ARCH_PREBUILT_DIRS_RELEASE}/openjp2.dll")
     add_custom_command( TARGET llui_libtest POST_BUILD
         COMMAND ${CMAKE_COMMAND} -E copy_if_different 
             ${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR}
         COMMENT "Copying OpenJPEG DLLs to binary directory"
         )
     set(OPENJPEG_DEBUG
-        "${ARCH_PREBUILT_DIRS_DEBUG}/openjpegd.dll")
+        "${ARCH_PREBUILT_DIRS_DEBUG}/openjp2.dll")
     add_custom_command( TARGET llui_libtest POST_BUILD
         COMMAND ${CMAKE_COMMAND} -E copy_if_different 
             ${OPENJPEG_DEBUG} ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 925da5674bfc5591faa941221c035a4aea8da1da..944629cf4c16db434d25bac4f9c2d4a38f523d6e 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -29,40 +29,41 @@
 
 // this is defined so that we get static linking.
 #include "openjpeg.h"
+#include "event.h"
+#include "cio.h"
 
-#include "lltimer.h"
-//#include "llmemory.h"
+#define MAX_ENCODED_DISCARD_LEVELS 5
 
 // Factory function: see declaration in llimagej2c.cpp
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
 {
-	return new LLImageJ2COJ();
+    return new LLImageJ2COJ();
 }
 
 std::string LLImageJ2COJ::getEngineInfo() const
 {
 #ifdef OPENJPEG_VERSION
-	return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
-		+ opj_version();
+    return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
+        + opj_version();
 #else
-	return std::string("OpenJPEG runtime: ") + opj_version();
+    return std::string("OpenJPEG runtime: ") + opj_version();
 #endif
 }
 
 // Return string from message, eliminating final \n if present
 static std::string chomp(const char* msg)
 {
-	// stomp trailing \n
-	std::string message = msg;
-	if (!message.empty())
-	{
-		size_t last = message.size() - 1;
-		if (message[last] == '\n')
-		{
-			message.resize( last );
-		}
-	}
-	return message;
+    // stomp trailing \n
+    std::string message = msg;
+    if (!message.empty())
+    {
+        size_t last = message.size() - 1;
+        if (message[last] == '\n')
+        {
+            message.resize(last);
+        }
+}
+    return message;
 }
 
 /**
@@ -70,419 +71,761 @@ sample error callback expecting a LLFILE* client object
 */
 void error_callback(const char* msg, void*)
 {
-	LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
+    LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
 }
 /**
 sample warning callback expecting a LLFILE* client object
 */
 void warning_callback(const char* msg, void*)
 {
-	LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
+    LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
 }
 /**
 sample debug callback expecting no client object
 */
 void info_callback(const char* msg, void*)
 {
-	LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
+    LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL;
 }
 
 // Divide a by 2 to the power of b and round upwards
 int ceildivpow2(int a, int b)
 {
-	return (a + (1 << b) - 1) >> b;
+    return (a + (1 << b) - 1) >> b;
 }
 
-
-LLImageJ2COJ::LLImageJ2COJ()
-	: LLImageJ2CImpl()
+class JPEG2KBase
 {
-}
+public:
+    JPEG2KBase() {}
 
+    U8*        buffer = nullptr;
+    OPJ_SIZE_T size = 0;
+    OPJ_OFF_T  offset = 0;
+};
 
-LLImageJ2COJ::~LLImageJ2COJ()
+#define WANT_VERBOSE_OPJ_SPAM LL_DEBUG
+
+static void opj_info(const char* msg, void* user_data)
 {
+    llassert(user_data);
+#if WANT_VERBOSE_OPJ_SPAM
+    LL_INFOS("OpenJPEG") << msg << LL_ENDL;
+#endif
 }
 
-bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+static void opj_warn(const char* msg, void* user_data)
 {
-	// No specific implementation for this method in the OpenJpeg case
-	return false;
+    llassert(user_data);
+#if WANT_VERBOSE_OPJ_SPAM
+    LL_WARNS("OpenJPEG") << msg << LL_ENDL;
+#endif
 }
 
-bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
+static void opj_error(const char* msg, void* user_data)
 {
-	// No specific implementation for this method in the OpenJpeg case
-	return false;
+    llassert(user_data);
+#if WANT_VERBOSE_OPJ_SPAM
+    LL_WARNS("OpenJPEG") << msg << LL_ENDL;
+#endif
 }
 
-bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
+static OPJ_SIZE_T opj_read(void * buffer, OPJ_SIZE_T bytes, void* user_data)
 {
-	//
-	// FIXME: Get the comment field out of the texture
-	//
-
-	LLTimer decode_timer;
-
-	opj_dparameters_t parameters;	/* decompression parameters */
-	opj_event_mgr_t event_mgr;		/* event manager */
-	opj_image_t *image = NULL;
-
-	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
-	opj_cio_t *cio = NULL;
-
-
-	/* configure the event callbacks (not required) */
-	memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-	event_mgr.error_handler = error_callback;
-	event_mgr.warning_handler = warning_callback;
-	event_mgr.info_handler = info_callback;
-
-	/* set decoding parameters to default values */
-	opj_set_default_decoder_parameters(&parameters);
-
-	parameters.cp_reduce = base.getRawDiscardLevel();
-
-	/* decode the code-stream */
-	/* ---------------------- */
-
-	/* JPEG-2000 codestream */
-
-	/* get a decoder handle */
-	dinfo = opj_create_decompress(CODEC_J2K);
-
-	/* catch events using our callbacks and give a local context */
-	opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);			
-
-	/* setup the decoder decoding parameters using user parameters */
-	opj_setup_decoder(dinfo, &parameters);
-
-	/* open a byte stream */
-	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
-
-	/* decode the stream and fill the image structure */
-	image = opj_decode(dinfo, cio);
-
-	/* close the byte stream */
-	opj_cio_close(cio);
-
-	/* free remaining structures */
-	if(dinfo)
-	{
-		opj_destroy_decompress(dinfo);
-	}
-
-	// The image decode failed if the return was NULL or the component
-	// count was zero.  The latter is just a sanity check before we
-	// dereference the array.
-	if(!image || !image->numcomps)
-	{
-		LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
-		if (image)
-		{
-			opj_image_destroy(image);
-		}
-
-		return true; // done
-	}
-
-	// sometimes we get bad data out of the cache - check to see if the decode succeeded
-	for (S32 i = 0; i < image->numcomps; i++)
-	{
-		if (image->comps[i].factor != base.getRawDiscardLevel())
-		{
-			// if we didn't get the discard level we're expecting, fail
-			opj_image_destroy(image);
-			base.mDecoding = false;
-			return true;
-		}
-	}
-	
-	if(image->numcomps <= first_channel)
-	{
-		LL_WARNS() << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << LL_ENDL;
-		if (image)
-		{
-			opj_image_destroy(image);
-		}
-			
-		return true;
-	}
-
-	// Copy image data into our raw image format (instead of the separate channel format
-
-	S32 img_components = image->numcomps;
-	S32 channels = img_components - first_channel;
-	if( channels > max_channel_count )
-		channels = max_channel_count;
-
-	// Component buffers are allocated in an image width by height buffer.
-	// The image placed in that buffer is ceil(width/2^factor) by
-	// ceil(height/2^factor) and if the factor isn't zero it will be at the
-	// top left of the buffer with black filled in the rest of the pixels.
-	// It is integer math so the formula is written in ceildivpo2.
-	// (Assuming all the components have the same width, height and
-	// factor.)
-	S32 comp_width = image->comps[0].w;
-	S32 f=image->comps[0].factor;
-	S32 width = ceildivpow2(image->x1 - image->x0, f);
-	S32 height = ceildivpow2(image->y1 - image->y0, f);
-	raw_image.resize(width, height, channels);
-	U8 *rawp = raw_image.getData();
-
-	// first_channel is what channel to start copying from
-	// dest is what channel to copy to.  first_channel comes from the
-	// argument, dest always starts writing at channel zero.
-	for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
-		comp++, dest++)
-	{
-		if (image->comps[comp].data)
-		{
-			S32 offset = dest;
-			for (S32 y = (height - 1); y >= 0; y--)
-			{
-				for (S32 x = 0; x < width; x++)
-				{
-					rawp[offset] = image->comps[comp].data[y*comp_width + x];
-					offset += channels;
-				}
-			}
-		}
-		else // Some rare OpenJPEG versions have this bug.
-		{
-			LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
-			opj_image_destroy(image);
-
-			return true; // done
-		}
-	}
-
-	/* free image data structure */
-	opj_image_destroy(image);
-
-	return true; // done
+    llassert(user_data);
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    OPJ_SIZE_T remainder = (jpeg_codec->size - jpeg_codec->offset);
+    if (remainder <= 0)
+    {
+        jpeg_codec->offset = jpeg_codec->size;
+        // Indicate end of stream (hacky?)
+        return (OPJ_OFF_T)-1;
+    }
+    OPJ_SIZE_T to_read = llclamp(U32(bytes), U32(0), U32(remainder));
+    memcpy(buffer, jpeg_codec->buffer + jpeg_codec->offset, to_read);
+    jpeg_codec->offset += to_read;
+    return to_read;
 }
 
-
-bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
+static OPJ_SIZE_T opj_write(void * buffer, OPJ_SIZE_T bytes, void* user_data)
 {
-	const S32 MAX_COMPS = 5;
-	opj_cparameters_t parameters;	/* compression parameters */
-	opj_event_mgr_t event_mgr;		/* event manager */
-
-
-	/* 
-	configure the event callbacks (not required)
-	setting of each callback is optional 
-	*/
-	memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-	event_mgr.error_handler = error_callback;
-	event_mgr.warning_handler = warning_callback;
-	event_mgr.info_handler = info_callback;
-
-	/* set encoding parameters to default values */
-	opj_set_default_encoder_parameters(&parameters);
-	parameters.cod_format = 0;
-	parameters.cp_disto_alloc = 1;
-
-	if (reversible)
-	{
-		parameters.tcp_numlayers = 1;
-		parameters.tcp_rates[0] = 0.0f;
-	}
-	else
-	{
-		parameters.tcp_numlayers = 5;
-                parameters.tcp_rates[0] = 1920.0f;
-                parameters.tcp_rates[1] = 480.0f;
-                parameters.tcp_rates[2] = 120.0f;
-                parameters.tcp_rates[3] = 30.0f;
-		parameters.tcp_rates[4] = 10.0f;
-		parameters.irreversible = 1;
-		if (raw_image.getComponents() >= 3)
-		{
-			parameters.tcp_mct = 1;
-		}
-	}
-
-	if (!comment_text)
-	{
-		parameters.cp_comment = (char *) "";
-	}
-	else
-	{
-		// Awful hacky cast, too lazy to copy right now.
-		parameters.cp_comment = (char *) comment_text;
-	}
-
-	//
-	// Fill in the source image from our raw image
-	//
-	OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
-	opj_image_cmptparm_t cmptparm[MAX_COMPS];
-	opj_image_t * image = NULL;
-	S32 numcomps = raw_image.getComponents();
-	S32 width = raw_image.getWidth();
-	S32 height = raw_image.getHeight();
-
-	memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
-	for(S32 c = 0; c < numcomps; c++) {
-		cmptparm[c].prec = 8;
-		cmptparm[c].bpp = 8;
-		cmptparm[c].sgnd = 0;
-		cmptparm[c].dx = parameters.subsampling_dx;
-		cmptparm[c].dy = parameters.subsampling_dy;
-		cmptparm[c].w = width;
-		cmptparm[c].h = height;
-	}
-
-	/* create the image */
-	image = opj_image_create(numcomps, &cmptparm[0], color_space);
-
-	image->x1 = width;
-	image->y1 = height;
-
-	S32 i = 0;
-	const U8 *src_datap = raw_image.getData();
-	for (S32 y = height - 1; y >= 0; y--)
-	{
-		for (S32 x = 0; x < width; x++)
-		{
-			const U8 *pixel = src_datap + (y*width + x) * numcomps;
-			for (S32 c = 0; c < numcomps; c++)
-			{
-				image->comps[c].data[i] = *pixel;
-				pixel++;
-			}
-			i++;
-		}
-	}
-
-
-
-	/* encode the destination image */
-	/* ---------------------------- */
-
-	int codestream_length;
-	opj_cio_t *cio = NULL;
-
-	/* get a J2K compressor handle */
-	opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
-
-	/* catch events using our callbacks and give a local context */
-	opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);			
-
-	/* setup the encoder parameters using the current image and using user parameters */
-	opj_setup_encoder(cinfo, &parameters, image);
-
-	/* open a byte stream for writing */
-	/* allocate memory for all tiles */
-	cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
-
-	/* encode the image */
-	bool bSuccess = opj_encode(cinfo, cio, image, NULL);
-	if (!bSuccess)
-	{
-		opj_cio_close(cio);
-		LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL;
-		return false;
-	}
-	codestream_length = cio_tell(cio);
-
-	base.copyData(cio->buffer, codestream_length);
-	base.updateData(); // set width, height
-
-	/* close and free the byte stream */
-	opj_cio_close(cio);
-
-	/* free remaining compression structures */
-	opj_destroy_compress(cinfo);
-
-
-	/* free user parameters structure */
-	if(parameters.cp_matrice) free(parameters.cp_matrice);
-
-	/* free image data */
-	opj_image_destroy(image);
-	return true;
+    llassert(user_data);
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    OPJ_SIZE_T remainder = jpeg_codec->size - jpeg_codec->offset;
+    if (remainder < bytes)
+    {
+        OPJ_SIZE_T new_size = jpeg_codec->size + (bytes - remainder);
+        U8* new_buffer = (U8*)ll_aligned_malloc_16(new_size);
+        memcpy(new_buffer, jpeg_codec->buffer, jpeg_codec->offset);
+        U8* old_buffer = jpeg_codec->buffer;
+        jpeg_codec->buffer = new_buffer;
+        ll_aligned_free_16(old_buffer);
+        jpeg_codec->size = new_size;
+    }
+    memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, bytes);
+    jpeg_codec->offset += bytes;
+    return bytes;
 }
 
-bool LLImageJ2COJ::getMetadata(LLImageJ2C &base)
+static OPJ_OFF_T opj_skip(OPJ_OFF_T bytes, void* user_data)
 {
-	//
-	// FIXME: We get metadata by decoding the ENTIRE image.
-	//
-
-	// Update the raw discard level
-	base.updateRawDiscardLevel();
-
-	opj_dparameters_t parameters;	/* decompression parameters */
-	opj_event_mgr_t event_mgr;		/* event manager */
-	opj_image_t *image = NULL;
-
-	opj_dinfo_t* dinfo = NULL;	/* handle to a decompressor */
-	opj_cio_t *cio = NULL;
-
-
-	/* configure the event callbacks (not required) */
-	memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
-	event_mgr.error_handler = error_callback;
-	event_mgr.warning_handler = warning_callback;
-	event_mgr.info_handler = info_callback;
-
-	/* set decoding parameters to default values */
-	opj_set_default_decoder_parameters(&parameters);
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    jpeg_codec->offset += bytes;
+    if (jpeg_codec->offset > jpeg_codec->size)
+    {
+        jpeg_codec->offset = jpeg_codec->size;
+        // Indicate end of stream
+        return (OPJ_OFF_T)-1;
+    }
+    return bytes;
+}
 
-	// Only decode what's required to get the size data.
-	parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER;
+static OPJ_BOOL opj_seek(OPJ_OFF_T bytes, void * user_data)
+{
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    jpeg_codec->offset += bytes;
+    jpeg_codec->offset = llclamp(U32(jpeg_codec->offset), U32(0), U32(jpeg_codec->size));
+    return OPJ_TRUE;
+}
 
-	//parameters.cp_reduce = mRawDiscardLevel;
+static void opj_free_user_data(void * user_data)
+{
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    // Don't free, data is managed externally
+    jpeg_codec->buffer = nullptr;
+    jpeg_codec->size = 0;
+    jpeg_codec->offset = 0;
+}
 
-	/* decode the code-stream */
-	/* ---------------------- */
+static void opj_free_user_data_write(void * user_data)
+{
+    JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
+    // Free, data was allocated here
+    ll_aligned_free_16(jpeg_codec->buffer);
+    jpeg_codec->buffer = nullptr;
+    jpeg_codec->size = 0;
+    jpeg_codec->offset = 0;
+}
 
-	/* JPEG-2000 codestream */
+class JPEG2KDecode : public JPEG2KBase
+{
+public:
+
+    JPEG2KDecode(S8 discardLevel)
+    {
+        memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+        memset(&parameters, 0, sizeof(opj_dparameters_t));
+        event_mgr.error_handler = error_callback;
+        event_mgr.warning_handler = warning_callback;
+        event_mgr.info_handler = info_callback;
+        opj_set_default_decoder_parameters(&parameters);
+        parameters.cp_reduce = discardLevel;
+    }
+
+    ~JPEG2KDecode()
+    {
+        if (decoder)
+        {
+            opj_destroy_codec(decoder);
+        }
+        decoder = nullptr;
+
+        if (image)
+        {
+            opj_image_destroy(image);
+        }
+        image = nullptr;
+
+        if (stream)
+        {
+            opj_stream_destroy(stream);
+        }
+        stream = nullptr;
+
+        if (codestream_info)
+        {
+            opj_destroy_cstr_info(&codestream_info);
+        }
+        codestream_info = nullptr;
+    }
+
+    bool readHeader(
+        U8* data,
+        U32 dataSize,
+        S32& widthOut,
+        S32& heightOut,
+        S32& components,
+        S32& discard_level)
+    {
+        parameters.flags |= OPJ_DPARAMETERS_DUMP_FLAG;
+
+        decoder = opj_create_decompress(OPJ_CODEC_J2K);
+
+        if (!opj_setup_decoder(decoder, &parameters))
+        {
+            return false;
+        }
+
+        if (stream)
+        {
+            opj_stream_destroy(stream);
+        }
+
+        stream = opj_stream_create(dataSize, true);
+        if (!stream)
+        {
+            return false;
+        }
+
+        opj_stream_set_user_data(stream, this, opj_free_user_data);
+        opj_stream_set_user_data_length(stream, dataSize);
+        opj_stream_set_read_function(stream, opj_read);
+        opj_stream_set_write_function(stream, opj_write);
+        opj_stream_set_skip_function(stream, opj_skip);
+        opj_stream_set_seek_function(stream, opj_seek);
+
+        buffer = data;
+        size = dataSize;
+        offset = 0;
+
+        // enable decoding partially loaded images
+        opj_decoder_set_strict_mode(decoder, OPJ_FALSE);
+
+        /* Read the main header of the codestream and if necessary the JP2 boxes*/
+        if (!opj_read_header((opj_stream_t*)stream, decoder, &image))
+        {
+            return false;
+        }
+
+        codestream_info = opj_get_cstr_info(decoder);
+
+        if (!codestream_info)
+        {
+            return false;
+        }
+
+        U32 tileDimX = codestream_info->tdx;
+        U32 tileDimY = codestream_info->tdy;
+        U32 tilesW = codestream_info->tw;
+        U32 tilesH = codestream_info->th;
+
+        widthOut = S32(tilesW * tileDimX);
+        heightOut = S32(tilesH * tileDimY);
+        components = codestream_info->nbcomps;
+
+        discard_level = 0;
+        while (tilesW > 1 && tilesH > 1 && discard_level < MAX_DISCARD_LEVEL)
+        {
+            discard_level++;
+            tilesW >>= 1;
+            tilesH >>= 1;
+        }
+
+        return true;
+    }
+
+    bool decode(U8* data, U32 dataSize, U32* channels, U8 discard_level)
+    {
+        parameters.flags &= ~OPJ_DPARAMETERS_DUMP_FLAG;
+
+        decoder = opj_create_decompress(OPJ_CODEC_J2K);
+        opj_setup_decoder(decoder, &parameters);
+
+        opj_set_info_handler(decoder, opj_info, this);
+        opj_set_warning_handler(decoder, opj_warn, this);
+        opj_set_error_handler(decoder, opj_error, this);
+
+        if (stream)
+        {
+            opj_stream_destroy(stream);
+        }
+
+        stream = opj_stream_create(dataSize, true);
+        if (!stream)
+        {
+            return false;
+        }
+
+        opj_stream_set_user_data(stream, this, opj_free_user_data);
+        opj_stream_set_user_data_length(stream, dataSize);
+        opj_stream_set_read_function(stream, opj_read);
+        opj_stream_set_write_function(stream, opj_write);
+        opj_stream_set_skip_function(stream, opj_skip);
+        opj_stream_set_seek_function(stream, opj_seek);
+
+        buffer = data;
+        size = dataSize;
+        offset = 0;
+
+        if (image)
+        {
+            opj_image_destroy(image);
+            image = nullptr;
+        }
+
+        // needs to happen before opj_read_header and opj_decode...
+        opj_set_decoded_resolution_factor(decoder, discard_level);
+
+        // enable decoding partially loaded images
+        opj_decoder_set_strict_mode(decoder, OPJ_FALSE);
+
+        if (!opj_read_header(stream, decoder, &image))
+        {
+            return false;
+        }
+
+        // needs to happen before decode which may fail
+        if (channels)
+        {
+            *channels = image->numcomps;
+        }
+
+        OPJ_BOOL decoded = opj_decode(decoder, stream, image);
+
+        // count was zero.  The latter is just a sanity check before we
+        // dereference the array.
+        if (!decoded || !image || !image->numcomps)
+        {
+            opj_end_decompress(decoder, stream);
+            return false;
+        }
+
+        opj_end_decompress(decoder, stream);
+
+        return true;
+    }
+
+    opj_image_t* getImage() { return image; }
+
+private:
+    opj_dparameters_t         parameters;
+    opj_event_mgr_t           event_mgr;
+    opj_image_t*              image = nullptr;
+    opj_codec_t*              decoder = nullptr;
+    opj_stream_t*             stream = nullptr;
+    opj_codestream_info_v2_t* codestream_info = nullptr;
+};
+
+class JPEG2KEncode : public JPEG2KBase
+{
+public:
+    const OPJ_UINT32 TILE_SIZE = 64 * 64 * 3;
+
+    JPEG2KEncode(const char* comment_text_in, bool reversible)
+    {
+        memset(&parameters, 0, sizeof(opj_cparameters_t));
+        memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+        event_mgr.error_handler = error_callback;
+        event_mgr.warning_handler = warning_callback;
+        event_mgr.info_handler = info_callback;
+
+        opj_set_default_encoder_parameters(&parameters);
+        parameters.cod_format = 0;
+        parameters.cp_disto_alloc = 1;
+        parameters.max_cs_size = (1 << 15);
+
+        if (reversible)
+        {
+            parameters.tcp_numlayers = 1;
+            parameters.tcp_rates[0] = 1.0f;
+        }
+        else
+        {
+            parameters.tcp_numlayers = 5;
+            parameters.tcp_rates[0] = 1920.0f;
+            parameters.tcp_rates[1] = 960.0f;
+            parameters.tcp_rates[2] = 480.0f;
+            parameters.tcp_rates[3] = 120.0f;
+            parameters.tcp_rates[4] = 30.0f;
+            parameters.irreversible = 1;
+            parameters.tcp_mct = 1;
+        }
+
+        if (comment_text)
+        {
+            free(comment_text);
+        }
+        comment_text = comment_text_in ? strdup(comment_text_in) : nullptr;
+
+        parameters.cp_comment = comment_text ? comment_text : (char*)"no comment";
+        llassert(parameters.cp_comment);
+    }
+
+    ~JPEG2KEncode()
+    {
+        if (encoder)
+        {
+            opj_destroy_codec(encoder);
+        }
+        encoder = nullptr;
+
+        if (image)
+        {
+            opj_image_destroy(image);
+        }
+        image = nullptr;
+
+        if (stream)
+        {
+            opj_stream_destroy(stream);
+        }
+        stream = nullptr;
+
+        if (comment_text)
+        {
+            free(comment_text);
+        }
+        comment_text = nullptr;
+    }
+
+    bool encode(const LLImageRaw& rawImageIn, LLImageJ2C &compressedImageOut)
+    {
+        setImage(rawImageIn);
+
+        encoder = opj_create_compress(OPJ_CODEC_J2K);
+
+        parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0;
+        parameters.cod_format = OPJ_CODEC_J2K;
+        parameters.numresolution = MAX_ENCODED_DISCARD_LEVELS;
+        parameters.prog_order = OPJ_RLCP;
+        parameters.cp_disto_alloc = 1;
+
+        opj_setup_encoder(encoder, &parameters, image);
+
+        opj_set_info_handler(encoder, opj_info, this);
+        opj_set_warning_handler(encoder, opj_warn, this);
+        opj_set_error_handler(encoder, opj_error, this);
+
+        U32 tile_count = (rawImageIn.getWidth() >> 6) * (rawImageIn.getHeight() >> 6);
+        U32 data_size_guess = tile_count * TILE_SIZE;
+
+        // will be freed in opj_free_user_data_write
+        buffer = (U8*)ll_aligned_malloc_16(data_size_guess);
+        size = data_size_guess;
+        offset = 0;
+
+#if LL_DEBUG
+        memset(buffer, 0, data_size_guess);
+#endif
 
-	/* get a decoder handle */
-	dinfo = opj_create_decompress(CODEC_J2K);
+        if (stream)
+        {
+            opj_stream_destroy(stream);
+        }
+
+        stream = opj_stream_create(data_size_guess, false);
+        if (!stream)
+        {
+            return false;
+        }
+
+        opj_stream_set_user_data(stream, this, opj_free_user_data_write);
+        opj_stream_set_user_data_length(stream, data_size_guess);
+        opj_stream_set_read_function(stream, opj_read);
+        opj_stream_set_write_function(stream, opj_write);
+        opj_stream_set_skip_function(stream, opj_skip);
+        opj_stream_set_seek_function(stream, opj_seek);
+
+        OPJ_BOOL started = opj_start_compress(encoder, image, stream);
+
+        if (!started)
+        {
+            return false;
+        }
+
+        if (!opj_encode(encoder, stream))
+        {
+            return false;
+        }
+
+        OPJ_BOOL encoded = opj_end_compress(encoder, stream);
+
+        // if we successfully encoded, then stream out the compressed data...
+        if (encoded)
+        {
+            // "append" (set) the data we "streamed" (memcopied) for writing to the formatted image
+            // with side-effect of setting the actually encoded size  to same
+            compressedImageOut.allocateData(offset);
+            memcpy(compressedImageOut.getData(), buffer, offset);
+            compressedImageOut.updateData(); // update width, height etc from header
+        }
+        return encoded;
+    }
+
+    void setImage(const LLImageRaw& raw)
+    {
+        opj_image_cmptparm_t cmptparm[MAX_ENCODED_DISCARD_LEVELS];
+        memset(&cmptparm[0], 0, MAX_ENCODED_DISCARD_LEVELS * sizeof(opj_image_cmptparm_t));
+
+        S32 numcomps = raw.getComponents();
+        S32 width = raw.getWidth();
+        S32 height = raw.getHeight();
+
+        for (S32 c = 0; c < numcomps; c++)
+        {
+            cmptparm[c].prec = 8;
+            cmptparm[c].bpp = 8;
+            cmptparm[c].sgnd = 0;
+            cmptparm[c].dx = parameters.subsampling_dx;
+            cmptparm[c].dy = parameters.subsampling_dy;
+            cmptparm[c].w = width;
+            cmptparm[c].h = height;
+        }
+
+        image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB);
+
+        image->x1 = width;
+        image->y1 = height;
+
+        const U8 *src_datap = raw.getData();
+
+        S32 i = 0;
+        for (S32 y = height - 1; y >= 0; y--)
+        {
+            for (S32 x = 0; x < width; x++)
+            {
+                const U8 *pixel = src_datap + (y*width + x) * numcomps;
+                for (S32 c = 0; c < numcomps; c++)
+                {
+                    image->comps[c].data[i] = *pixel;
+                    pixel++;
+                }
+                i++;
+            }
+        }
+
+        // This likely works, but there seems to be an issue openjpeg side
+        // check over after gixing that.
+
+        // De-interleave to component plane data
+        /*
+        switch (numcomps)
+        {
+        case 0:
+        default:
+            break;
+
+        case 1:
+        {
+            U32 rBitDepth = image->comps[0].bpp;
+            U32 bytesPerPixel = rBitDepth >> 3;
+            memcpy(image->comps[0].data, src, width * height * bytesPerPixel);
+        }
+        break;
+
+        case 2:
+        {
+            U32 rBitDepth = image->comps[0].bpp;
+            U32 gBitDepth = image->comps[1].bpp;
+            U32 totalBitDepth = rBitDepth + gBitDepth;
+            U32 bytesPerPixel = totalBitDepth >> 3;
+            U32 stride = width * bytesPerPixel;
+            U32 offset = 0;
+            for (S32 y = height - 1; y >= 0; y--)
+            {
+                const U8* component = src + (y * stride);
+                for (S32 x = 0; x < width; x++)
+                {
+                    image->comps[0].data[offset] = *component++;
+                    image->comps[1].data[offset] = *component++;
+                    offset++;
+                }
+            }
+        }
+        break;
+
+        case 3:
+        {
+            U32 rBitDepth = image->comps[0].bpp;
+            U32 gBitDepth = image->comps[1].bpp;
+            U32 bBitDepth = image->comps[2].bpp;
+            U32 totalBitDepth = rBitDepth + gBitDepth + bBitDepth;
+            U32 bytesPerPixel = totalBitDepth >> 3;
+            U32 stride = width * bytesPerPixel;
+            U32 offset = 0;
+            for (S32 y = height - 1; y >= 0; y--)
+            {
+                const U8* component = src + (y * stride);
+                for (S32 x = 0; x < width; x++)
+                {
+                    image->comps[0].data[offset] = *component++;
+                    image->comps[1].data[offset] = *component++;
+                    image->comps[2].data[offset] = *component++;
+                    offset++;
+                }
+            }
+        }
+        break;
+
+
+        case 4:
+        {
+            U32 rBitDepth = image->comps[0].bpp;
+            U32 gBitDepth = image->comps[1].bpp;
+            U32 bBitDepth = image->comps[2].bpp;
+            U32 aBitDepth = image->comps[3].bpp;
+
+            U32 totalBitDepth = rBitDepth + gBitDepth + bBitDepth + aBitDepth;
+            U32 bytesPerPixel = totalBitDepth >> 3;
+
+            U32 stride = width * bytesPerPixel;
+            U32 offset = 0;
+            for (S32 y = height - 1; y >= 0; y--)
+            {
+                const U8* component = src + (y * stride);
+                for (S32 x = 0; x < width; x++)
+                {
+                    image->comps[0].data[offset] = *component++;
+                    image->comps[1].data[offset] = *component++;
+                    image->comps[2].data[offset] = *component++;
+                    image->comps[3].data[offset] = *component++;
+                    offset++;
+                }
+            }
+        }
+        break;
+        }*/
+    }
+
+    opj_image_t* getImage() { return image; }
+
+private:
+    opj_cparameters_t   parameters;
+    opj_event_mgr_t     event_mgr;
+    opj_image_t*        image = nullptr;
+    opj_codec_t*        encoder = nullptr;
+    opj_stream_t*       stream = nullptr;
+    char*               comment_text = nullptr;
+};
 
-	/* catch events using our callbacks and give a local context */
-	opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);			
 
-	/* setup the decoder decoding parameters using user parameters */
-	opj_setup_decoder(dinfo, &parameters);
+LLImageJ2COJ::LLImageJ2COJ()
+	: LLImageJ2CImpl()
+{
+}
 
-	/* open a byte stream */
-	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
 
-	/* decode the stream and fill the image structure */
-	image = opj_decode(dinfo, cio);
+LLImageJ2COJ::~LLImageJ2COJ()
+{
+}
 
-	/* close the byte stream */
-	opj_cio_close(cio);
+bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+{
+    base.mDiscardLevel = discard_level;
+	return false;
+}
 
-	/* free remaining structures */
-	if(dinfo)
-	{
-		opj_destroy_decompress(dinfo);
-	}
+bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
+{
+	// No specific implementation for this method in the OpenJpeg case
+	return false;
+}
 
-	if(!image)
-	{
-		LL_WARNS() << "ERROR -> getMetadata: failed to decode image!" << LL_ENDL;
-		return false;
-	}
+bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
+{
+    JPEG2KDecode decoder(0);
+
+    U32 image_channels = 0;
+    S32 data_size = base.getDataSize();
+    S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
+    bool decoded = decoder.decode(base.getData(), max_bytes, &image_channels, base.mDiscardLevel);
+
+    // set correct channel count early so failed decodes don't miss it...
+    S32 channels = (S32)image_channels - first_channel;
+    channels = llmin(channels, max_channel_count);
+
+    if (!decoded)
+    {
+        // reset the channel count if necessary
+        if (raw_image.getComponents() != channels)
+        {
+            raw_image.resize(raw_image.getWidth(), raw_image.getHeight(), S8(channels));
+        }
+
+        LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
+        return true; // done
+    }
+
+    opj_image_t *image = decoder.getImage();
+
+    // Component buffers are allocated in an image width by height buffer.
+    // The image placed in that buffer is ceil(width/2^factor) by
+    // ceil(height/2^factor) and if the factor isn't zero it will be at the
+    // top left of the buffer with black filled in the rest of the pixels.
+    // It is integer math so the formula is written in ceildivpo2.
+    // (Assuming all the components have the same width, height and
+    // factor.)
+    U32 comp_width = image->comps[0].w; // leave this unshifted by 'f' discard factor, the strides are always for the full buffer width
+    U32 f = image->comps[0].factor;
+
+    // do size the texture to the mem we'll acrually use...
+    U32 width = image->comps[0].w;
+    U32 height = image->comps[0].h;
+
+    raw_image.resize(U16(width), U16(height), S8(channels));
+
+    U8 *rawp = raw_image.getData();
+
+    // first_channel is what channel to start copying from
+    // dest is what channel to copy to.  first_channel comes from the
+    // argument, dest always starts writing at channel zero.
+    for (S32 comp = first_channel, dest = 0; comp < first_channel + channels; comp++, dest++)
+    {
+        llassert(image->comps[comp].data);
+        if (image->comps[comp].data)
+        {
+            S32 offset = dest;
+            for (S32 y = (height - 1); y >= 0; y--)
+            {
+                for (S32 x = 0; x < width; x++)
+                {
+                    rawp[offset] = image->comps[comp].data[y*comp_width + x];
+                    offset += channels;
+                }
+            }
+        }
+        else // Some rare OpenJPEG versions have this bug.
+        {
+            LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed! (OpenJPEG bug)" << LL_ENDL;
+        }
+    }
+
+    base.setDiscardLevel(f);
+
+    return true; // done
+}
 
-	// Copy image data into our raw image format (instead of the separate channel format
-	S32 width = 0;
-	S32 height = 0;
 
-	S32 img_components = image->numcomps;
-	width = image->x1 - image->x0;
-	height = image->y1 - image->y0;
-	base.setSize(width, height, img_components);
+bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
+{
+    JPEG2KEncode encode(comment_text, reversible);
+    bool encoded = encode.encode(raw_image, base);
+    if (encoded)
+    {
+        LL_WARNS() << "Openjpeg encoding implementation isn't complete, returning false" << LL_ENDL;
+    }
+    //return encoded;
+    return false;
+}
 
-	/* free image data structure */
-	opj_image_destroy(image);
-	return true;
+bool LLImageJ2COJ::getMetadata(LLImageJ2C &base)
+{
+    JPEG2KDecode decode(0);
+
+    S32 width = 0;
+    S32 height = 0;
+    S32 components = 0;
+    S32 discard_level = 0;
+
+    U32 dataSize = base.getDataSize();
+    U8* data = base.getData();
+    bool header_read = decode.readHeader(data, dataSize, width, height, components, discard_level);
+    if (!header_read)
+    {
+        return false;
+    }
+
+    base.mDiscardLevel = discard_level;
+    base.setSize(width, height, components);
+    return true;
 }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7d78ec9e3c80bb6f99d3a29379dc11acf68e4409..4fe83f0c45ca5329c15b3996289855e6f289c245 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1825,9 +1825,9 @@ if (WINDOWS)
       ${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll
       ${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
-      ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
+      ${SHARED_LIB_STAGING_DIR}/Release/openjp2.dll
+      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjp2.dll
+      ${SHARED_LIB_STAGING_DIR}/Debug/openjp2.dll
       ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
       ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de5ac5ed3da126099e5e37df294ee632d7c2f175..a1d2d12779454fec83c6c7a6aad2fd01fb2b5779 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -518,7 +518,7 @@ def construct(self):
                 self.path("alut.dll")
 
             # For textures
-            self.path("openjpeg.dll")
+            self.path("openjp2.dll")
 
             # Uriparser
             self.path("uriparser.dll")
@@ -1498,7 +1498,7 @@ def construct(self):
             self.path("libdirectfb-1.*.so.*")
             self.path("libfusion-1.*.so.*")
             self.path("libdirect-1.*.so.*")
-            self.path("libopenjpeg.so*")
+            self.path("libopenjp2.so*")
             self.path("libdirectfb-1.4.so.5")
             self.path("libfusion-1.4.so.5")
             self.path("libdirect-1.4.so.5*")