Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Robot with AdderLink iPEPS [feeling blue]

Help
Castor Fu
2011-02-08
2013-02-18
  • Castor Fu
    Castor Fu
    2011-02-08

    I'm trying to use TPlan robot with the AdderLink iPEPS IP KVM.  AdderLink's product is a RealVNC-based server.

    I've had several problems so far.  The first one was that the iPEPS unit would drop the connection when using the default encoding requested by TPlan robot.

    I worked around this by making "RAW" format the default. 

    The second problem is that the colors seem to be getting messed up.  Everything looks bluish.  I believe the problem here is that the VNC server is serving 16-bit pixels in raw encoding, and that there is no translation step to the native color model.

    Any suggestions?
    Thanks.

     
  • Robert Pes
    Robert Pes
    2011-02-08

    The bluish screen can not be in general caused by an encoding unless there's a bug in the code. All encodings basically transfer the same image data (pixels) of the remote screen and differ just in the compression and format. As the pixels are in standard RGB, no translation to native colors is needed.

    The last time I saw a bluish screen was on Mac 10.5 PPC. The issue was that the server used big endian order of RGB components which were read by Robot mistakenly as little endian (in fact as BGR). This caused swapping of red for blue and it was at the time described as "bluish cast" on the screen which is very similar to what you mention.

    This bug has been however fixed several years ago. I checked the code once again and I do not see any obvious bug. To verify whether this is the problem you would have to run Robot as follows and check the console (command prompt) output:

    java -Dvncrobot.rfb.debug=true -jar robot.jar

    This flag activates RFB debug messages. Search for the pixel format (somewhere close to line 15) and check the Big Endian flag. Most desktop servers nowadays use the little endian order and the flag is set to false. If your output says that it is true, it is worth of further experimenting.

    Another obvious question is whether you may connect successfully with another VNC viewer. If you can do that and you see the correct image with the same encoding and pixel format settings, it would indicate a bug on Robot's side.

    You may try to play with the pixel format parameter in RFB preferences and test both configurations where (1) the client accepts the pixel format suggested by the server and (2) the client requests a custom pixel format. If this doesn't help, all I can suggest you is to tweak the bigEndian flag in the com.tplan.robot.remoteclient.rfb.PixelFormat class, rebuild the code and retry.

     
  • Castor Fu
    Castor Fu
    2011-02-08

    Thanks for the quick reply.

    If I set the pixel format explicitly rather than letting the server define it then the colors are not garbled.

    The default pixel settings from the server are as follows:

    S2C/ServerInit: Connected to '' (800x600)S2C/ServerInit: Server suggests following pixel format:
       Bits per pixel: 16
       Color depth:    15
       Big endian:     false
       True color:     true
       Red max:        31
       Green max:      31
       Blue max:       31
       Red shift:      10
       Green shift:    5
       Blue shift:     0

    which differ slightly from the 16-bit pixel format which tplan robot chooses:
    S2C/ServerInit: Connected to '' (800x600)S2C/ServerInit: Server suggests following pixel format:
       Bits per pixel: 16
       Color depth:    15
       Big endian:     false
       True color:     true
       Red max:        31
       Green max:      31
       Blue max:       31
       Red shift:      10
       Green shift:    5
       Blue shift:     0

    I had not tried the 16 bit setting before.  Thanks for the suggestion.  The 24-bit suggestion resulted in horrible performance
    bit it seems to be running ok in 16-bit mode.  As you can see, both use little-endian formatting for the data.

    So they are different pixel formats, (as you pointed out, the encoding should not matter.).

    -castor

     
  • Robert Pes
    Robert Pes
    2011-02-09

    The pixel format shown above is indeed a bit unusual. Each pixel is encoded in 16 bits where each of the R, G, B components has 5 bits. This leaves 1 bit unused. Other servers usually in this situation use 6 bits for one of the components, typically for green. I'm glad to hear that forcing the client use this standard format works as expected.

    If you see performance issues, try moving various encodings to the first place in the list. The Raw one is the slowest one because it transfers the pixel data in raw uncompressed format. It should not be used in the first place as long as the server can work with other encoding(s). Most servers support Hextile and/or RRE/CoRRE which provide at least some compression of the image data while not spending too much CPU resources to decode it.

     
  • tomuo
    tomuo
    2011-06-02

    I am evaluating 2.0.6 against my product which uses 8 bit palettized (non true color) native format.
    I see exactly the same problem, colors are all wrong unless you specify an explicit setting.

    With a friend's help, we debugged the code and found a bug in the PixelFormat class.    Even after the color map (i.e. palette) has been received from the server, the first update request still has "initialized = false", so the colorModel gets overwritten with the default DirectColorModel.
    Also getColorMap is garbling the R,G and B values,  it recreates the U16 correctly by shifting and concatenating the values, but then casts it back to a byte, stripping off the interesting part of the RGB intensitiy.

    patch to follow.

     
  • tomuo
    tomuo
    2011-06-02

        public void setColorMap(int offset, int length, byte colorData) {
            final int cnt = colorData.length;
            final int size = cnt / 6;
            byte red = new byte;
            byte green = new byte;
            byte blue = new byte;
            int index;

            for (int i = 0; i < size; i++) {
                index = i * 6;
                if (bigEndian) {
    -               red_ = (byte) ((colorData << 8) + colorData);
    +               red = (byte) (colorData);
    -               green = (byte) ((colorData << 8) + colorData);
    +               green = (byte) (colorData);
    -               blue = (byte) ((colorData << 8) + colorData);
    +                blue = (byte) (colorData );
                } else {
    -               red = (byte) ((colorData << 8) + colorData);
    +               red = (byte) (colorData );
    -                green = (byte) ((colorData << 8) + colorData);
    +                green = (byte) (colorData);
    -                blue = (byte) ((colorData << 8) + colorData);
    +                blue = (byte) (colorData);
                }
            }
            colorModel = new IndexColorModel(bitsPerPixel, red.length, red, green, blue);
    +       initialized = true;
        }
    _

     
  • tomuo
    tomuo
    2011-06-02

    Actually, looking at it further, the protocol specified under SetColourMapEntries says nothing about the endian of the RGB color intensities in the message - so I suspect they should be interpreted as Big Endian (on the network stream), and the
    if (bigEndian) statement can be removed.
    With my product and "RealVNC 4.13", setting the color level to medium "256"  lets it handshake in non-true color (palette) mode, and the colors are displayed correctly, so the SetColourMapEntries RGB entries should indeed be big-endian even though the server is little endian.  i.e. The Endian flag is only  used during UpdateRequest.

     
  • Robert Pes
    Robert Pes
    2011-06-05

    Thanks a lot for your research!

    As Robot was originally being developed against 16-bit+ true color PC desktops, the low color legacy modes didn't get much attention and functionality of the SetColourMapEntries message has not been tested properly.

    You are right about the big endian flag. It shouldn't be there. Just opposite to what you say the data is in little endian order (least significant value first) and that is why it's enough to read just the first byte of the 2-byte unsigned short color value. It is not even necessary to cast the value to byte which makes the code even shorter. 

    While testing the fix I discovered another potential issue. Though I have never seen it to happen in real client-server communication, the SetColourMapEntries message may be used to define the initial color map or to update the previously defined one or its part. The latter operation is however not handled properly in the code. The PixelFormat class must actually store the RGB component arrays as member variables to keep track of the previously defined intensities. Also the "first color" offset delivered in the message must be added to the color index.

    I also discovered a problem in the readSetColorMapEntries() method of the RfbClientImpl class. The color map byte buffer is retrieved from the stream using read() which doesn't guarantee that it reads all the data in one go. This caused the connection to crash intermittently right after the SetColourMapEntries message. I have updated the code to call readFully() instead.

    Both the RfbClientImpl and PixelFormat classes have been committed to the CVS. The fixes will be included in the 2.0.7 release (no schedule yet). If you build from the source  please help yourself to the updated code.

    Thanks for your help!