xref: /reactos/win32ss/gdi/eng/rlecomp.c (revision c3483339)
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 
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