I think we can do much better than that if we don't allow arbitrary mazes, but add some constraints such as no one-way passages and closed outer walls (except for entry/exit). In this case, you actually need LESS than 4 bits per tile, provided you choose an encoding order (for example, top/down, left/right, just because that's my writing direction). In fact, you need *at most* two bits per tile!
Let's see why.
Anyway, I really don't feel like coding such a compression algorithm at the moment, so I've been focusing on improving the #FingerMaze presentation, which is … not easy. Here's what I would like to do: the maze is always defined in “landscape” mode (rows <= cols), and it should always fit the viewport. When the viewport aspect ratio doesn't match the maze orientation, the maze is rotated to fit (and movement is correctly remapped).
Simple right?
AHAHAHA NO.
The maze itself is represented by an HTML table, which is actually rather straightforward.
There's some JavaScript involved in getting the sizing right without depending on too many experimental features —but it doesn't work when rows or cols is high, at least not in a cross-browser compatible way. So now I'm experimenting with different ways to do it.