Sorry again that I just don't have much time to dink with this....
[disclaimer: I've really only glanced through the code and article. I have not put the code through any stress tests.]
The code looks good, so no complaints. I'm glad you lowered the dictionary limit. It is true that the dictionary can be arbitrarily large, but there is an upper limit to where growth is actually useful. You've currently got it set to that upper limit (20 bits). Most LZW systems get along just fine at 12 bits. You might want to mention this kind of stuff in your article.
I have more of an issue with the article itself. It
is very wordy, and at time rambles along with your effort to figure this stuff out. People reading the article don't need to know that stuff.
Cut out all the non-essential rambling and trying-to-figure-it-out stuff, and leave it only with the cold technical details of what you have chosen to do.
Don't mention stuff like
endianness (as you are only mentioning it to say that it has nothing to do with the article -- get it?).
You also mention in your code that keeping track of the current bit size complicates your code. Well, yes, but your code knows a lot about it. You should have kept that stuff in a class so that it can take care of itself. (IMHO.)
For example, here's an fairly elegant implementation using C++11
http://marknelson.us/2011/11/08/lzw-revisited/
Notice how his
input_foo_stream<> and
output_foo_stream<> classes handle this so that the calling code remains agnostic about it. (Though there should be some care to watch for things like breached dictionary size, etc.)
Don't aim users at some specific version of a MinGW compiler. Test your code in at
least MSVC and a standard MinGW and a standard (non-Windows) GCC.
Sorry I'm not more help.
[edit] Oh yeah... make sure you stress test your code with evil files!