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