Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
5.8 KiB

4 years ago
  1. AVI and Palettes
  2. ----------------
  3. This is an overview of AVI's use of palettes: there are some small
  4. complexities beyond this that are not generally significant.
  5. Palette Sources
  6. ---------------
  7. When playing on a palettised display, AVI must use a palette for
  8. drawing the frames. It gets these palettes from one of these places:
  9. - from the AVI file header. Attached to the DIB header at the
  10. start of an 8-bit file will be a colour table (an array of 4-byte
  11. RGBQUAD values). The frame DIBs will consist of indices into this
  12. table. In addition, new palettes can appear throughout the movie
  13. to be used for frames from that point onwards.
  14. - from the dither proc. If the movie is a higher colour
  15. resolution, drawdib will dither it to the display colour resolution.
  16. In the case of 8-bit displays, 16 and 24-bit videos will be dithered
  17. to a standard 256-colour palette created in drawdib\dith775.c which
  18. has 7 levels of red and green and 5 levels of blue.
  19. - from the codec. If the video is a higher colour resolution
  20. and being decompressed to 8-bit palettised, the codec will supply the
  21. palette. for example, the Video 1 codec will decompress 16-bit CRAM
  22. videos directly to 8-bit pal using the standard 7-7-5 palette (same
  23. as the dither code's palette).
  24. - 4-bit displays will always use the 16-colour VGA palette.
  25. In all of the cases, once we have a frame fully decompressed/dithered
  26. and ready to draw, it is a DIB that consists of a series of indices
  27. into one of these palettes. We may also have:
  28. - A client palette: a palette handle can be sent us from the
  29. client. This represents the palette used by the window we are playing
  30. in. We need to draw using this palette to avoid redraws of the
  31. surrounding window when playing in place. In this case we need to
  32. deal with two palettes: the palette containing the colours actually
  33. used in the DIBs (from the avi file or supplied by dither/codec), and
  34. the palette we need to draw with, supplied by the client.
  35. Using The Palette
  36. -----------------
  37. We draw the frame using SetDIBitsToDevice (or possibly
  38. StretchDIBits). This will interpret the DIB bits in one of two ways
  39. depending on the fuColorUse flag (in fact there are more than two,
  40. but we only use these)
  41. DIB_PAL_INDICES: this means that the bytes in the DIB are
  42. indices directly into the system palette.
  43. DIB_PAL_COLORS the bytes in the DIB are indices into a colour table
  44. supplied as the bmiColors field of the bitmapinfoheader supplied.
  45. This colour table must contain indices into the logical palette
  46. selected into the DC (the header including colour table, and the DC
  47. are supplied as arguments).
  48. The DIB_PAL_COLORS case is slower since GDI has to translate the DIB
  49. bytes once using the bmiColors table, and then once again from the
  50. logical palette of the DC to the system palette. However, since we
  51. can't realistically change the DIB data, we can only use
  52. DIB_PAL_INDICES if the system palette is the same as our palette,
  53. which depends on the RealizePalette behaviour:
  54. Realizing Palettes:
  55. -------------------
  56. Before drawing the DIB, we select the palette we want to draw with
  57. into the DC and then call RealizePalette. This has one of two
  58. behaviours:
  59. - if we are the foreground app, RealizePalette assigns entries in the
  60. system palette to contain the colours in our logical palette. The
  61. system keeps some entries in the palette with standard colours in
  62. (the first 10 and last 10 entries) - these are the 'static' colours;
  63. it will allow us to use the remaining entries.
  64. - if not, RealizePalette creates a mapping between our logical
  65. palette and the nearest colours in the current system palette.
  66. When a foreground app realizes a palette, it changes entries in the
  67. system palette, and all other apps need to re-Realize their palettes
  68. in order to get a mapping to the new system palette (unless they are
  69. only using the default, static colours). Thus when we start playing a
  70. video, all other palette-aware apps change colours (when the system
  71. palette changes) and then redraw with the mapping to the new system
  72. palette.
  73. Support for DIB_PAL_INDICES.
  74. ---------------------------
  75. Using DIB_PAL_INDICES is only possible if the system palette not only
  76. contains all our colours, but in exactly the same order. To ensure
  77. that this is possible, AVI palettes are generally created containing
  78. the static colours as the first and last 10 colours, and
  79. movie-specific colours in between. Thus when we are foreground and
  80. realize the palette, the system palette will end up exactly the same
  81. as the movie palette, and we can use DIB_PAL_INDICES with its
  82. significant performance benefits.
  83. Whenever the system palette changes, we compare all the colours in
  84. the system palette with the colours in our DIBs. If the two colour
  85. tables are the same, we know it is safe to use DIB_PAL_INDICES. If
  86. not, then we use DIB_PAL_COLORS with a colour table. This colour
  87. table maps the contents of the DIB to the logical palette: this is a
  88. no-op, since the logical palette for our dc is the same as the DIB
  89. palette. The real translation is being done between the logical
  90. palette and the current system palette, and this is set up by GDI
  91. when we issue a 'realizepalette' call.
  92. Support for client Palettes
  93. ---------------------------
  94. We are sometimes given a client palette to use (mplayer does this if
  95. playing in place, in an app that is using a non-default palette). The
  96. reason for this is to avoid the flash and re-draw of the client app
  97. that would be necessary if we realized our palette and changed the
  98. system palette. In this case, we select the client palette as our dc
  99. palette, and we build a colour table that maps entries in our palette
  100. to the nearest entry in the client palette. When we then draw - using
  101. DIB_PAL_COLORS - GDI will use this colour table to translate between
  102. the DIB palette and the DC's logical palette ( which is the client
  103. app's palette), and then will translate between the logical palette
  104. and the system palette (probably the same).