Previous attempts to fix this had failed, because the approaches were similar in that they fed a byte[] -> DataBuffer -> WritableRaster -> BufferedImage, in such a way that the bytes were not being explicitly described as ARGB, RGB, BGR, or BGRA. Different JVMs, on different platforms, made different assumptions about the ordering.
While working on JBIG2 integration in PDF-9, optimising the code to not redundantly allocate memory, I recognised that the appoach used there, of creating the BufferedImage with an explicit type, of BufferedImage.TYPE_INT_ARGB, could be adapted here. In PDF-9, I took the pre-existing code, that created a BufferedImage (which internally allocates an int[] backed raster), and then explicitly allocates an int[], and replaces the internally created one with the explicitly created one. I then altered the code to not allocate an explicit int[], but simply access the internally created one, and fill it with the pixel data. So, the idea was to translate that technique over, but instead of using int[] and TYPE_INT_ARGB, use byte[] and TYPE_4BYTE_ABGR or TYPE_3BYTE_BGR. That way when not using alpha, we'd still only use 3 bytes per pixel, and only use 4 bytes per pixel when using alpha.
Unfortunately, that didn't fix anything. Instead of further investigation as to how to re-order the bytes, I decided to simply use the int[] and TYPE_INT_ARGB. Along with that, I could then replace the implicit access to the red green blue and alpha, via array indexes, with explicit access to each component. The drawback being that we always use 4 bytes per pixel, even without alpha.
One benefit to memory usage, of the new approach, over the old one, is that the old one used a byte[] output stream, which dynamically grew as it built up the byte[]. The negative side-effect of that was that it would typically over-grow. And trimming it down to size would require allocating an intermediary byte[] and copying between them. That could get costly. The new approach uses an exactly size int[] and fills it without any intermediary buffer, let alone a dynamically sized one.
Testing shows that the colours are now as they should be, both for alpha and non-alpha RGB images.
Subversion 20103
icepdf\core\src\org\icepdf\core\pobjects\Stream.java
The issue of red and blue switching, with transparency, is fixed. Any other colour switching is due to other issues, and should be put under a different jira, specific to that other cause.