Q:

How can I update a large legacy codebase to meet specific quality standards?

There is a lot of information about tools and techniques for improving legacy codebases, but I haven't come across any successful real world case studies.  Most advice is on the micro level, and while helpful, doesn't convince many people because of a lack of evidence it can help at the macro level.
I am looking specifically for incremental improvements that have been proven to be a success in the real world when updating a large legacy codebase to meet today's quality standards, and not a complete rewrite.
Before:

Large: greater than 1MLOC
Legacy: no automated tests
Poor quality: high complexity, high coupling, high escaped defects

After

Automated tests
Easier updates/maintenance
High quality: lowered complexity, decoupled code, few escaped defects

What kind of incremental steps have been proven in the real world to update a large legacy codebase successfully to meet above quality standards, without going through a total rewrite?
If possible, include an example company or case study of a large legacy project that has gone through a "successful" quality improvement process in your answer to back it up.

A:

Books like http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 should be witness enough to how large, legacy poor quality code bases are common in the industry.
My guess at why you have not heard or seen, and, more importantly, you will never likely hear about them until you work on one of them yourself, is, nobody seems capable for various reasons, to come out clean and say that their code base was all the above without facing non-trivial repercussions.
This could explain the dearth of studies you speak of.  If you read enough books, for example, Peter van der Linden's Deep C Secrets, you will read about million dollar bugs where the part about which project had them will be missing.
NOTE: I wanted to make this a comment, but it was too long.  I understand this does not answer the question fully.
EDIT: C++11 & The long term viability of GCC is questioned -- if the developers refactor GCC and make it more toolable as LLVM/clang, it might provide a good example.  The discussion notes that the documentation is poor at some places pushing the entry barrier for new developers higher.

A:

On February 3, 2013, Michael Meeks, one of the LibreOffice developers, is giving a talk in a couple of days entitled, "LibreOffice: cleaning and re-factoring a giant code-base, or why re-writing it would be even worse."  It sounds like exactly what you're asking for: a discussion of what they've done to take " a poorly-understood, gigantic code-base extensively commented in German, with no unit tests, a tangled build infrastructure, and twenty-five years of un-paid technical debt" and modernize it.
The presentation can be streamed online, and (I think) recordings will be available at some future date.

A:

I've actually been through a fairly significant refactoring three times in my career.  Code has a tendency to decay, so if your code base is around long enough, a large refactor is pretty much unavoidable.  All my examples were on private code bases, which might explain why public examples are hard to find.
The first time was an application which, believe it or not, had a fundamental architecture that made it only work with dot matrix printers.  When my company could no longer find a vendor to supply the ribbons, they assigned me to make it work with a laser printer.
The second time was a migration of several hundred automated test scripts from C to Java, partly because we needed better cross platform capability, and partly because it was getting difficult to hire new C developers.
The third time I am still in the middle of, which is modularizing a huge monolithic application to allow unit testing by reducing coupling, and for cross platform purposes.
I compare the effort to climbing a mountain.  You have this huge goal ahead of you, but you don't tackle it at the macro level.  You take it one handhold at a time, always having a close fallback position, never disconnecting the previous safety until the next one is in place.  You start out just making small incremental improvements, and after a while you turn around and there's suddenly this beautiful view.
Let's say you have 60,000 files of highly coupled code, for example.  You want to start putting it under unit test, but the dependencies make it impossible.  How do you fix it?  You decouple one file.  You add automated tests.  You get back to stable ground before moving on.  Repeat 59,999 times.
If that sounds simple, that's because it is simple.  It's not easy, but it's simple.  It's hard to notice any progress at first.  We are two years into what seemed an impossible refactor, and likely have years ahead of us until we're finished, but looking back we suddenly realize how much better the code has gotten already, and we have been able to continue to deliver new functionality to our customers in the mean time.
The other two times worked the same way.  You find the smallest safe step you can take, and you take it, always keeping the application in a working state.  You only worry about the big picture to make sure you're heading in the right direction.  All your actions are small, steady, and incremental.

