Quick question: is the input image always going to be the same size, and the output shape always going to be the same? If so then there’s a cheating way of doing it by preparing an offline mapping.
Basically you set up a texture with a column of 0x000000, then a column of 0x000004, etc. Render it with JOGL with antialiasing disabled and dump to file. Repeat with horizontal rather than vertical lines. The colour values in the files can be processed into sub-pixel texture coordinates (to the quarter-pixel) which you can then apply to an arbitrary image. If you want antialiased edges then you repeat with a texture of full-white on a full-black background to get the alpha channel.