Bitwise puzzle in com.sun.glass.ui.monocle.Framebuffer
Nir Lisker
nlisker at gmail.com
Sat Nov 17 13:40:43 UTC 2018
Hi John,
I agree with your math. I guess you could submit an enhancement request to
have it evaluated.
- Nir
On Mon, Nov 5, 2018 at 8:21 PM John Neffenger <john at status6.com> wrote:
> I am completely puzzled by the bitwise operations in the Framebuffer
> class (package com.sun.glass.ui.monocle). I'm overriding its methods to
> support a "Y8" 8-bit grayscale frame buffer, yet I have no idea why it's
> doing what it's doing. Can anyone shed light on its complexity?
>
> The Framebuffer class converts a buffer with 32-bit pixels in ARGB32
> format into a buffer with 16-bit pixels in RGB565 format, as illustrated
> below for one pixel.
>
> aaaa aaaa rrrr rrrr gggg gggg bbbb bbbb
> --> rrrr rggg gggb bbbb
>
> I would convert the pixels with a method like the following:
>
> void copyNextPixel(IntBuffer source, ShortBuffer target) {
> int pixel32 = source.get();
> int r = (pixel32 >> 8) & 0xF800;
> int g = (pixel32 >> 5) & 0x07E0;
> int b = (pixel32 >> 3) & 0x001F;
> int pixel16 = r | g | b;
> target.put((short) pixel16);
> }
>
> The JavaFX Framebuffer class converts the pixels like this:
>
> void copyNextPixelOriginal(IntBuffer source, ShortBuffer target) {
> int pixel32 = source.get();
> int r = ((((pixel32 >> 19) & 31) * 539219) >> 8) & (31 << 11);
> int g = ((((pixel32 >> 10) & 63) * 265395) >> 13) & (63 << 5);
> int b = (((pixel32 >> 3) & 31) * 539219) >> 19;
> int pixel16 = r | g | b;
> target.put((short) pixel16);
> }
>
> Both of these methods produce identical results when tested against all
> 16,777,216 possible 24-bit RGB values. To understand what is happening,
> I show each step in the creation and positioning of the 5-bit red color
> value for both algorithms below (best viewed in a monospaced font).
>
> My version
> int r = (pixel32 >> 8) & 0xF800;
>
> ____ ____ xxxx xxxx ____ ____ ____ ____ pixel32 (x = red)
> ____ ____ ____ ____ xxxx xxxx ____ ____ >> 8
> 0000 0000 0000 0000 xxxx x000 0000 0000 & 0xF800
>
> JavaFX version
> int r = ((((pixel32 >> 19) & 31) * 539219) >> 8) & (31 << 11);
>
> ____ ____ xxxx xxxx ____ ____ ____ ____ pixel32 (x = red)
> ____ ____ ____ ____ ____ ____ ___x xxxx >> 19
> 0000 0000 0000 0000 0000 0000 000x xxxx & 31 = 0x1F
> 0000 0000 xxxx x___ ____ ____ ____ ____ * 539219 = 2^19 + 14931
> 0000 0000 0000 0000 xxxx x___ ____ ____ >> 8
> 0000 0000 0000 0000 xxxx x000 0000 0000 & (31 << 11) = 0xF800
>
> Why all the back and forth? Why introduce varying bits to the right of
> the red color value (* 539219), only to clear those bits later? The last
> three steps could be replaced with a single logical shift left operation
> (<< 11).
>
> The Framebuffer class was added to the repository on January 21, 2014,
> by Daniel Blaukopf.
>
> Thank you,
> John
>
>
More information about the openjfx-dev
mailing list