height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1) [mapbox/maptiler]
height = (R * 256 + G + B / 256) - 32768 [mapzen terrarium]
If you only care about elevations above sea level (0-8848 meters), you can pack the data into just two bytes maintaining a .13 meter precision (Mapbox precision is .1)
height = (R * 256 + B) / (256 * 256) * 8848 [shademap]
This is the encoding I'm going to use. I've already trialed it and it saves space (I'm not sure about processing time).
The best encoding would be to encode the min elevation for an entire tile in the header and then just store the delta between the tile's min elevation and the elevation for a given pixel. It would be the most space efficient but would involve loading the whole tile data into memory to find the minimum elevation (which is less efficient then streaming and encoding one pixel at a time)