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 <[email protected]> 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 > >
