JRiver does smart leveling.
If the playlist has a random collection of tracks from several albums, they will use individual track-based leveling.
If the playlist has full albums, or tracks from the same album played one after the other, they will be leveled as a group, applying one adjustment to all tracks equally, to preserve the album dynamics.
It can mix track-based and album-based leveling together, as it's handled dynamically.
The only case that it does not currently handle, is when you have a custom mix of tracks which you have tagged as a single album. Not a playlist with random tracks, but a collection of tracks that have been tagged as an "album".
If they're tagged as an album, they will be leveled together as one, instead of using individual track-based leveling.
R128 does not use any compression, it only adjusts the volume level of a track up or down.
The target for R128 is set to provide enough headroom that it should not be required.
If a track has so much dynamic range that it cannot be leveled without clipping, JRiver will play it at a lower volume instead of allowing it to clip or compressing it. This is very rare, and applies to less than 10 tracks in my library.