You have lots of choices, and it depends on how much effort you want to put in, and what constraints you have regarding the execution platform.
Many developers would simply make System.exec() calls to external decode/encode/label executables, writing the intermediate files to disk. This is slightly clunky, but once it's set up properly, it works.
A more sophisticated option is to use libraries such as the ones you've found. You can still use the filesystem to temporarily store the uncompressed version.
You can, however, avoid storing the intermediate step -- and maybe make it faster -- by pipelining. You need to feed the output of the decoder as the input of the encoder, and set them both going.
The details of this depends on the API. If you're lucky, they can work with chunks, and you may be able to manage them in a single thread.
If they work with streams, you might need to get your hands dirty and work with threads. One thread for the encoder, one for the decoder.