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