Uploaded image for project: 'Core ReactOS'
  1. Core ReactOS
  2. CORE-42

RLE Bitmap support in Win32k

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Major
    • None
    • Win32SS
    • None
    • Operating System: ReactOS
      Platform: x86 Hardware

    Description

      ReactOS Win32k.sys (eng/surface.c:136 or there abouts) lacks a implementation
      of RLE4/8 Bitmap support. This keeps us from being able to run our own
      autorun.exe/explorer.exe or use any third party application that has RLE
      encoded resources built in.

      Here is example code on run-length decoding used in WINE. It shouldn't be very
      hard to adapt to use in ReactOS.

      enum Rle_EscapeCodes
      {
      RLE_EOL = 0, /* End of line */
      RLE_END = 1, /* End of bitmap */
      RLE_DELTA = 2 /* Delta */
      };

      /***********************************************************************

      • X11DRV_DIB_SetImageBits_RLE4
        *
      • SetDIBits for a 4-bit deep compressed DIB.
        */
        static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
        DWORD width, DWORD dstwidth,
        int left, int *colors,
        XImage *bmpImage )
        {
        int x = 0, y = lines - 1, c, length;
        const BYTE *begin = bits;

      while (y >= 0)
      {
      length = *bits++;
      if (length) { /* encoded */
      c = *bits++;
      while (length--)

      { if (x >= width) break; XPutPixel(bmpImage, x++, y, colors[c >> 4]); if (!length--) break; if (x >= width) break; XPutPixel(bmpImage, x++, y, colors[c & 0xf]); }

      } else {
      length = *bits++;
      switch (length)
      {
      case RLE_EOL:
      x = 0;
      y--;
      break;

      case RLE_END:
      return;

      case RLE_DELTA:
      x = *bits+;
      y -= *bits++;
      break;

      default: /* absolute */
      while (length--)

      { c = *bits++; if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]); if (!length--) break; if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]); }

      if ((bits - begin) & 1)
      bits++;
      }
      }
      }
      }

      /***********************************************************************

      • X11DRV_DIB_SetImageBits_RLE8
        *
      • SetDIBits for an 8-bit deep compressed DIB.
        *
      • This function rewritten 941113 by James Youngman. WINE blew out when I
      • first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
        *
      • This was because the algorithm assumed that all RLE8 bitmaps end with the
      • 'End of bitmap' escape code. This code is very much laxer in what it
      • allows to end the expansion. Possibly too lax. See the note by
      • case RleDelta. BTW, MS's documentation implies that a correct RLE8
      • bitmap should end with RleEnd, but on the other hand, software exists
      • that produces ones that don't and Windows 3.1 doesn't complain a bit
      • about it.
        *
      • (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
      • James A. Youngman <mbcstjy@afs.man.ac.uk>
      • [JAY]
        */
        static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
        DWORD width, DWORD dstwidth,
        int left, int *colors,
        XImage *bmpImage )
        {
        int x; /* X-positon on each line. Increases. */
        int y; /* Line #. Starts at lines-1, decreases */
        const BYTE pIn = bits; / Pointer to current position in bits */
        BYTE length; /* The length pf a run */
        BYTE escape_code; /* See enum Rle8_EscapeCodes.*/

      /*

      • Note that the bitmap data is stored by Windows starting at the
      • bottom line of the bitmap and going upwards. Within each line,
      • the data is stored left-to-right. That's the reason why line
      • goes from lines-1 to 0. [JAY]
        */

      x = 0;
      y = lines - 1;
      while (y >= 0)
      {
      length = *pIn++;

      /*

      • If the length byte is not zero (which is the escape value),
      • We have a run of length pixels all the same colour. The colour
      • index is stored next.
        *
      • If the length byte is zero, we need to read the next byte to
      • know what to do. [JAY]
        */
        if (length != 0) { /* * [Run-Length] Encoded mode */ int color = colors[*pIn++]; while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color); }

        else
        {
        /*

      • Escape codes (may be an absolute sequence though)
        */
        escape_code = (*pIn++);
        switch(escape_code)
        {
        case RLE_EOL:
        x = 0;
        y--;
        break;

      case RLE_END:
      /* Not all RLE8 bitmaps end with this code. For

      • example, Paint Shop Pro produces some that don't.
      • That's (I think) what caused the previous
      • implementation to fail. [JAY]
        */
        return;

      case RLE_DELTA:
      x = (*pIn+);
      y -= (*pIn++);
      break;

      default: /* switch to absolute mode */
      length = escape_code;
      while (length--)
      {
      int color = colors[*pIn++];
      if (x >= dstwidth)

      { pIn += length; break; }

      XPutPixel(bmpImage, x++, y, color);
      }
      /*

      • If you think for a moment you'll realise that the
      • only time we could ever possibly read an odd
      • number of bytes is when there is a 0x00 (escape),
      • a value >0x02 (absolute mode) and then an odd-
      • length run. Therefore this is the only place we
      • need to worry about it. Everywhere else the
      • bytes are always read in pairs. [JAY]
        */
        if (escape_code & 1) pIn++; /* Throw away the pad byte. */
        break;
        } /* switch (escape_code) : Escape sequence */
        }
        }
        }

      Attachments

        Activity

          People

            bug zilla Bug Zilla
            sedwards sedwards
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: