========================================================================================================================
========================================================================================================================

These are notes to accompany the ATEN iKVM "AST2100" (0x59) encoding implementation that this branch contains.

This implementation is the product of clean-room reverse engineering (that is, I am not and have never been subject to
nondisclosure agreements, nor have I had access to proprietary information, related to the subject matter of this
project).

(c) Copyright 2015-2016 Kevin Kelley <kelleyk@kelleyk.net>

========================================================================================================================
========================================================================================================================

- three major parts of implementation

- Text/console quality in 4:4:4 will ALSO be higher because that's the only mode where VQ blocks happen, and VQ blocks
  give very high quality for blocks containing only a few colors.

- Currently unchecked, but we expect to get a "video settings changed" message from the Ast2100Decoder after the first
  framebuffer update message that we send it following a settings change command.

========================================================================================================================
========================================================================================================================

- Much more extensive notes on the reverse engineering process, the iKVM protocol, the 0x59 video encoding, and the rest
  of this adventure are forthcoming!  There is also a Python implementation of many of these ideas that is
  better-documented (and where clarity has not been sacrificed for performance).  Stay tuned!

- Current problems / limitations (aka "TODOs")

  - Especially on lower quality settings, you will notice that the picture is not as clear as what the ATEN iKVM client
    will show you (using the same settings).  I'm aware of this issue and intend to fix it.

  - The code could stand to be much better-tested.

  - The JavaScript files related to the AST2100 decoder are loaded even when noVNC does not use the decoder.  It would
    be nice to lazy-load them only when they are necessary.

  - Lots of globals (functions, constants, etc.) are exposed.  Some quick refactoring could tuck the majority of them
    away to avoid cluttering the namespace.

  - There is not any UI associated with sending messages to control power or to change picture mode/quality settings.

- Profiling

  - For some reason, when I use blitImageData() (with the noVNC render queue disabled), that function shows up as the
    "heaviest" function in Chrome's CPU profiler, even though the function is doing nothing other than evaluating a
    branch condition or two and then calling _rgbxImageData().  When I call _rgbxImageData() directly, then
    putImageData() (the Canvas method that's actually doing the heavy lifting) is correctly shown as the "heaviest"
    function.

  - Profiler oddness aside, putImageData() is overwhelmingly the dominant cost; it seems to occupy 75-85% of the CPU
    time that noVNC uses.  There are plenty of places that we could get small performance improvements in Ast2100Decoder
    (and elsewhere in noVNC) but they seem unlikely to have a worthwhile impact, given that fact.

- About the implementation

  - One large, remaining inefficiency is the several times that image data is copied around before being blitted.  The
    Ast2100Decoder class generates as output 256-element arrays (representing 64 pixels as (R,G,B,A) 4-tuples).  This is
    exactly what winds up in the ImageData object that is eventually passed to putImageData(); we could just have the
    decoder write its output directly into those arrays if we wanted.

- Performance questions

  - Is it faster to call putImageData() fewer times with larger buffers?  We could collect groups of blocks (or even an
    entire frame) and then call putImageData() once.  (Of course, this would require redrawing unchanged regions every
    frame, too.)

  - Can we use WebGL instead of Canvas?
