Commits

simon_linden committed 631214d Merge

Merge latest from lindenlab/viewer-development

Comments (0)

Files changed (31)

 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
 5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
+11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start
+11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start
+e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start

indra/integration_tests/llimage_libtest/llimage_libtest.cpp

 "        be used. Blocks must be smaller than precincts. Like precincts, this option adds\n"
 "        PLT, tile markers and uses RPCL.\n"
 "        Only valid for output j2c images. Default is 64.\n"
+" -l, --levels <n>\n"
+"        Number of decomposition levels (aka discard levels) in the output image.\n"
+"        The maximum number of levels authorized is 32.\n"
+"        Only valid for output j2c images. Default is 5.\n"
 " -rev, --reversible\n"
 "        Set the compression to be lossless (reversible in j2c parlance).\n"
 "        Only valid for output j2c images.\n"
 }
 
 // Save a raw image instance into a file
-bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, bool reversible, bool output_stats)
+bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, int levels, bool reversible, bool output_stats)
 {
 	LLPointer<LLImageFormatted> image = create_image(dest_filename);
 	
 	{
 		// That method doesn't exist (and likely, doesn't make sense) for any other image file format
 		// hence the required cryptic cast.
-		if ((blocks_size != -1) || (precincts_size != -1))
+		if ((blocks_size != -1) || (precincts_size != -1) || (levels != 0))
 		{
-			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size);
+			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size, levels);
 		}
 		((LLImageJ2C*)(image.get()))->setReversible(reversible);
 	}
 	int discard_level = -1;
 	int precincts_size = -1;
 	int blocks_size = -1;
+	int levels = 0;
 	bool reversible = false;
 
 	// Init whatever is necessary
 			else
 			{
 				precincts_size = atoi(value_str.c_str());
-				// *TODO: make sure precincts_size is a power of 2
 			}
 		}
 		else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b"))
 			else
 			{
 				blocks_size = atoi(value_str.c_str());
-				// *TODO: make sure blocks_size is a power of 2
+			}
+		}
+		else if (!strcmp(argv[arg], "--levels") || !strcmp(argv[arg], "-l"))
+		{
+			std::string value_str;
+			if ((arg + 1) < argc)
+			{
+				value_str = argv[arg+1];
+			}
+			if (((arg + 1) >= argc) || (value_str[0] == '-'))
+			{
+				std::cout << "No valid --levels argument given, default (5) will be used" << std::endl;
+			}
+			else
+			{
+				levels = atoi(value_str.c_str());
 			}
 		}
 		else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev"))
 		// Save file
 		if (out_file != out_end)
 		{
-			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, reversible, image_stats))
+			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, levels, reversible, image_stats))
 			{
 				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;
 			}

indra/llimage/llimage.h

 
 const S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2
 const S32 MAX_IMAGE_MIP = 11; // 2048x2048
+
+// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number 
+// of levels is read from the header's file, not inferred from its size.
 const S32 MAX_DISCARD_LEVEL = 5;
 
+// JPEG2000 size constraints
+// Those are declared here as they are germane to other image constraints used in the viewer
+// and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL.
+const S32 MAX_DECOMPOSITION_LEVELS = 32;	// Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
+const S32 MIN_DECOMPOSITION_LEVELS = 5;		// the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
+const S32 MAX_PRECINCT_SIZE = 2048;			// No reason to be bigger than MAX_IMAGE_SIZE 
+const S32 MIN_PRECINCT_SIZE = 4;			// Can't be smaller than MIN_BLOCK_SIZE
+const S32 MAX_BLOCK_SIZE = 64;				// Max total block size is 4096, hence 64x64 when using square blocks
+const S32 MIN_BLOCK_SIZE = 4;				// Min block dim is 4 according to jpeg2000 spec
+
 const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
 const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
 const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE;

indra/llimage/llimagej2c.cpp

 	return mImpl->initDecode(*this,raw_image,discard_level,region);
 }
 
-BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size)
+BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
 {
-	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size);
+	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size,levels);
 }
 
 BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)

indra/llimage/llimagej2c.h

 	/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string());
 	
 	BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region);
