1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: RLE compression
5 * FILE: win32ss/gdi/eng/rlecomp.c
6 * PROGRAMER: Jason Filby
7 */
8
9 #include <win32k.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 enum Rle_EscapeCodes
15 {
16 RLE_EOL = 0, /* End of line */
17 RLE_END = 1, /* End of bitmap */
18 RLE_DELTA = 2 /* Delta */
19 };
20
DecompressBitmap(SIZEL Size,BYTE * CompressedBits,BYTE * UncompressedBits,LONG Delta,ULONG Format,ULONG cjSizeImage)21 VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits,
22 LONG Delta, ULONG Format, ULONG cjSizeImage)
23 {
24 INT x = 0, y = Size.cy - 1;
25 INT i, c, c2, length;
26 INT width = Size.cx, height = y;
27 BYTE *begin = CompressedBits;
28 BYTE *bits = CompressedBits;
29 BYTE *temp;
30 BOOL is4bpp = FALSE;
31
32 if ((Format == BMF_4RLE) || (Format == BMF_4BPP))
33 is4bpp = TRUE;
34 else if ((Format != BMF_8RLE) && (Format != BMF_8BPP))
35 return;
36
37 _SEH2_TRY
38 {
39 while (y >= 0 && (bits - begin) <= cjSizeImage)
40 {
41 length = *bits++;
42 if (length)
43 {
44 c = *bits++;
45 for (i = 0; i < length; i++)
46 {
47 if (x >= width) break;
48 temp = UncompressedBits + (height - y) * Delta;
49 if (is4bpp)
50 {
51 temp += x / 2;
52 if (i & 1)
53 c2 = c & 0x0F;
54 else
55 c2 = c >> 4;
56 if (x & 1)
57 *temp |= c2;
58 else
59 *temp |= c2 << 4;
60 }
61 else
62 {
63 temp += x;
64 *temp = c;
65 }
66 x++;
67 }
68 }
69 else
70 {
71 length = *bits++;
72 switch (length)
73 {
74 case RLE_EOL:
75 x = 0;
76 y--;
77 break;
78 case RLE_END:
79 _SEH2_YIELD(return);
80 case RLE_DELTA:
81 x += *bits++;
82 y -= *bits++;
83 break;
84 default:
85 for (i = 0; i < length; i++)
86 {
87 if (!(is4bpp && i & 1))
88 c = *bits++;
89
90 if (x < width)
91 {
92 temp = UncompressedBits + (height - y) * Delta;
93 if (is4bpp)
94 {
95 temp += x / 2;
96 if (i & 1)
97 c2 = c & 0x0F;
98 else
99 c2 = c >> 4;
100 if (x & 1)
101 *temp |= c2;
102 else
103 *temp |= c2 << 4;
104 }
105 else
106 {
107 temp += x;
108 *temp = c;
109 }
110 x++;
111 }
112 }
113 if ((bits - begin) & 1)
114 {
115 bits++;
116 }
117 }
118 }
119 }
120 }
121 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
122 {
123 DPRINT1("Decoding error\n");
124 }
125 _SEH2_END;
126
127 return;
128 }
129