-	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size);
+	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels);
 	
 	// Encode with comment text 
 	BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0);
 	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
 							BOOL reversible=FALSE) = 0;
 	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0;
-	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1) = 0;
+	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0;
 
 	friend class LLImageJ2C;
 };

indra/llimagej2coj/llimagej2coj.cpp

 	return FALSE;
 }
 
-BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size)
+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;

indra/llimagej2coj/llimagej2coj.h

 	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
 								BOOL reversible = FALSE);
 	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);
+	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
 };
 
 #endif

indra/llkdu/llimagej2ckdu.cpp

 
 #include "lltimer.h"
 #include "llpointer.h"
+#include "llmath.h"
 #include "llkdumem.h"
 
 
 mRawImagep(NULL),
 mDecodeState(NULL),
 mBlocksSize(-1),
-mPrecinctsSize(-1)
+mPrecinctsSize(-1),
+mLevels(0)
 {
 }
 
 	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);
 }
 
-BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size)
+BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
 {
+	mPrecinctsSize = precincts_size;
+	if (mPrecinctsSize != -1)
+	{
+		mPrecinctsSize = get_lower_power_two(mPrecinctsSize,MAX_PRECINCT_SIZE);
+		mPrecinctsSize = llmax(mPrecinctsSize,MIN_PRECINCT_SIZE);
+	}
 	mBlocksSize = blocks_size;
-	mPrecinctsSize = precincts_size;
+	if (mBlocksSize != -1)
+	{
+		mBlocksSize = get_lower_power_two(mBlocksSize,MAX_BLOCK_SIZE);
+		mBlocksSize = llmax(mBlocksSize,MIN_BLOCK_SIZE);
+		if (mPrecinctsSize != -1)
+		{
+			mBlocksSize = llmin(mBlocksSize,mPrecinctsSize);	// blocks *must* be smaller than precincts
+		}
+	}
+	mLevels = levels;
+	if (mLevels != 0)
+	{
+		mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MIN_DECOMPOSITION_LEVELS);		
+	}
 	return TRUE;
 }
 
 
 		// Resize raw_image according to the image to be decoded
 		kdu_dims dims; mCodeStreamp->get_dims(0,dims);
+		// *TODO: Use the real number of levels read from the file throughout the code instead of relying on an infered value from dimensions
+		//S32 levels = mCodeStreamp->get_min_dwt_levels();
 		S32 channels = base.getComponents() - first_channel;
 		channels = llmin(channels,max_channel_count);
 		raw_image.resize(dims.size.x, dims.size.y, channels);
-		//	llinfos << "Resizing raw_image to " << dims.size.x << ":" << dims.size.y << llendl;
+		//llinfos << "j2c image dimension: width = " << dims.size.x << ", height = " << dims.size.y << ", channels = " << channels << ", levels = " << levels << llendl;
 
 		if (!mTileIndicesp)
 		{
 			std::string Parts_string = llformat("ORGtparts=R");
 			codestream.access_siz()->parse_string(Parts_string.c_str());
 		}
+		if (mLevels != 0)
+		{
+			std::string levels_string = llformat("Clevels=%d",mLevels);
+			codestream.access_siz()->parse_string(levels_string.c_str());
+		}
 		
 		codestream.access_siz()->finalize_all();
 		codestream.change_appearance(transpose,vflip,hflip);

indra/llkdu/llimagej2ckdu.h

 	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
 								BOOL reversible=FALSE);
 	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);
+	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
 
 private:
 	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
 	kdu_dims *mTileIndicesp;
 	int mBlocksSize;
 	int mPrecinctsSize;
+	int mLevels;
 
 	// Temporary variables for in-progress decodes...
 	LLImageRaw *mRawImagep;

indra/llkdu/tests/llimagej2ckdu_test.cpp

 void kdu_codestream::set_fast() { }
 void kdu_codestream::set_fussy() { }
 void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
+int kdu_codestream::get_min_dwt_levels() { return 5; }
 void kdu_codestream::change_appearance(bool, bool, bool) { }
 void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
 void kdu_codestream::destroy() { }

indra/llmessage/tests/commtest.h

 #include "llhost.h"
 #include "stringize.h"
 #include <string>
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+
+struct CommtestError: public std::runtime_error
+{
+    CommtestError(const std::string& what): std::runtime_error(what) {}
+};
 
 /**
  * This struct is shared by a couple of standalone comm tests (ADD_COMM_BUILD_TEST).
         replyPump("reply"),
         errorPump("error"),
         success(false),
-        host("127.0.0.1", 8000),
+        host("127.0.0.1", getport("PORT")),
         server(STRINGIZE("http://" << host.getString() << "/"))
     {
         replyPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, true));
         errorPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, false));
     }
 
+    static int getport(const std::string& var)
+    {
+        const char* port = getenv(var.c_str());
+        if (! port)
+        {
+            throw CommtestError("missing $PORT environment variable");
+        }
+        // This will throw, too, if the value of PORT isn't numeric.
+        return boost::lexical_cast<int>(port);
+    }
+
     bool outcome(const LLSD& _result, bool _success)
     {
 //      std::cout << "commtest_data::outcome(" << _result << ", " << _success << ")\n";

indra/llmessage/tests/test_llsdmessage_peer.py

 sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
 from indra.util.fastest_elementtree import parse as xml_parse
 from indra.base import llsd
-from testrunner import run, debug
+from testrunner import freeport, run, debug
 
 class TestHTTPRequestHandler(BaseHTTPRequestHandler):
     """This subclass of BaseHTTPRequestHandler is to receive and echo
             self.wfile.write(response)
         else:                           # fail requested
             status = data.get("status", 500)
+            # self.responses maps an int status to a (short, long) pair of
+            # strings. We want the longer string. That's why we pass a string
+            # pair to get(): the [1] will select the second string, whether it
+            # came from self.responses or from our default pair.
             reason = data.get("reason",
                                self.responses.get(status,
                                                   ("fail requested",
         # Suppress error output as well
         pass
 
-class TestHTTPServer(Thread):
-    def run(self):
-        httpd = HTTPServer(('127.0.0.1', 8000), TestHTTPRequestHandler)
-        debug("Starting HTTP server...\n")
-        httpd.serve_forever()
-
 if __name__ == "__main__":
-    sys.exit(run(server=TestHTTPServer(name="httpd"), *sys.argv[1:]))
+    # Instantiate an HTTPServer(TestHTTPRequestHandler) on the first free port
+    # in the specified port range. Doing this inline is better than in a
+    # daemon thread: if it blows up here, we'll get a traceback. If it blew up
+    # in some other thread, the traceback would get eaten and we'd run the
+    # subject test program anyway.
+    httpd, port = freeport(xrange(8000, 8020),
+                           lambda port: HTTPServer(('127.0.0.1', port), TestHTTPRequestHandler))
+    # Pass the selected port number to the subject test program via the
+    # environment. We don't want to impose requirements on the test program's
+    # command-line parsing -- and anyway, for C++ integration tests, that's
+    # performed in TUT code rather than our own.
+    os.environ["PORT"] = str(port)
+    sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:]))

indra/llmessage/tests/testrunner.py

 
 import os
 import sys
+import errno
+import socket
 
 def debug(*args):
     sys.stdout.writelines(args)
 # comment out the line below to enable debug output
 debug = lambda *args: None
 
+def freeport(portlist, expr):
+    """
+    Find a free server port to use. Specifically, evaluate 'expr' (a
+    callable(port)) until it stops raising EADDRINUSE exception.
+
+    Pass:
+
+    portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the
+    range, freeport() lets the socket.error exception propagate. If you want
+    unbounded, you could pass itertools.count(baseport), though of course in
+    practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain
+    the range much more sharply: if we're iterating an absurd number of times,
+    probably something else is wrong.
+
+    expr: a callable accepting a port number, specifically one of the items
+    from portlist. If calling that callable raises socket.error with
+    EADDRINUSE, freeport() retrieves the next item from portlist and retries.
+
+    Returns: (expr(port), port)
+
+    port: the value from portlist for which expr(port) succeeded
+
+    Raises:
+
+    Any exception raised by expr(port) other than EADDRINUSE.
+
+    socket.error if, for every item from portlist, expr(port) raises
+    socket.error. The exception you see is the one from the last item in
+    portlist.
+
+    StopIteration if portlist is completely empty.
+
+    Example:
+
+    server, port = freeport(xrange(8000, 8010),
+                            lambda port: HTTPServer(("localhost", port),
+                                                    MyRequestHandler))
+    # pass 'port' to client code
+    # call server.serve_forever()
+    """
+    # If portlist is completely empty, let StopIteration propagate: that's an
+    # error because we can't return meaningful values. We have no 'port',
+    # therefore no 'expr(port)'.
+    portiter = iter(portlist)
+    port = portiter.next()
+
+    while True:
+        try:
+            # If this value of port works, return as promised.
+            return expr(port), port
+
+        except socket.error, err:
+            # Anything other than 'Address already in use', propagate
+            if err.args[0] != errno.EADDRINUSE:
+                raise
+
+            # Here we want the next port from portiter. But on StopIteration,
+            # we want to raise the original exception rather than
+            # StopIteration. So save the original exc_info().
+            type, value, tb = sys.exc_info()
+            try:
+                try:
+                    port = portiter.next()
+                except StopIteration:
+                    raise type, value, tb
+            finally:
+                # Clean up local traceback, see docs for sys.exc_info()
+                del tb
+
+        # Recap of the control flow above:
+        # If expr(port) doesn't raise, return as promised.
+        # If expr(port) raises anything but EADDRINUSE, propagate that
+        # exception.
+        # If portiter.next() raises StopIteration -- that is, if the port
+        # value we just passed to expr(port) was the last available -- reraise
+        # the EADDRINUSE exception.
+        # If we've actually arrived at this point, portiter.next() delivered a
+        # new port value. Loop back to pass that to expr(port).
+
 def run(*args, **kwds):
     """All positional arguments collectively form a command line, executed as
     a synchronous child process.

indra/newview/app_settings/settings.xml

       <key>Value</key>
         <real>0.25</real>
       </map>
+	<key>Jpeg2000AdvancedCompression</key>
+	  <map>
+      <key>Comment</key>
+        <string>Use advanced Jpeg2000 compression options (precincts, blocks, ordering, markers)</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>Boolean</string>
+      <key>Value</key>
+        <integer>0</integer>
+	  </map>
+	<key>Jpeg2000PrecinctsSize</key>
+	  <map>
+      <key>Comment</key>
+        <string>Size of image precincts. Assumed square and same for all levels. Must be power of 2.</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>S32</string>
+      <key>Value</key>
+        <integer>256</integer>
+	  </map>
+	<key>Jpeg2000BlocksSize</key>
+	  <map>
+      <key>Comment</key>
+        <string>Size of encoding blocks. Assumed square and same for all levels. Must be power of 2. Max 64, Min 4.</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>S32</string>
+      <key>Value</key>
+        <integer>64</integer>
+	  </map>
     <key>KeepAspectForSnapshot</key>
     <map>
       <key>Comment</key>

indra/newview/app_settings/settings_minimal.xml

         <key>Value</key>
             <integer>0</integer>
         </map>
-    <key>EnableVoiceChat</key>
-        <map>
-        <key>Comment</key>
-            <string>Enable talking to other residents with a microphone</string>
-        <key>Type</key>
-            <string>Boolean</string>
-        <key>Value</key>
-            <integer>1</integer>
-        </map>
     <key>HelpURLFormat</key>
         <map>
         <key>Comment</key>

indra/newview/app_settings/settings_per_account.xml

         <key>Value</key>
             <integer>0</integer>
         </map>
+    <key>LastPostcardRecipient</key>
+      <map>
+        <key>Comment</key>
+          <string>Last recipient of postcard</string>
+        <key>Persist</key>
+          <integer>1</integer>
+        <key>Type</key>
+          <string>String</string>
+        <key>Value</key>
+          <string />
+      </map>
     <key>LogNearbyChat</key>
         <map>
         <key>Comment</key>

indra/newview/llbottomtray.cpp

 	else
 	{
 		LLTransientFloaterMgr::getInstance()->addControlView(getChild<LLButton>("speak_btn"));
-		LLTransientFloaterMgr::getInstance()->addControlView(getChild<LLButton>("speak_flyout_btn"));
+		LLTransientFloaterMgr::getInstance()->addControlView(getChild<LLButton>("flyout_btn"));
 	}
 
 
 // because it resets chatbar's width according to resize logic.
 void LLBottomTray::initButtonsVisibility()
 {
-	setVisibleAndFitWidths(RS_BUTTON_SPEAK, gSavedSettings.getBOOL("EnableVoiceChat"));
+	setVisibleAndFitWidths(RS_BUTTON_SPEAK, gSavedSettings.getBOOL("EnableVoiceChat") || !mSpeakBtn );
 	setVisibleAndFitWidths(RS_BUTTON_GESTURES, gSavedSettings.getBOOL("ShowGestureButton"));
 	setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton"));
 	setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton"));
 
 void LLBottomTray::setButtonsControlsAndListeners()
 {
-	gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SPEAK, _2));
+	// always show the speak panel if using the basic skin
+	if (mSpeakBtn)
+	{
+		gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SPEAK, _2));
+	}	
+
 	gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_GESTURES, _2));
 	gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2));
 	gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2));

indra/newview/llfloatersearch.cpp

File contents unchanged.

indra/newview/llfloatersounddevices.cpp

 {
 	LLTransientDockableFloater::postBuild();
 		
-	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_flyout_btn");
+	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("flyout_btn");
 	setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(), LLDockControl::TOP));
 
 	setIsChrome(TRUE);

indra/newview/llpanellogin.cpp

 	gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
 	
 	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
-	web_browser->navigateTo( oStr.str(), "text/html" );
+	if (web_browser->getCurrentNavUrl() != oStr.str())
+	{
+		web_browser->navigateTo( oStr.str(), "text/html" );
+	}
 }
 
 void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)

indra/newview/llpanelvoicedevicesettings.cpp

 				iter != LLVoiceClient::getInstance()->getCaptureDevices().end();
 				iter++)
 			{
-				// Lets try to localize some system device names. EXT-8375
-				std::string device_name = *iter;
-				LLStringUtil::toLower(device_name); //compare in low case
-				if ("default system device" == device_name)
-				{
-					device_name = getString(device_name);
-				}
-				else if ("no device" == device_name)
-				{
-					device_name = getString(device_name);
-				}
-				else
-				{
-					// restore original value
-					device_name = *iter;
-				}
-				mCtrlInputDevices->add(device_name, ADD_BOTTOM );
+				mCtrlInputDevices->add( *iter, ADD_BOTTOM );
 			}
 
 			if(!mCtrlInputDevices->setSimple(mInputDevice))
 			for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin(); 
 				iter !=  LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)
 			{
-				// Lets try to localize some system device names. EXT-8375
-				std::string device_name = *iter;
-				LLStringUtil::toLower(device_name); //compare in low case
-				if ("default system device" == device_name)
-				{
-					device_name = getString(device_name);
-				}
-				else if ("no device" == device_name)
-				{
-					device_name = getString(device_name);
-				}
-				else
-				{
-					// restore original value
-					device_name = *iter;
-				}
-				mCtrlOutputDevices->add(device_name, ADD_BOTTOM );
+				mCtrlOutputDevices->add( *iter, ADD_BOTTOM );
 			}
 
 			if(!mCtrlOutputDevices->setSimple(mOutputDevice))

indra/newview/llviewermessage.cpp

 	{
 		// notification was specified using the new mechanism, so we can just handle it here
 		std::string notificationID;
+		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+		if (!LLNotifications::getInstance()->templateExists(notificationID))
+		{
+			return false;
+		}
+
 		std::string llsdRaw;
 		LLSD llsdBlock;
 		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);

indra/newview/llviewertexturelist.cpp

 	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
 	if (image.isNull())
 	{
+		image->setLastError("Couldn't open the image to be uploaded.");
 		return FALSE;
 	}	
 	if (!image->load(filename))
 	{
+		image->setLastError("Couldn't load the image to be uploaded.");
 		return FALSE;
 	}
 	// Decompress or expand it in a raw image structure
 	LLPointer<LLImageRaw> raw_image = new LLImageRaw;
 	if (!image->decode(raw_image, 0.0f))
 	{
+		image->setLastError("Couldn't decode the image to be uploaded.");
 		return FALSE;
 	}
 	// Check the image constraints
 	}
 	// Convert to j2c (JPEG2000) and save the file locally
 	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);	
+	if (compressedImage.isNull())
+	{
+		image->setLastError("Couldn't convert the image to jpeg2000.");
+		llinfos << "Couldn't convert to j2c, file : " << filename << llendl;
+		return FALSE;
+	}
 	if (!compressedImage->save(out_filename))
 	{
+		image->setLastError("Couldn't create the jpeg2000 image for upload.");
 		llinfos << "Couldn't create output file : " << out_filename << llendl;
 		return FALSE;
 	}
 	LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
 	if (!integrity_test->loadAndValidate( out_filename ))
 	{
+		image->setLastError("The created jpeg2000 image is corrupt.");
 		llinfos << "Image file : " << out_filename << " is corrupt" << llendl;
 		return FALSE;
 	}
 		(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
 		compressedImage->setReversible(TRUE);
 	
-	compressedImage->encode(raw_image, 0.0f);
+
+	if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
+	{
+		// This test option will create jpeg2000 images with precincts for each level, RPCL ordering
+		// and PLT markers. The block size is also optionally modifiable.
+		// Note: the images hence created are compatible with older versions of the viewer.
+		// Read the blocks and precincts size settings
+		S32 block_size = gSavedSettings.getS32("Jpeg2000BlocksSize");
+		S32 precinct_size = gSavedSettings.getS32("Jpeg2000PrecinctsSize");
+		llinfos << "Advanced JPEG2000 Compression: precinct = " << precinct_size << ", block = " << block_size << llendl;
+		compressedImage->initEncode(*raw_image, block_size, precinct_size, 0);
+	}
+	
+	if (!compressedImage->encode(raw_image, 0.0f))
+	{
+		llinfos << "convertToUploadFile : encode returns with error!!" << llendl;
+		// Clear up the pointer so we don't leak that one
+		compressedImage = NULL;
+	}
 	
 	return compressedImage;
 }

indra/newview/llvoicechannel.cpp

 {
 	EState old_state = mState;
 	mState = new_state;
+
 	if (!mStateChangedCallback.empty())
 		mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent);
 }
 		// otherwise answering the call
 		else
 		{
-			LLVoiceClient::getInstance()->answerInvite(mSessionHandle);
-			
+			if (!LLVoiceClient::getInstance()->answerInvite(mSessionHandle))
+			{
+				mCallEndedByAgent = false;
+				mSessionHandle.clear();
+				handleError(ERROR_UNKNOWN);
+				return;
+			}
 			// using the session handle invalidates it.  Clear it out here so we can't reuse it by accident.
 			mSessionHandle.clear();
 		}

indra/newview/skins/default/xui/en/floater_postcard.xml

         Recipient&apos;s Email:
     </text>
     <line_editor
+     control_name="LastPostcardRecipient"
      follows="left|top"
      height="20"
      layout="topleft"

indra/newview/skins/default/xui/en/floater_script_debug_panel.xml

      parse_highlights="true" 
      read_only="true"
      width="420"
+     track_bottom="true" 
      word_wrap="true" />
 </floater>

indra/newview/skins/default/xui/en/floater_sound_devices.xml

  save_rect="true"
  single_instance="true"
  bevel_style="in"
- height="140"
+ height="164"
  layout="topleft"
  name="floater_sound_devices"
  title="Sound Devices"
     left="2"
     top="26"
     class="panel_voice_device_settings"/>
+  <text
+    name="voice_label"
+    top="136"
+    left="12"
+    height="14"
+    width="80"
+    layout="topleft"
+    >Voice Chat</text>
+  <check_box
+    layout="topleft"
+    control_name="EnableVoiceChat"
+    follows="bottom|left"
+    top="138"
+    left="80"
+    name="enable_voice"
+    width="100"
+    height="14"
+    label="Enabled"
+    />
 </floater>

indra/newview/skins/default/xui/en/panel_sound_devices.xml

 	  name="default_text">
 		Default
 	</panel.string>
-	<panel.string
-	  name="default system device">
-		Default system device
-	</panel.string>
-	<panel.string
-	  name="no device">
-		No device
-	</panel.string>
 	<icon
 		   height="18"
 		   image_name="Microphone_On"

indra/newview/skins/minimal/xui/en/panel_bottomtray.xml

         top="5"
      left="0"
      height="23"
-     name="speak_flyout_btn"
+     name="flyout_btn"
      label=""
      tab_stop="false"
      tool_tip="Change your sound preferences"

indra/newview/tests/llxmlrpclistener_test.cpp

 #include "llevents.h"
 #include "lleventfilter.h"
 #include "llsd.h"
+#include "llhost.h"
 #include "llcontrol.h"
 #include "tests/wrapllerrs.h"
+#include "tests/commtest.h"
 
 LLControlGroup gSavedSettings("Global");
 
     {
         data():
             pumps(LLEventPumps::instance()),
-            uri("http://127.0.0.1:8000")
+            uri(std::string("http://") +
+                LLHost("127.0.0.1", commtest_data::getport("PORT")).getString())
         {
             // These variables are required by machinery used by
             // LLXMLRPCTransaction. The values reflect reality for this test
         pumps.obtain("LLXMLRPCTransaction").post(request);
         // Set the timer
         F32 timeout(10);
-        watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
         // and pump "mainloop" until we get something, whether from
         // LLXMLRPCListener or from the watchdog filter.
         LLTimer timer;
         pumps.obtain("LLXMLRPCTransaction").post(request);
         // Set the timer
         F32 timeout(10);
-        watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
         // and pump "mainloop" until we get something, whether from
         // LLXMLRPCListener or from the watchdog filter.
         LLTimer timer;
         pumps.obtain("LLXMLRPCTransaction").post(request);
         // Set the timer
         F32 timeout(10);
-        watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
         // and pump "mainloop" until we get something, whether from
         // LLXMLRPCListener or from the watchdog filter.
         LLTimer timer;

indra/newview/tests/test_llxmlrpc_peer.py

 mydir = os.path.dirname(__file__)       # expected to be .../indra/newview/tests/
 sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
 sys.path.insert(1, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests"))
-from testrunner import run, debug
+from testrunner import freeport, run, debug
 
 class TestServer(SimpleXMLRPCServer):
     def _dispatch(self, method, params):
         # Suppress error output as well
         pass
 
-class ServerRunner(Thread):
-    def run(self):
-        server = TestServer(('127.0.0.1', 8000))
-        debug("Starting XMLRPC server...\n")
-        server.serve_forever()
-
 if __name__ == "__main__":
-    sys.exit(run(server=ServerRunner(name="xmlrpc"), *sys.argv[1:]))
+    # Instantiate a TestServer on the first free port in the specified port
+    # range. Doing this inline is better than in a daemon thread: if it blows
+    # up here, we'll get a traceback. If it blew up in some other thread, the
+    # traceback would get eaten and we'd run the subject test program anyway.
+    xmlrpcd, port = freeport(xrange(8000, 8020),
+                             lambda port: TestServer(('127.0.0.1', port)))
+    # Pass the selected port number to the subject test program via the
+    # environment. We don't want to impose requirements on the test program's
+    # command-line parsing -- and anyway, for C++ integration tests, that's
+    # performed in TUT code rather than our own.
+    os.environ["PORT"] = str(port)
+    sys.exit(run(server=Thread(name="xmlrpc", target=xmlrpcd.serve_forever), *sys.argv[1:]))